diff --git a/3rd party/Procyuon avrlib/a2d.c b/3rd party/Procyuon avrlib/a2d.c new file mode 100644 index 0000000..d974c00 --- /dev/null +++ b/3rd party/Procyuon avrlib/a2d.c @@ -0,0 +1,115 @@ +/*! \file a2d.c \brief Analog-to-Digital converter function library. */ +//***************************************************************************** +// +// File Name : 'a2d.c' +// Title : Analog-to-digital converter functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002-04-08 +// Revised : 2002-09-30 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "a2d.h" + +// global variables + +//! Software flag used to indicate when +/// the a2d conversion is complete. +volatile unsigned char a2dCompleteFlag; + +// functions + +// initialize a2d converter +void a2dInit(void) +{ + sbi(ADCSR, ADEN); // enable ADC (turn on ADC power) + cbi(ADCSR, ADFR); // default to single sample convert mode + a2dSetPrescaler(ADC_PRESCALE); // set default prescaler + a2dSetReference(ADC_REFERENCE); // set default reference + cbi(ADMUX, ADLAR); // set to right-adjusted result + + sbi(ADCSR, ADIE); // enable ADC interrupts + + a2dCompleteFlag = FALSE; // clear conversion complete flag + sei(); // turn on interrupts (if not already on) +} + +// turn off a2d converter +void a2dOff(void) +{ + cbi(ADCSR, ADIE); // disable ADC interrupts + cbi(ADCSR, ADEN); // disable ADC (turn off ADC power) +} + +// configure A2D converter clock division (prescaling) +void a2dSetPrescaler(unsigned char prescale) +{ + outb(ADCSR, ((inb(ADCSR) & ~ADC_PRESCALE_MASK) | prescale)); +} + +// configure A2D converter voltage reference +void a2dSetReference(unsigned char ref) +{ + outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6))); +} + +// sets the a2d input channel +void a2dSetChannel(unsigned char ch) +{ + outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel +} + +// start a conversion on the current a2d input channel +void a2dStartConvert(void) +{ + sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag + sbi(ADCSR, ADSC); // start conversion +} + +// return TRUE if conversion is complete +u08 a2dIsComplete(void) +{ + return bit_is_set(ADCSR, ADSC); +} + +// Perform a 10-bit conversion +// starts conversion, waits until conversion is done, and returns result +unsigned short a2dConvert10bit(unsigned char ch) +{ + a2dCompleteFlag = FALSE; // clear conversion complete flag + outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel + sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag + sbi(ADCSR, ADSC); // start conversion + //while(!a2dCompleteFlag); // wait until conversion complete + //while( bit_is_clear(ADCSR, ADIF) ); // wait until conversion complete + while( bit_is_set(ADCSR, ADSC) ); // wait until conversion complete + + // CAUTION: MUST READ ADCL BEFORE ADCH!!! + return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits); +} + +// Perform a 8-bit conversion. +// starts conversion, waits until conversion is done, and returns result +unsigned char a2dConvert8bit(unsigned char ch) +{ + // do 10-bit conversion and return highest 8 bits + return a2dConvert10bit(ch)>>2; // return ADC MSB byte +} + +//! Interrupt handler for ADC complete interrupt. +SIGNAL(SIG_ADC) +{ + // set the a2d conversion flag to indicate "complete" + a2dCompleteFlag = TRUE; +} + diff --git a/3rd party/Procyuon avrlib/a2d.h b/3rd party/Procyuon avrlib/a2d.h new file mode 100644 index 0000000..e81103d --- /dev/null +++ b/3rd party/Procyuon avrlib/a2d.h @@ -0,0 +1,151 @@ +/*! \file a2d.h \brief Analog-to-Digital converter function library. */ +//***************************************************************************** +// +// File Name : 'a2d.h' +// Title : Analog-to-digital converter functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 4/08/2002 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_avr +/// \defgroup a2d A/D Converter Function Library (a2d.c) +/// \code #include "a2d.h" \endcode +/// \par Overview +/// This library provides an easy interface to the analog-to-digital +/// converter available on many AVR processors. Updated to support +/// the ATmega128. +// +//**************************************************************************** +//@{ + +#ifndef A2D_H +#define A2D_H + +// defines + +// A2D clock prescaler select +// *selects how much the CPU clock frequency is divided +// to create the A2D clock frequency +// *lower division ratios make conversion go faster +// *higher division ratios make conversions more accurate +#define ADC_PRESCALE_DIV2 0x00 ///< 0x01,0x00 -> CPU clk/2 +#define ADC_PRESCALE_DIV4 0x02 ///< 0x02 -> CPU clk/4 +#define ADC_PRESCALE_DIV8 0x03 ///< 0x03 -> CPU clk/8 +#define ADC_PRESCALE_DIV16 0x04 ///< 0x04 -> CPU clk/16 +#define ADC_PRESCALE_DIV32 0x05 ///< 0x05 -> CPU clk/32 +#define ADC_PRESCALE_DIV64 0x06 ///< 0x06 -> CPU clk/64 +#define ADC_PRESCALE_DIV128 0x07 ///< 0x07 -> CPU clk/128 +// default value +#define ADC_PRESCALE ADC_PRESCALE_DIV64 +// do not change the mask value +#define ADC_PRESCALE_MASK 0x07 + +// A2D voltage reference select +// *this determines what is used as the +// full-scale voltage point for A2D conversions +#define ADC_REFERENCE_AREF 0x00 ///< 0x00 -> AREF pin, internal VREF turned off +#define ADC_REFERENCE_AVCC 0x01 ///< 0x01 -> AVCC pin, internal VREF turned off +#define ADC_REFERENCE_RSVD 0x02 ///< 0x02 -> Reserved +#define ADC_REFERENCE_256V 0x03 ///< 0x03 -> Internal 2.56V VREF +// default value +#define ADC_REFERENCE ADC_REFERENCE_AVCC +// do not change the mask value +#define ADC_REFERENCE_MASK 0xC0 + +// bit mask for A2D channel multiplexer +#define ADC_MUX_MASK 0x1F + +// channel defines (for reference and use in code) +// these channels supported by all AVRs with A2D +#define ADC_CH_ADC0 0x00 +#define ADC_CH_ADC1 0x01 +#define ADC_CH_ADC2 0x02 +#define ADC_CH_ADC3 0x03 +#define ADC_CH_ADC4 0x04 +#define ADC_CH_ADC5 0x05 +#define ADC_CH_ADC6 0x06 +#define ADC_CH_ADC7 0x07 +#define ADC_CH_122V 0x1E ///< 1.22V voltage reference +#define ADC_CH_AGND 0x1F ///< AGND +// these channels supported only in ATmega128 +// differential with gain +#define ADC_CH_0_0_DIFF10X 0x08 +#define ADC_CH_1_0_DIFF10X 0x09 +#define ADC_CH_0_0_DIFF200X 0x0A +#define ADC_CH_1_0_DIFF200X 0x0B +#define ADC_CH_2_2_DIFF10X 0x0C +#define ADC_CH_3_2_DIFF10X 0x0D +#define ADC_CH_2_2_DIFF200X 0x0E +#define ADC_CH_3_2_DIFF200X 0x0F +// differential +#define ADC_CH_0_1_DIFF1X 0x10 +#define ADC_CH_1_1_DIFF1X 0x11 +#define ADC_CH_2_1_DIFF1X 0x12 +#define ADC_CH_3_1_DIFF1X 0x13 +#define ADC_CH_4_1_DIFF1X 0x14 +#define ADC_CH_5_1_DIFF1X 0x15 +#define ADC_CH_6_1_DIFF1X 0x16 +#define ADC_CH_7_1_DIFF1X 0x17 + +#define ADC_CH_0_2_DIFF1X 0x18 +#define ADC_CH_1_2_DIFF1X 0x19 +#define ADC_CH_2_2_DIFF1X 0x1A +#define ADC_CH_3_2_DIFF1X 0x1B +#define ADC_CH_4_2_DIFF1X 0x1C +#define ADC_CH_5_2_DIFF1X 0x1D + +// compatibility for new Mega processors +// ADCSR hack apparently no longer necessary in new AVR-GCC +#ifdef ADCSRA +#ifndef ADCSR + #define ADCSR ADCSRA +#endif +#endif +#ifdef ADATE + #define ADFR ADATE +#endif + +// function prototypes + +//! Initializes the A/D converter. +/// Turns ADC on and prepares it for use. +void a2dInit(void); + +//! Turn off A/D converter +void a2dOff(void); + +//! Sets the division ratio of the A/D converter clock. +/// This function is automatically called from a2dInit() +/// with a default value. +void a2dSetPrescaler(unsigned char prescale); + +//! Configures which voltage reference the A/D converter uses. +/// This function is automatically called from a2dInit() +/// with a default value. +void a2dSetReference(unsigned char ref); + +//! sets the a2d input channel +void a2dSetChannel(unsigned char ch); + +//! start a conversion on the current a2d input channel +void a2dStartConvert(void); + +//! return TRUE if conversion is complete +u08 a2dIsComplete(void); + +//! Starts a conversion on A/D channel# ch, +/// returns the 10-bit value of the conversion when it is finished. +unsigned short a2dConvert10bit(unsigned char ch); + +//! Starts a conversion on A/D channel# ch, +/// returns the 8-bit value of the conversion when it is finished. +unsigned char a2dConvert8bit(unsigned char ch); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/ads7828.c b/3rd party/Procyuon avrlib/ads7828.c new file mode 100644 index 0000000..7d12e1e --- /dev/null +++ b/3rd party/Procyuon avrlib/ads7828.c @@ -0,0 +1,92 @@ +/*! \file ads7828.c \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7828.c' +// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "i2c.h" +#include "ads7828.h" + +// global variables +u08 Ads7282RefMode; + +// Functions +u08 ads7828Init(u08 i2cAddr) +{ + u08 channel = 0x80; + + // setup default A/D voltage reference + ads7828SetReference(0); + + // issue a convserion to test chip presence + // return TRUE if chip detected + // return FALSE if chip does not respond + return (i2cMasterSendNI(i2cAddr, 1, &channel) == I2C_OK); +} + +u16 ads7828Convert(u08 i2cAddr, u08 channel) +{ + // re-order channel bits for + // logical single-ended channel selection + // channel bit0 -> C2 + // channel bit1 -> C0 + // channel bit2 -> C1 + channel = (((channel>>1) | (channel&0x01)<<2)<<4) | ADS7828_CMD_SD; + // do conversion + return ads7828ConvertRaw(i2cAddr, channel); +} + +u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel) +{ + // clear single-ended channel bit + channel = (channel&0x07)<<4; + // do conversion + return ads7828ConvertRaw(i2cAddr, channel); +} + +u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel) +{ + u08 buffer[2]; + // combine raw channel and reference bits + channel &= 0xF0; + channel |= Ads7282RefMode; + // start conversion on requested channel + i2cMasterSendNI(i2cAddr, 1, &channel); + // retrieve conversion result + i2cMasterReceiveNI(i2cAddr, 2, buffer); + // pack bytes and return result + return ((buffer[0]<<8) | buffer[1]); +} + +void ads7828SetReference(u08 ref) +{ + if(ref) + { + // use internal reference + Ads7282RefMode = ADS7828_CMD_PDMODE2; + } + else + { + // use external reference + Ads7282RefMode = ADS7828_CMD_PDMODE0; + } +} diff --git a/3rd party/Procyuon avrlib/ads7828.h b/3rd party/Procyuon avrlib/ads7828.h new file mode 100644 index 0000000..cdf4319 --- /dev/null +++ b/3rd party/Procyuon avrlib/ads7828.h @@ -0,0 +1,91 @@ +/*! \file ads7828.h \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7828.h' +// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_hw +/// \defgroup ads7828 TI ADS7828 I2C A/D Converter Driver (ads7828.c) +/// \code #include "ads7828.h" \endcode +/// \par Overview +/// This library provides high-level functions for accessing the Texas +/// Instruments ADS7828 I2C A/D Converter. +/// +/// The basic specs of the ADS7828 are: +/// - 12-bit results +/// - 8 input channels +/// - up to 50KHz conversion rate +/// - External reference or internal 2.5V reference +// +//***************************************************************************** +//@{ + +#ifndef ADS7828_H +#define ADS7828_H + +#include "global.h" + +// constants/macros/typdefs +#define ADS7828_I2C_ADDR 0x90 ///< Base I2C address of ADS7828 devices + +// command register bit defines +#define ADS7828_CMD_PD0 0x04 ///< ADS7828 Power-down bit 0 +#define ADS7828_CMD_PD1 0x08 ///< ADS7828 Power-down bit 1 +#define ADS7828_CMD_C0 0x10 ///< ADS7828 Channel Select bit 0 +#define ADS7828_CMD_C1 0x20 ///< ADS7828 Channel Select bit 1 +#define ADS7828_CMD_C2 0x40 ///< ADS7828 Channel Select bit 2 +#define ADS7828_CMD_SD 0x80 ///< ADS7828 Single-ended/Differential Select bit + +// single-ended channel order defines +#define ADS7828_CMD_CH0 0x00 ///< ADS7828 Convert Channel 0 +#define ADS7828_CMD_CH1 0x04 ///< ADS7828 Convert Channel 1 +#define ADS7828_CMD_CH2 0x01 ///< ADS7828 Convert Channel 2 +#define ADS7828_CMD_CH3 0x05 ///< ADS7828 Convert Channel 3 +#define ADS7828_CMD_CH4 0x02 ///< ADS7828 Convert Channel 4 +#define ADS7828_CMD_CH5 0x06 ///< ADS7828 Convert Channel 5 +#define ADS7828_CMD_CH6 0x03 ///< ADS7828 Convert Channel 6 +#define ADS7828_CMD_CH7 0x07 ///< ADS7828 Convert Channel 7 + +// power-down mode defines +#define ADS7828_CMD_PDMODE0 0x00 ///< ADS7828 Power-down Mode 0 +#define ADS7828_CMD_PDMODE1 0x04 ///< ADS7828 Power-down Mode 1 +#define ADS7828_CMD_PDMODE2 0x08 ///< ADS7828 Power-down Mode 2 +#define ADS7828_CMD_PDMODE3 0x0C ///< ADS7828 Power-down Mode 3 + +// functions + +//! Initialize the ADS7828 chip. +/// Returns: +/// TRUE if successful, +/// FALSE if unsuccessful (chip not present). +u08 ads7828Init(u08 i2cAddr); + +//! Set the voltage reference to use for A/D conversion. +/// - ref = 0 => External reference voltage on Ref pin. +/// - ref = 1 => Internal 2.5V reference voltage (Ref pin left open). +void ads7828SetReference(u08 ref); + +//! Begin single-ended conversion on given logical channel#, and return result. +u16 ads7828Convert(u08 i2cAddr, u08 channel); + +//! Begin differential conversion on given channel pair, and return result. +u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel); + +//! Begin conversion on given raw channel#, and return result. +u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/ads7870.c b/3rd party/Procyuon avrlib/ads7870.c new file mode 100644 index 0000000..beb632a --- /dev/null +++ b/3rd party/Procyuon avrlib/ads7870.c @@ -0,0 +1,119 @@ +/*! \file ads7870.c \brief TI ADS7870 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7870.c' +// Title : TI ADS7870 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2005 +// Created : 2005.07.19 +// Revised : 2005.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "spi.h" +#include "ads7870.h" + +// global variables + +// Functions +u08 ads7870Init(void) +{ + // initialize spi interface + spiInit(); + // switch to f/4 bitrate + cbi(SPCR, SPR0); + cbi(SPCR, SPR1); + //sbi(SPSR, SPI2X); + + // setup chip select + sbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + sbi(ADS7870_CS_DDR, ADS7870_CS_PIN); + + // check ID register + if(ads7870ReadReg(ADS7870_ID) != ADS7870_ID_VALUE) + return 0; + + // setup reference and buffer + ads7870WriteReg(ADS7870_REFOSC, ADS7870_REFOSC_OSCE | ADS7870_REFOSC_REFE | ADS7870_REFOSC_BUFE); + + // return success + return 1; +} + +s16 ads7870Convert(u08 channel) +{ + // set single-ended channel bit + channel |= ADS7870_CH_SINGLE_ENDED; + // do conversion + return ads7870ConvertRaw(channel); +} + +s16 ads7870ConvertDiff(u08 channel) +{ + // clear single-ended channel bit + channel &= ~ADS7870_CH_SINGLE_ENDED; + // do conversion + return ads7870ConvertRaw(channel); +} + +s16 ads7870ConvertRaw(u08 channel) +{ + s16 result; + // assert chip select + cbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // start conversion + spiTransferByte(ADS7870_CONVERT | channel); + // wait for completion + while( ads7870ReadReg(ADS7870_GAINMUX) & ADS7870_GAINMUX_CNVBSY); + // assert chip select + cbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // read result + spiTransferByte(ADS7870_REG_READ | ADS7870_REG_16BIT | ADS7870_RESULTHI); + result = spiTransferByte(0x00)<<8; + result |= spiTransferByte(0x00); + // release chip select + sbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // return result + return result; +} + +u08 ads7870ReadReg(u08 reg) +{ + u08 data; + // assert chip select + cbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // issue reg read command + spiTransferByte(ADS7870_REG_READ | reg); + // read data + data = spiTransferByte(0x00); + // release chip select + sbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // return data + return data; +} + +void ads7870WriteReg(u08 reg, u08 value) +{ + // assert chip select + cbi(ADS7870_CS_PORT, ADS7870_CS_PIN); + // issue reg write command + spiTransferByte(ADS7870_REG_WRITE | reg); + // write data + spiTransferByte(value); + // release chip select + sbi(ADS7870_CS_PORT, ADS7870_CS_PIN); +} + diff --git a/3rd party/Procyuon avrlib/ads7870.h b/3rd party/Procyuon avrlib/ads7870.h new file mode 100644 index 0000000..bc08fe8 --- /dev/null +++ b/3rd party/Procyuon avrlib/ads7870.h @@ -0,0 +1,153 @@ +/*! \file ads7870.h \brief TI ADS7870 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7870.h' +// Title : TI ADS7870 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2005 +// Created : 2005.07.19 +// Revised : 2005.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_hw +/// \defgroup ads7870 TI ADS7870 SPI A/D Converter Driver (ads7870.c) +/// \code #include "ads7870.h" \endcode +/// \par Overview +/// This library provides high-level functions for accessing the Texas +/// Instruments ADS7870 I2C A/D Converter. +/// +/// The basic specs of the ADS7870 are: +/// - Fast SPI interface (up to 20MHz) +/// - 12-bit results +/// - 8 single-ended or 4 differential input channels +/// - Programmable gain stage (1,2,4,5,8,10,16,20x gains) +/// - Software or hardware triggered conversion +/// - 4-bit auxiliary digital I/O lines (controlled via serial interface) +/// - Up to 50KHz conversion rate +/// - External reference or internal 2.5V, 2.048V, 1.15V reference +/// - NOTE: use pin-compatible ADS7871 for 14-bit results +// +//***************************************************************************** +//@{ + +#ifndef ADS7870_H +#define ADS7870_H + +#include "global.h" + +// constants/macros/typdefs +#define ADS7870_CS_PORT PORTB +#define ADS7870_CS_DDR DDRB +#define ADS7870_CS_PIN PB0 + +// instruction bit defines +#define ADS7870_CONVERT 0x80 + +#define ADS7870_REG_READ 0x40 +#define ADS7870_REG_WRITE 0x00 +#define ADS7870_REG_16BIT 0x20 + +// register addresses +#define ADS7870_RESULTLO 0x00 +#define ADS7870_RESULTHI 0x01 +#define ADS7870_PGAVALID 0x02 +#define ADS7870_ADCTRL 0x03 +#define ADS7870_GAINMUX 0x04 +#define ADS7870_DIGIOSTATE 0x05 +#define ADS7870_DIGIOCTRL 0x06 +#define ADS7870_REFOSC 0x07 +#define ADS7870_SERIFCTRL 0x18 +#define ADS7870_ID 0x1F + +// register bit defines +#define ADS7870_RESULTLO_OVR 0x01 + +#define ADS7870_ADCTRL_BIN 0x20 +#define ADS7870_ADCTRL_RMB1 0x08 +#define ADS7870_ADCTRL_RMB0 0x04 +#define ADS7870_ADCTRL_CFD1 0x02 +#define ADS7870_ADCTRL_CFD0 0x01 + +#define ADS7870_GAINMUX_CNVBSY 0x80 + +#define ADS7870_REFOSC_OSCR 0x20 +#define ADS7870_REFOSC_OSCE 0x10 +#define ADS7870_REFOSC_REFE 0x08 +#define ADS7870_REFOSC_BUFE 0x04 +#define ADS7870_REFOSC_R2V 0x02 +#define ADS7870_REFOSC_RBG 0x01 + +#define ADS7870_SERIFCTRL_LSB 0x01 +#define ADS7870_SERIFCTRL_2W3W 0x02 +#define ADS7870_SERIFCTRL_8051 0x04 + +#define ADS7870_ID_VALUE 0x01 + +// gain defines +#define ADS7870_GAIN_1X 0x00 +#define ADS7870_GAIN_2X 0x10 +#define ADS7870_GAIN_4X 0x20 +#define ADS7870_GAIN_5X 0x30 +#define ADS7870_GAIN_8X 0x40 +#define ADS7870_GAIN_10X 0x50 +#define ADS7870_GAIN_16X 0x60 +#define ADS7870_GAIN_20X 0x70 +// channel defines +#define ADS7870_CH_0_1_DIFF 0x00 +#define ADS7870_CH_2_3_DIFF 0x01 +#define ADS7870_CH_4_5_DIFF 0x02 +#define ADS7870_CH_6_7_DIFF 0x03 +#define ADS7870_CH_1_0_DIFF 0x04 +#define ADS7870_CH_3_2_DIFF 0x05 +#define ADS7870_CH_5_4_DIFF 0x06 +#define ADS7870_CH_7_6_DIFF 0x07 +#define ADS7870_CH_SINGLE_ENDED 0x08 +#define ADS7870_CH_0 0x08 +#define ADS7870_CH_1 0x09 +#define ADS7870_CH_2 0x0A +#define ADS7870_CH_3 0x0B +#define ADS7870_CH_4 0x0C +#define ADS7870_CH_5 0x0D +#define ADS7870_CH_6 0x0E +#define ADS7870_CH_7 0x0F + +// functions + +//! Initialize the ADS7870 chip. +/// Returns: +/// TRUE if successful, +/// FALSE if unsuccessful (chip not responding). +u08 ads7870Init(void); + +//! Begin single-ended conversion on given logical channel#0-7, and return result. +/// \note Result is returned left-justified. +s16 ads7870Convert(u08 channel); + +//! Begin differential conversion on given channel pair, and return result. +/// \note Result is returned left-justified. +s16 ads7870ConvertDiff(u08 channel); + +//! Begin conversion on given raw channel#, and return result. +/// \note Result is returned left-justified. +s16 ads7870ConvertRaw(u08 channel); + +//! Read value from ADS7870 register. +/// +u08 ads7870ReadReg(u08 reg); + +//! Write value into ADS7870 register. +/// +void ads7870WriteReg(u08 reg, u08 value); + + + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/ata.c b/3rd party/Procyuon avrlib/ata.c new file mode 100644 index 0000000..3be48fc --- /dev/null +++ b/3rd party/Procyuon avrlib/ata.c @@ -0,0 +1,605 @@ +/*! \file ata.c \brief IDE-ATA hard disk interface driver. */ +//***************************************************************************** +// +// File Name : 'ata.c' +// Title : IDE-ATA interface driver for hard disks +// Author : Pascal Stang +// Date : 11/22/2000 +// Revised : 4/19/2003 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include +// #include +#endif +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "ata.h" + +//#define DEBUG_ATA 1 + +// global variables + +// drive information +typeDriveInfo ataDriveInfo; + + +void ataInit(void) +{ + +} + +void ataDriveInit(void) +{ + u08 i; + unsigned char* buffer = (unsigned char*) SECTOR_BUFFER_ADDR; + + // read drive identity + rprintfProgStrM("\r\nScanning IDE interface...\r\n"); + // Wait for drive to be ready + ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + // issue identify command + ataWriteByte(ATA_REG_CMDSTATUS1, 0xEC); + // wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, ATA_SR_DRQ); + timerPause(200); + // read in the data + ataReadDataBuffer(buffer, 512); + + // set local drive info parameters + ataDriveInfo.cylinders = *( ((unsigned int*) buffer) + ATA_IDENT_CYLINDERS ); + ataDriveInfo.heads = *( ((unsigned int*) buffer) + ATA_IDENT_HEADS ); + ataDriveInfo.sectors = *( ((unsigned int*) buffer) + ATA_IDENT_SECTORS ); + ataDriveInfo.LBAsupport = *( ((unsigned int*) buffer) + ATA_IDENT_FIELDVALID ); + ataDriveInfo.sizeinsectors = *( (unsigned long*) (buffer + ATA_IDENT_LBASECTORS*2) ); + // copy model string + for(i=0; i<40; i+=2) + { + // correct for byte order + ataDriveInfo.model[i ] = buffer[(ATA_IDENT_MODEL*2) + i + 1]; + ataDriveInfo.model[i+1] = buffer[(ATA_IDENT_MODEL*2) + i ]; + } + // terminate string + ataDriveInfo.model[40] = 0; + + // process and print info + if(ataDriveInfo.LBAsupport) + { + // LBA support + rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) ); + rprintf("LBA mode -- MODEL: "); + } + else + { + // CHS, no LBA support + // calculate drive size + ataDriveInfo.sizeinsectors = (unsigned long) ataDriveInfo.cylinders* + ataDriveInfo.heads*ataDriveInfo.sectors; + rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) ); + rprintf("CHS mode C=%d H=%d S=%d -- MODEL: ", ataDriveInfo.cylinders, ataDriveInfo.heads, ataDriveInfo.sectors ); + } + // print model information + rprintfStr(ataDriveInfo.model); rprintfCRLF(); + + // initialize local disk parameters + //ataDriveInfo.cylinders = ATA_DISKPARM_CLYS; + //ataDriveInfo.heads = ATA_DISKPARM_HEADS; + //ataDriveInfo.sectors = ATA_DISKPARM_SECTORS; + +} + +void ataDiskErr(void) +{ + unsigned char b; + + b = ataReadByte(ATA_REG_ERROR); + rprintfProgStrM("ATA Error: "); + rprintfu08(b); + rprintfCRLF(); +} + +void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout) +{ + // select drive + ataDriveSelect(DriveNo); + // Wait for drive to be ready + ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // set mode + switch(mode) + { + case ATA_DISKMODE_SPINDOWN: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINDOWN); break; + case ATA_DISKMODE_SPINUP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINUP); break; + case ATA_DISKMODE_SETTIMEOUT: + ataWriteByte(ATA_REG_SECCOUNT, timeout); + ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_IDLE_5SU); + break; + case ATA_DISKMODE_SLEEP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SLEEP); break; + default: + break; + } +} + +void ataPrintSector( u08 *Buffer) +{ + u08 i; + u16 j; + u08 *buf; + u08 s; + + buf = Buffer; + + // print the low order address indicies + rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n"); + rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n"); + + // print the data + for(j=0; j<0x20; j++) + { + // print the high order address index for this line + rprintfu16(j<<4); + rprintfProgStrM(" "); + + // print the hex data + for(i=0; i<0x10; i++) + { + rprintfu08(buf[(j<<4)+i]); + rprintfProgStrM(" "); + } + + // leave some space + rprintfProgStrM(" "); + + // print the ascii data + for(i=0; i<0x10; i++) + { + s = buf[(j<<4)+i]; + // make sure character is printable + if(s >= 0x20) + { + rprintfChar(s); + } + else + { + rprintfChar(0x20); + } + + } + rprintfCRLF(); + } +} + +void ataReadDataBuffer(u08 *Buffer, u16 numBytes) +{ + unsigned int i; + + //sbi(MCUCR, SRW); // enable RAM waitstate + + // read data from drive + for (i=0; i<(numBytes/16); i++) + { + // optimize by reading 16 bytes in-line before looping + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + } + //cbi(MCUCR, SRW); // disable RAM waitstate + +} + +void ataWriteDataBuffer(u08 *Buffer, u16 numBytes) +{ + register unsigned char temp; + unsigned int i; + + //sbi(MCUCR, SRW); // enable RAM waitstate + + // write data to drive + for (i=0; i<(numBytes/16); i++) + { + // optimize by writing 16 bytes in-line before looping + // keep byte order correct by using temp register + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + } + //cbi(MCUCR, SRW); // disable RAM waitstate + +} + +u08 ataStatusWait(u08 mask, u08 waitStatus) +{ + register u08 status; + + delay(100); + + // wait for desired status + while( ((status = ataReadByte(ATA_REG_CMDSTATUS1)) & mask) == waitStatus ); + + return status; +} + + +unsigned char ataReadSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned char temp; + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // Prepare parameters... + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head + ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track + ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track + ataWriteByte(ATA_REG_STARTSEC, Sector); // sector + ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors + + // Issue read sector command... + ataWriteByte(ATA_REG_CMDSTATUS1, 0x21); + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + if (temp & ATA_SR_ERR) + { + rprintfProgStrM("RD ERR\r\n"); + return 1; + } + + // Wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, 0); + + // read data from drive + ataReadDataBuffer(Buffer, 512*numsectors); + + // Return the error bit from the status register... + temp = ataReadByte(ATA_REG_CMDSTATUS1); // read status register + + return (temp & ATA_SR_ERR) ? 1:0; +} + + +unsigned char ataWriteSectorsCHS(unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned char temp; + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // Prepare parameters... + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head + ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track + ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track + ataWriteByte(ATA_REG_STARTSEC, Sector); // sector + ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors + + // Issue write sector command + ataWriteByte(ATA_REG_CMDSTATUS1, 0x31); + + //delay(100); + + // Wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, 0); + + // write data to drive + ataWriteDataBuffer(Buffer, 512*numsectors); + + // Wait for drive to finish write + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // check for errors + if (temp & ATA_SR_ERR) + { + rprintfProgStrM("WR ERR\r\n"); + return 1; + } + + // Return the error bit from the status register... + return (temp & ATA_SR_ERR) ? 1:0; +} + +unsigned char ataReadSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + +#ifdef DEBUG_ATA + rprintfProgStrM("ATA LBA read "); + rprintfu32(lba); rprintfProgStrM(" "); + rprintfu16(numsectors); rprintfProgStrM(" "); + rprintfu16((unsigned int)Buffer); + rprintfCRLF(); +#endif + + sect = (int) ( lba & 0x000000ffL ); + lba = lba >> 8; + cyl = (int) ( lba & 0x0000ffff ); + lba = lba >> 16; + head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA; + + temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + + if(temp) + ataDiskErr(); + return temp; +} + +unsigned char ataWriteSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + +#ifdef DEBUG_ATA + rprintfProgStrM("ATA LBA write "); + rprintfu32(lba); rprintfProgStrM(" "); + rprintfu16(numsectors); rprintfProgStrM(" "); + rprintfu16((unsigned int)Buffer); + rprintfCRLF(); +#endif + + sect = (int) ( lba & 0x000000ffL ); + lba = lba >> 8; + cyl = (int) ( lba & 0x0000ffff ); + lba = lba >> 16; + head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA; + + temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + + if(temp) + ataDiskErr(); + return temp; +} + + +unsigned char ataReadSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + + // check if drive supports native LBA mode + if(ataDriveInfo.LBAsupport) + { + // drive supports using native LBA + temp = ataReadSectorsLBA(Drive, lba, numsectors, Buffer); + } + else + { + // drive required CHS access + #ifdef DEBUG_ATA + // do this defore destroying lba + rprintfProgStrM("ATA LBA for CHS read: "); + rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" "); + #endif + + // convert LBA to pseudo CHS + // remember to offset the sector count by one + sect = (u08) (lba % ataDriveInfo.sectors)+1; + lba = lba / ataDriveInfo.sectors; + head = (u08) (lba % ataDriveInfo.heads); + lba = lba / ataDriveInfo.heads; + cyl = (u16) lba; + + #ifdef DEBUG_ATA + rprintfProgStrM("C:H:S="); + rprintfu16(cyl); rprintfProgStrM(":"); + rprintfu08(head); rprintfProgStrM(":"); + rprintfu08(sect); rprintfCRLF(); + #endif + + temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + } + + if(temp) + ataDiskErr(); + return temp; +} + + +unsigned char ataWriteSectors(unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + + // check if drive supports native LBA mode + if(ataDriveInfo.LBAsupport) + { + // drive supports using native LBA + temp = ataWriteSectorsLBA(Drive, lba, numsectors, Buffer); + } + else + { + // drive required CHS access + #ifdef DEBUG_ATA + // do this defore destroying lba + rprintfProgStrM("ATA LBA for CHS write: "); + rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" "); + #endif + + // convert LBA to pseudo CHS + // remember to offset the sector count by one + sect = (u08) (lba % ataDriveInfo.sectors)+1; + lba = lba / ataDriveInfo.sectors; + head = (u08) (lba % ataDriveInfo.heads); + lba = lba / ataDriveInfo.heads; + cyl = (u16) lba; + + #ifdef DEBUG_ATA + rprintfProgStrM("C:H:S="); + rprintfu16(cyl); rprintfProgStrM(":"); + rprintfu08(head); rprintfProgStrM(":"); + rprintfu08(sect); rprintfCRLF(); + #endif + + temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + } + + if(temp) + ataDiskErr(); + return temp; +} + +void ataDriveSelect(u08 DriveNo) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(DriveNo ? 0x10:00)); // Drive selection +} + +//---------------------------------------------------------------------------- +// Set drive mode (STANDBY, IDLE) +//---------------------------------------------------------------------------- +/*#define STANDBY 0 +#define IDLE 1 +#define SLEEP 2 +*/ + +/* +unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown) +{ + WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive + WriteBYTE(CMD, 2, (PwrDown ? 0x01:0x00)); // Enable automatic power down + switch (Mode) + { + case STANDBY: WriteBYTE(CMD,7, 0xE2); break; + case IDLE: WriteBYTE(CMD,7, 0xE3); break; + // NOTE: To recover from sleep, either issue a soft or hardware reset ! + // (But not on all drives, f.ex seagate ST3655A it's not nessecary to reset + // but only to go in Idle mode, But on a Conner CFA170A it's nessecary with + // a reset) + case SLEEP: WriteBYTE(CMD,7, 0xE6); break; + } + Timer10mSec=10000; + while ((ReadBYTE(CMD,7) & 0xC0)!=0x40 && Timer10mSec); // Wait for DRDY & NOT BUSY + if (Timer10mSec==0) return 0xFF; // or timeout + + // Return the error register... + return ReadBYTE(CMD, 1); +} + +*/ + +u08 ataReadByte(u08 reg) +{ + register u08 ret; + //sbi(MCUCR, SRW); // enable RAM waitstate + ret = *((volatile unsigned char*) ATA_REG_BASE + reg); + //cbi(MCUCR, SRW); // disable RAM waitstate + return ret; +} + +void ataWriteByte(u08 reg, u08 data) +{ + //sbi(MCUCR, SRW); // enable RAM waitstate + *((volatile unsigned char*) ATA_REG_BASE + reg) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +} + + +void ataShowRegisters(unsigned char DriveNo) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive + + rprintfProgStrM("R0: DATALOW = 0x"); rprintfu08(ataReadByte(ATA_REG_DATAL )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R1: ERROR = 0x"); rprintfu08(ataReadByte(ATA_REG_ERROR )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R2: SECT CNT = 0x"); rprintfu08(ataReadByte(ATA_REG_SECCOUNT)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R3: SECT NUM = 0x"); rprintfu08(ataReadByte(ATA_REG_STARTSEC)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R4: CYL LOW = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLLO )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R5: CYL HIGH = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLHI )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R6: HEAD/DEV = 0x"); rprintfu08(ataReadByte(ATA_REG_HDDEVSEL)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R7: CMD/STA = 0x"); rprintfu08(ataReadByte(ATA_REG_CMDSTATUS1)); rprintfProgStrM("\r\n"); +} + +unsigned char ataSWReset(void) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0x06); // SRST and nIEN bits + delay(10); // 10uS delay + ataWriteByte(ATA_REG_HDDEVSEL, 0x02); // nIEN bits + delay(10); // 10 uS delay + + while( (ataReadByte(ATA_REG_CMDSTATUS1) & 0xC0) != 0x40 ); // Wait for DRDY and not BSY + + return ataReadByte(ATA_REG_CMDSTATUS1) + ataReadByte(ATA_REG_ERROR); +} + +/* +unsigned char ATA_Idle(unsigned char Drive) +{ + + WriteBYTE(CMD, 6, 0xA0 + (Drive ? 0x10:0x00)); // Select drive + WriteBYTE(CMD,7, 0xE1); + + while ((ReadBYTE(CMD,7) & 0xC0)!=0x40); // Wait for DRDY & NOT BUSY + + // Return the error register... + return ReadBYTE(CMD, 1); +} +*/ diff --git a/3rd party/Procyuon avrlib/ata.h b/3rd party/Procyuon avrlib/ata.h new file mode 100644 index 0000000..59940cc --- /dev/null +++ b/3rd party/Procyuon avrlib/ata.h @@ -0,0 +1,196 @@ +/*! \file ata.h \brief IDE-ATA hard disk interface driver. */ +//***************************************************************************** +// +// File Name : 'ata.h' +// Title : IDE-ATA interface driver for hard disks +// Author : Pascal Stang +// Date : 11/22/2000 +// Revised : 12/29/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +/// \ingroup driver_hw +/// \defgroup ata IDE/ATA Interface Driver (ata.c) +/// \code #include "ata.h" \endcode +/// \par Overview +/// This library provides an interface from AVR processors to IDE/ATA +/// devices. Such devices can include hard disks, CF memory cards, and +/// PCMCIA disks and memory devices.  The library supports automatic drive +/// identification and sector-level reading and writing.  Some minimal +/// address decoding hardware is required to use this interface. For an +/// example of interface hardware, see the Procyon MP3 Player docs here: +/// http://hubbard.engr.scu.edu/embedded/procyonmp3/index.html. +/// Future revisions if this library may include a direct hardware-less +/// interface option. +/// +/// \note This code is quite old and in some level of disrepair. Nonetheless, +/// it works quite well. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef ATA_H +#define ATA_H + +#include "global.h" +#include "ataconf.h" + +// constants +#define DRIVE0 0 + +#define STANDBY 0 +#define SLEEP 1 +#define IDLE 2 + +// ATA status register bits +#define ATA_SR_BSY 0x80 +#define ATA_SR_DRDY 0x40 +#define ATA_SR_DF 0x20 +#define ATA_SR_DSC 0x10 +#define ATA_SR_DRQ 0x08 +#define ATA_SR_CORR 0x04 +#define ATA_SR_IDX 0x02 +#define ATA_SR_ERR 0x01 + +// ATA error register bits +#define ATA_ER_UNC 0x40 +#define ATA_ER_MC 0x20 +#define ATA_ER_IDNF 0x10 +#define ATA_ER_MCR 0x08 +#define ATA_ER_ABRT 0x04 +#define ATA_ER_TK0NF 0x02 +#define ATA_ER_AMNF 0x01 + +// ATA head register bits +#define ATA_HEAD_USE_LBA 0x40 +/* +// ATA registers +#define ATA_REG_BASE 0x8000 +#define ATA_REG_DATAL 0x00 +#define ATA_REG_ERROR 0x01 +#define ATA_REG_SECCOUNT 0x02 +#define ATA_REG_STARTSEC 0x03 +#define ATA_REG_CYLLO 0x04 +#define ATA_REG_CYLHI 0x05 +#define ATA_REG_HDDEVSEL 0x06 +#define ATA_REG_CMDSTATUS1 0x07 +#define ATA_REG_CMDSTATUS2 0x08 +#define ATA_REG_ACTSTATUS 0x09 + +#define ATA_REG_DATAH 0x10 +*/ +// ATA commands +#define ATA_CMD_READ 0x20 +#define ATA_CMD_READNR 0x21 +#define ATA_CMD_WRITE 0x30 +#define ATA_CMD_WRITENR 0x31 +#define ATA_CMD_IDENTIFY 0xEC +#define ATA_CMD_RECALIBRATE 0x10 +#define ATA_CMD_SPINDOWN 0xE0 // spin down disk immediately +#define ATA_CMD_SPINUP 0xE1 // spin up disk immediately +#define ATA_CMD_STANDBY_5SU 0xE2 // spin down disk and set auto-power-down timer (sectorcount*5sec) +#define ATA_CMD_IDLE_5SU 0xE3 // keep disk spinning and set auto-power-down timer (sectorcount*5sec) +#define ATA_CMD_SLEEP 0xE6 // sleep disk (wakeup only on HW or SW reset) +#define ATA_CMD_STANDBY_01SU 0xF2 // spin down disk and set auto-power-down timer (sectorcount*0.1sec) +#define ATA_CMD_IDLE_01SU 0xF3 // keep disk spinning and set auto-power-down timer (sectorcount*0.1sec) + + +// ATA CHS disk parameters (examples, now we autodetect) +#define ATA_DISKPARM_CLYS 0x03A6 // number of cylinders per platter +#define ATA_DISKPARM_HEADS 0x10 // number of heads (usable plater sides) +#define ATA_DISKPARM_SECTORS 0x11 // number of sectors per head per cylinder + +// ATA Identity fields +// all offsets refer to word offset (2 byte increments) +#define ATA_IDENT_DEVICETYPE 0 // specifies ATA/ATAPI, removable/non-removable +#define ATA_IDENT_CYLINDERS 1 // number of logical cylinders +#define ATA_IDENT_HEADS 3 // number of logical heads +#define ATA_IDENT_SECTORS 6 // number of sectors per track +#define ATA_IDENT_SERIAL 10 // drive model name (20 characters) +#define ATA_IDENT_MODEL 27 // drive model name (40 characters) +#define ATA_IDENT_FIELDVALID 53 // indicates field validity of higher words (bit0: words54-58, bit1: words 64-70) +#define ATA_IDENT_LBASECTORS 60 // number of sectors in LBA translation mode + +// drive mode defines (for ataSetDrivePowerMode() ) +#define ATA_DISKMODE_SPINDOWN 0 +#define ATA_DISKMODE_SPINUP 1 +#define ATA_DISKMODE_SETTIMEOUT 2 +#define ATA_DISKMODE_SLEEP 3 + +// typedefs +// drive info structure +typedef struct +{ + unsigned int cylinders; + unsigned char heads; + unsigned char sectors; + unsigned long sizeinsectors; + unsigned char LBAsupport; + char model[41]; +} typeDriveInfo; + + +// Prototypes +void ataInit(void); +void ataDriveInit(void); +void ataDriveSelect(u08 DriveNo); +void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout); +u08 ataReadByte(u08 reg); +void ataWriteByte(u08 reg, u08 data); +void ataShowRegisters(unsigned char DriveNo); +u08 ataSWReset(void); +void ataDiskErr(void); +void ataPrintSector( u08 *Buffer); +void ataReadDataBuffer(u08 *Buffer, u16 numBytes); +void ataWriteDataBuffer(u08 *Buffer, u16 numBytes); +u08 ataStatusWait(u08 mask, u08 waitStatus); + +// read and write routines for CHS based drives +unsigned char ataReadSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer); + +// read and write routines for LBA based drives +unsigned char ataReadSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +// generic read and write routines using LBA +// uses native or translated LBA addressing +// given autodetected drive type +unsigned char ataReadSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +//unsigned char IdentifyDrive(unsigned char DriveNo, unsigned char *Buffer, tdefDriveInfo *DriveInfo); +//unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown); +//unsigned char ATA_Idle(unsigned char Drive); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/avrlibdefs.h b/3rd party/Procyuon avrlib/avrlibdefs.h new file mode 100644 index 0000000..a8dea50 --- /dev/null +++ b/3rd party/Procyuon avrlib/avrlibdefs.h @@ -0,0 +1,83 @@ +/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ +//***************************************************************************** +// +// File Name : 'avrlibdefs.h' +// Title : AVRlib global defines and macros include file +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects, regardless of specific implementation. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef AVRLIBDEFS_H +#define AVRLIBDEFS_H + +// Code compatibility to new AVR-libc +// outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli() +#ifndef outb + #define outb(addr, data) addr = (data) +#endif +#ifndef inb + #define inb(addr) (addr) +#endif +#ifndef outw + #define outw(addr, data) addr = (data) +#endif +#ifndef inw + #define inw(addr) (addr) +#endif +#ifndef BV + #define BV(bit) (1<<(bit)) +#endif +#ifndef cbi + #define cbi(reg,bit) reg &= ~(BV(bit)) +#endif +#ifndef sbi + #define sbi(reg,bit) reg |= (BV(bit)) +#endif +#ifndef cli + #define cli() __asm__ __volatile__ ("cli" ::) +#endif +#ifndef sei + #define sei() __asm__ __volatile__ ("sei" ::) +#endif + +// support for individual port pin naming in the mega128 +// see port128.h for details +#ifdef __AVR_ATmega128__ +// not currently necessary due to inclusion +// of these defines in newest AVR-GCC +// do a quick test to see if include is needed +#ifndef PD0 + #include "port128.h" +#endif +#endif + +// use this for packed structures +// (this is seldom necessary on an 8-bit architecture like AVR, +// but can assist in code portability to AVR) +#define GNUC_PACKED __attribute__((packed)) + +// port address helpers +#define DDR(x) ((x)-1) // address of data direction register of port x +#define PIN(x) ((x)-2) // address of input register of port x + +// MIN/MAX/ABS macros +#define MIN(a,b) ((ab)?(a):(b)) +#define ABS(x) ((x>0)?(x):(-x)) + +// constants +#define PI 3.14159265359 + +#endif diff --git a/3rd party/Procyuon avrlib/avrlibtypes.h b/3rd party/Procyuon avrlib/avrlibtypes.h new file mode 100644 index 0000000..4d44ac5 --- /dev/null +++ b/3rd party/Procyuon avrlib/avrlibtypes.h @@ -0,0 +1,84 @@ +/*! \file avrlibtypes.h \brief AVRlib global types and typedefines. */ +//***************************************************************************** +// +// File Name : 'avrlibtypes.h' +// Title : AVRlib global types and typedefines include file +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : Type-defines required and used by AVRlib. Most types are also +// generally useful. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef AVRLIBTYPES_H +#define AVRLIBTYPES_H + +#ifndef WIN32 + // true/false defines + #define FALSE 0 + #define TRUE -1 +#endif + +// datatype definitions macros +typedef unsigned char u08; +typedef signed char s08; +typedef unsigned short u16; +typedef signed short s16; +typedef unsigned long u32; +typedef signed long s32; +typedef unsigned long long u64; +typedef signed long long s64; + +/* use inttypes.h instead +// C99 standard integer type definitions +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +typedef unsigned long uint32_t; +typedef signed long int32_t; +typedef unsigned long uint64_t; +typedef signed long int64_t; +*/ +// maximum value that can be held +// by unsigned data types (8,16,32bits) +#define MAX_U08 255 +#define MAX_U16 65535 +#define MAX_U32 4294967295 + +// maximum values that can be held +// by signed data types (8,16,32bits) +#define MIN_S08 -128 +#define MAX_S08 127 +#define MIN_S16 -32768 +#define MAX_S16 32767 +#define MIN_S32 -2147483648 +#define MAX_S32 2147483647 + +#ifndef WIN32 + // more type redefinitions + typedef unsigned char BOOL; + typedef unsigned char BYTE; + typedef unsigned int WORD; + typedef unsigned long DWORD; + + typedef unsigned char UCHAR; + typedef unsigned int UINT; + typedef unsigned short USHORT; + typedef unsigned long ULONG; + + typedef char CHAR; + typedef int INT; + typedef long LONG; +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/bitbuf.c b/3rd party/Procyuon avrlib/bitbuf.c new file mode 100644 index 0000000..aeb84eb --- /dev/null +++ b/3rd party/Procyuon avrlib/bitbuf.c @@ -0,0 +1,131 @@ +/*! \file bitbuf.c \brief Multipurpose bit buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'bitbuf.c' +// Title : Multipurpose bit buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/10/2002 +// Revised : 7/10/2002 +// Version : 0.5 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "bitbuf.h" + +// global variables + +//! Initialize the bit buffer +// sets the start location and size of the buffer in memory +void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize) +{ + // set start pointer of the buffer + bitBuffer->dataptr = start; + bitBuffer->size = bytesize; + // initialize indexing and length + bitBuffer->dataindex = 0; + bitbufFlush(bitBuffer); +} + +// access routines + +//! Get a bit from the current position in the buffer +// returns the bit at the current position in the buffer +// and increments the bit position +unsigned char bitbufGet(BitBuf* bitBuffer) +{ + unsigned char byte; + unsigned char bit; + + // get current working byte + byte = bitBuffer->dataptr[bitBuffer->bytePos]; + // read data bit + bit = (byte & (1<bitPos))?(1):(0); + + // increment bit counter + if(bitBuffer->bitPos < 7) + { + bitBuffer->bitPos++; + } + else + { + // increment byte counter + bitBuffer->bitPos = 0; + bitBuffer->bytePos++; + } + + // return bit value + return bit; +} + +//! Get a bit from a given index into the buffer +// returns the bit at position [bitIndex] in the buffer +unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex) +{ + // return bit at index in buffer + return (bitBuffer->dataptr[bitIndex>>3] & (1<<(bitIndex & 0x07)))?(1):(0); +} + +//! Store a bit at the current position in the buffer +// stores the bit at the current position in the buffer +// and increments the bit position +void bitbufStore(BitBuf* bitBuffer, unsigned char bit) +{ + unsigned char byte; + // get current working byte + byte = bitBuffer->dataptr[bitBuffer->bytePos]; + // apply data bit + if(bit) + byte |= (1<bitPos); + else + byte &= ~(1<bitPos); + // store data + bitBuffer->dataptr[bitBuffer->bytePos] = byte; + bitBuffer->datalength++; + + // increment bit counter + if(bitBuffer->bitPos < 7) + { + bitBuffer->bitPos++; + } + else + { + // increment byte counter + bitBuffer->bitPos = 0; + bitBuffer->bytePos++; + } +} + +void bitbufReset(BitBuf* bitBuffer) +{ + // reset counters + bitBuffer->bytePos = 0; + bitBuffer->bitPos = 0; +} + +void bitbufFlush(BitBuf* bitBuffer) +{ + // flush contents of the buffer + bitBuffer->datalength = 0; + // reset indexing + bitbufReset(bitBuffer); +} + +unsigned short bitbufGetDataLength(BitBuf* bitBuffer) +{ + return bitBuffer->datalength; +} + +/* +unsigned char bitbufIsNotFull(cBuffer* buffer) +{ + // check to see if the buffer has room + // return true if there is room + return (buffer->datalength < buffer->size); +} +*/ + diff --git a/3rd party/Procyuon avrlib/bitbuf.h b/3rd party/Procyuon avrlib/bitbuf.h new file mode 100644 index 0000000..6472bd4 --- /dev/null +++ b/3rd party/Procyuon avrlib/bitbuf.h @@ -0,0 +1,75 @@ +/*! \file bitbuf.h \brief Multipurpose bit buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'bitbuf.c' +// Title : Multipurpose bit buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/10/2002 +// Revised : 7/10/2002 +// Version : 0.5 +// Target MCU : any +// Editor Tabs : 4 +// +/// \ingroup general +/// \defgroup bitbuf Generic Bit-Buffer Structure and Function Library (bitbuf.c) +/// \code #include "bitbuf.h" \endcode +/// \par Overview +/// This bit-buffer structure provides an easy and efficient way to store and +/// process bits. You can create as many bit buffers as you like (within +/// memory limits), and then use this common set of functions to access each +/// buffer. Supported functions include sequential getting and storing of +/// bits, array-like get, buffer flush (dump data), and reset-to-beginning. +/// This buffer is not dynamically allocated, it has a user-defined fixed +/// maximum size. +/// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef BITBUF_H +#define BITBUF_H + +// structure/typdefs + +// the BitBuffer structure +typedef struct struct_BitBuf +{ + unsigned char *dataptr; // the physical memory address where the buffer is stored + unsigned short size; // the allocated byte size of the buffer + unsigned short bytePos; // current byte position + unsigned short bitPos; // current bit position + unsigned short datalength; // the length of the data (in bits) currently in the buffer + unsigned short dataindex; // the index (in bits) into the buffer where the data starts +} BitBuf; + +// function prototypes + +//! initialize a buffer to start at a given address and have given size +void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize); + +//! get the bit at the current position in the buffer +unsigned char bitbufGet(BitBuf* bitBuffer); + +//! get a bit at the specified index in the buffer (kind of like array access) +// ** note: this does not remove/delete the bit that was read +unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex); + +//! store a bit at the current position in the buffer +void bitbufStore(BitBuf* bitBuffer, unsigned char bit); + +//! return the number of bits in the buffer +unsigned short bitbufGetDataLength(BitBuf* bitBuffer); + +// check if the buffer is full/not full (returns non-zero value if not full) +//unsigned char bitbufIsNotFull(cBuffer* buffer); + +//! resets the read/write position of the buffer to beginning +void bitbufReset(BitBuf* bitBuffer); + +//! flush (clear) the contents of the buffer +void bitbufFlush(BitBuf* bitBuffer); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/buffer.c b/3rd party/Procyuon avrlib/buffer.c new file mode 100644 index 0000000..e212b26 --- /dev/null +++ b/3rd party/Procyuon avrlib/buffer.c @@ -0,0 +1,149 @@ +/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'buffer.c' +// Title : Multipurpose byte buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 9/23/2001 +// Revised : 9/23/2001 +// Version : 1.0 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "buffer.h" +#include "global.h" +#include "avr/io.h" + +#ifndef CRITICAL_SECTION_START +#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli() +#define CRITICAL_SECTION_END SREG = _sreg +#endif + +// global variables + +// initialization + +void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) +{ + // begin critical section + CRITICAL_SECTION_START; + // set start pointer of the buffer + buffer->dataptr = start; + buffer->size = size; + // initialize index and length + buffer->dataindex = 0; + buffer->datalength = 0; + // end critical section + CRITICAL_SECTION_END; +} + +// access routines +unsigned char bufferGetFromFront(cBuffer* buffer) +{ + unsigned char data = 0; + // begin critical section + CRITICAL_SECTION_START; + // check to see if there's data in the buffer + if(buffer->datalength) + { + // get the first character from buffer + data = buffer->dataptr[buffer->dataindex]; + // move index down and decrement length + buffer->dataindex++; + if(buffer->dataindex >= buffer->size) + { + buffer->dataindex -= buffer->size; + } + buffer->datalength--; + } + // end critical section + CRITICAL_SECTION_END; + // return + return data; +} + +void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) +{ + // begin critical section + CRITICAL_SECTION_START; + // dump numbytes from the front of the buffer + // are we dumping less than the entire buffer? + if(numbytes < buffer->datalength) + { + // move index down by numbytes and decrement length by numbytes + buffer->dataindex += numbytes; + if(buffer->dataindex >= buffer->size) + { + buffer->dataindex -= buffer->size; + } + buffer->datalength -= numbytes; + } + else + { + // flush the whole buffer + buffer->datalength = 0; + } + // end critical section + CRITICAL_SECTION_END; +} + +unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) +{ + // begin critical section + CRITICAL_SECTION_START; + // return character at index in buffer + unsigned char data = buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; + // end critical section + CRITICAL_SECTION_END; + return data; +} + +unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) +{ + // begin critical section + CRITICAL_SECTION_START; + // make sure the buffer has room + if(buffer->datalength < buffer->size) + { + // save data byte at end of buffer + buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; + // increment the length + buffer->datalength++; + // end critical section + CRITICAL_SECTION_END; + // return success + return -1; + } + // end critical section + CRITICAL_SECTION_END; + // return failure + return 0; +} + +unsigned short bufferIsNotFull(cBuffer* buffer) +{ + // begin critical section + CRITICAL_SECTION_START; + // check to see if the buffer has room + // return true if there is room + unsigned short bytesleft = (buffer->size - buffer->datalength); + // end critical section + CRITICAL_SECTION_END; + return bytesleft; +} + +void bufferFlush(cBuffer* buffer) +{ + // begin critical section + CRITICAL_SECTION_START; + // flush contents of the buffer + buffer->datalength = 0; + // end critical section + CRITICAL_SECTION_END; +} + diff --git a/3rd party/Procyuon avrlib/buffer.h b/3rd party/Procyuon avrlib/buffer.h new file mode 100644 index 0000000..88525d3 --- /dev/null +++ b/3rd party/Procyuon avrlib/buffer.h @@ -0,0 +1,74 @@ +/*! \file buffer.h \brief Multipurpose byte buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'buffer.h' +// Title : Multipurpose byte buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 9/23/2001 +// Revised : 11/16/2002 +// Version : 1.1 +// Target MCU : any +// Editor Tabs : 4 +// +/// \ingroup general +/// \defgroup buffer Circular Byte-Buffer Structure and Function Library (buffer.c) +/// \code #include "buffer.h" \endcode +/// \par Overview +/// This byte-buffer structure provides an easy and efficient way to store +/// and process a stream of bytes.  You can create as many buffers as you +/// like (within memory limits), and then use this common set of functions to +/// access each buffer.  The buffers are designed for FIFO operation (first +/// in, first out).  This means that the first byte you put in the buffer +/// will be the first one you get when you read out the buffer.  Supported +/// functions include buffer initialize, get byte from front of buffer, add +/// byte to end of buffer, check if buffer is full, and flush buffer.  The +/// buffer uses a circular design so no copying of data is ever necessary. +/// This buffer is not dynamically allocated, it has a user-defined fixed +/// maximum size.  This buffer is used in many places in the avrlib code. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef BUFFER_H +#define BUFFER_H + +// structure/typdefs + +//! cBuffer structure +typedef struct struct_cBuffer +{ + unsigned char *dataptr; ///< the physical memory address where the buffer is stored + unsigned short size; ///< the allocated size of the buffer + unsigned short datalength; ///< the length of the data currently in the buffer + unsigned short dataindex; ///< the index into the buffer where the data starts +} cBuffer; + +// function prototypes + +//! initialize a buffer to start at a given address and have given size +void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size); + +//! get the first byte from the front of the buffer +unsigned char bufferGetFromFront(cBuffer* buffer); + +//! dump (discard) the first numbytes from the front of the buffer +void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes); + +//! get a byte at the specified index in the buffer (kind of like array access) +// ** note: this does not remove the byte that was read from the buffer +unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index); + +//! add a byte to the end of the buffer +unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data); + +//! check if the buffer is full/not full (returns zero value if full) +unsigned short bufferIsNotFull(cBuffer* buffer); + +//! flush (clear) the contents of the buffer +void bufferFlush(cBuffer* buffer); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/ccrma/debug.c b/3rd party/Procyuon avrlib/ccrma/debug.c new file mode 100644 index 0000000..c63ce1d --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/debug.c @@ -0,0 +1,55 @@ + +#include +#include + +#include "debug.h" +#include "lcd.h" +#include "rprintf.h" +#include "timer.h" +#include "osc.h" + + +u08 debugMode = 0; +u08 lcdDebugX; +u08 lcdDebugY; + +void debugInitLCD(u08 x, u08 y) { + lcdInit(); + lcdClear(); + + lcdDebugX = x; + lcdDebugY = y; + + debugMode |= DEBUG_MODE_LCD; + + debug(PSTR("LCD Debug init()")); +} + +void debugInitOSC(void) { + oscInit(); + debugMode |= DEBUG_MODE_OSC; +} + +void debug(const char PROGMEM *fmt) { + int code; + + if (debugMode & DEBUG_MODE_OSC) { + oscSendMessageString("/debug",fmt); + } + if (debugMode & DEBUG_MODE_LCD) { + rprintfInit(&lcdDataWrite); + lcdGotoXY(lcdDebugX,lcdDebugY); + rprintf1RamRom(STRING_IN_ROM, fmt); + } + +} + +// debugFlush assumes that timerInit() have been called already +void debugFlash(const u08 port, const u08 pin) { + sbi(DDR(port), pin); + cbi(port, pin); + timerPause(500); + sbi(port, pin); +} + + diff --git a/3rd party/Procyuon avrlib/ccrma/debug.h b/3rd party/Procyuon avrlib/ccrma/debug.h new file mode 100644 index 0000000..3f18c66 --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/debug.h @@ -0,0 +1,22 @@ + + +#ifndef _DEBUG_H +#define _DEBUG_H + +#include +#include "global.h" + +#define DEBUG_MODE_LCD 0x01 +#define DEBUG_MODE_SERIAL 0x02 +#define DEBUG_MODE_OSC 0x04 + +void debugInitLCD(u08 x, u08 y); + +void debugInitOSC(void); + +void debug(const char * fmt); + +void debugFlash(u08 port, u08 pin); + +#endif + diff --git a/3rd party/Procyuon avrlib/ccrma/midi.c b/3rd party/Procyuon avrlib/ccrma/midi.c new file mode 100644 index 0000000..59b35ce --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/midi.c @@ -0,0 +1,84 @@ +// Midi.c +// +// Midi output routines for the atmel atmega163 (and others) +// +// depends on avrlib for buffer +// + +#include "uart.h" +#include "midi.h" +//#include "debug.h" + + +void midiInit() { + uartInit(); + uartSetBaudRate(MIDI_BAUD_RATE); +} + +// send a midi NOTE ON message from the uart of the form [0x9n, note, vel] +// where n is the midi channel from 0-F, note and vel are 7-bit numbers +u08 midiNoteOnOut(u08 note, u08 vel, u08 channel) { + uartSendByte(MIDI_NOTE_ON | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & note); + uartSendByte(MIDI_DATA_MASK & vel); + + return 0; +} + +// send a midi NOTE OFF message from the uart of the form [0x8n, note, vel] +// where n is the midi channel from 0-F, note and vel are 7-bit numbers +u08 midiNoteOffOut(u08 note, u08 vel, u08 channel) { + uartSendByte(MIDI_NOTE_OFF | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & note); + uartSendByte(MIDI_DATA_MASK & vel); + + return 0; +} + +// send a midi CONTROL CHANGE message from the uart of the form [0xBn, controller, value] +// where n is the midi channel from 0-F, controller and value are 7-bit numbers +u08 midiControlChangeOut(u08 controller, u08 value, u08 channel) { + uartSendByte(MIDI_CONTROL_CHANGE | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & controller); + uartSendByte(MIDI_DATA_MASK & value); + + return 0; +} + +// send a midi PROGRAM CHANGE message from the uart of the form [0xCn, program] +// where n is the midi channel from 0-F, program is a 7-bit number +u08 midiProgramChangeOut(u08 program, u08 channel) { + uartSendByte(MIDI_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & program); + + return 0; +} + +// send a midi POLYPHONIC AFTERTOUCH message from the uart of the form [0xCn, controller, value] +// where n is the midi channel from 0-F, note and pressure are 7-bit numbers +u08 midiPolyTouchOut(u08 note, u08 pressure, u08 channel) { + uartSendByte(MIDI_POLY_TOUCH | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & note); + uartSendByte(MIDI_DATA_MASK & pressure); + + return 0; +} + +// send a midi CHANNEL AFTERTOUCH message from the uart of the form [0xDn, pressure] +// where n is the midi channel from 0-F, and pressure is a 7-bit number +u08 midiChannelTouchOut(u08 pressure, u08 channel) { + uartSendByte(MIDI_CHANNEL_TOUCH | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & pressure); + + return 0; +} + +// send a midi PITCH BEND message from the uart of the form [0xEn, bendLSB, bendMSB ] +// where n is the midi channel from 0-F, and bendLSB and bendMSB are 7-bit numbers +// note that MIDI devices normally pack together bendLSB and bendMSB to make a 14-bit number +u08 midiPitchBendOut(u08 bendLSB, u08 bendMSB, u08 channel) { + uartSendByte(MIDI_PITCH_BEND | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & bendLSB); + uartSendByte(MIDI_DATA_MASK & bendMSB); + return 0; +} diff --git a/3rd party/Procyuon avrlib/ccrma/midi.h b/3rd party/Procyuon avrlib/ccrma/midi.h new file mode 100644 index 0000000..b00f5fc --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/midi.h @@ -0,0 +1,36 @@ +#ifndef _MIDI_H +#define _MIDI_H + +#define MIDI_NOTE_ON 0x90 +#define MIDI_NOTE_OFF 0x80 + +// 1010cccc 0nnnnnnn 0vvvvvvv +#define MIDI_POLY_TOUCH 0xA0 +// 1011cccc 0nnnnnnn 0vvvvvvv +#define MIDI_CONTROL_CHANGE 0xB0 +// 1100cccc 0ppppppp +#define MIDI_PROGRAM_CHANGE 0xC0 + +#define MIDI_CHANNEL_TOUCH 0xD0 + +#define MIDI_PITCH_BEND 0xE0 + +#define MIDI_DATA_MASK 0x7F +#define MIDI_STATUS_MASK 0xF0 +#define MIDI_CHANNEL_MASK 0x0F + +#define MIDI_BAUD_RATE 31250 + +#include "global.h" +#include "buffer.h" + +void midiInit(void); +u08 midiNoteOnOut(u08 note, u08 vel, u08 channel); +u08 midiNoteOffOut(u08 note, u08 vel, u08 channel); +u08 midiControlChangeOut(u08 controller, u08 value, u08 channel); +u08 midiProgramChangeOut(u08 program, u08 channel); +u08 midiPolyTouchOut(u08 note, u08 pressure, u08 channel); +u08 midiChannelTouchOut(u08 pressure, u08 channel); +u08 midiPitchBendOut(u08 bendLSB, u08 bendMSB, u08 channel); + +#endif diff --git a/3rd party/Procyuon avrlib/ccrma/osc.c b/3rd party/Procyuon avrlib/ccrma/osc.c new file mode 100644 index 0000000..53d6b0c --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/osc.c @@ -0,0 +1,175 @@ +/*! \file osc.c \brief Open Sound Control (OSC) client functions. */ +//***************************************************************************** +// +// File Name : 'osc.c' +// Title : Open Sound Control (OSC) client functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 10/30/2002 +// Revised : 11/4/2002 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This code implements a subset of the OSC protocol and +// messages. It is meant to be used with the OSC extension for the visual +// programming and data-processing package Pure-Data (or PD). Note that +// this code sends OSC messages over serial RS-232, not a network. You +// must use these functions with a suitable OSC SERIAL server (receiver) +// on a host machine. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "buffer.h" +#include "uart.h" +#include "osc.h" + +// global variables +// ready flag from uart +extern volatile u08 uartReadyTx; + +// functions +void oscInit(void) +{ + // initialize uart (if not already done) + uartInit(); + // set the default communication rate + uartSetBaudRate(38400); +} + +void oscSendMessage(char *address) +{ + // write OSC packet header, argument length = 0bytes + oscWriteHeader(address, 0); + // write OSC address to packet + oscWriteString(address); + // apply checksum + oscWriteChecksum(); + // send buffer + uartSendTxBuffer(); + // wait for completion, transmitter to be ready + while(!uartReadyTx); +} + +void oscSendMessageInt(char *address, u32 arg) +{ + // write OSC packet header, argument length = 4bytes + oscWriteHeader(address, 4); + // write OSC address to packet + oscWriteString(address); + // copy arg to buffer + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg))+3) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg))+2) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg))+1) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg))+0) ); + // apply checksum + oscWriteChecksum(); + // send buffer + uartSendTxBuffer(); + // wait for completion, transmitter to be ready + while(!uartReadyTx); +} + +void oscSendMessageIntInt(char *address, u32 arg1, u32 arg2) +{ + // write OSC packet header, argument length = 8bytes + oscWriteHeader(address, 8); + // write OSC address to packet + oscWriteString(address); + // copy arg1 to buffer + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg1))+3) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg1))+2) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg1))+1) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg1))+0) ); + // copy arg2 to buffer + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg2))+3) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg2))+2) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg2))+1) ); + bufferAddToEnd(uartGetTxBuffer(), *(((unsigned char*)(&arg2))+0) ); + // apply checksum + oscWriteChecksum(); + // send buffer + uartSendTxBuffer(); + // wait for completion, transmitter to be ready + while(!uartReadyTx); +} + +void oscSendMessageString(char *address, char *arg) +{ + u08 len; + + // calculate length of argument string + for(len=0; PRG_RDB(arg+len); len++); + len++; // count a minumum of one null for termination + if(len&0x03) // are pad bytes necessary? + len += 4-(len&0x03); // add null pad bytes to reach multiple of four + + // write OSC packet header, argument length = 8bytes + oscWriteHeader(address, len); + // write OSC address to packet + oscWriteString(address); + // write string buffer + oscWriteString(arg); + // apply checksum + oscWriteChecksum(); + // send buffer + uartSendTxBuffer(); + // wait for completion, transmitter to be ready + while(!uartReadyTx); +} + +void oscWriteHeader(char *address, u08 arglen) +{ + u08 len; + // write OSC packet header + bufferAddToEnd(uartGetTxBuffer(), OSC_HEADER); + // determine padded length of address + for(len=0; PRG_RDB(address+len); len++); + len++; // count a minumum of one null for termination + if(len&0x03) // are pad bytes necessary? + len += 4-(len&0x03); // add null pad bytes to reach multiple of four + // write length to packet header + bufferAddToEnd(uartGetTxBuffer(), len+arglen); +} + +void oscWriteString(char *string) +{ + u08 temp=1; + u08 len=0; + + // write OSC string to packet + // copy string's null-termination intentionally + while(temp) + { + temp = PRG_RDB(string++); + bufferAddToEnd(uartGetTxBuffer(), temp); + len++; + } + + // pad the string as necessary to reach a 4-byte multiple + // Note: (len&0x03) == (len%4) + //for(; (len&0x03); len++) + while(len&0x03) + { + bufferAddToEnd(uartGetTxBuffer(), 0); + len++; + } +} + +void oscWriteChecksum(void) +{ + u08 i; + u08 chksum = 0; + // calculate checksum + for(i=2; idatalength; i++) + chksum += bufferGetAtIndex(uartGetTxBuffer(), i); + // write checksum to packet + bufferAddToEnd(uartGetTxBuffer(), chksum); +} diff --git a/3rd party/Procyuon avrlib/ccrma/osc.h b/3rd party/Procyuon avrlib/ccrma/osc.h new file mode 100644 index 0000000..b3224df --- /dev/null +++ b/3rd party/Procyuon avrlib/ccrma/osc.h @@ -0,0 +1,63 @@ +/*! \file osc.h \brief Open Sound Control (OSC) client functions. */ +//***************************************************************************** +// +// File Name : 'osc.h' +// Title : Open Sound Control (OSC) client functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 10/30/2002 +// Revised : 11/4/2002 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This code implements a subset of the OSC protocol and +// messages. It is meant to be used with the OSC extension for the visual +// programming and data-processing package Pure-Data (or PD). Note that +// this code sends OSC messages over serial RS-232, not a network. You +// must use these functions with a suitable OSC SERIAL server (receiver) +// on a host machine. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef OSC_H +#define OSC_H + +#include "global.h" + +// OSC serial packet structure: +// [HEADER][LENGTH][OSC MESSAGE][CHECKSUM] +// where +// [HEADER] is the byte 0xBE +// [LENGTH] is the number of bytes in OSC MESSGAGE (must be a multiple of four) +// [OSC MESSAGE] is defined by the OSC specification +// [CHECKSUM] is the 8-bit sum of bytes in the OSC MESSAGE + +// defines +#define OSC_HEADER 0xBE + +// function prototypes + +//! Initializes the OSC function library +void oscInit(void); + +//! sends an OSC message without any arguments (message with OSC address only) +void oscSendMessage(char *address); + +//! sends an OSC message with one 32-bit integer argument +void oscSendMessageInt(char *address, u32 arg); + +//! sends an OSC message with two 32-bit integer arguments +void oscSendMessageIntInt(char *address, u32 arg, u32 arg2); + +//! sends an OSC message with a null-terminated string argument +void oscSendMessageString(char *address, char *arg); + +// private functions +void oscWriteHeader(char *address, u08 arglen); ///< writes the OSC header+length +void oscWriteString(char *address); ///< writes the OSC address or strings +void oscWriteChecksum(void); ///< calculates and writes the OSC checksum + +#endif diff --git a/3rd party/Procyuon avrlib/cmdline.c b/3rd party/Procyuon avrlib/cmdline.c new file mode 100644 index 0000000..7c92379 --- /dev/null +++ b/3rd party/Procyuon avrlib/cmdline.c @@ -0,0 +1,447 @@ +/*! \file cmdline.c \brief Command-Line Interface Library. */ +//***************************************************************************** +// +// File Name : 'cmdline.c' +// Title : Command-Line Interface Library +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.16 +// Revised : 2003.07.23 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include AVR program memory support +#include // include standard C string functions +#include // include stdlib for string conversion functions + +#include "global.h" // include our global settings +#include "cmdline.h" + +// include project-specific configuration +#include "cmdlineconf.h" + +// defines +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_CR 0x0D +#define ASCII_LF 0x0A +#define ASCII_ESC 0x1B +#define ASCII_DEL 0x7F + +#define VT100_ARROWUP 'A' +#define VT100_ARROWDOWN 'B' +#define VT100_ARROWRIGHT 'C' +#define VT100_ARROWLEFT 'D' + +#define CMDLINE_HISTORY_SAVE 0 +#define CMDLINE_HISTORY_PREV 1 +#define CMDLINE_HISTORY_NEXT 2 + + +// Global variables + +// strings +u08 PROGMEM CmdlinePrompt[] = "cmd>"; +u08 PROGMEM CmdlineNotice[] = "cmdline: "; +u08 PROGMEM CmdlineCmdNotFound[] = "command not found"; + +// command list +// -commands are null-terminated strings +static char CmdlineCommandList[CMDLINE_MAX_COMMANDS][CMDLINE_MAX_CMD_LENGTH]; +// command function pointer list +static CmdlineFuncPtrType CmdlineFunctionList[CMDLINE_MAX_COMMANDS]; +// number of commands currently registered +u08 CmdlineNumCommands; + +u08 CmdlineBuffer[CMDLINE_BUFFERSIZE]; +u08 CmdlineBufferLength; +u08 CmdlineBufferEditPos; +u08 CmdlineInputVT100State; +u08 CmdlineHistory[CMDLINE_HISTORYSIZE][CMDLINE_BUFFERSIZE]; +CmdlineFuncPtrType CmdlineExecFunction; + +// Functions + +// function pointer to single character output routine +static void (*cmdlineOutputFunc)(unsigned char c); + +void cmdlineInit(void) +{ + // reset vt100 processing state + CmdlineInputVT100State = 0; + // initialize input buffer + CmdlineBufferLength = 0; + CmdlineBufferEditPos = 0; + // initialize executing function + CmdlineExecFunction = 0; + // initialize command list + CmdlineNumCommands = 0; +} + +void cmdlineAddCommand(u08* newCmdString, CmdlineFuncPtrType newCmdFuncPtr) +{ + // add command string to end of command list + strcpy(CmdlineCommandList[CmdlineNumCommands], newCmdString); + // add command function ptr to end of function list + CmdlineFunctionList[CmdlineNumCommands] = newCmdFuncPtr; + // increment number of registered commands + CmdlineNumCommands++; +} + +void cmdlineSetOutputFunc(void (*output_func)(unsigned char c)) +{ + // set new output function + cmdlineOutputFunc = output_func; + + // should we really do this? + // print a prompt + //cmdlinePrintPrompt(); +} + +void cmdlineInputFunc(unsigned char c) +{ + u08 i; + // process the received character + + // VT100 handling + // are we processing a VT100 command? + if(CmdlineInputVT100State == 2) + { + // we have already received ESC and [ + // now process the vt100 code + switch(c) + { + case VT100_ARROWUP: + cmdlineDoHistory(CMDLINE_HISTORY_PREV); + break; + case VT100_ARROWDOWN: + cmdlineDoHistory(CMDLINE_HISTORY_NEXT); + break; + case VT100_ARROWRIGHT: + // if the edit position less than current string length + if(CmdlineBufferEditPos < CmdlineBufferLength) + { + // increment the edit position + CmdlineBufferEditPos++; + // move cursor forward one space (no erase) + cmdlineOutputFunc(ASCII_ESC); + cmdlineOutputFunc('['); + cmdlineOutputFunc(VT100_ARROWRIGHT); + } + else + { + // else, ring the bell + cmdlineOutputFunc(ASCII_BEL); + } + break; + case VT100_ARROWLEFT: + // if the edit position is non-zero + if(CmdlineBufferEditPos) + { + // decrement the edit position + CmdlineBufferEditPos--; + // move cursor back one space (no erase) + cmdlineOutputFunc(ASCII_BS); + } + else + { + // else, ring the bell + cmdlineOutputFunc(ASCII_BEL); + } + break; + default: + break; + } + // done, reset state + CmdlineInputVT100State = 0; + return; + } + else if(CmdlineInputVT100State == 1) + { + // we last received [ESC] + if(c == '[') + { + CmdlineInputVT100State = 2; + return; + } + else + CmdlineInputVT100State = 0; + } + else + { + // anything else, reset state + CmdlineInputVT100State = 0; + } + + // Regular handling + if( (c >= 0x20) && (c < 0x7F) ) + { + // character is printable + // is this a simple append + if(CmdlineBufferEditPos == CmdlineBufferLength) + { + // echo character to the output + cmdlineOutputFunc(c); + // add it to the command line buffer + CmdlineBuffer[CmdlineBufferEditPos++] = c; + // update buffer length + CmdlineBufferLength++; + } + else + { + // edit/cursor position != end of buffer + // we're inserting characters at a mid-line edit position + // make room at the insert point + CmdlineBufferLength++; + for(i=CmdlineBufferLength; i>CmdlineBufferEditPos; i--) + CmdlineBuffer[i] = CmdlineBuffer[i-1]; + // insert character + CmdlineBuffer[CmdlineBufferEditPos++] = c; + // repaint + cmdlineRepaint(); + // reposition cursor + for(i=CmdlineBufferEditPos; i PD2 (PORTD, pin 2) +// INT1 -> PD3 (PORTD, pin 3) +// +// The external interrupt pins on the processors mega128 and mega64 are: +// +// INT0 -> PD0 (PORTD, pin 0) +// INT1 -> PD1 (PORTD, pin 1) +// INT2 -> PD2 (PORTD, pin 2) +// INT3 -> PD3 (PORTD, pin 3) +// INT4 -> PE4 (PORTE, pin 4) +// INT5 -> PE5 (PORTE, pin 5) +// INT6 -> PE6 (PORTE, pin 6) +// INT7 -> PE7 (PORTE, pin 7) +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENCODERCONF_H +#define ENCODERCONF_H + +// constants/macros/typdefs + +// defines for processor compatibility +// quick compatiblity for mega128, mega64 +//#ifndef MCUCR +// #define MCUCR EICRA +//#endif + +// Set the total number of encoders you wish to support +#define NUM_ENCODERS 2 + + +// -------------------- Encoder 0 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt PORT, DDR, and PIN must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC0_SIGNAL SIG_INTERRUPT0 // Interrupt signal name +#define ENC0_INT INT0 // matching INTx bit in GIMSK/EIMSK +#define ENC0_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC0_ISCX0 ISC00 // matching Interrupt Sense Config bit0 +#define ENC0_ISCX1 ISC01 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEA_PORT PORTD // PhaseA port register +#define ENC0_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC0_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC0_PHASEA_PIN PD2 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEB_PORT PORTC // PhaseB port register +#define ENC0_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC0_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC0_PHASEB_PIN PC0 // PhaseB port pin + + +// -------------------- Encoder 1 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC1_SIGNAL SIG_INTERRUPT1 // Interrupt signal name +#define ENC1_INT INT1 // matching INTx bit in GIMSK/EIMSK +#define ENC1_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC1_ISCX0 ISC10 // matching Interrupt Sense Config bit0 +#define ENC1_ISCX1 ISC11 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEA_PORT PORTD // PhaseA port register +#define ENC1_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC1_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC1_PHASEA_PIN PD3 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEB_PORT PORTC // PhaseB port register +#define ENC1_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC1_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC1_PHASEB_PIN PC1 // PhaseB port pin + + +// -------------------- Encoder 2 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC2_SIGNAL SIG_INTERRUPT6 // Interrupt signal name +#define ENC2_INT INT6 // matching INTx bit in GIMSK/EIMSK +#define ENC2_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC2_ISCX0 ISC60 // matching Interrupt Sense Config bit0 +#define ENC2_ISCX1 ISC61 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEA_PORT PORTE // PhaseA port register +#define ENC2_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC2_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC2_PHASEA_PIN PE6 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEB_PORT PORTC // PhaseB port register +#define ENC2_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC2_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC2_PHASEB_PIN PC2 // PhaseB port pin + + +// -------------------- Encoder 3 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC3_SIGNAL SIG_INTERRUPT7 // Interrupt signal name +#define ENC3_INT INT7 // matching INTx bit in GIMSK/EIMSK +#define ENC3_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC3_ISCX0 ISC70 // matching Interrupt Sense Config bit0 +#define ENC3_ISCX1 ISC71 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEA_PORT PORTE // PhaseA port register +#define ENC3_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC3_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC3_PHASEA_PIN PE7 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEB_PORT PORTC // PhaseB port register +#define ENC3_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC3_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC3_PHASEB_PIN PC3 // PhaseB port pin + +#endif diff --git a/3rd party/Procyuon avrlib/conf/fatconf.h b/3rd party/Procyuon avrlib/conf/fatconf.h new file mode 100644 index 0000000..e8821ec --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/fatconf.h @@ -0,0 +1,40 @@ +/*! \file fatconf.h \brief FAT16/32 file system driver configuration. */ +//***************************************************************************** +// +// File Name : 'fatconf.h' +// Title : FAT16/32 file system driver configuration +// Author : Pascal Stang +// Date : 4/19/2003 +// Revised : 4/19/2003 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef FATCONF_H +#define FATCONF_H + +// debug on/off +#define DEBUG_FAT + +#define SECTOR_BUFFER1_ADDR 0x0600+0x0600 +#define SECTOR_BUFFER1_SIZE 0x0200 + +#define LONGNAME_BUFFER_ADDR 0x0200+0x0600 +#define LONGNAME_BUFFER_SIZE 0x0100 + +#define DIRNAME_BUFFER_ADDR 0x0300+0x0600 +#define DIRNAME_BUFFER_SIZE 0x0100 + +#define FAT_CACHE_ADDR 0x0400+0x0600 +#define FAT_CACHE_SIZE 0x0200 + +#endif diff --git a/3rd party/Procyuon avrlib/conf/global.h b/3rd party/Procyuon avrlib/conf/global.h new file mode 100644 index 0000000..e5e3b51 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/global.h @@ -0,0 +1,40 @@ +/*! \file global.h \brief AVRlib project global include. */ +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVRlib project global include +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/conf/i2cconf.h b/3rd party/Procyuon avrlib/conf/i2cconf.h new file mode 100644 index 0000000..8152167 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2cconf.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/3rd party/Procyuon avrlib/conf/i2cswconf.h b/3rd party/Procyuon avrlib/conf/i2cswconf.h new file mode 100644 index 0000000..008f12e --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/i2cswconf.h @@ -0,0 +1,32 @@ +/*! \file i2cswconf.h \brief Software-driven I2C interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cswconf.h' +// Title : software-driven I2C interface using port pins +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 5/2/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CSWCONF_H +#define I2CSWCONF_H + +// clock line port +#define SCLPORT PORTD // i2c clock port +#define SCLDDR DDRD // i2c clock port direction +// data line port +#define SDAPORT PORTD // i2c data port +#define SDADDR DDRD // i2c data port direction +#define SDAPIN PIND // i2c data port input +// pin assignments +#define SCL PD0 // i2c clock pin +#define SDA PD1 // i2c data pin + +#endif diff --git a/3rd party/Procyuon avrlib/conf/ks0108conf.h b/3rd party/Procyuon avrlib/conf/ks0108conf.h new file mode 100644 index 0000000..69e12af --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/ks0108conf.h @@ -0,0 +1,85 @@ +/*! \file ks0108conf.h \brief Graphic LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'ks0108conf.h' +// Title : Graphic LCD driver for HD61202/KS0108 displays +// Author : Pascal Stang - Copyright (C) 2001-2003 +// Date : 10/19/2001 +// Revised : 5/1/2003 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef KS0108CONF_H +#define KS0108CONF_H + +// define LCD hardware interface +// -LCD_MEMORY_INTERFACE assumes that the registers of the LCD have been mapped +// into the external memory space of the AVR processor memory bus +// -LCD_PORT_INTERFACE is a direct-connection interface from port pins to LCD +// SELECT (UNCOMMENT) ONLY ONE! + +// *** NOTE: memory interface is not yet fully supported, but it might work + +//#define GLCD_MEMORY_INTERFACE +#define GLCD_PORT_INTERFACE + +// GLCD_PORT_INTERFACE specifics +#ifdef GLCD_PORT_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CTRL_PORT + #define GLCD_CTRL_PORT PORTB // PORT for LCD control signals + #define GLCD_CTRL_DDR DDRB // DDR register of LCD_CTRL_PORT + #define GLCD_CTRL_RS PB0 // pin for LCD Register Select + #define GLCD_CTRL_RW PB1 // pin for LCD Read/Write + #define GLCD_CTRL_E PB2 // pin for LCD Enable + #define GLCD_CTRL_CS0 PB3 // pin for LCD Controller 0 Chip Select + #define GLCD_CTRL_CS1 PB4 // pin for LCD Controller 1 Chip Select(*) + #define GLCD_CTRL_CS2 PB6 // pin for LCD Controller 2 Chip Select(*) + #define GLCD_CTRL_CS3 PB7 // pin for LCD Controller 3 Chip Select(*) + #define GLCD_CTRL_RESET PB5 // pin for LCD Reset + // (*) NOTE: additonal controller chip selects are optional and + // will be automatically used per each step in 64 pixels of display size + // Example: Display with 128 hozizontal pixels uses 2 controllers + #endif + #ifndef GLCD_DATA_PORT + #define GLCD_DATA_PORT PORTC // PORT for LCD data signals + #define GLCD_DATA_DDR DDRC // DDR register of LCD_DATA_PORT + #define GLCD_DATA_PIN PINC // PIN register of LCD_DATA_PORT + #endif +#endif + +// GLCD_MEMORY_INTERFACE specifics +#ifdef GLCD_MEMORY_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CONTROLLER0_CTRL_ADDR + // absolute address of LCD Controller #0 CTRL and DATA registers + #define GLCD_CONTROLLER0_CTRL_ADDR 0x1000 + #define GLCD_CONTROLLER0_DATA_ADDR 0x1001 + // offset of other controllers with respect to controller0 + #define GLCD_CONTROLLER_ADDR_OFFSET 0x0002 + #endif +#endif + + +// LCD geometry defines (change these definitions to adapt code/settings) +#define GLCD_XPIXELS 128 // pixel width of entire display +#define GLCD_YPIXELS 64 // pixel height of entire display +#define GLCD_CONTROLLER_XPIXELS 64 // pixel width of one display controller + +// Set text size of display +// These definitions are not currently used and will probably move to glcd.h +#define GLCD_TEXT_LINES 8 // visible lines +#define GLCD_TEXT_LINE_LENGTH 22 // internal line length + +#endif diff --git a/3rd party/Procyuon avrlib/conf/lcdconf.h b/3rd party/Procyuon avrlib/conf/lcdconf.h new file mode 100644 index 0000000..eeede5c --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/lcdconf.h @@ -0,0 +1,104 @@ +/*! \file lcdconf.h \brief Character LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'lcdconf.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCDCONF_H +#define LCDCONF_H + +// Define type of interface used to access the LCD +// LCD_MEMORY_INTERFACE: +// To use this mode you must supply the necessary hardware to connect the +// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD +// (HD44780 chip) must appear in the CPU's memory map. This mode is faster +// than the port interface but requires a little extra hardware to make it +// work. It is especially useful when your CPU is already configured to +// use an external memory bus for other purposes (like accessing memory). +// +// LCD_PORT_INTERFACE: +// This mode allows you to connect the control and data lines of the LCD +// directly to the I/O port pins (no interfacing hardware is needed), +// but it generally runs slower than the LCD_MEMORY_INTERFACE. +// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may +// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port +// (pins 0-7) is required for the LCD data lines, but transfers are faster. +// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD +// access is slower. In either mode, three additional port pins are +// required for the LCD interface control lines (RS, R/W, and E). + +// Enable one of the following interfaces to your LCD +//#define LCD_MEMORY_INTERFACE +#define LCD_PORT_INTERFACE + +// Enter the parameters for your chosen interface' +// if you chose the LCD_PORT_INTERFACE: +#ifdef LCD_PORT_INTERFACE + #ifndef LCD_CTRL_PORT + // port and pins you will use for control lines + #define LCD_CTRL_PORT PORTC + #define LCD_CTRL_DDR DDRC + #define LCD_CTRL_RS 2 + #define LCD_CTRL_RW 3 + #define LCD_CTRL_E 4 + #endif + #ifndef LCD_DATA_POUT + // port you will use for data lines + #define LCD_DATA_POUT PORTA + #define LCD_DATA_PIN PINA + #define LCD_DATA_DDR DDRA + // access mode you will use (default is 8bit unless 4bit is selected) + //#define LCD_DATA_4BIT + #endif +#endif + +// if you chose the LCD_MEMORY_INTERFACE: +#ifdef LCD_MEMORY_INTERFACE + #ifndef LCD_CTRL_ADDR + // CPU memory address of the LCD control register + #define LCD_CTRL_ADDR 0x1000 + #endif + #ifndef LCD_DATA_ADDR + // CPU memory address of the LCD data register + #define LCD_DATA_ADDR 0x1001 + #endif +#endif + + +// LCD display geometry +// change these definitions to adapt settings +#define LCD_LINES 4 // visible lines +#define LCD_LINE_LENGTH 20 // line length (in characters) +// cursor position to DDRAM mapping +#define LCD_LINE0_DDRAMADDR 0x00 +#define LCD_LINE1_DDRAMADDR 0x40 +#define LCD_LINE2_DDRAMADDR 0x14 +#define LCD_LINE3_DDRAMADDR 0x54 + +// LCD delay +// This delay affects how quickly accesses are made to the LCD controller. +// The HD44780 LCD controller requires an access time of at least 1us. +// LCD_DELAY should be scaled to take at least half that time (500us). +// Each NOP takes 1 CPU clock cycle to execute. Thus, at 4MHz, you should +// use at least 2 NOPs, at 8MHz at least 4 NOPs, etc. +// You can also use the delay_us(xx) command for longer access times. + +// LCD_DELAY is now automatically set in lcd.h, +// however, if you define it here, this definition will override the automatic setting + +// use this for a fail-safe delay +//#define LCD_DELAY delay_us(5); + +#endif diff --git a/3rd party/Procyuon avrlib/conf/mmcconf.h b/3rd party/Procyuon avrlib/conf/mmcconf.h new file mode 100644 index 0000000..adb887d --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/mmcconf.h @@ -0,0 +1,33 @@ +/*! \file mmcconf.h \brief MultiMedia and SD Flash Card Interface Configuration. */ +//***************************************************************************** +// +// File Name : 'mmc.h' +// Title : MultiMedia and SD Flash Card Interface Configuration +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MMCCONF_H +#define MMCCONF_H + +// define to enable debugging print statements +//#define MMC_DEBUG + +// MMC card chip select pin defines +#define MMC_CS_PORT PORTB +#define MMC_CS_DDR DDRB +#define MMC_CS_PIN 0 + +#endif diff --git a/3rd party/Procyuon avrlib/conf/readme-conf.txt b/3rd party/Procyuon avrlib/conf/readme-conf.txt new file mode 100644 index 0000000..0011bad --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/readme-conf.txt @@ -0,0 +1,24 @@ + +--- AVRlib "conf" files --- + +AVRlib contains many function/code libraries which depend upon particular aspects of the +user's hardware. The most basic of these is the processor clock rate. The clock rate defines +dozens of aspects of processor operation from code delays to UART baud rates. + +To allow AVRlib to work easily with hardware that may vary from project to project, all +user-configurable parameters of AVRlib are contained in the template configuration files in +this directory. NOTE that these files are only templates and should be copied, as needed, +to an individual project's code directory and edited to suit that project's hardware. + + +global.h is the only configuration include file that is common to the entire AVRlib code base. +To use AVRlib libraries, you must copy global.h to your project's code directory and modify +the options inside global.h to match your hardware.) Each project should have its own global.h. + +Other *conf.h files should be copied to your project's code directory as needed. For example, +if you intend to use the lcd.c library, you will need to copy lcdconf.h and modify it to match +the I/O and LCD configuration of your hardware. + +** If you fail to copy the configuration files needed for the AVRlib libraries you use, +the problem will usually exhibit itself as a compile-time error. + diff --git a/3rd party/Procyuon avrlib/conf/servoconf.h b/3rd party/Procyuon avrlib/conf/servoconf.h new file mode 100644 index 0000000..a930792 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/servoconf.h @@ -0,0 +1,82 @@ +/*! \file servoconf.h \brief Interrupt-driven RC Servo configuration. */ +//***************************************************************************** +// +// File Name : 'servoconf.h' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 07/31/2002 +// Revised : 09/30/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: you need the latest version (3.2+) of the AVR-GCC compiler to use this +// function library. Download it from http://www.avrfreaks.net/AVRGCC +// +// Description : This code allows you to drive up to 8 RC servos from any +// combination of ports and pins on the AVR processor. Using interrupts, +// this code continuously sends control signals to the servo to maintain +// position even while your code is doing other work. +// +// The servoInit and servoOff effectively turn on and turn off servo +// control. When you run ServoInit, it automatically assigns each +// "channel" of servo control to be output on the SERVO_DEFAULT_PORT. +// One "channel" of servo control can control one servo and must be +// assigned single I/O pin for output. +// +// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then +// then by default the code will use SERVO_DEFAULT_PORT pins 0-7. +// If you're only using four channels, then pins 0-3 will be used by +// default. +// +// The command servoSetChannelIO(channel, port, pin) allows you to +// reassign the output of any channel to any port and I/O pin you +// choose. For exampe, if you have an RC servo connected to PORTC, pin 6, +// and you wish to use channel 2 to control it, use: +// +// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6) +// +// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port) +// +// The servoSetPostion and servoGetPosition commands allow you to command +// a given servo to your desired position. The position you request must +// lie between the SERVO_MIN and SERVO_MAX limit you defined. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SERVOCONF_H +#define SERVOCONF_H + +// set number of servo channels (1 to 8) +// This is the number of servos you would like to drive +// Each "Channel" can control one servo and by default will +// map directly to the port pin of the same number on the +// SERVO_DEFAULT_PORT. You can change this default port/pin +// assignment for a given channel to any port/pin you like. +// See the "servoSetChannelIO" function. +#define SERVO_NUM_CHANNELS 4 +// set default SERVO output port +// This is the AVR port which you have connected to your servos +// See top of file for how servo "channels" map to port pins +#define SERVO_DEFAULT_PORT PORTB +// set servo characteristics (min and max raw position) +// You must find these by testing using your brand/type of servos. +// The min/max settings will change proportional to F_CPU, the CPU +// clock frequency. +// The numbers below good for parallax servos at an F_CPU of ~8MHz. +//#define SERVO_MAX 71 +//#define SERVO_MIN 17 +// The numbers below good for parallax servos at an F_CPU of ~14.745MHz. +#define SERVO_MAX 138 +#define SERVO_MIN 34 + +// set servo scaled range +// This sets the scaled position range of the servo. Allowed scaled +// positions are 0 -> SERVO_POSITION_MAX, and correspond to raw +// positions of SERVO_MIN -> SERVO_MAX. +#define SERVO_POSITION_MAX 255 + +#endif diff --git a/3rd party/Procyuon avrlib/conf/sramswconf.h b/3rd party/Procyuon avrlib/conf/sramswconf.h new file mode 100644 index 0000000..d5c1f25 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/sramswconf.h @@ -0,0 +1,42 @@ +/*! \file sramswconf.h \brief Software-driven SRAM memory bus access configuration. */ +//***************************************************************************** +// +// File Name : 'sramswconf.h' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SRAMSWCONF_H +#define SRAMSWCONF_H + +// defines + +// data bus (DATA[0:7]) and low address (ADDR[0:7]) port +#define SRAM_ADL PORTA +#define SRAM_ADL_DDR DDRA +#define SRAM_ADL_IN PINA +// high address port (ADDR[8:15]) +#define SRAM_AH PORTC +#define SRAM_AH_DDR DDRC +// page address port (PAGE[0:3]) +#define SRAM_PAGE PORTB +#define SRAM_PAGE_DDR DDRB +#define SRAM_PAGE_MASK 0x0F +// control port +#define SRAM_CTRL PORTD +#define SRAM_CTRL_DDR DDRD +// control lines +#define SRAM_ALE PD5 +#define SRAM_WR PD6 +#define SRAM_RD PD7 + +#endif diff --git a/3rd party/Procyuon avrlib/conf/sta013conf.h b/3rd party/Procyuon avrlib/conf/sta013conf.h new file mode 100644 index 0000000..5882c44 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/sta013conf.h @@ -0,0 +1,34 @@ +/*! \file sta013conf.h \brief STA013 MP3 player driver configuration. */ +//***************************************************************************** +// +// File Name : 'sta013.h' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 10/22/2000 +// Revised : 12/04/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef STA013CONF_H +#define STA013CONF_H + +// STA013 Configuration + +// STA013 demand line +#define STA013_DEMAND_PORT PORTE // port to which DEMAND line is connected +#define STA013_DEMAND_PORTIN PINE // input port to which DEMAND line is connected +#define STA013_DEMAND_PIN PE4 // port pin to which DEMAND line is connected +#define STA013_DEMAND_INTR SIG_INTERRUPT4 // interrupt to which DEMAND line is connected + +#endif diff --git a/3rd party/Procyuon avrlib/conf/stxetxconf.h b/3rd party/Procyuon avrlib/conf/stxetxconf.h new file mode 100644 index 0000000..7e67166 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/stxetxconf.h @@ -0,0 +1,28 @@ +/*! \file stxetxconf.h \brief STX/ETX Packet Protocol Implementation Configuration. */ +//***************************************************************************** +// +// File Name : 'stxetx.h' +// Title : STX/ETX Packet Protocol Implementation Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 10/9/2002 +// Revised : 02/10/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef STXETXCONF_H +#define STXETXCONF_H + +// STX/ETX Configuration Options + +// This determines the size of the Packet Receive Buffer +// where whole verified packets are copied after being received +#define STXETX_MAXRXPACKETSIZE 20 // length of packet buffer + + +#endif diff --git a/3rd party/Procyuon avrlib/conf/uartsw2conf.h b/3rd party/Procyuon avrlib/conf/uartsw2conf.h new file mode 100644 index 0000000..88a34d0 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/uartsw2conf.h @@ -0,0 +1,68 @@ +/*! \file uartsw2conf.h \brief Interrupt-driven Software UART Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'uartsw2conf.h' +// Title : Interrupt-driven Software UART Driver Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 2 Output Capture for transmit timing +// -Timer 0 Output Capture for receive timing +// -External Interrupt 2 for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +// be used for other timing, but the prescalers for these timers must not be +// changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +// These options should be configured by editing your local copy of +// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2CONF_H +#define UARTSW2CONF_H + +// constants/macros/typdefs + +#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes + +#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals +// when non-inverted, the serial line is appropriate for passing though +// an RS232 driver like the MAX232. When inverted, the serial line can +// directly drive/receive RS232 signals to/from a DB9 connector. Be sure +// to use a current-limiting resistor and perhaps a diode-clamp circuit when +// connecting incoming RS232 signals to a microprocessor I/O pin. + +// if non-inverted, the serial line idles high (logic 1) between bytes +// if inverted, the serial line idles low (logic 0) between bytes + + +// UART transmit pin defines +#define UARTSW_TX_PORT PORTB ///< UART Transmit Port +#define UARTSW_TX_DDR DDRB ///< UART Transmit DDR +#define UARTSW_TX_PIN PB3 ///< UART Transmit Pin + +// UART receive pin defines +// This pin must correspond to the +// External Interrupt 2 (INT2) pin for your processor +#define UARTSW_RX_PORT PORTB ///< UART Receive Port +#define UARTSW_RX_DDR DDRB ///< UART Receive DDR +#define UARTSW_RX_PORTIN PINB ///< UART Receive Port Input +#define UARTSW_RX_PIN PB2 ///< UART Receive Pin + +#endif diff --git a/3rd party/Procyuon avrlib/conf/uartswconf.h b/3rd party/Procyuon avrlib/conf/uartswconf.h new file mode 100644 index 0000000..36d81c1 --- /dev/null +++ b/3rd party/Procyuon avrlib/conf/uartswconf.h @@ -0,0 +1,67 @@ +/*! \file uartswconf.h \brief Interrupt-driven Software UART Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'uartswconf.h' +// Title : Interrupt-driven Software UART Driver Configuration +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 1 Output Compare A for transmit timing +// -Timer 1 Output Compare B for receive timing +// -Timer 1 Input Capture for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupt from Timer1 can still be used for +// other timing, but the prescaler for Timer1 must not be changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the Timer1 Input Capture (IC1) I/O pin. +// These options should be configured by editing your local copy of +// "uartswconf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSWCONF_H +#define UARTSWCONF_H + +// constants/macros/typdefs + +#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes + +#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals +// when non-inverted, the serial line is appropriate for passing though +// an RS232 driver like the MAX232. When inverted, the serial line can +// directly drive/receive RS232 signals to/from a DB9 connector. Be sure +// to use a current-limiting resistor and perhaps a diode-clamp circuit when +// connecting incoming RS232 signals to a microprocessor I/O pin. + +// if non-inverted, the serial line idles high (logic 1) between bytes +// if inverted, the serial line idles low (logic 0) between bytes + + +// UART transmit pin defines +#define UARTSW_TX_PORT PORTD ///< UART Transmit Port +#define UARTSW_TX_DDR DDRD ///< UART Transmit DDR +#define UARTSW_TX_PIN PD5 ///< UART Transmit Pin + +// UART receive pin defines +// This pin must correspond to the +// Timer1 Input Capture (ICP or IC1) pin for your processor +#define UARTSW_RX_PORT PORTD ///< UART Receive Port +#define UARTSW_RX_DDR DDRD ///< UART Receive DDR +#define UARTSW_RX_PORTIN PIND ///< UART Receive Port Input +#define UARTSW_RX_PIN PD6 ///< UART Receive Pin + +#endif diff --git a/3rd party/Procyuon avrlib/debug.c b/3rd party/Procyuon avrlib/debug.c new file mode 100644 index 0000000..4974fbe --- /dev/null +++ b/3rd party/Procyuon avrlib/debug.c @@ -0,0 +1,98 @@ +/*! \file debug.c \brief Debugging function library. */ +//***************************************************************************** +// +// File Name : 'debug.c' +// Title : Helpful debugging functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003-03-13 +// Revised : 2003-03-13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This file contains a set of functions which may be useful +// for general debugging. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "debug.h" + +#include "rprintf.h" // include printf support + +// global variables + +// functions + +// Print a part of memory as a formatted hex table with ascii translation +void debugPrintHexTable(u16 length, u08 *buffer) +{ + u08 i; + u16 j; + u08 *buf; + u08 s; + + buf = buffer; + + // print the low order address indicies and ASCII header + rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n"); + rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n"); + + // print the data + for(j=0; j<((length+15)>>4); j++) + { + // print the high order address index for this line + rprintfu16(j<<4); + rprintfChar(' '); + + // print the hex data + for(i=0; i<0x10; i++) + { + // be nice and print only up to the exact end of the data + if( ((j<<4)+i) < length) + { + // print hex byte + rprintfu08(buf[(j<<4)+i]); + rprintfChar(' '); + } + else + { + // we're past the end of the data's length + // print spaces + rprintfProgStrM(" "); + } + } + + // leave some space + rprintfChar(' '); + + // print the ascii data + for(i=0; i<0x10; i++) + { + // be nice and print only up to the exact end of the data + if( ((j<<4)+i) < length) + { + // get the character + s = buf[(j<<4)+i]; + // make sure character is printable + if(s >= 0x20) + rprintfChar(s); + else + rprintfChar('.'); + } + else + { + // we're past the end of the data's length + // print a space + rprintfChar(' '); + } + } + rprintfCRLF(); + } +} diff --git a/3rd party/Procyuon avrlib/debug.h b/3rd party/Procyuon avrlib/debug.h new file mode 100644 index 0000000..20148dc --- /dev/null +++ b/3rd party/Procyuon avrlib/debug.h @@ -0,0 +1,34 @@ +/*! \file debug.h \brief Debugging function library. */ +//***************************************************************************** +// +// File Name : 'debug.h' +// Title : Helpful debugging functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003-03-13 +// Revised : 2003-03-13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This file contains a set of functions which may be useful +// for general debugging. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DEBUG_H +#define DEBUG_H + +#include "global.h" + +// defines + +// function prototypes + +//! Print a part of memory as a formatted hex table with ascii translation +void debugPrintHexTable(u16 length, u08 *buffer); + + +#endif diff --git a/3rd party/Procyuon avrlib/ds1631.c b/3rd party/Procyuon avrlib/ds1631.c new file mode 100644 index 0000000..aa228cd --- /dev/null +++ b/3rd party/Procyuon avrlib/ds1631.c @@ -0,0 +1,146 @@ +/*! \file ds1631.c \brief Dallas DS1631 Temperature Sensor Driver Library. */ +//***************************************************************************** +// +// File Name : 'ds1631.c' +// Title : Dallas DS1631 Temperature Sensor Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer.h" +#include "i2c.h" +#include "ds1631.h" + +// global variables + +// Functions +u08 ds1631Init(u08 i2cAddr) +{ + u08 chip_ok; + // issue a reset + if(ds1631Reset(i2cAddr) == I2C_OK) + chip_ok = TRUE; + else + chip_ok = FALSE; + // set a default configuration + // (1-shot mode, T_OUT active high, and 12-bit conversion) + ds1631SetConfig(i2cAddr, + DS1631_CONFIG_1SHOT | DS1631_CONFIG_POL | + DS1631_CONFIG_R0 | DS1631_CONFIG_R1); + return chip_ok; +} + +u08 ds1631Reset(u08 i2cAddr) +{ + u08 buffer[1]; + // return the DS1631 to power-on reset defaults + buffer[0] = DS1631_CMD_SWPOR; + return i2cMasterSendNI(i2cAddr, 1, buffer); +} + +void ds1631SetConfig(u08 i2cAddr, u08 config) +{ + u08 buffer[2]; + // write the DS1631 configuration byte + buffer[0] = DS1631_CMD_ACCESSCONFIG; + buffer[1] = config; + i2cMasterSendNI(i2cAddr, 2, buffer); +} + +u08 ds1631GetConfig(u08 i2cAddr) +{ + u08 buffer[1]; + // write the DS1631 configuration byte + buffer[0] = DS1631_CMD_ACCESSCONFIG; + i2cMasterSendNI(i2cAddr, 2, buffer); + i2cMasterReceiveNI(i2cAddr, 2, buffer); + return buffer[0]; +} + +void ds1631StartConvert(u08 i2cAddr) +{ + u08 buffer[1]; + // send the DS1631 Start Convert command + buffer[0] = DS1631_CMD_STARTCONV; + i2cMasterSendNI(i2cAddr, 1, buffer); +} + +void ds1631StopConvert(u08 i2cAddr) +{ + u08 buffer[1]; + // send the DS1631 Stop Convert command + buffer[0] = DS1631_CMD_STOPCONV; + i2cMasterSendNI(i2cAddr, 1, buffer); +} + +s16 ds1631ReadTemp(u08 i2cAddr) +{ + // read the Temperature register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_READTEMP); +} + +void ds1631SetTH(u08 i2cAddr, s16 value) +{ + // write the TH register + ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTH, value); +} + +void ds1631SetTL(u08 i2cAddr, s16 value) +{ + // write the TL register + ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTL, value); +} + +s16 ds1631GetTH(u08 i2cAddr) +{ + // read the TH register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTH); +} + +s16 ds1631GetTL(u08 i2cAddr) +{ + // read the TL register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTL); +} + + +s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd) +{ + u08 buffer[2]; + s16 T; + + // read the temperature value from the requested register + i2cMasterSendNI(i2cAddr, 1, &cmd); + i2cMasterReceiveNI(i2cAddr, 2, buffer); + // pack bytes + T = (s16)((buffer[0]<<8) | buffer[1]); + // return result + return T; +} + +void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value) +{ + u08 buffer[3]; + + // write the requested register with a temperature value + buffer[0] = cmd; + buffer[1] = value>>8; + buffer[2] = value; + i2cMasterSendNI(i2cAddr, 3, buffer); +} diff --git a/3rd party/Procyuon avrlib/ds1631.h b/3rd party/Procyuon avrlib/ds1631.h new file mode 100644 index 0000000..939cbbb --- /dev/null +++ b/3rd party/Procyuon avrlib/ds1631.h @@ -0,0 +1,99 @@ +/*! \file ds1631.h \brief Dallas DS1631 Temperature Sensor Driver Library. */ +//***************************************************************************** +// +// File Name : 'ds1631.h' +// Title : Dallas DS1631 Temperature Sensor Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_hw +/// \defgroup ds1631 Dallas DS1631 Temperature Sensor Driver (ds1631.c) +/// \code #include "ds1632.h" \endcode +/// \par Overview +/// This library provides high-level functions for accessing the Dallas +/// Semiconductor DS1631 I2C Temperature Sensor. +/// +/// The basic specs of the DS1631 are: +/// - operating temperature range -55 to +125 degrees C +/// - high accuracy of +/-0.5C over 0 to +70 degrees C +/// - 8 to 12-bit signed output +/// - thermostat functionality +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DS1631_H +#define DS1631_H + +#include "global.h" + +// constants/macros/typdefs +#define DS1631_I2C_ADDR 0x90 ///< Base I2C address of DS1631 devices + +#define DS1631_CMD_STARTCONV 0x51 ///< DS1631 Start conversion command byte +#define DS1631_CMD_STOPCONV 0x22 ///< DS1631 Stop conversion command byte +#define DS1631_CMD_READTEMP 0xAA ///< DS1631 Read Temperature command byte +#define DS1631_CMD_ACCESSTH 0xA1 ///< DS1631 TH read/write command byte +#define DS1631_CMD_ACCESSTL 0xA2 ///< DS1631 TL read/write command byte +#define DS1631_CMD_ACCESSCONFIG 0xAC ///< DS1631 Config read/write command byte +#define DS1631_CMD_SWPOR 0x54 ///< DS1631 Software Reset command byte + +#define DS1631_CONFIG_1SHOT 0x01 +#define DS1631_CONFIG_POL 0x02 +#define DS1631_CONFIG_R0 0x04 +#define DS1631_CONFIG_R1 0x08 +#define DS1631_CONFIG_NVB 0x10 +#define DS1631_CONFIG_TLF 0x20 +#define DS1631_CONFIG_THF 0x40 +#define DS1631_CONFIG_DONE 0x80 + +// functions + +//! Initialize the DS1631 chip +u08 ds1631Init(u08 i2cAddr); + +//! Reset the DS1631 chip to its power-on defaults +u08 ds1631Reset(u08 i2cAddr); + +//! Set the configuration byte of the DS1631 +void ds1631SetConfig(u08 i2cAddr, u08 config); + +//! Get the configuration byte of the DS1631 +u08 ds1631GetConfig(u08 i2cAddr); + +//! Start a temperature conversion +void ds1631StartConvert(u08 i2cAddr); + +//! Stop a temperature conversion (or stop continuous conversion mode) +void ds1631StopConvert(u08 i2cAddr); + +//! Read the result of a temperature conversion +s16 ds1631ReadTemp(u08 i2cAddr); + +//! Set the Temp-High threshold +void ds1631SetTH(u08 i2cAddr, s16 value); + +//! Set the Temp-Low threshold +void ds1631SetTL(u08 i2cAddr, s16 value); + +//! Get the Temp-High threshold +s16 ds1631GetTH(u08 i2cAddr); + +//! Get the Temp-Low threshold +s16 ds1631GetTL(u08 i2cAddr); + +void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value); +s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd); + + +#endif diff --git a/3rd party/Procyuon avrlib/enc28j60.c b/3rd party/Procyuon avrlib/enc28j60.c new file mode 100644 index 0000000..5dd5e72 --- /dev/null +++ b/3rd party/Procyuon avrlib/enc28j60.c @@ -0,0 +1,543 @@ +/*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'enc28j60.c' +// Title : Microchip ENC28J60 Ethernet Interface Driver +// Author : Pascal Stang (c)2005 +// Created : 9/22/2005 +// Revised : 9/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. +// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin +// chip, using an SPI interface to the host processor. +// +//***************************************************************************** + +#include "avr/io.h" +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "enc28j60.h" + +#ifdef SPDR0 +#define SPDR SPDR0 +#define SPCR SPCR0 +#define SPSR SPSR0 + +#define SPIF SPIF0 +#define MSTR MSTR0 +#define CPOL CPOL0 +#define DORD DORD0 +#define SPR0 SPR00 +#define SPR1 SPR01 +#define SPI2X SPI2X0 +#define SPE SPE0 +#endif + +// include configuration +#include "enc28j60conf.h" + +u08 Enc28j60Bank; +u16 NextPacketPtr; + +void nicInit(void) +{ + enc28j60Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + enc28j60PacketSend(len, packet); +} + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + return enc28j60PacketReceive(maxlen, packet); +} + +void nicGetMacAddress(u08* macaddr) +{ + // read MAC address registers + // NOTE: MAC address in ENC28J60 is byte-backward + *macaddr++ = enc28j60Read(MAADR5); + *macaddr++ = enc28j60Read(MAADR4); + *macaddr++ = enc28j60Read(MAADR3); + *macaddr++ = enc28j60Read(MAADR2); + *macaddr++ = enc28j60Read(MAADR1); + *macaddr++ = enc28j60Read(MAADR0); +} + +void nicSetMacAddress(u08* macaddr) +{ + // write MAC address + // NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, *macaddr++); + enc28j60Write(MAADR4, *macaddr++); + enc28j60Write(MAADR3, *macaddr++); + enc28j60Write(MAADR2, *macaddr++); + enc28j60Write(MAADR1, *macaddr++); + enc28j60Write(MAADR0, *macaddr++); +} + +void nicRegDump(void) +{ + enc28j60RegDump(); +} + +/* +void ax88796SetupPorts(void) +{ +#if NIC_CONNECTION == MEMORY_MAPPED + // enable external SRAM interface - no wait states + sbi(MCUCR, SRE); +// sbi(MCUCR, SRW10); +// sbi(XMCRA, SRW00); +// sbi(XMCRA, SRW01); +// sbi(XMCRA, SRW11); +#else + // set address port to output + AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK; + + // set data port to input with pull-ups + AX88796_DATA_DDR = 0x00; + AX88796_DATA_PORT = 0xFF; + + // initialize the control port read and write pins to de-asserted + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN ); + // set the read and write pins to output + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN ); +#endif + // set reset pin to output + sbi( AX88796_RESET_DDR, AX88796_RESET_PIN ); +} +*/ + +u08 enc28j60ReadOp(u08 op, u08 address) +{ + u08 data; + + // assert CS + ENC28J60_CONTROL_PORT &= ~(1<>5); + Enc28j60Bank = (address & BANK_MASK); + } +} + +u08 enc28j60Read(u08 address) +{ + // set the bank + enc28j60SetBank(address); + // do the read + return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); +} + +void enc28j60Write(u08 address, u08 data) +{ + // set the bank + enc28j60SetBank(address); + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +} + +u16 enc28j60PhyRead(u08 address) +{ + u16 data; + + // Set the right address and start the register read operation + enc28j60Write(MIREGADR, address); + enc28j60Write(MICMD, MICMD_MIIRD); + + // wait until the PHY read completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY); + + // quit reading + enc28j60Write(MICMD, 0x00); + + // get data value + data = enc28j60Read(MIRDL); + data |= enc28j60Read(MIRDH); + // return the data + return data; +} + +void enc28j60PhyWrite(u08 address, u16 data) +{ + // set the PHY register address + enc28j60Write(MIREGADR, address); + + // write the PHY data + enc28j60Write(MIWRL, data); + enc28j60Write(MIWRH, data>>8); + + // wait until the PHY write completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY); +} + +void enc28j60Init(void) +{ + // initialize I/O + sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS); + sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); + + // setup SPI I/O pins + sbi(ENC28J60_SPI_PORT, ENC28J60_SPI_SCK); // set SCK hi + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SCK); // set SCK as output + cbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MISO); // set MISO as input + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MOSI); // set MOSI as output + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SS); // SS must be output for Master mode to work + // initialize SPI interface + // master mode + sbi(SPCR, MSTR); + // select clock phase positive-going in middle of data + cbi(SPCR, CPOL); + // Data order MSB first + cbi(SPCR,DORD); + // switch to f/4 2X = f/2 bitrate + cbi(SPCR, SPR0); + cbi(SPCR, SPR1); + sbi(SPSR, SPI2X); + // enable SPI + sbi(SPCR, SPE); + + // perform system reset + enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); + // check CLKRDY bit to see if reset is complete + delay_us(50); + while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); + + // do bank 0 stuff + // initialize receive buffer + // 16-bit transfers, must write low byte first + // set receive buffer start address + NextPacketPtr = RXSTART_INIT; + enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXSTH, RXSTART_INIT>>8); + // set receive pointer address + enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + // set receive buffer end + // ERXND defaults to 0x1FFF (end of ram) + enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + // set transmit buffer start + // ETXST defaults to 0x0000 (beginnging of ram) + enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + enc28j60Write(ETXSTH, TXSTART_INIT>>8); + + // do bank 2 stuff + // enable MAC receive + enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + // bring MAC out of reset + enc28j60Write(MACON2, 0x00); + // enable automatic padding and CRC operations + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); +// enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + // set inter-frame gap (non-back-to-back) + enc28j60Write(MAIPGL, 0x12); + enc28j60Write(MAIPGH, 0x0C); + // set inter-frame gap (back-to-back) + enc28j60Write(MABBIPG, 0x12); + // Set the maximum packet size which the controller will accept + enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + + // do bank 3 stuff + // write MAC address + // NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, ENC28J60_MAC0); + enc28j60Write(MAADR4, ENC28J60_MAC1); + enc28j60Write(MAADR3, ENC28J60_MAC2); + enc28j60Write(MAADR2, ENC28J60_MAC3); + enc28j60Write(MAADR1, ENC28J60_MAC4); + enc28j60Write(MAADR0, ENC28J60_MAC5); + + // no loopback of transmitted frames + enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + + // switch to bank 0 + enc28j60SetBank(ECON1); + // enable interrutps + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + // enable packet reception + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +/* + enc28j60PhyWrite(PHLCON, 0x0AA2); + + // setup duplex ---------------------- + + // Disable receive logic and abort any packets currently being transmitted + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN); + + { + u16 temp; + // Set the PHY to the proper duplex mode + temp = enc28j60PhyRead(PHCON1); + temp &= ~PHCON1_PDPXMD; + enc28j60PhyWrite(PHCON1, temp); + // Set the MAC to the proper duplex mode + temp = enc28j60Read(MACON3); + temp &= ~MACON3_FULDPX; + enc28j60Write(MACON3, temp); + } + + // Set the back-to-back inter-packet gap time to IEEE specified + // requirements. The meaning of the MABBIPG value changes with the duplex + // state, so it must be updated in this function. + // In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex + //enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12); + + // Reenable receive logic + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); + + // setup duplex ---------------------- +*/ +} + +void enc28j60PacketSend(unsigned int len, unsigned char* packet) +{ + // Set the write pointer to start of transmit buffer area + enc28j60Write(EWRPTL, TXSTART_INIT); + enc28j60Write(EWRPTH, TXSTART_INIT>>8); + // Set the TXND pointer to correspond to the packet size given + enc28j60Write(ETXNDL, (TXSTART_INIT+len)); + enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + + // write per-packet control byte + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, packet); + + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); +} + +unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet) +{ + u16 rxstat; + u16 len; + + // check if a packet has been received and buffered +// if( !(enc28j60Read(EIR) & EIR_PKTIF) ) + if( !enc28j60Read(EPKTCNT) ) + return 0; + + // Make absolutely certain that any previous packet was discarded + //if( WasDiscarded == FALSE) + // MACDiscardRx(); + + // Set the read pointer to the start of the received packet + enc28j60Write(ERDPTL, (NextPacketPtr)); + enc28j60Write(ERDPTH, (NextPacketPtr)>>8); + // read the next packet pointer + NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the packet length + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the receive status + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + + // limit retrieve length + // (we reduce the MAC-reported length by 4 to remove the CRC) + len = MIN(len, maxlen); + + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, packet); + + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out + enc28j60Write(ERXRDPTL, (NextPacketPtr)); + enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8); + + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + + return len; +} + +void enc28j60ReceiveOverflowRecover(void) +{ + // receive buffer overflow handling procedure + + // recovery completed +} + +void enc28j60RegDump(void) +{ +// unsigned char macaddr[6]; +// result = ax88796Read(TR); + +// rprintf("Media State: "); +// if(!(result & AUTOD)) +// rprintf("Autonegotiation\r\n"); +// else if(result & RST_B) +// rprintf("PHY in Reset \r\n"); +// else if(!(result & RST_10B)) +// rprintf("10BASE-T \r\n"); +// else if(!(result & RST_TXB)) +// rprintf("100BASE-T \r\n"); + + rprintf("RevID: 0x%x\r\n", enc28j60Read(EREVID)); + + rprintfProgStrM("Cntrl: ECON1 ECON2 ESTAT EIR EIE\r\n"); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ECON1)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ECON2)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ESTAT)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(EIR)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(EIE)); + rprintfCRLF(); + + rprintfProgStrM("MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON1)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON2)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON3)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON4)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(MAADR5)); + rprintfu08(enc28j60Read(MAADR4)); + rprintfu08(enc28j60Read(MAADR3)); + rprintfu08(enc28j60Read(MAADR2)); + rprintfu08(enc28j60Read(MAADR1)); + rprintfu08(enc28j60Read(MAADR0)); + rprintfCRLF(); + + rprintfProgStrM("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXSTH)); + rprintfu08(enc28j60Read(ERXSTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXNDH)); + rprintfu08(enc28j60Read(ERXNDL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXWRPTH)); + rprintfu08(enc28j60Read(ERXWRPTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXRDPTH)); + rprintfu08(enc28j60Read(ERXRDPTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXFCON)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(EPKTCNT)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MAMXFLH)); + rprintfu08(enc28j60Read(MAMXFLL)); + rprintfCRLF(); + + rprintfProgStrM("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ETXSTH)); + rprintfu08(enc28j60Read(ETXSTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ETXNDH)); + rprintfu08(enc28j60Read(ETXNDL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACLCON1)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACLCON2)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MAPHSUP)); + rprintfCRLF(); + + delay_ms(25); +} + + diff --git a/3rd party/Procyuon avrlib/enc28j60.h b/3rd party/Procyuon avrlib/enc28j60.h new file mode 100644 index 0000000..71f3733 --- /dev/null +++ b/3rd party/Procyuon avrlib/enc28j60.h @@ -0,0 +1,229 @@ +#ifndef _ENC28J60 +#define _ENC28j60 + +#define nop() asm volatile ("nop") +#define ADDR_MASK 0x1F +#define BANK_MASK 0x60 +#define SPRD_MASK 0x80 +#define EIE 0x1B +#define EIR 0x1C +#define ESTAT 0x1D +#define ECON2 0x1E +#define ECON1 0x1F +#define ERDPTL (0x00|0x00) +#define ERDPTH (0x01|0x00) +#define EWRPTL (0x02|0x00) +#define EWRPTH (0x03|0x00) +#define ETXSTL (0x04|0x00) +#define ETXSTH (0x05|0x00) +#define ETXNDL (0x06|0x00) +#define ETXNDH (0x07|0x00) +#define ERXSTL (0x08|0x00) +#define ERXSTH (0x09|0x00) +#define ERXNDL (0x0A|0x00) +#define ERXNDH (0x0B|0x00) +#define ERXRDPTL (0x0C|0x00) +#define ERXRDPTH (0x0D|0x00) +#define ERXWRPTL (0x0E|0x00) +#define ERXWRPTH (0x0F|0x00) +#define EDMASTL (0x10|0x00) +#define EDMASTH (0x11|0x00) +#define EDMANDL (0x12|0x00) +#define EDMANDH (0x13|0x00) +#define EDMADSTL (0x14|0x00) +#define EDMADSTH (0x15|0x00) +#define EDMACSL (0x16|0x00) +#define EDMACSH (0x17|0x00) +#define EHT0 (0x00|0x20) +#define EHT1 (0x01|0x20) +#define EHT2 (0x02|0x20) +#define EHT3 (0x03|0x20) +#define EHT4 (0x04|0x20) +#define EHT5 (0x05|0x20) +#define EHT6 (0x06|0x20) +#define EHT7 (0x07|0x20) +#define EPMM0 (0x08|0x20) +#define EPMM1 (0x09|0x20) +#define EPMM2 (0x0A|0x20) +#define EPMM3 (0x0B|0x20) +#define EPMM4 (0x0C|0x20) +#define EPMM5 (0x0D|0x20) +#define EPMM6 (0x0E|0x20) +#define EPMM7 (0x0F|0x20) +#define EPMCSL (0x10|0x20) +#define EPMCSH (0x11|0x20) +#define EPMOL (0x14|0x20) +#define EPMOH (0x15|0x20) +#define EWOLIE (0x16|0x20) +#define EWOLIR (0x17|0x20) +#define ERXFCON (0x18|0x20) +#define EPKTCNT (0x19|0x20) +#define MACON1 (0x00|0x40|0x80) +#define MACON2 (0x01|0x40|0x80) +#define MACON3 (0x02|0x40|0x80) +#define MACON4 (0x03|0x40|0x80) +#define MABBIPG (0x04|0x40|0x80) +#define MAIPGL (0x06|0x40|0x80) +#define MAIPGH (0x07|0x40|0x80) +#define MACLCON1 (0x08|0x40|0x80) +#define MACLCON2 (0x09|0x40|0x80) +#define MAMXFLL (0x0A|0x40|0x80) +#define MAMXFLH (0x0B|0x40|0x80) +#define MAPHSUP (0x0D|0x40|0x80) +#define MICON (0x11|0x40|0x80) +#define MICMD (0x12|0x40|0x80) +#define MIREGADR (0x14|0x40|0x80) +#define MIWRL (0x16|0x40|0x80) +#define MIWRH (0x17|0x40|0x80) +#define MIRDL (0x18|0x40|0x80) +#define MIRDH (0x19|0x40|0x80) +#define MAADR1 (0x00|0x60|0x80) +#define MAADR0 (0x01|0x60|0x80) +#define MAADR3 (0x02|0x60|0x80) +#define MAADR2 (0x03|0x60|0x80) +#define MAADR5 (0x04|0x60|0x80) +#define MAADR4 (0x05|0x60|0x80) +#define EBSTSD (0x06|0x60) +#define EBSTCON (0x07|0x60) +#define EBSTCSL (0x08|0x60) +#define EBSTCSH (0x09|0x60) +#define MISTAT (0x0A|0x60|0x80) +#define EREVID (0x12|0x60) +#define ECOCON (0x15|0x60) +#define EFLOCON (0x17|0x60) +#define EPAUSL (0x18|0x60) +#define EPAUSH (0x19|0x60) +#define PHCON1 0x00 +#define PHSTAT1 0x01 +#define PHHID1 0x02 +#define PHHID2 0x03 +#define PHCON2 0x10 +#define PHSTAT2 0x11 +#define PHIE 0x12 +#define PHIR 0x13 +#define PHLCON 0x14 +#define EIE_INTIE 0x80 +#define EIE_PKTIE 0x40 +#define EIE_DMAIE 0x20 +#define EIE_LINKIE 0x10 +#define EIE_TXIE 0x08 +#define EIE_WOLIE 0x04 +#define EIE_TXERIE 0x02 +#define EIE_RXERIE 0x01 +#define EIR_PKTIF 0x40 +#define EIR_DMAIF 0x20 +#define EIR_LINKIF 0x10 +#define EIR_TXIF 0x08 +#define EIR_WOLIF 0x04 +#define EIR_TXERIF 0x02 +#define EIR_RXERIF 0x01 +#define ESTAT_INT 0x80 +#define ESTAT_LATECOL 0x10 +#define ESTAT_RXBUSY 0x04 +#define ESTAT_TXABRT 0x02 +#define ESTAT_CLKRDY 0x01 +#define ECON2_AUTOINC 0x80 +#define ECON2_PKTDEC 0x40 +#define ECON2_PWRSV 0x20 +#define ECON2_VRPS 0x08 +#define ECON1_TXRST 0x80 +#define ECON1_RXRST 0x40 +#define ECON1_DMAST 0x20 +#define ECON1_CSUMEN 0x10 +#define ECON1_TXRTS 0x08 +#define ECON1_RXEN 0x04 +#define ECON1_BSEL1 0x02 +#define ECON1_BSEL0 0x01 +#define MACON1_LOOPBK 0x10 +#define MACON1_TXPAUS 0x08 +#define MACON1_RXPAUS 0x04 +#define MACON1_PASSALL 0x02 +#define MACON1_MARXEN 0x01 +#define MACON2_MARST 0x80 +#define MACON2_RNDRST 0x40 +#define MACON2_MARXRST 0x08 +#define MACON2_RFUNRST 0x04 +#define MACON2_MATXRST 0x02 +#define MACON2_TFUNRST 0x01 +#define MACON3_PADCFG2 0x80 +#define MACON3_PADCFG1 0x40 +#define MACON3_PADCFG0 0x20 +#define MACON3_TXCRCEN 0x10 +#define MACON3_PHDRLEN 0x08 +#define MACON3_HFRMLEN 0x04 +#define MACON3_FRMLNEN 0x02 +#define MACON3_FULDPX 0x01 +#define MICMD_MIISCAN 0x02 +#define MICMD_MIIRD 0x01 +#define MISTAT_NVALID 0x04 +#define MISTAT_SCAN 0x02 +#define MISTAT_BUSY 0x01 +#define PHCON1_PRST 0x8000 +#define PHCON1_PLOOPBK 0x4000 +#define PHCON1_PPWRSV 0x0800 +#define PHCON1_PDPXMD 0x0100 +#define PHSTAT1_PFDPX 0x1000 +#define PHSTAT1_PHDPX 0x0800 +#define PHSTAT1_LLSTAT 0x0004 +#define PHSTAT1_JBSTAT 0x0002 +#define PHCON2_FRCLINK 0x4000 +#define PHCON2_TXDIS 0x2000 +#define PHCON2_JABBER 0x0400 +#define PHCON2_HDLDIS 0x0100 +#define PKTCTRL_PHUGEEN 0x08 +#define PKTCTRL_PPADEN 0x04 +#define PKTCTRL_PCRCEN 0x02 +#define PKTCTRL_POVERRIDE 0x01 +#define ENC28J60_READ_CTRL_REG 0x00 +#define ENC28J60_READ_BUF_MEM 0x3A +#define ENC28J60_WRITE_CTRL_REG 0x40 +#define ENC28J60_WRITE_BUF_MEM 0x7A +#define ENC28J60_BIT_FIELD_SET 0x80 +#define ENC28J60_BIT_FIELD_CLR 0xA0 +#define ENC28J60_SOFT_RESET 0xFF +#define TXSTART_INIT 0x0000 +#define RXSTART_INIT 0x0600 +#define RXSTOP_INIT 0x1FFF +#define MAX_FRAMELEN 1518 +#define ETHERNET_MIN_PACKET_LENGTH 0x3C + +Functions +/// do a ENC28J60 read operation +u08 enc28j60ReadOp (u08 op, u08 address); + +/// do a ENC28J60 write operation +void enc28j60WriteOp (u08 op, u08 address, u08 data); + +/// read the packet buffer memory +void enc28j60ReadBuffer (u16 len, u08 *data); + +/// write the packet buffer memory +void enc28j60WriteBuffer (u16 len, u08 *data); + +/// set the register bank for register at address +void enc28j60SetBank (u08 address); + +/// read ax88796 register +u08 enc28j60Read (u08 address); + +/// write ax88796 register +void enc28j60Write (u08 address, u08 data); + +/// read a PHY register +u16 enc28j60PhyRead (u08 address); + +/// write a PHY register +void enc28j60PhyWrite (u08 address, u16 data); + +/// initialize the ethernet interface for transmit/receive +void enc28j60Init (void); + +void enc28j60PacketSend (unsigned int len, unsigned char *packet) + +unsigned int enc28j60PacketReceive (unsigned int maxlen, unsigned char *packet) + +void enc28j60ReceiveOverflowRecover (void) + +/// formatted print of important ENC28J60 registers +void enc28j60RegDump (void) +#endif diff --git a/3rd party/Procyuon avrlib/enc28j60_2.c b/3rd party/Procyuon avrlib/enc28j60_2.c new file mode 100644 index 0000000..028b626 --- /dev/null +++ b/3rd party/Procyuon avrlib/enc28j60_2.c @@ -0,0 +1,544 @@ +00001 /*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */ +00002 //***************************************************************************** +00003 // +00004 // File Name : 'enc28j60.c' +00005 // Title : Microchip ENC28J60 Ethernet Interface Driver +00006 // Author : Pascal Stang (c)2005 +00007 // Created : 9/22/2005 +00008 // Revised : 9/22/2005 +00009 // Version : 0.1 +00010 // Target MCU : Atmel AVR series +00011 // Editor Tabs : 4 +00012 // +00013 // Description : This driver provides initialization and transmit/receive +00014 // functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. +00015 // This chip is novel in that it is a full MAC+PHY interface all in a 28-pin +00016 // chip, using an SPI interface to the host processor. +00017 // +00018 //***************************************************************************** +00019 +00020 #include "avr/io.h" +00021 +00022 #include "global.h" +00023 #include "timer.h" +00024 #include "rprintf.h" +00025 +00026 #include "enc28j60.h" +00027 +00028 #ifdef SPDR0 +00029 #define SPDR SPDR0 +00030 #define SPCR SPCR0 +00031 #define SPSR SPSR0 +00032 +00033 #define SPIF SPIF0 +00034 #define MSTR MSTR0 +00035 #define CPOL CPOL0 +00036 #define DORD DORD0 +00037 #define SPR0 SPR00 +00038 #define SPR1 SPR01 +00039 #define SPI2X SPI2X0 +00040 #define SPE SPE0 +00041 #endif +00042 +00043 // include configuration +00044 #include "enc28j60conf.h" +00045 +00046 u08 Enc28j60Bank; +00047 u16 NextPacketPtr; +00048 +00049 void nicInit(void) +00050 { +00051 enc28j60Init(); +00052 } +00053 +00054 void nicSend(unsigned int len, unsigned char* packet) +00055 { +00056 enc28j60PacketSend(len, packet); +00057 } +00058 +00059 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +00060 { +00061 return enc28j60PacketReceive(maxlen, packet); +00062 } +00063 +00064 void nicGetMacAddress(u08* macaddr) +00065 { +00066 // read MAC address registers +00067 // NOTE: MAC address in ENC28J60 is byte-backward +00068 *macaddr++ = enc28j60Read(MAADR5); +00069 *macaddr++ = enc28j60Read(MAADR4); +00070 *macaddr++ = enc28j60Read(MAADR3); +00071 *macaddr++ = enc28j60Read(MAADR2); +00072 *macaddr++ = enc28j60Read(MAADR1); +00073 *macaddr++ = enc28j60Read(MAADR0); +00074 } +00075 +00076 void nicSetMacAddress(u08* macaddr) +00077 { +00078 // write MAC address +00079 // NOTE: MAC address in ENC28J60 is byte-backward +00080 enc28j60Write(MAADR5, *macaddr++); +00081 enc28j60Write(MAADR4, *macaddr++); +00082 enc28j60Write(MAADR3, *macaddr++); +00083 enc28j60Write(MAADR2, *macaddr++); +00084 enc28j60Write(MAADR1, *macaddr++); +00085 enc28j60Write(MAADR0, *macaddr++); +00086 } +00087 +00088 void nicRegDump(void) +00089 { +00090 enc28j60RegDump(); +00091 } +00092 +00093 /* +00094 void ax88796SetupPorts(void) +00095 { +00096 #if NIC_CONNECTION == MEMORY_MAPPED +00097 // enable external SRAM interface - no wait states +00098 sbi(MCUCR, SRE); +00099 // sbi(MCUCR, SRW10); +00100 // sbi(XMCRA, SRW00); +00101 // sbi(XMCRA, SRW01); +00102 // sbi(XMCRA, SRW11); +00103 #else +00104 // set address port to output +00105 AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK; +00106 +00107 // set data port to input with pull-ups +00108 AX88796_DATA_DDR = 0x00; +00109 AX88796_DATA_PORT = 0xFF; +00110 +00111 // initialize the control port read and write pins to de-asserted +00112 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN ); +00113 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN ); +00114 // set the read and write pins to output +00115 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN ); +00116 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN ); +00117 #endif +00118 // set reset pin to output +00119 sbi( AX88796_RESET_DDR, AX88796_RESET_PIN ); +00120 } +00121 */ +00122 +00123 u08 enc28j60ReadOp(u08 op, u08 address) +00124 { +00125 u08 data; +00126 +00127 // assert CS +00128 ENC28J60_CONTROL_PORT &= ~(1<>5); +00211 Enc28j60Bank = (address & BANK_MASK); +00212 } +00213 } +00214 +00215 u08 enc28j60Read(u08 address) +00216 { +00217 // set the bank +00218 enc28j60SetBank(address); +00219 // do the read +00220 return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); +00221 } +00222 +00223 void enc28j60Write(u08 address, u08 data) +00224 { +00225 // set the bank +00226 enc28j60SetBank(address); +00227 // do the write +00228 enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +00229 } +00230 +00231 u16 enc28j60PhyRead(u08 address) +00232 { +00233 u16 data; +00234 +00235 // Set the right address and start the register read operation +00236 enc28j60Write(MIREGADR, address); +00237 enc28j60Write(MICMD, MICMD_MIIRD); +00238 +00239 // wait until the PHY read completes +00240 while(enc28j60Read(MISTAT) & MISTAT_BUSY); +00241 +00242 // quit reading +00243 enc28j60Write(MICMD, 0x00); +00244 +00245 // get data value +00246 data = enc28j60Read(MIRDL); +00247 data |= enc28j60Read(MIRDH); +00248 // return the data +00249 return data; +00250 } +00251 +00252 void enc28j60PhyWrite(u08 address, u16 data) +00253 { +00254 // set the PHY register address +00255 enc28j60Write(MIREGADR, address); +00256 +00257 // write the PHY data +00258 enc28j60Write(MIWRL, data); +00259 enc28j60Write(MIWRH, data>>8); +00260 +00261 // wait until the PHY write completes +00262 while(enc28j60Read(MISTAT) & MISTAT_BUSY); +00263 } +00264 +00265 void enc28j60Init(void) +00266 { +00267 // initialize I/O +00268 sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS); +00269 sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); +00270 +00271 // setup SPI I/O pins +00272 sbi(ENC28J60_SPI_PORT, ENC28J60_SPI_SCK); // set SCK hi +00273 sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SCK); // set SCK as output +00274 cbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MISO); // set MISO as input +00275 sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MOSI); // set MOSI as output +00276 sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SS); // SS must be output for Master mode to work +00277 // initialize SPI interface +00278 // master mode +00279 sbi(SPCR, MSTR); +00280 // select clock phase positive-going in middle of data +00281 cbi(SPCR, CPOL); +00282 // Data order MSB first +00283 cbi(SPCR,DORD); +00284 // switch to f/4 2X = f/2 bitrate +00285 cbi(SPCR, SPR0); +00286 cbi(SPCR, SPR1); +00287 sbi(SPSR, SPI2X); +00288 // enable SPI +00289 sbi(SPCR, SPE); +00290 +00291 // perform system reset +00292 enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); +00293 // check CLKRDY bit to see if reset is complete +00294 delay_us(50); +00295 while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); +00296 +00297 // do bank 0 stuff +00298 // initialize receive buffer +00299 // 16-bit transfers, must write low byte first +00300 // set receive buffer start address +00301 NextPacketPtr = RXSTART_INIT; +00302 enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); +00303 enc28j60Write(ERXSTH, RXSTART_INIT>>8); +00304 // set receive pointer address +00305 enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); +00306 enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); +00307 // set receive buffer end +00308 // ERXND defaults to 0x1FFF (end of ram) +00309 enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); +00310 enc28j60Write(ERXNDH, RXSTOP_INIT>>8); +00311 // set transmit buffer start +00312 // ETXST defaults to 0x0000 (beginnging of ram) +00313 enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); +00314 enc28j60Write(ETXSTH, TXSTART_INIT>>8); +00315 +00316 // do bank 2 stuff +00317 // enable MAC receive +00318 enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); +00319 // bring MAC out of reset +00320 enc28j60Write(MACON2, 0x00); +00321 // enable automatic padding and CRC operations +00322 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); +00323 // enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); +00324 // set inter-frame gap (non-back-to-back) +00325 enc28j60Write(MAIPGL, 0x12); +00326 enc28j60Write(MAIPGH, 0x0C); +00327 // set inter-frame gap (back-to-back) +00328 enc28j60Write(MABBIPG, 0x12); +00329 // Set the maximum packet size which the controller will accept +00330 enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); +00331 enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); +00332 +00333 // do bank 3 stuff +00334 // write MAC address +00335 // NOTE: MAC address in ENC28J60 is byte-backward +00336 enc28j60Write(MAADR5, ENC28J60_MAC0); +00337 enc28j60Write(MAADR4, ENC28J60_MAC1); +00338 enc28j60Write(MAADR3, ENC28J60_MAC2); +00339 enc28j60Write(MAADR2, ENC28J60_MAC3); +00340 enc28j60Write(MAADR1, ENC28J60_MAC4); +00341 enc28j60Write(MAADR0, ENC28J60_MAC5); +00342 +00343 // no loopback of transmitted frames +00344 enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); +00345 +00346 // switch to bank 0 +00347 enc28j60SetBank(ECON1); +00348 // enable interrutps +00349 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); +00350 // enable packet reception +00351 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +00352 /* +00353 enc28j60PhyWrite(PHLCON, 0x0AA2); +00354 +00355 // setup duplex ---------------------- +00356 +00357 // Disable receive logic and abort any packets currently being transmitted +00358 enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN); +00359 +00360 { +00361 u16 temp; +00362 // Set the PHY to the proper duplex mode +00363 temp = enc28j60PhyRead(PHCON1); +00364 temp &= ~PHCON1_PDPXMD; +00365 enc28j60PhyWrite(PHCON1, temp); +00366 // Set the MAC to the proper duplex mode +00367 temp = enc28j60Read(MACON3); +00368 temp &= ~MACON3_FULDPX; +00369 enc28j60Write(MACON3, temp); +00370 } +00371 +00372 // Set the back-to-back inter-packet gap time to IEEE specified +00373 // requirements. The meaning of the MABBIPG value changes with the duplex +00374 // state, so it must be updated in this function. +00375 // In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex +00376 //enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12); +00377 +00378 // Reenable receive logic +00379 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +00380 +00381 // setup duplex ---------------------- +00382 */ +00383 } +00384 +00385 void enc28j60PacketSend(unsigned int len, unsigned char* packet) +00386 { +00387 // Set the write pointer to start of transmit buffer area +00388 enc28j60Write(EWRPTL, TXSTART_INIT); +00389 enc28j60Write(EWRPTH, TXSTART_INIT>>8); +00390 // Set the TXND pointer to correspond to the packet size given +00391 enc28j60Write(ETXNDL, (TXSTART_INIT+len)); +00392 enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); +00393 +00394 // write per-packet control byte +00395 enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); +00396 +00397 // copy the packet into the transmit buffer +00398 enc28j60WriteBuffer(len, packet); +00399 +00400 // send the contents of the transmit buffer onto the network +00401 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); +00402 } +00403 +00404 unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet) +00405 { +00406 u16 rxstat; +00407 u16 len; +00408 +00409 // check if a packet has been received and buffered +00410 // if( !(enc28j60Read(EIR) & EIR_PKTIF) ) +00411 if( !enc28j60Read(EPKTCNT) ) +00412 return 0; +00413 +00414 // Make absolutely certain that any previous packet was discarded +00415 //if( WasDiscarded == FALSE) +00416 // MACDiscardRx(); +00417 +00418 // Set the read pointer to the start of the received packet +00419 enc28j60Write(ERDPTL, (NextPacketPtr)); +00420 enc28j60Write(ERDPTH, (NextPacketPtr)>>8); +00421 // read the next packet pointer +00422 NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); +00423 NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; +00424 // read the packet length +00425 len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); +00426 len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; +00427 // read the receive status +00428 rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); +00429 rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; +00430 +00431 // limit retrieve length +00432 // (we reduce the MAC-reported length by 4 to remove the CRC) +00433 len = MIN(len, maxlen); +00434 +00435 // copy the packet from the receive buffer +00436 enc28j60ReadBuffer(len, packet); +00437 +00438 // Move the RX read pointer to the start of the next received packet +00439 // This frees the memory we just read out +00440 enc28j60Write(ERXRDPTL, (NextPacketPtr)); +00441 enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8); +00442 +00443 // decrement the packet counter indicate we are done with this packet +00444 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); +00445 +00446 return len; +00447 } +00448 +00449 void enc28j60ReceiveOverflowRecover(void) +00450 { +00451 // receive buffer overflow handling procedure +00452 +00453 // recovery completed +00454 } +00455 +00456 void enc28j60RegDump(void) +00457 { +00458 // unsigned char macaddr[6]; +00459 // result = ax88796Read(TR); +00460 +00461 // rprintf("Media State: "); +00462 // if(!(result & AUTOD)) +00463 // rprintf("Autonegotiation\r\n"); +00464 // else if(result & RST_B) +00465 // rprintf("PHY in Reset \r\n"); +00466 // else if(!(result & RST_10B)) +00467 // rprintf("10BASE-T \r\n"); +00468 // else if(!(result & RST_TXB)) +00469 // rprintf("100BASE-T \r\n"); +00470 +00471 rprintf("RevID: 0x%x\r\n", enc28j60Read(EREVID)); +00472 +00473 rprintfProgStrM("Cntrl: ECON1 ECON2 ESTAT EIR EIE\r\n"); +00474 rprintfProgStrM(" "); +00475 rprintfu08(enc28j60Read(ECON1)); +00476 rprintfProgStrM(" "); +00477 rprintfu08(enc28j60Read(ECON2)); +00478 rprintfProgStrM(" "); +00479 rprintfu08(enc28j60Read(ESTAT)); +00480 rprintfProgStrM(" "); +00481 rprintfu08(enc28j60Read(EIR)); +00482 rprintfProgStrM(" "); +00483 rprintfu08(enc28j60Read(EIE)); +00484 rprintfCRLF(); +00485 +00486 rprintfProgStrM("MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address\r\n"); +00487 rprintfProgStrM(" 0x"); +00488 rprintfu08(enc28j60Read(MACON1)); +00489 rprintfProgStrM(" 0x"); +00490 rprintfu08(enc28j60Read(MACON2)); +00491 rprintfProgStrM(" 0x"); +00492 rprintfu08(enc28j60Read(MACON3)); +00493 rprintfProgStrM(" 0x"); +00494 rprintfu08(enc28j60Read(MACON4)); +00495 rprintfProgStrM(" "); +00496 rprintfu08(enc28j60Read(MAADR5)); +00497 rprintfu08(enc28j60Read(MAADR4)); +00498 rprintfu08(enc28j60Read(MAADR3)); +00499 rprintfu08(enc28j60Read(MAADR2)); +00500 rprintfu08(enc28j60Read(MAADR1)); +00501 rprintfu08(enc28j60Read(MAADR0)); +00502 rprintfCRLF(); +00503 +00504 rprintfProgStrM("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n"); +00505 rprintfProgStrM(" 0x"); +00506 rprintfu08(enc28j60Read(ERXSTH)); +00507 rprintfu08(enc28j60Read(ERXSTL)); +00508 rprintfProgStrM(" 0x"); +00509 rprintfu08(enc28j60Read(ERXNDH)); +00510 rprintfu08(enc28j60Read(ERXNDL)); +00511 rprintfProgStrM(" 0x"); +00512 rprintfu08(enc28j60Read(ERXWRPTH)); +00513 rprintfu08(enc28j60Read(ERXWRPTL)); +00514 rprintfProgStrM(" 0x"); +00515 rprintfu08(enc28j60Read(ERXRDPTH)); +00516 rprintfu08(enc28j60Read(ERXRDPTL)); +00517 rprintfProgStrM(" 0x"); +00518 rprintfu08(enc28j60Read(ERXFCON)); +00519 rprintfProgStrM(" 0x"); +00520 rprintfu08(enc28j60Read(EPKTCNT)); +00521 rprintfProgStrM(" 0x"); +00522 rprintfu08(enc28j60Read(MAMXFLH)); +00523 rprintfu08(enc28j60Read(MAMXFLL)); +00524 rprintfCRLF(); +00525 +00526 rprintfProgStrM("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\r\n"); +00527 rprintfProgStrM(" 0x"); +00528 rprintfu08(enc28j60Read(ETXSTH)); +00529 rprintfu08(enc28j60Read(ETXSTL)); +00530 rprintfProgStrM(" 0x"); +00531 rprintfu08(enc28j60Read(ETXNDH)); +00532 rprintfu08(enc28j60Read(ETXNDL)); +00533 rprintfProgStrM(" 0x"); +00534 rprintfu08(enc28j60Read(MACLCON1)); +00535 rprintfProgStrM(" 0x"); +00536 rprintfu08(enc28j60Read(MACLCON2)); +00537 rprintfProgStrM(" 0x"); +00538 rprintfu08(enc28j60Read(MAPHSUP)); +00539 rprintfCRLF(); +00540 +00541 delay_ms(25); +00542 } + + diff --git a/3rd party/Procyuon avrlib/encoder.c b/3rd party/Procyuon avrlib/encoder.c new file mode 100644 index 0000000..188a5f3 --- /dev/null +++ b/3rd party/Procyuon avrlib/encoder.c @@ -0,0 +1,226 @@ +/*! \file encoder.c \brief Quadrature Encoder reader/driver. */ +//***************************************************************************** +// +// File Name : 'encoder.c' +// Title : Quadrature Encoder reader/driver +// Author : Pascal Stang - Copyright (C) 2003-2004 +// Created : 2003.01.26 +// Revised : 2004.06.25 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "encoder.h" + +// Program ROM constants + +// Global variables +volatile EncoderStateType EncoderState[NUM_ENCODERS]; + +// Functions + +// encoderInit() initializes hardware and encoder position readings +// Run this init routine once before using any other encoder functions. +void encoderInit(void) +{ + u08 i; + + // initialize/clear encoder data + for(i=0; iright), PhaseB is always low (logic 0) at +/// the rising edge of PhaseA. When we travel backwards in time (right->left), +/// PhaseB is always high (logic 1) at the rising edge of PhaseA. Note that +/// traveling forward or backwards in time is the same thing as rotating +/// forwards or bardwards. Thus, if PhaseA is our counter, PhaseB indicates +/// direction. +/// +/// Here is an example waveform from a quadrature encoder: +/* +/// /---\ /---\ /---\ /---\ /---\ /---\ +/// Phase A: | | | | | | | | | | | | +/// ---/ \---/ \---/ \---/ \---/ \---/ \- +/// -\ /---\ /---\ /---\ /---\ /---\ /--- +/// Phase B: | | | | | | | | | | | | +/// \---/ \---/ \---/ \---/ \---/ \---/ +/// Time: <---------------------------------------------------> +/// Rotate FWD: >----------------------------------------------> +/// Rotate REV: <----------------------------------------------< +*/ +/// To keep track of the encoder position in software, we connect PhaseA to an +/// external processor interrupt line, and PhaseB to any I/O pin. We set up +/// the external interrupt to trigger whenever PhaseA produces a rising edge. +/// When a rising edge is detected, our interrupt handler function is executed. +/// Inside the handler function, we quickly check the PhaseB line to see if it +/// is high or low. If it is high, we increment the encoder's position +/// counter, otherwise we decrement it. The encoder position counter can be +/// read at any time to find out the current position. +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENCODER_H +#define ENCODER_H + +#include "global.h" + +// include encoder configuration file +#include "encoderconf.h" + +// constants/macros/typdefs + +// defines for processor compatibility +// chose proper Interrupt Mask (IMSK) +#ifdef EIMSK + #define IMSK EIMSK // for processors mega128, mega64 +#endif +#ifdef GICR + #define IMSK GICR // for mega16,32,etc +#endif +// default +#ifndef IMSK + #define IMSK GIMSK // for other processors 90s8515, mega163, etc +#endif + + +//! Encoder state structure +// stores the position and other information from each encoder +typedef struct struct_EncoderState +{ + s32 position; ///< position +} EncoderStateType; + + +// functions + +//! encoderInit() initializes hardware and encoder position readings +// Run this init routine once before using any other encoder function. +void encoderInit(void); + +//! encoderOff() disables hardware and stops encoder position updates +void encoderOff(void); + +//! encoderGetPosition() reads the current position of the encoder +s32 encoderGetPosition(u08 encoderNum); + +//! encoderSetPosition() sets the current position of the encoder +void encoderSetPosition(u08 encoderNum, s32 position); + +#endif diff --git a/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsp new file mode 100644 index 0000000..0646b88 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\a2dtest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/a2d/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/a2d/a2dtest.c b/3rd party/Procyuon avrlib/examples/a2d/a2dtest.c new file mode 100644 index 0000000..9737974 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/a2d/a2dtest.c @@ -0,0 +1,82 @@ +//***************************************************************************** +// File Name : a2dtest.c +// +// Title : example usage of some avr library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 20-Oct-2002 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "a2d.h" // include A/D converter function library +#include "vt100.h" // include VT100 terminal support + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + u16 a=0; + u08 i=0; + + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // turn on and initialize A/D converter + a2dInit(); + + // print a little intro message so we know things are working + vt100ClearScreen(); + vt100SetCursorPos(1,1); + rprintf("Welcome to the a2d test!\r\n"); + + // configure a2d port (PORTA) as input + // so we can receive analog signals + DDRA = 0x00; + // make sure pull-up resistors are turned off + PORTA = 0x00; + + // set the a2d prescaler (clock division ratio) + // - a lower prescale setting will make the a2d converter go faster + // - a higher setting will make it go slower but the measurements + // will be more accurate + // - other allowed prescale values can be found in a2d.h + a2dSetPrescaler(ADC_PRESCALE_DIV32); + + // set the a2d reference + // - the reference is the voltage against which a2d measurements are made + // - other allowed reference values can be found in a2d.h + a2dSetReference(ADC_REFERENCE_AVCC); + + // use a2dConvert8bit(channel#) to get an 8bit a2d reading + // use a2dConvert10bit(channel#) to get a 10bit a2d reading + + while(1) + { + // sample all a2d channels and print them to the terminal + vt100SetCursorPos(2,1); + for(i=0; i<8; i++) + { + rprintf("Channel %d: %d \r\n", i, a2dConvert8bit(i)); + } + // print the sample number so far + rprintf("Sample # : %d \r\n", a++); + } + + return 0; +} diff --git a/3rd party/Procyuon avrlib/examples/a2d/global.h b/3rd party/Procyuon avrlib/examples/a2d/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/a2d/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/a2d/makefile b/3rd party/Procyuon avrlib/examples/a2d/makefile new file mode 100644 index 0000000..ac2d123 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/a2d/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = a2dtest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/a2d.c $(AVRLIB)/vt100.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsp new file mode 100644 index 0000000..4f862b5 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ads7828test.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\i2cconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/ads7828/ads7828test.c b/3rd party/Procyuon avrlib/examples/ads7828/ads7828test.c new file mode 100644 index 0000000..c8279a8 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/ads7828test.c @@ -0,0 +1,94 @@ +//***************************************************************************** +// File Name : ads7828test.c +// +// Title : example usage of ADS7828 library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 20-Feb-2004 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support +#include "i2c.h" // include i2c support +#include "ads7828.h" // include ADS7828 support + +void ads7828test(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + uartSetBaudRate(115200); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // clear terminal screen + vt100ClearScreen(); + vt100SetCursorPos(1,1); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to ADS7828 test!\r\n"); + + // run tests + ads7828test(); + + return 0; +} + + +void ads7828test(void) +{ + u08 i; + u16 conv=0; + + // initialize i2c function library + i2cInit(); + i2cSetBitrate(30); + + // initialize + if(ads7828Init(ADS7828_I2C_ADDR)) + { + rprintf("ADS7828 detected and initialized!\r\n"); + } + else + { + rprintf("Cannot detect ADS7828!\r\n"); + return; + } + + // use the externally applied voltage on REF pin + ads7828SetReference(0); + // or use the internal 2.5V voltage reference + //ads7828SetReference(1); + + while(1) + { + // position cursor + vt100SetCursorPos(4,1); + + for(i=0; i<8; i++) + { + // convert + conv = ads7828Convert(ADS7828_I2C_ADDR, i); + // print results + rprintf("CH#%d: Conversion result is: %d \r\n", i, conv-2048); + } + // pause between readings + timerPause(100); + } +} diff --git a/3rd party/Procyuon avrlib/examples/ads7828/global.h b/3rd party/Procyuon avrlib/examples/ads7828/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/ads7828/i2cconf.h b/3rd party/Procyuon avrlib/examples/ads7828/i2cconf.h new file mode 100644 index 0000000..93d369a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2c.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/ads7828/makefile b/3rd party/Procyuon avrlib/examples/ads7828/makefile new file mode 100644 index 0000000..71190c3 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7828/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = ads7828test + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/i2c.c $(AVRLIB)/ads7828.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsp new file mode 100644 index 0000000..438f773 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ads7870test.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7870/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/ads7870/ads7870test.c b/3rd party/Procyuon avrlib/examples/ads7870/ads7870test.c new file mode 100644 index 0000000..f9cae6a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7870/ads7870test.c @@ -0,0 +1,84 @@ +//***************************************************************************** +// File Name : ads7870test.c +// +// Title : example usage of ADS7870 library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 07-Jul-2005 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support +#include "spi.h" // include spi support +#include "ads7870.h" // include ADS7828 support + +void ads7870test(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + uartSetBaudRate(115200); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // clear terminal screen + vt100ClearScreen(); + vt100SetCursorPos(1,1); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to ADS7870 test!\r\n"); + + // run tests + ads7870test(); + + return 0; +} + +void ads7870test(void) +{ + u08 i; + u16 conv=0; + + // initialize a/d converter + if(ads7870Init()) + { + rprintf("ADS7870 detected and initialized!\r\n"); + } + else + { + rprintf("Cannot detect ADS7870!\r\n"); + return; + } + + while(1) + { + // position cursor + vt100SetCursorPos(4,1); + + for(i=0; i<8; i++) + { + // convert + conv = ads7870Convert(i); + // print results + rprintf("CH#%d: Conversion result is: %d \r\n", i, conv); + } + // pause between readings + timerPause(100); + } +} diff --git a/3rd party/Procyuon avrlib/examples/ads7870/global.h b/3rd party/Procyuon avrlib/examples/ads7870/global.h new file mode 100644 index 0000000..34619e3 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7870/global.h @@ -0,0 +1,41 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 18432000 // 18.432MHz processor +//#define F_CPU 16000000 // 16.000MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8.000MHz processor +#define F_CPU 7372800 // 7.373MHz processor +//#define F_CPU 4000000 // 4.000MHz processor +//#define F_CPU 3686400 // 3.686MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/ads7870/makefile b/3rd party/Procyuon avrlib/examples/ads7870/makefile new file mode 100644 index 0000000..dfae090 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ads7870/makefile @@ -0,0 +1,97 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = ads7870test + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + AVRLIB_SRC = buffer.c uart.c rprintf.c timer.c vt100.c spi.c ads7870.c + + SRC = $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsp new file mode 100644 index 0000000..4e2225a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\basiciotest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/basic_io/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/basic_io/basiciotest.c b/3rd party/Procyuon avrlib/examples/basic_io/basiciotest.c new file mode 100644 index 0000000..4bbf453 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/basic_io/basiciotest.c @@ -0,0 +1,118 @@ +//***************************************************************************** +// File Name : basiciotest.c +// +// Title : example usage of basic input and output functions on the AVR +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 02-Feb-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +//#include "uart.h" // include uart function library +//#include "rprintf.h" // include printf function library +//#include "timer.h" // include timer function library (timing, PWM, etc) +//#include "vt100.h" // include VT100 terminal support +//#include "encoder.h" // include encoder driver + + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) +// uartInit(); + // set the baud rate of the UART for our debug/reporting output +// uartSetBaudRate(9600); + // initialize the timer system +// timerInit(); + // initialize rprintf system +// rprintfInit(uartSendByte); + // initialize vt100 library +// vt100Init(); + + // clear the terminal screen +// vt100ClearScreen(); + + u08 a; + + // All AVR processors have I/O ports which each contain up to 8 + // user-controllable pins. From a hardware perspective, these I/O pins + // are each an actual physical pin coming out of the processor chip. + // The voltage on the pins can be sensed or controlled via software, + // hence their designation as Input/Output pins. + + // While I/O pins are actual wires in the real world, they also exist + // inside the processor as special memory locations called registers. + // The software-controlled contents of these registers is what + // determines the state and operation of I/O pins and I/O ports. + + // Since AVR processors deal naturally with 8 bits at a time, I/O pins + // are grouped into sets of 8 to form I/O ports. Three registers + // are assigned to each I/O port to control the function and state of + // that port's pins. The registers are 8-bits wide, and each bit (#0-7) + // determines the operation of the corresponding number pin (pin 0-7). + // The three registers are: + + // DDRx - this register determines the direction (input/output) of the pins on port[x] + // A '0' bit in the DDR makes that port pin act as input + // A '1' bit in the DDR makes that port pin act as output + + // PORTx - this register contains the output state of the pins on port[x] + // A '0' bit makes the port pin output a LOW (~0V) + // A '1' bit makes the port pin output a HIGH (~5V) + + // PINx - this register contains the input state of the pins on port[x] + // A '0' bit indicates that the port pin is LOW (at ~0V) + // A '1' bit indicates that the port pin is HIGH (at ~5V) + + // The x should be replaced with A,B,C,D,E,F, or G depending on the + // desired port. Note that not all AVR processors have the same set + // or number of ports. Consult the datasheet for your specific processor + // to find out which ports it has. + + // in the AVR-GCC C language, ports can be accessed using two kinds of + // commands: + // inb() and outb() - in-byte and out-byte + // cbi() and sbi() - clear-bit and set-bit + + // inb() and outb() should be used when you intend to read or write + // several bits of a register at once. Here are some examples: + + outb(DDRA, 0x00); // set all port A pins to input + a = inb(PINA); // read the input state of all pins on port A + + outb(DDRB, 0xFF); // set all port B pins to output + outb(PORTB, 0xF0); // set PB4-7 to HIGH and PB0-3 to LOW + + // Often you may wish to change only a single bit in the registers + // while leaving the rest unaltered. For this, use cbi() and sbi(). + // For example: + + sbi(DDRC, 0); // sets PC0 to be an output + sbi(DDRC, 1); // sets PC1 to be an output + + cbi(PORTC, 1); // sets PC1 to output a LOW without altering any other pin + + // the lines below will cause PC0 to pulse twice, + // but will leave all other port C pins unchanged + cbi(PORTC, 0); // sets PC0 to output a LOW + sbi(PORTC, 0); // sets PC0 to output a HIGH + cbi(PORTC, 0); // sets PC0 to output a LOW + sbi(PORTC, 0); // sets PC0 to output a HIGH + cbi(PORTC, 0); // sets PC0 to output a LOW + + + return 0; +} + diff --git a/3rd party/Procyuon avrlib/examples/basic_io/global.h b/3rd party/Procyuon avrlib/examples/basic_io/global.h new file mode 100644 index 0000000..f1bc7a0 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/basic_io/global.h @@ -0,0 +1,41 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/basic_io/makefile b/3rd party/Procyuon avrlib/examples/basic_io/makefile new file mode 100644 index 0000000..272eb41 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/basic_io/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = basiciotest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsp new file mode 100644 index 0000000..4de9c2c --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\cmdlinetest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\cmdlineconf.h +# End Source File +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/cmdline/cmdlineconf.h b/3rd party/Procyuon avrlib/examples/cmdline/cmdlineconf.h new file mode 100644 index 0000000..fc6dd78 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/cmdlineconf.h @@ -0,0 +1,46 @@ +/*! \file cmdlineconf.c \brief Command-Line Interface Library Configuration. */ +//***************************************************************************** +// +// File Name : 'cmdlineconf.c' +// Title : Command-Line Interface Library Configuration +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.16 +// Revised : 2003.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef CMDLINECONF_H +#define CMDLINECONF_H + +#include "global.h" + +// constants/macros/typdefs + +// size of command database +// (maximum number of commands the cmdline system can handle) +#define CMDLINE_MAX_COMMANDS 10 + +// maximum length (number of characters) of each command string +// (quantity must include one additional byte for a null terminator) +#define CMDLINE_MAX_CMD_LENGTH 15 + +// allotted buffer size for command entry +// (must be enough chars for typed commands and the arguments that follow) +#define CMDLINE_BUFFERSIZE 80 + +// number of lines of command history to keep +// (each history buffer is CMDLINE_BUFFERSIZE in size) +// ***** ONLY ONE LINE OF COMMAND HISTORY IS CURRENTLY SUPPORTED +#define CMDLINE_HISTORYSIZE 1 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/cmdline/cmdlinetest.c b/3rd party/Procyuon avrlib/examples/cmdline/cmdlinetest.c new file mode 100644 index 0000000..54012dd --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/cmdlinetest.c @@ -0,0 +1,171 @@ +//***************************************************************************** +// File Name : cmdlinetest.c +// +// Title : example usage of cmdline (command line) functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 21-Jul-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "a2d.h" // include A/D converter function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include vt100 terminal support +#include "cmdline.h" // include cmdline function library + +// global variables +u08 Run; + +// functions +void goCmdline(void); +void exitFunction(void); +void helpFunction(void); +void dumpArgsStr(void); +void dumpArgsInt(void); +void dumpArgsHex(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + uartSetBaudRate(9600); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // turn on and initialize A/D converter + a2dInit(); + // initialize the timer system + timerInit(); + // initialize vt100 terminal + vt100Init(); + + // configure port B for led output and pushbutton input + outb(DDRB, 0x0F); + // all LEDs on + outb(PORTB, 0x00); + // wait for hardware to power up + timerPause(100); + // all LEDs off + outb(PORTB, 0x0F); + + // start command line + goCmdline(); + + return 0; +} + +void goCmdline(void) +{ + u08 c; + + // print welcome message + vt100ClearScreen(); + vt100SetCursorPos(1,0); + rprintfProgStrM("\r\nWelcome to the Command Line Test Suite!\r\n"); + + // initialize cmdline system + cmdlineInit(); + + // direct cmdline output to uart (serial port) + cmdlineSetOutputFunc(uartSendByte); + + // add commands to the command database + cmdlineAddCommand("exit", exitFunction); + cmdlineAddCommand("help", helpFunction); + cmdlineAddCommand("dumpargs1", dumpArgsStr); + cmdlineAddCommand("dumpargs2", dumpArgsInt); + cmdlineAddCommand("dumpargs3", dumpArgsHex); + + // send a CR to cmdline input to stimulate a prompt + cmdlineInputFunc('\r'); + + // set state to run + Run = TRUE; + + // main loop + while(Run) + { + // pass characters received on the uart (serial port) + // into the cmdline processor + while(uartReceiveByte(&c)) cmdlineInputFunc(c); + + // run the cmdline execution functions + cmdlineMainLoop(); + } + + rprintfCRLF(); + rprintf("Exited program!\r\n"); +} + +void exitFunction(void) +{ + // to exit, we set Run to FALSE + Run = FALSE; +} + +void helpFunction(void) +{ + rprintfCRLF(); + + rprintf("Available commands are:\r\n"); + rprintf("help - displays available commands\r\n"); + rprintf("dumpargs1 - dumps command arguments as strings\r\n"); + rprintf("dumpargs2 - dumps command arguments as decimal integers\r\n"); + rprintf("dumpargs3 - dumps command arguments as hex integers\r\n"); + + rprintfCRLF(); +} + +void dumpArgsStr(void) +{ + rprintfCRLF(); + rprintf("Dump arguments as strings\r\n"); + + rprintfProgStrM("Arg0: "); rprintfStr(cmdlineGetArgStr(0)); rprintfCRLF(); + rprintfProgStrM("Arg1: "); rprintfStr(cmdlineGetArgStr(1)); rprintfCRLF(); + rprintfProgStrM("Arg2: "); rprintfStr(cmdlineGetArgStr(2)); rprintfCRLF(); + rprintfProgStrM("Arg3: "); rprintfStr(cmdlineGetArgStr(3)); rprintfCRLF(); + rprintfCRLF(); +} + +void dumpArgsInt(void) +{ + rprintfCRLF(); + rprintf("Dump arguments as integers\r\n"); + + // printf %d will work but only if your numbers are less than 16-bit values + //rprintf("Arg1 as int: %d\r\n", cmdlineGetArgInt(1)); + //rprintf("Arg2 as int: %d\r\n", cmdlineGetArgInt(2)); + //rprintf("Arg3 as int: %d\r\n", cmdlineGetArgInt(3)); + + // printfNum is good for longs too + rprintf("Arg1 as int: "); rprintfNum(10, 10, TRUE, ' ', cmdlineGetArgInt(1)); rprintfCRLF(); + rprintf("Arg2 as int: "); rprintfNum(10, 10, TRUE, ' ', cmdlineGetArgInt(2)); rprintfCRLF(); + rprintf("Arg3 as int: "); rprintfNum(10, 10, TRUE, ' ', cmdlineGetArgInt(3)); rprintfCRLF(); + rprintfCRLF(); +} + +void dumpArgsHex(void) +{ + rprintfCRLF(); + rprintf("Dump arguments as hex integers\r\n"); + + rprintf("Arg1 as hex: "); rprintfNum(16, 8, FALSE, ' ', cmdlineGetArgHex(1)); rprintfCRLF(); + rprintf("Arg2 as hex: "); rprintfNum(16, 8, FALSE, ' ', cmdlineGetArgHex(2)); rprintfCRLF(); + rprintf("Arg3 as hex: "); rprintfNum(16, 8, FALSE, ' ', cmdlineGetArgHex(3)); rprintfCRLF(); + rprintfCRLF(); +} diff --git a/3rd party/Procyuon avrlib/examples/cmdline/global.h b/3rd party/Procyuon avrlib/examples/cmdline/global.h new file mode 100644 index 0000000..da730c8 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/global.h @@ -0,0 +1,42 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +// CYCLES_PER_US is used by some short delay loops +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/cmdline/makefile b/3rd party/Procyuon avrlib/examples/cmdline/makefile new file mode 100644 index 0000000..7a74a36 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/cmdline/makefile @@ -0,0 +1,49 @@ +# Makefile for avrproject +# Pascal Stang + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) + TRG = cmdlinetest + +#put your C sourcefiles here + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/a2d.c $(AVRLIB)/vt100.c $(AVRLIB)/cmdline.c $(TRG).c + +#put additional assembler source file here + ASRC = + +#additional libraries and object files to link + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +buffer.o : buffer.c buffer.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer128.o : timer128.c timer128.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +rtc.o : rtc.c rtc.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsp new file mode 100644 index 0000000..0df74a3 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ds1631test.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\i2cconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/ds1631/ds1631test.c b/3rd party/Procyuon avrlib/examples/ds1631/ds1631test.c new file mode 100644 index 0000000..a554a56 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/ds1631test.c @@ -0,0 +1,107 @@ +//***************************************************************************** +// File Name : ds1631test.c +// +// Title : example usage of DS1631 library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 20-Feb-2004 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support +#include "i2c.h" // include i2c support +#include "ds1631.h" // include DS1631 support + +void ds1631test(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + uartSetBaudRate(115200); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // clear terminal screen + vt100ClearScreen(); + vt100SetCursorPos(1,1); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to DS6131 test!\r\n"); + + // run tests + ds1631test(); + + return 0; +} + + +void ds1631test(void) +{ + s16 T=0; + + // initialize i2c function library + i2cInit(); + i2cSetBitrate(100); + + // initialize + if(ds1631Init(DS1631_I2C_ADDR)) + { + rprintf("DS1631 detected and initialized!\r\n"); + } + else + { + rprintf("Cannot detect DS1631!\r\n"); + return; + } + + // set config + ds1631SetConfig(DS1631_I2C_ADDR, 0x0F); + // set the temperature limit registers + ds1631SetTH(DS1631_I2C_ADDR, 35<<8); + ds1631SetTL(DS1631_I2C_ADDR, 30<<8); + // read them back for verification + rprintf("TH is set to: %d\r\n",ds1631GetTH(DS1631_I2C_ADDR)>>8); + rprintf("TL is set to: %d\r\n",ds1631GetTL(DS1631_I2C_ADDR)>>8); + + while(1) + { + // start convert + ds1631StartConvert(DS1631_I2C_ADDR); + // wait until done + // this works but seems to take forever (5-10 seconds) + //while(!(ds1631GetConfig(DS1631_I2C_ADDR) & DS1631_CONFIG_DONE)); + // 12-bit conversion are only suppored to take this long + timerPause(750); + + // read temp + T = ds1631ReadTemp(DS1631_I2C_ADDR); + + + // Print the raw temperature reading + rprintf("Raw Temp: %d ", T); + // Print the formatted temperature reading + rprintf("Real Temp is: "); + rprintfNum(10, 4, TRUE , ' ', T>>8); + rprintf("."); + rprintfNum(10, 4, FALSE, '0', (10000*((u32)(T&0x00FF)))/256 ); + rprintf(" degrees C\r\n"); + + timerPause(50); + } +} diff --git a/3rd party/Procyuon avrlib/examples/ds1631/global.h b/3rd party/Procyuon avrlib/examples/ds1631/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/ds1631/i2cconf.h b/3rd party/Procyuon avrlib/examples/ds1631/i2cconf.h new file mode 100644 index 0000000..93d369a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2c.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/ds1631/makefile b/3rd party/Procyuon avrlib/examples/ds1631/makefile new file mode 100644 index 0000000..4f0f222 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/ds1631/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = ds1631test + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/i2c.c $(AVRLIB)/ds1631.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsp new file mode 100644 index 0000000..af31f00 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\encodertest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\encoderconf.h +# End Source File +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/encoder/encoderconf.h b/3rd party/Procyuon avrlib/examples/encoder/encoderconf.h new file mode 100644 index 0000000..3718217 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/encoderconf.h @@ -0,0 +1,167 @@ +/*! \file encoderconf.h \brief Quadrature Encoder driver configuration. */ +//***************************************************************************** +// +// File Name : 'encoderconf.h' +// Title : Quadrature Encoder driver configuration +// Author : Pascal Stang - Copyright (C) 2003-2004 +// Created : 2003.01.26 +// Revised : 2004.06.25 +// Version : 0.2 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// The default number of encoders supported is 2 because most AVR processors +// have two external interrupts. To use more or fewer encoders, you must do +// four things: +// +// 1. Use a processor with at least as many external interrutps as number of +// encoders you want to have. +// 2. Set NUM_ENCODERS to the number of encoders you will use. +// 3. Comment/Uncomment the proper ENCx_SIGNAL defines for your encoders +// (the encoders must be used sequentially, 0 then 1 then 2 then 3) +// 4. Configure the various defines so that they match your processor and +// specific hardware. The notes below may help. +// +// +// -------------------- NOTES -------------------- +// The external interrupt pins are mapped as follows on most AVR processors: +// (90s8515, mega161, mega163, mega323, mega16, mega32, etc) +// +// INT0 -> PD2 (PORTD, pin 2) +// INT1 -> PD3 (PORTD, pin 3) +// +// The external interrupt pins on the processors mega128 and mega64 are: +// +// INT0 -> PD0 (PORTD, pin 0) +// INT1 -> PD1 (PORTD, pin 1) +// INT2 -> PD2 (PORTD, pin 2) +// INT3 -> PD3 (PORTD, pin 3) +// INT4 -> PE4 (PORTE, pin 4) +// INT5 -> PE5 (PORTE, pin 5) +// INT6 -> PE6 (PORTE, pin 6) +// INT7 -> PE7 (PORTE, pin 7) +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENCODERCONF_H +#define ENCODERCONF_H + +// constants/macros/typdefs + +// defines for processor compatibility +// quick compatiblity for mega128, mega64 +//#ifndef MCUCR +// #define MCUCR EICRA +//#endif + +// Set the total number of encoders you wish to support +#define NUM_ENCODERS 2 + + +// -------------------- Encoder 0 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt PORT, DDR, and PIN must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC0_SIGNAL SIG_INTERRUPT0 // Interrupt signal name +#define ENC0_INT INT0 // matching INTx bit in GIMSK/EIMSK +#define ENC0_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC0_ISCX0 ISC00 // matching Interrupt Sense Config bit0 +#define ENC0_ISCX1 ISC01 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEA_PORT PORTD // PhaseA port register +#define ENC0_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC0_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC0_PHASEA_PIN PD2 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEB_PORT PORTC // PhaseB port register +#define ENC0_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC0_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC0_PHASEB_PIN PC0 // PhaseB port pin + + +// -------------------- Encoder 1 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC1_SIGNAL SIG_INTERRUPT1 // Interrupt signal name +#define ENC1_INT INT1 // matching INTx bit in GIMSK/EIMSK +#define ENC1_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC1_ISCX0 ISC10 // matching Interrupt Sense Config bit0 +#define ENC1_ISCX1 ISC11 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEA_PORT PORTD // PhaseA port register +#define ENC1_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC1_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC1_PHASEA_PIN PD3 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEB_PORT PORTC // PhaseB port register +#define ENC1_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC1_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC1_PHASEB_PIN PC1 // PhaseB port pin + + +// -------------------- Encoder 2 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC2_SIGNAL SIG_INTERRUPT6 // Interrupt signal name +#define ENC2_INT INT6 // matching INTx bit in GIMSK/EIMSK +#define ENC2_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC2_ISCX0 ISC60 // matching Interrupt Sense Config bit0 +#define ENC2_ISCX1 ISC61 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEA_PORT PORTE // PhaseA port register +#define ENC2_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC2_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC2_PHASEA_PIN PE6 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEB_PORT PORTC // PhaseB port register +#define ENC2_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC2_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC2_PHASEB_PIN PC2 // PhaseB port pin + + +// -------------------- Encoder 3 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC3_SIGNAL SIG_INTERRUPT7 // Interrupt signal name +#define ENC3_INT INT7 // matching INTx bit in GIMSK/EIMSK +#define ENC3_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC3_ISCX0 ISC70 // matching Interrupt Sense Config bit0 +#define ENC3_ISCX1 ISC71 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEA_PORT PORTE // PhaseA port register +#define ENC3_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC3_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC3_PHASEA_PIN PE7 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEB_PORT PORTC // PhaseB port register +#define ENC3_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC3_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC3_PHASEB_PIN PC3 // PhaseB port pin + +#endif diff --git a/3rd party/Procyuon avrlib/examples/encoder/encodertest.c b/3rd party/Procyuon avrlib/examples/encoder/encodertest.c new file mode 100644 index 0000000..ff71dbf --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/encodertest.c @@ -0,0 +1,79 @@ +//***************************************************************************** +// File Name : encodertest.c +// +// Title : example usage of encoder driver functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 27-Jan-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support +#include "encoder.h" // include encoder driver + +void encoderTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(9600); + // initialize the timer system + timerInit(); + // initialize rprintf system + rprintfInit(uartSendByte); + // initialize vt100 library + vt100Init(); + + // clear the terminal screen + vt100ClearScreen(); + + // run the test + encoderTest(); + + return 0; +} + +void encoderTest(void) +{ + // initialize the encoders + encoderInit(); + + // print a little intro message so we know things are working + rprintf("\r\nWelcome to the encoder test!\r\n"); + + // report encoder position continuously + while(1) + { + rprintfProgStrM("Encoder0: "); + // print encoder0 position + // use base-10, 10 chars, signed, pad with spaces + rprintfNum(10, 10, TRUE, ' ', encoderGetPosition(0)); + + rprintfProgStrM(" Encoder1: "); + // print encoder1 position + // use base-10, 10 chars, signed, pad with spaces + rprintfNum(10, 10, TRUE, ' ', encoderGetPosition(1)); + + // print carriage return and line feed + rprintfCRLF(); + } +} + diff --git a/3rd party/Procyuon avrlib/examples/encoder/global.h b/3rd party/Procyuon avrlib/examples/encoder/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/encoder/makefile b/3rd party/Procyuon avrlib/examples/encoder/makefile new file mode 100644 index 0000000..010cf3d --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/encoder/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = encodertest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/encoder.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsp new file mode 100644 index 0000000..26f2448 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\extinttest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/extint/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/extint/extinttest.c b/3rd party/Procyuon avrlib/examples/extint/extinttest.c new file mode 100644 index 0000000..ba6b5fd --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/extint/extinttest.c @@ -0,0 +1,116 @@ +//***************************************************************************** +// File Name : extinttest.c +// +// Title : example usage of external interrupt library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 14-Dec-2004 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library +#include "extint.h" // include external interrupt library + +// global variables +volatile u16 Int0Count; +volatile u16 Int1Count; + +// functions +void extintTest(void); +void myInt0Handler(void); +void myInt1Handler(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(115200); + // initialize rprintf system + rprintfInit(uartSendByte); + // initialize timers + timerInit(); + + // run the test + extintTest(); + + return 0; +} + +void extintTest(void) +{ + u16 temp0, temp1; + + // print a little intro message so we know things are working + rprintf("\r\n\n\nWelcome to the External Interrupt library test program!\r\n"); + + // initialize the external interrupt library + rprintf("Initializing external interrupt library\r\n"); + extintInit(); + + // configure external interrupts for rising-edge triggering. + // when a rising-edge pulse arrives on INT0 or INT1, + // the interrupt will be triggered + rprintf("Configuring external interrupts\r\n"); + extintConfigure(EXTINT0, EXTINT_EDGE_RISING); + extintConfigure(EXTINT1, EXTINT_EDGE_RISING); + + // attach user interrupt routines. + // when the interrupt is triggered, the user routines will be executed + rprintf("Attaching user interrupt routines\r\n"); + extintAttach(EXTINT0, myInt0Handler); + extintAttach(EXTINT1, myInt1Handler); + + // enable the interrupts + rprintf("Enabling external interrupts\r\n"); + // (support for this has not yet been added to the library) + sbi(GIMSK, INT0); + sbi(GIMSK, INT1); + + // In this loop we will count the number of external interrupts, + // and therefore the number of rising edges, that occur in one second. + // This is precisely the frequency, in cycles/second or Hz, of the signal + // that is triggering the interrupt. + + while(1) + { + // reset interrupt counters + Int0Count = 0; + Int1Count = 0; + // wait 1 second + timerPause(1000); + // get counter values + temp0 = Int0Count; + temp1 = Int1Count; + // print results + rprintf("Frequency on INT0 pin: %dHz -- On INT1 pin: %dHz\r\n", temp0, temp1); + } +} + +void myInt0Handler(void) +{ + // count this interrupt event + Int0Count++; +} + +void myInt1Handler(void) +{ + // count this interrupt event + Int1Count++; +} + diff --git a/3rd party/Procyuon avrlib/examples/extint/global.h b/3rd party/Procyuon avrlib/examples/extint/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/extint/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/extint/makefile b/3rd party/Procyuon avrlib/examples/extint/makefile new file mode 100644 index 0000000..df5e130 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/extint/makefile @@ -0,0 +1,98 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = at90s8515 + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = extinttest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + AVRLIB_SRC = buffer.c uart.c rprintf.c timer.c extint.c + + SRC = $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h makefile diff --git a/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsp new file mode 100644 index 0000000..7236252 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\glcdtest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\ks0108conf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/glcd/glcdtest.c b/3rd party/Procyuon avrlib/examples/glcd/glcdtest.c new file mode 100644 index 0000000..314f4df --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/glcdtest.c @@ -0,0 +1,236 @@ +//***************************************************************************** +// +// File Name : 'glcdtest.h' +// Title : Graphic LCD test and examples code +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This code tests and demonstrates the AVRlib graphic LCD +// driver, glcd.c. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#include + +#include "global.h" +#include "uart.h" +#include "rprintf.h" +#include "timer.h" +#include "a2d.h" + +#include "ks0108.h" +#include "glcd.h" + +#define KEY1 0x01 // Key1 +#define KEY2 0x02 // Key2 +#define KEY3 0x04 // Key3 +#define KEY4 0x08 // Key4 +#define KEY5 0x10 // Key5 +#define KEY6 0x20 // Key6 +#define KEY7 0x40 // Key7 +#define KEY8 0x80 // Key8 + +void lcdtest(void); +void oscope(void); + +int main (void) +{ + // initialize + uartInit(); + timerInit(); + a2dInit(); + glcdInit(); + outb(DDRA, 0x00); + + // send rprintf output to serial port + rprintfInit(uartSendByte); + // print welcome message to serial port + rprintfProgStrM("\r\nWelcome to glcdtest...\r\n"); + // send rprintf output to lcd display + rprintfInit(glcdWriteChar); + + // perform basic functionality tests + rprintfProgStrM("All initialized..."); + + glcdSetAddress(4,LINE2); + glcdWriteChar('H'); + glcdWriteChar('E'); + glcdWriteChar('L'); + glcdWriteChar('L'); + glcdWriteChar('O'); + + glcdSetAddress(4,LINE3); + rprintfProgStrM("line 3"); + glcdSetAddress(4,LINE4); + rprintfProgStrM("line 4"); + glcdSetAddress(4,LINE5); + rprintfProgStrM("line 5"); + + // run application program + //oscope(); + lcdtest(); + + return 0; +} + +void oscope(void) +{ + u08 i=0; + u08 oldbuffer[128]; + u08 newbuffer[128]; + + glcdClearScreen(); + + while(1) + { + for(i=0; i<128; i++) + oldbuffer[i] = newbuffer[i]; + + for(i=0; i<128; i++) + newbuffer[i] = a2dConvert8bit(0); + + for(i=0; i<128; i++) + { + glcdClearDot(i,oldbuffer[i]>>2); + glcdSetDot(i,newbuffer[i]>>2); + } + } +} + +void lcdtest(void) +{ + unsigned char key = 0; + + glcdClearScreen(); + + glcdSetAddress(4,LINE2); + glcdPutStr("Graphic LCD Test"); + glcdSetAddress(4,LINE3); + glcdPutStr("HD61202/3 controller"); + glcdSetAddress(4,LINE4); + glcdPutStr("KS0108/7 controller"); + glcdSetAddress(4,LINE5); + glcdPutStr("Press buttons to"); + glcdSetAddress(4,LINE6); + glcdPutStr("test functions..."); + glcdRectangle(0, 0, 64, 128); + + while(1) + { + timerPause(10); + key = ~inb(PINA); + glcdSetAddress(4,LINE7); + rprintf("Button status: %x ", key); + + if(key == KEY1) + { + unsigned char i ; + glcdClearScreen(); + for ( i=0; i<128; i+=3) + { + glcdSetDot(i,63 - i/2); + glcdDelay(0x5fff); + } + for ( i=0; i<128; i+=3) + { + glcdClearDot(i,63 - i/2); + glcdDelay(0x5fff); + } + } + + if(key == KEY2) + { + glcdClearScreen(); + glcdCircle(25,20,17); + glcdDelay(0xffff); + glcdCircle(90,30,15); + glcdDelay(0xffff); + glcdCircle(55,30,23); + glcdDelay(0xffff); + glcdCircle(100,48,15); + glcdDelay(0xffff); + glcdCircle(34,50,10); + glcdDelay(0xffff); + glcdCircle(60,55,8); + } + + if(key == KEY3) + { + glcdClearScreen(); + glcdRectangle(54, 41, 6 , 12); + glcdDelay(0xffff); + glcdRectangle(34, 12, 32, 2); + glcdDelay(0xffff); + glcdRectangle(23, 34, 17, 21); + glcdDelay(0xffff); + glcdRectangle(62, 20, 42, 58); + glcdDelay(0xffff); + glcdRectangle(4 , 30, 12, 12); + } + + if(key == KEY4) + { + glcdClearScreen(); + glcdSetAddress(0,LINE1); + glcdPutStr("LINE 1"); glcdDelay(0xffff); + glcdSetAddress(5,LINE2); + glcdPutStr("LINE 2"); glcdDelay(0xffff); + glcdSetAddress(10,LINE3); + glcdPutStr("LINE 3"); glcdDelay(0xffff); + glcdSetAddress(15,LINE4); + glcdPutStr("LINE 4"); glcdDelay(0xffff); + glcdSetAddress(20,LINE5); + glcdPutStr("LINE 5"); glcdDelay(0xffff); + glcdSetAddress(25,LINE6); + glcdPutStr("LINE 6"); glcdDelay(0xffff); + glcdSetAddress(30,LINE7); + glcdPutStr("LINE 7"); glcdDelay(0xffff); + glcdSetAddress(35,LINE8); + glcdPutStr("LINE 8"); glcdDelay(0xffff); + } + + if(key == KEY5) + { + glcdClearScreen(); + glcdSetAddress(0,LINE2); + glcdPutStr(" !"); + glcdWriteChar('"'); + glcdPutStr("#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + glcdPutStr("[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); + } + + if(key == KEY6) + { + unsigned char i; + for (i=0; i<64; i++) + { + glcdStartLine(64- i - 1); + glcdDelay(0x5fff); + } + } + + if(key == KEY7) + { + unsigned char i; + for (i=0; i<64; i++) + { + glcdStartLine(i + 1); + glcdDelay(0x5fff); + } + } + + if (key == KEY8) + { + // glcdBackLight(OFF); + // glcdBackLight(ON); + } + } +} diff --git a/3rd party/Procyuon avrlib/examples/glcd/global.h b/3rd party/Procyuon avrlib/examples/glcd/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/glcd/ks0108conf.h b/3rd party/Procyuon avrlib/examples/glcd/ks0108conf.h new file mode 100644 index 0000000..69e12af --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/ks0108conf.h @@ -0,0 +1,85 @@ +/*! \file ks0108conf.h \brief Graphic LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'ks0108conf.h' +// Title : Graphic LCD driver for HD61202/KS0108 displays +// Author : Pascal Stang - Copyright (C) 2001-2003 +// Date : 10/19/2001 +// Revised : 5/1/2003 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef KS0108CONF_H +#define KS0108CONF_H + +// define LCD hardware interface +// -LCD_MEMORY_INTERFACE assumes that the registers of the LCD have been mapped +// into the external memory space of the AVR processor memory bus +// -LCD_PORT_INTERFACE is a direct-connection interface from port pins to LCD +// SELECT (UNCOMMENT) ONLY ONE! + +// *** NOTE: memory interface is not yet fully supported, but it might work + +//#define GLCD_MEMORY_INTERFACE +#define GLCD_PORT_INTERFACE + +// GLCD_PORT_INTERFACE specifics +#ifdef GLCD_PORT_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CTRL_PORT + #define GLCD_CTRL_PORT PORTB // PORT for LCD control signals + #define GLCD_CTRL_DDR DDRB // DDR register of LCD_CTRL_PORT + #define GLCD_CTRL_RS PB0 // pin for LCD Register Select + #define GLCD_CTRL_RW PB1 // pin for LCD Read/Write + #define GLCD_CTRL_E PB2 // pin for LCD Enable + #define GLCD_CTRL_CS0 PB3 // pin for LCD Controller 0 Chip Select + #define GLCD_CTRL_CS1 PB4 // pin for LCD Controller 1 Chip Select(*) + #define GLCD_CTRL_CS2 PB6 // pin for LCD Controller 2 Chip Select(*) + #define GLCD_CTRL_CS3 PB7 // pin for LCD Controller 3 Chip Select(*) + #define GLCD_CTRL_RESET PB5 // pin for LCD Reset + // (*) NOTE: additonal controller chip selects are optional and + // will be automatically used per each step in 64 pixels of display size + // Example: Display with 128 hozizontal pixels uses 2 controllers + #endif + #ifndef GLCD_DATA_PORT + #define GLCD_DATA_PORT PORTC // PORT for LCD data signals + #define GLCD_DATA_DDR DDRC // DDR register of LCD_DATA_PORT + #define GLCD_DATA_PIN PINC // PIN register of LCD_DATA_PORT + #endif +#endif + +// GLCD_MEMORY_INTERFACE specifics +#ifdef GLCD_MEMORY_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CONTROLLER0_CTRL_ADDR + // absolute address of LCD Controller #0 CTRL and DATA registers + #define GLCD_CONTROLLER0_CTRL_ADDR 0x1000 + #define GLCD_CONTROLLER0_DATA_ADDR 0x1001 + // offset of other controllers with respect to controller0 + #define GLCD_CONTROLLER_ADDR_OFFSET 0x0002 + #endif +#endif + + +// LCD geometry defines (change these definitions to adapt code/settings) +#define GLCD_XPIXELS 128 // pixel width of entire display +#define GLCD_YPIXELS 64 // pixel height of entire display +#define GLCD_CONTROLLER_XPIXELS 64 // pixel width of one display controller + +// Set text size of display +// These definitions are not currently used and will probably move to glcd.h +#define GLCD_TEXT_LINES 8 // visible lines +#define GLCD_TEXT_LINE_LENGTH 22 // internal line length + +#endif diff --git a/3rd party/Procyuon avrlib/examples/glcd/makefile b/3rd party/Procyuon avrlib/examples/glcd/makefile new file mode 100644 index 0000000..a31c2ea --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/glcd/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = glcdtest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/a2d.c $(AVRLIB)/glcd.c $(AVRLIB)/ks0108.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsp new file mode 100644 index 0000000..8fa4317 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsp @@ -0,0 +1,133 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\gpstest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\..\gps.c +# End Source File +# Begin Source File + +SOURCE=..\..\gps.h +# End Source File +# Begin Source File + +SOURCE=.\makefile +# End Source File +# Begin Source File + +SOURCE=..\..\nmea.c +# End Source File +# Begin Source File + +SOURCE=..\..\nmea.h +# End Source File +# Begin Source File + +SOURCE=..\..\tsip.c +# End Source File +# Begin Source File + +SOURCE=..\..\tsip.h +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/gps/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/gps/global.h b/3rd party/Procyuon avrlib/examples/gps/global.h new file mode 100644 index 0000000..29f4b9f --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/gps/global.h @@ -0,0 +1,43 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// back-door way to enable floating-point print support +#define RPRINTF_FLOAT + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/gps/gpstest.c b/3rd party/Procyuon avrlib/examples/gps/gpstest.c new file mode 100644 index 0000000..ab03ce6 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/gps/gpstest.c @@ -0,0 +1,126 @@ +//***************************************************************************** +// File Name : gpstest.c +// +// Title : example usage of gps processing library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 10-Sep-2002 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +//#include +#include + +#include "global.h" // include our global settings +#include "uart2.h" // include dual-uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "gps.h" // include gps data support +#include "tsip.h" // include TSIP gps packet handling +#include "nmea.h" // include NMEA gps packet handling +#include "vt100.h" // include VT100 terminal commands + +// uartRxOverflow is a global variable defined in uart.c/uart2.c +// we define it here as here so that we can use its value +// in code contained in this file +extern unsigned short uartRxOverflow[2]; + +void gpsTsipTest(void); +void gpsNmeaTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of UART 0 for our debug/reporting output + uartSetBaudRate(0,9600); + // set uart0SendByte as the output for all rprintf statements + rprintfInit(uart0SendByte); + // initialize the timer system + timerInit(); + // initialize vt100 library + vt100Init(); + + // print a little intro message so we know things are working + vt100ClearScreen(); + rprintf("\r\nWelcome to GPS Test!\r\n"); + + // run example gps processing loop + // (pick the one appropriate for your GPS packet format) +// gpsTsipTest(); + gpsNmeaTest(); + + return 0; +} + +void gpsTsipTest(void) +{ + // set the baud rate of UART 1 for TSIP + uartSetBaudRate(1,9600); + + // clear screen + vt100ClearScreen(); + // initialize gps library + gpsInit(); + // initialize gps packet decoder + tsipInit(uart1SendByte); // use uart1 for tsip packet output + + // begin gps packet processing loop + while(1) + { + // process received gps packets until receive buffer is exhausted + while( tsipProcess(uartGetRxBuffer(1)) ); + + // set cursor position to top left of screen + vt100SetCursorPos(0,0); + // print/dump current formatted GPS data + gpsInfoPrint(); + // print UART 1 overflow status to verify that we're processing packets + // fast enough and that our receive buffer is large enough + rprintf("Uart1RxOvfl: %d\r\n",uartRxOverflow[1]); + // pause for 100ms + timerPause(100); + } +} + +void gpsNmeaTest(void) +{ + // set the baud rate of UART 1 for NMEA + uartSetBaudRate(1,4800); + + // clear screen + vt100ClearScreen(); + // initialize gps library + gpsInit(); + // initialize gps packet decoder + nmeaInit(); + + // begin gps packet processing loop + while(1) + { + // process received gps packets until receive buffer is exhausted + while( nmeaProcess(uartGetRxBuffer(1)) ); + + // set cursor position to top left of screen + vt100SetCursorPos(0,0); + // print/dump current formatted GPS data + gpsInfoPrint(); + // print UART 1 overflow status to verify that we're processing packets + // fast enough and that our receive buffer is large enough + rprintf("Uart1RxOvfl: %d\r\n",uartRxOverflow[1]); + // pause for 100ms + timerPause(100); + } +} + diff --git a/3rd party/Procyuon avrlib/examples/gps/makefile b/3rd party/Procyuon avrlib/examples/gps/makefile new file mode 100644 index 0000000..8825504 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/gps/makefile @@ -0,0 +1,94 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = atmega163 +# MCU = atmega161 + MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = gpstest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart2.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/tsip.c $(AVRLIB)/nmea.c $(AVRLIB)/gps.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref + LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsp new file mode 100644 index 0000000..8a8d808 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\i2ctest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/i2c/global.h b/3rd party/Procyuon avrlib/examples/i2c/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/i2c/i2cconf.h b/3rd party/Procyuon avrlib/examples/i2c/i2cconf.h new file mode 100644 index 0000000..93d369a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2c.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/i2c/i2ctest.c b/3rd party/Procyuon avrlib/examples/i2c/i2ctest.c new file mode 100644 index 0000000..6752081 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/i2ctest.c @@ -0,0 +1,287 @@ +//***************************************************************************** +// File Name : i2ctest.c +// +// Title : example usage of I2C library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 03-Feb-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "a2d.h" // include A/D converter function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support +#include "i2c.h" // include i2c support +#include "debug.h" // include debug functions + + +#define LOCAL_ADDR 0xA0 +#define TARGET_ADDR 0xA0 + +// local data buffer +unsigned char localBuffer[] = "Pascal is cool!!Pascal is Cool!!"; +unsigned char localBufferLength = 0x20; + +void i2cTest(void); +void i2cSlaveReceiveService(u08 receiveDataLength, u08* receiveData); +u08 i2cSlaveTransmitService(u08 transmitDataLengthMax, u08* transmitData); +void i2cMasterSendDiag(u08 deviceAddr, u08 length, u08* data); +void testI2cMemory(void); +void showByte(u08 byte); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // clear terminal screen + vt100ClearScreen(); + vt100SetCursorPos(1,1); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to i2c test!\r\n"); + + // run tests + + i2cTest(); + + return 0; +} + + +void i2cTest(void) +{ + u08 c=0; + showByte(0x55); + + // initialize i2c function library + i2cInit(); + // set local device address and allow response to general call + i2cSetLocalDeviceAddr(LOCAL_ADDR, TRUE); + // set the Slave Receive Handler function + // (this function will run whenever a master somewhere else on the bus + // writes data to us as a slave) + i2cSetSlaveReceiveHandler( i2cSlaveReceiveService ); + // set the Slave Transmit Handler function + // (this function will run whenever a master somewhere else on the bus + // attempts to read data from us as a slave) + i2cSetSlaveTransmitHandler( i2cSlaveTransmitService ); + + timerPause(500); + showByte(0xAA); + + while(1) + { + rprintf("Command>"); + while(!c) uartReceiveByte(&c); + + switch(c) + { + case 's': + rprintf("Send: "); + // get string from terminal + localBufferLength = 0; + c = 0; + while((c != 0x0D) && (localBufferLength < 0x20)) + { + while(!uartReceiveByte(&c)); + localBuffer[localBufferLength++] = c; + uartSendByte(c); + } + // switch CR to NULL to terminate string + localBuffer[localBufferLength-1] = 0; + // send string over I2C + i2cMasterSend(TARGET_ADDR, localBufferLength, localBuffer); + //i2cMasterSendNI(TARGET_ADDR, localBufferLength, localBuffer); + rprintfCRLF(); + break; + case 'r': + rprintf("Receive: "); + // receive string over I2C + i2cMasterReceive(TARGET_ADDR, 0x10, localBuffer); + //i2cMasterReceiveNI(TARGET_ADDR, 0x10, localBuffer); + // format buffer + localBuffer[0x10] = 0; + rprintfStr(localBuffer); + rprintfCRLF(); + break; + case 'm': + testI2cMemory(); + break; + default: + rprintf("Unknown Command!"); + break; + } + c = 0; + rprintfCRLF(); + } + +} + + +// slave operations +void i2cSlaveReceiveService(u08 receiveDataLength, u08* receiveData) +{ + u08 i; + + // this function will run when a master somewhere else on the bus + // addresses us and wishes to write data to us + + showByte(*receiveData); + cbi(PORTB, PB6); + + // copy the received data to a local buffer + for(i=0; i>8); + txdata[1] = (addr&0x00FF); + i2cMasterSendNI(TARGET_ADDR, 2, txdata); + i2cMasterReceiveNI(TARGET_ADDR, 64, rxdata); + rprintfProgStrM("Received data at "); + rprintfu16(addr); + rprintfProgStrM(":\r\n"); + debugPrintHexTable(64, rxdata); + } +*/ +} + +void showByte(u08 byte) +{ + // set PORTB to output + outb(DDRB, 0xFF); + // output byte to LEDs + outb(PORTB, ~byte); +} diff --git a/3rd party/Procyuon avrlib/examples/i2c/makefile b/3rd party/Procyuon avrlib/examples/i2c/makefile new file mode 100644 index 0000000..6990c7e --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/i2c/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = i2ctest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/i2c.c $(AVRLIB)/debug.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsp new file mode 100644 index 0000000..68d21f2 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\lcdtest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\lcdconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/lcd/global.h b/3rd party/Procyuon avrlib/examples/lcd/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/lcd/lcdconf.h b/3rd party/Procyuon avrlib/examples/lcd/lcdconf.h new file mode 100644 index 0000000..eeede5c --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/lcdconf.h @@ -0,0 +1,104 @@ +/*! \file lcdconf.h \brief Character LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'lcdconf.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCDCONF_H +#define LCDCONF_H + +// Define type of interface used to access the LCD +// LCD_MEMORY_INTERFACE: +// To use this mode you must supply the necessary hardware to connect the +// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD +// (HD44780 chip) must appear in the CPU's memory map. This mode is faster +// than the port interface but requires a little extra hardware to make it +// work. It is especially useful when your CPU is already configured to +// use an external memory bus for other purposes (like accessing memory). +// +// LCD_PORT_INTERFACE: +// This mode allows you to connect the control and data lines of the LCD +// directly to the I/O port pins (no interfacing hardware is needed), +// but it generally runs slower than the LCD_MEMORY_INTERFACE. +// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may +// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port +// (pins 0-7) is required for the LCD data lines, but transfers are faster. +// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD +// access is slower. In either mode, three additional port pins are +// required for the LCD interface control lines (RS, R/W, and E). + +// Enable one of the following interfaces to your LCD +//#define LCD_MEMORY_INTERFACE +#define LCD_PORT_INTERFACE + +// Enter the parameters for your chosen interface' +// if you chose the LCD_PORT_INTERFACE: +#ifdef LCD_PORT_INTERFACE + #ifndef LCD_CTRL_PORT + // port and pins you will use for control lines + #define LCD_CTRL_PORT PORTC + #define LCD_CTRL_DDR DDRC + #define LCD_CTRL_RS 2 + #define LCD_CTRL_RW 3 + #define LCD_CTRL_E 4 + #endif + #ifndef LCD_DATA_POUT + // port you will use for data lines + #define LCD_DATA_POUT PORTA + #define LCD_DATA_PIN PINA + #define LCD_DATA_DDR DDRA + // access mode you will use (default is 8bit unless 4bit is selected) + //#define LCD_DATA_4BIT + #endif +#endif + +// if you chose the LCD_MEMORY_INTERFACE: +#ifdef LCD_MEMORY_INTERFACE + #ifndef LCD_CTRL_ADDR + // CPU memory address of the LCD control register + #define LCD_CTRL_ADDR 0x1000 + #endif + #ifndef LCD_DATA_ADDR + // CPU memory address of the LCD data register + #define LCD_DATA_ADDR 0x1001 + #endif +#endif + + +// LCD display geometry +// change these definitions to adapt settings +#define LCD_LINES 4 // visible lines +#define LCD_LINE_LENGTH 20 // line length (in characters) +// cursor position to DDRAM mapping +#define LCD_LINE0_DDRAMADDR 0x00 +#define LCD_LINE1_DDRAMADDR 0x40 +#define LCD_LINE2_DDRAMADDR 0x14 +#define LCD_LINE3_DDRAMADDR 0x54 + +// LCD delay +// This delay affects how quickly accesses are made to the LCD controller. +// The HD44780 LCD controller requires an access time of at least 1us. +// LCD_DELAY should be scaled to take at least half that time (500us). +// Each NOP takes 1 CPU clock cycle to execute. Thus, at 4MHz, you should +// use at least 2 NOPs, at 8MHz at least 4 NOPs, etc. +// You can also use the delay_us(xx) command for longer access times. + +// LCD_DELAY is now automatically set in lcd.h, +// however, if you define it here, this definition will override the automatic setting + +// use this for a fail-safe delay +//#define LCD_DELAY delay_us(5); + +#endif diff --git a/3rd party/Procyuon avrlib/examples/lcd/lcdtest.c b/3rd party/Procyuon avrlib/examples/lcd/lcdtest.c new file mode 100644 index 0000000..70a6342 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/lcdtest.c @@ -0,0 +1,68 @@ +//***************************************************************************** +// File Name : lcdtest.c +// +// Title : example usage of some avr library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 30-Apr-2002 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "a2d.h" // include A/D converter function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "lcd.h" + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + u08 a=0; + + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // turn on and initialize A/D converter + a2dInit(); + // initialize the timer system + timerInit(); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to AVRlib!\r\n"); + + // initialize LCD + lcdInit(); + // direct printf output to LCD + rprintfInit(lcdDataWrite); + + // print message on LCD + rprintf("Welcome to AVRlib!"); + + DDRA = 0x00; + PORTA = 0x00; + + // display a bargraph of the analog voltages on a2d channels 0,1 + while(1) + { + lcdGotoXY(0,0); + lcdProgressBar(a2dConvert8bit(0), 255, 20); + rprintf(" X: %d", a2dConvert8bit(0)); + rprintf(" Sample: %d", a++); + lcdGotoXY(0,1); + lcdProgressBar(a2dConvert8bit(1), 255, 20); + rprintf(" Y: %d", a2dConvert8bit(1)); + } + + return 0; +} diff --git a/3rd party/Procyuon avrlib/examples/lcd/makefile b/3rd party/Procyuon avrlib/examples/lcd/makefile new file mode 100644 index 0000000..7901e3c --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/lcd/makefile @@ -0,0 +1,94 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = lcdtest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/a2d.c $(AVRLIB)/lcd.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsp new file mode 100644 index 0000000..0ec23d7 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\mmcconf.h +# End Source File +# Begin Source File + +SOURCE=.\mmctest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/mmc/global.h b/3rd party/Procyuon avrlib/examples/mmc/global.h new file mode 100644 index 0000000..da730c8 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/global.h @@ -0,0 +1,42 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +// CYCLES_PER_US is used by some short delay loops +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/mmc/makefile b/3rd party/Procyuon avrlib/examples/mmc/makefile new file mode 100644 index 0000000..2e450d7 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/makefile @@ -0,0 +1,51 @@ +# Makefile for mmctest +# Pascal Stang + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without extension) + TRG = mmctest + +#put your C sourcefiles here + + AVRLIB_SRC = buffer.c uart.c rprintf.c timer.c vt100.c spi.c mmc.c debug.c + + SRC = $(TRG).c + +#put additional assembler source file here + ASRC = + +#additional libraries and object files to link + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +buffer.o : buffer.c buffer.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer128.o : timer128.c timer128.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +rtc.o : rtc.c rtc.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/mmc/mmcconf.h b/3rd party/Procyuon avrlib/examples/mmc/mmcconf.h new file mode 100644 index 0000000..f811fd0 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/mmcconf.h @@ -0,0 +1,33 @@ +/*! \file mmcconf.h \brief MultiMedia and SD Flash Card Interface Configuration. */ +//***************************************************************************** +// +// File Name : 'mmcconf.h' +// Title : MultiMedia and SD Flash Card Interface Configuration +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MMCCONF_H +#define MMCCONF_H + +// define to enable debugging print statements +#define MMC_DEBUG + +// MMC card chip select pin defines +#define MMC_CS_PORT PORTB +#define MMC_CS_DDR DDRB +#define MMC_CS_PIN 0 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/mmc/mmctest.c b/3rd party/Procyuon avrlib/examples/mmc/mmctest.c new file mode 100644 index 0000000..d76635d --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/mmc/mmctest.c @@ -0,0 +1,111 @@ +//***************************************************************************** +// File Name : mmctest.c +// +// Title : example usage of mmc functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 20-SEP-2004 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal commands +#include "spi.h" // include SPI interface functions +#include "mmc.h" // include MMC card access functions +#include "debug.h" + +void mmcTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + uartSetBaudRate(115200); + // make all rprintf statements use uart for output + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // initialize vt100 terminal + vt100Init(); + + timerPause(100); + + // print welcome message + vt100ClearScreen(); + vt100SetCursorPos(1,0); + rprintfProgStrM("\r\nWelcome to the MMC Test Suite!\r\n"); + + timerPause(1000); + + mmcTest(); + + return 0; +} + +void mmcTest(void) +{ + u32 sector=0; + u08 buffer[0x200]; + int c; + + // initialize MMC interface + mmcInit(); + + // print new prompt + rprintf("\r\ncmd>"); + + // testing loop + while(1) + { + // check for keypress + if((c=uartGetByte()) != -1) + { + switch(c) + { + case 'i': + // initialize card + rprintf("\r\nResetting MMC/SD Card\r\n"); + mmcReset(); + break; + case 'r': + // read current sector into buffer + rprintf("\r\nRead Sector %d\r\n", sector); + mmcRead(sector, buffer); + // print buffer contents + debugPrintHexTable(0x200, buffer); + break; + case 'w': + // write current sector with data from buffer + rprintf("\r\nWrite Sector %d\r\n", sector); + mmcWrite(sector, buffer); + break; + // move to new sector + case '+': sector++; rprintf("\r\nSector = %d", sector); break; + case '-': sector--; rprintf("\r\nSector = %d", sector); break; + case '*': sector+=512; rprintf("\r\nSector = %d", sector); break; + case '/': sector-=512; rprintf("\r\nSector = %d", sector); break; + case '\r': + default: + break; + } + // print new prompt + rprintf("\r\ncmd>"); + } + } + +} diff --git a/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsp new file mode 100644 index 0000000..ce430cc --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\netstacktest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/netstack/ax88796conf.h b/3rd party/Procyuon avrlib/examples/netstack/ax88796conf.h new file mode 100644 index 0000000..f2f8c2a --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/ax88796conf.h @@ -0,0 +1,84 @@ +/*! \file ax88796conf.h \brief ASIX AX88796 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'ax88796conf.h' +// Title : ASIX AX88796 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/22/2002 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef AX88796CONF_H +#define AX88796CONF_H + +// This driver supports an AX88796 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the AX88796 address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// Memory-mapped mode assumes that the AX88796 is connected the processor via +// the external memory bus, and that the AX88796 address space starts at the +// memory location AX88796_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the AX88796's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define AX88796_MEMORY_MAPPED_OFFSET 0x2000 +#else // NIC Interface through General I/O + // AX88796 address port + #define AX88796_ADDRESS_PORT PORTB + #define AX88796_ADDRESS_DDR DDRB + #define AX88796_ADDRESS_MASK 0x1F + // AX88796 data port + #define AX88796_DATA_PORT PORTA + #define AX88796_DATA_DDR DDRA + #define AX88796_DATA_PIN PINA + // AX88796 control port + #define AX88796_CONTROL_PORT PORTD + #define AX88796_CONTROL_DDR DDRD + #define AX88796_CONTROL_READPIN PD5 + #define AX88796_CONTROL_WRITEPIN PD4 +#endif + +// AX88796 RESET pin +#define AX88796_RESET_PORT PORTD +#define AX88796_RESET_DDR DDRD +#define AX88796_RESET_PIN PD6 + +// MAC address for this interface +#ifdef ETHADDR0 +#define AX88796_MAC0 ETHADDR0 +#define AX88796_MAC1 ETHADDR1 +#define AX88796_MAC2 ETHADDR2 +#define AX88796_MAC3 ETHADDR3 +#define AX88796_MAC4 ETHADDR4 +#define AX88796_MAC5 ETHADDR5 +#else +#define AX88796_MAC0 '0' +#define AX88796_MAC1 'F' +#define AX88796_MAC2 'F' +#define AX88796_MAC3 'I' +#define AX88796_MAC4 'C' +#define AX88796_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/examples/netstack/cs8900conf.h b/3rd party/Procyuon avrlib/examples/netstack/cs8900conf.h new file mode 100644 index 0000000..7b15d05 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/cs8900conf.h @@ -0,0 +1,83 @@ +/*! \file cs8900conf.h \brief Crystal CS8900 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'cs8900conf.h' +// Title : Crystal CS8900 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 11/7/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +// +// Description : This driver provides initialization and transmit/receive +// functions for the Crystal CS8900 10Mb Ethernet Controller and PHY. +// +//***************************************************************************** + +#ifndef CS8900CONF_H +#define CS8900CONF_H + +// This driver supports a CS8900 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +//#define MEMORY_MAPPED 1 (*** MEMORY-MAPPED NOT YET IMPLEMENTED ***) +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location CS8900_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define CS8900_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // CS8900 address port + #define CS8900_ADDRESS_PORT PORTF + #define CS8900_ADDRESS_DDR DDRF + #define CS8900_ADDRESS_MASK 0x0F + // CS8900 data port + #define CS8900_DATA_PORT PORTA + #define CS8900_DATA_DDR DDRA + #define CS8900_DATA_PIN PINA + // CS8900 control port + #define CS8900_CONTROL_PORT PORTB + #define CS8900_CONTROL_DDR DDRB + #define CS8900_CONTROL_READPIN 4 + #define CS8900_CONTROL_WRITEPIN 3 +#endif + +// CS8900 RESET pin +#define CS8900_RESET_PORT PORTB +#define CS8900_RESET_DDR DDRB +#define CS8900_RESET_PIN 1 + +// MAC address for this interface +#ifdef ETHADDR0 +#define CS8900_MAC0 ETHADDR0 +#define CS8900_MAC1 ETHADDR1 +#define CS8900_MAC2 ETHADDR2 +#define CS8900_MAC3 ETHADDR3 +#define CS8900_MAC4 ETHADDR4 +#define CS8900_MAC5 ETHADDR5 +#else +#define CS8900_MAC0 '0' +#define CS8900_MAC1 'F' +#define CS8900_MAC2 'F' +#define CS8900_MAC3 'I' +#define CS8900_MAC4 'C' +#define CS8900_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/examples/netstack/global.h b/3rd party/Procyuon avrlib/examples/netstack/global.h new file mode 100644 index 0000000..f88e449 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/global.h @@ -0,0 +1,47 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines +//#define UART_USE_UART1 +//#define ARP_DEBUG_PRINT +//#define ICMP_DEBUG_PRINT + + +// CPU clock speed +//#define F_CPU 20000000 // 20MHz processor +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +// CYCLES_PER_US is used by some short delay loops +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/netstack/makefile b/3rd party/Procyuon avrlib/examples/netstack/makefile new file mode 100644 index 0000000..5152bdb --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/makefile @@ -0,0 +1,106 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the compile and link process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = at90s8515 +# MCU = atmega161 +# MCU = atmega163 + MCU = atmega16 +# MCU = atmega32 +# MCU = atmega128 + +#put the name of the target file here (without .c extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = netstacktest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + AVRLIB_SRC = buffer.c uart.c rprintf.c timer.c vt100.c debug.c net/net.c net/arp.c net/ip.c net/icmp.c net/netstack.c + +# Select network interface + AVRLIB_SRC += net/rtl8019.c +# AVRLIB_SRC += net/cs8900.c +# AVRLIB_SRC += net/ax88796.c +# AVRLIB_SRC += net/prism2.c + + SRC = $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# Use the -lm flag if you need the floating-point math library +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +uartsw.o : uartsw.c uartsw.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c makefile global.h diff --git a/3rd party/Procyuon avrlib/examples/netstack/netstacktest.c b/3rd party/Procyuon avrlib/examples/netstack/netstacktest.c new file mode 100644 index 0000000..ac65264 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/netstacktest.c @@ -0,0 +1,214 @@ +//***************************************************************************** +// File Name : netstacktest.c +// +// Title : example usage of network library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 10-Aug-2005 pstang Created the program +//***************************************************************************** + +#include +#include +#include + +// include avrlib basics +#include "global.h" +#include "timer.h" +#include "uart.h" +#include "rprintf.h" +#include "vt100.h" +#include "debug.h" + +// include network support +#include "net/net.h" +#include "net/nic.h" +#include "net/arp.h" +#include "net/icmp.h" +#include "net/ip.h" +#include "net/netstack.h" + +// network defines +#define IPADDRESS IPDOT(192l,168l,1l,12l) +#define NETMASK IPDOT(255l,255l,255l,0l) +#define GATEWAY IPDOT(192l,168l,1l,1l) + +#define LOOPBACK_PORT 7 // UDP packets sent to this port will be returned to sender +#define CONTROL_PORT 4950 // UDP packets sent to this port will be used for control +#define SERIAL_PORT 4951 // UDP packets sent to this port will be printed via serial + +// timer defines +#define TIMER_PRESCALE 1024 +#define TIMER_INTERVAL (F_CPU/TIMER_PRESCALE/100) // 100ms interval + +// global variables +static volatile unsigned long UptimeMs; + +// functions +void processCommand(u16 len, u08* data); +void serviceLocal(void); +void systickHandler(void); + +// prototypes +int main(void) +{ + struct netEthAddr myEthAddress; + + timerInit(); + uartInit(); + uartSetBaudRate(115200); + rprintfInit(uartSendByte); + timerPause(100); + vt100ClearScreen(); + rprintf("\r\nNetwork Stack Example\r\n"); + + // initialize systick timer + rprintf("Initializing Periodic Timer\r\n"); + timer2SetPrescaler(TIMERRTC_CLK_DIV1024); + timerAttach(TIMER2OVERFLOW_INT, systickHandler); + + // init network stack + rprintf("Initializing Network Stack\r\n"); + netstackInit(IPADDRESS, NETMASK, GATEWAY); + + nicGetMacAddress(&myEthAddress.addr[0]); + rprintfProgStrM("Eth Addr is: "); netPrintEthAddr(&myEthAddress); rprintfCRLF(); + rprintfProgStrM("IP Addr is: "); netPrintIPAddr(ipGetConfig()->ip); rprintfCRLF(); + + rprintf("Network Stack is up!\r\n"); + rprintf("Starting packet receive loop\r\n"); + + while(1) + { + // service local stuff + serviceLocal(); + // service the network + netstackService(); + } + + return 0; +} + + +void netstackUDPIPProcess(unsigned int len, udpip_hdr* packet) +{ + u16 payloadlen=0; + u08* payloaddata=0; + u16 i; + + // get UDP payload length + payloadlen = htons(packet->udp.udplen); + payloadlen -= 8; // subtract header + // get UDP payload data + payloaddata = &((unsigned char*)packet)[IP_HEADER_LEN+UDP_HEADER_LEN]; + + rprintf("UDP packet, len: %d\r\n", len); +// debugPrintHexTable(len, (unsigned char*)packet); + + if(packet->udp.destport == HTONS(CONTROL_PORT)) + { + // command packet + processCommand(payloadlen, payloaddata); + } + else if(packet->udp.destport == HTONS(SERIAL_PORT)) + { + // serial output + for(i=0; iudp.destport == HTONS(LOOPBACK_PORT)) + { + // loopback - return packet to sender + udpSend(htonl(packet->ip.srcipaddr), LOOPBACK_PORT, payloadlen, payloaddata); + } +} + + +void netstackTCPIPProcess(unsigned int len, tcpip_hdr* packet) +{ + rprintf("Received TCP/IP Packet: len=%d\r\n", len); +} + + +void processCommand(u16 len, u08* data) +{ + rprintf("Received UDP command: CMD=0x%x ARG0=0x%x\r\n", data[0], data[1]); + + // do something based on command + switch(data[0]) + { + case 'C': // set PORTC + PORTC = data[1]; + break; // set DDRC + case 'c': + PORTC = data[1]; + break; + default: + rprintf("Unknown UDP command\r\n"); + break; + } +} + +void serviceLocal(void) +{ + int c; + unsigned char buffer[100]; + + if( (c = uartGetByte()) != -1) + { + // echo command to terminal + rprintfChar(c); + // process command + switch(c) + { + case 'i': + rprintfProgStrM("\r\nInitializing Ethernet Controller\r\n"); + nicInit(); + break; + case 'd': + rprintfProgStrM("\r\nEthernet Controller State\r\n"); + nicRegDump(); + break; + case 't': + rprintfProgStrM("\r\nCurrent Uptime: "); + rprintfNum(10, 9, FALSE, ' ', UptimeMs); + rprintfProgStrM("ms\r\n"); + break; + case 'c': + rprintfProgStrM("\r\nCrashing System....\r\n"); + while(1); + break; + case 'u': + rprintfProgStrM("\r\nSending UDP packet\r\n"); + strcpy(&buffer[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN], "hello"); + udpSend((ipGetConfig()->ip|~ipGetConfig()->netmask), CONTROL_PORT, 6, &buffer[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]); + break; + case '?': + rprintfProgStrM("\r\nCommands:\r\n"); + rprintfProgStrM("(i) Initialize Ethernet Controller\r\n"); + rprintfProgStrM("(d) Dump Ethernet Controller State\r\n"); + rprintfProgStrM("(u) Send Broadcast UDP frame\r\n"); + rprintfProgStrM("(t) Print current uptime\r\n"); + rprintfProgStrM("(?) Help\r\n"); + break; + case '\r': + default: + break; + } + // print new prompt + rprintfProgStrM("\r\ncmd>"); + } +} + +void systickHandler(void) +{ + // set timer for 10ms interval + TCNT2 = (unsigned char)-TIMER_INTERVAL; + // count up on uptime + UptimeMs += 10; +} diff --git a/3rd party/Procyuon avrlib/examples/netstack/prism2conf.h b/3rd party/Procyuon avrlib/examples/netstack/prism2conf.h new file mode 100644 index 0000000..2e0ca64 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/prism2conf.h @@ -0,0 +1,97 @@ +/*! \file prism2conf.h \brief Prism2 802.11b Wireless-LAN Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'prism2conf.h' +// Title : Prism2 802.11b Wireless-LAN Interface Driver Configuration +// Author : Pascal Stang +// Created : 12/27/2004 +// Revised : 1/7/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +// +// Description : This is the configuration file for the Prism2 802.11b +// Wireless-LAN Controller Driver. +// +//***************************************************************************** + +#ifndef PRISM2CONF_H +#define PRISM2CONF_H + +// This driver supports a PRISM2 NIC connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// *** MEMORY-MAPPED NOT YET IMPLEMENTED *** +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location PRISM2_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define PRISM2_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // PRISM2 address port + #define PRISM2_ADDRESS_PORT PORTA + #define PRISM2_ADDRESS_DDR DDRA + #define PRISM2_ADDRESS_MASK 0xFF + // PRISM2 high address port + #define PRISM2_HADDRESS_PORT PORTF + #define PRISM2_HADDRESS_DDR DDRF + #define PRISM2_HADDRESS_MASK 0x07 + // PRISM2 data port + #define PRISM2_DATA_PORT PORTC + #define PRISM2_DATA_DDR DDRC + #define PRISM2_DATA_PIN PINC + // PRISM2 control port + #define PRISM2_CONTROL_PORT PORTG + #define PRISM2_CONTROL_DDR DDRG + #define PRISM2_CONTROL_IORD 1 + #define PRISM2_CONTROL_IOWR 2 + #define PRISM2_CONTROL_MEMRD 0 + #define PRISM2_CONTROL_MEMWR 3 + // Set PRISM2 memory and I/O bus access delay + // NOTE: PRISM2 cards may not respond correctly if access time is too short or too long + // Typically good settings: MEM = ~12us, I/O = ~1us + #define PRISM2_MEM_ACCESS_DELAY delay_us(12) + #define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } + //#define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } +#endif + +// PRISM2 RESET pin +#define PRISM2_RESET_PORT PORTG +#define PRISM2_RESET_DDR DDRG +#define PRISM2_RESET_PIN 4 + + + +// MAC address for this interface +#ifdef ETHADDR0 +#define PRISM2_MAC0 ETHADDR0 +#define PRISM2_MAC1 ETHADDR1 +#define PRISM2_MAC2 ETHADDR2 +#define PRISM2_MAC3 ETHADDR3 +#define PRISM2_MAC4 ETHADDR4 +#define PRISM2_MAC5 ETHADDR5 +#else +#define PRISM2_MAC0 '0' +#define PRISM2_MAC1 'F' +#define PRISM2_MAC2 'F' +#define PRISM2_MAC3 'I' +#define PRISM2_MAC4 'C' +#define PRISM2_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/examples/netstack/rtl8019conf.h b/3rd party/Procyuon avrlib/examples/netstack/rtl8019conf.h new file mode 100644 index 0000000..3922973 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/netstack/rtl8019conf.h @@ -0,0 +1,84 @@ +/*! \file rtl8019conf.h \brief Realtek RTL8019AS Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'rtl8019conf.h' +// Title : Realtek RTL8019AS Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/5/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the RTL8019AS 10Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RTL8019CONF_H +#define RTL8019CONF_H + +// This driver supports an RTL8019 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location RTL8019_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define RTL8019_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // RTL8019 address port + #define RTL8019_ADDRESS_PORT PORTB + #define RTL8019_ADDRESS_DDR DDRB + #define RTL8019_ADDRESS_MASK 0x1F + // RTL8019 data port + #define RTL8019_DATA_PORT PORTA + #define RTL8019_DATA_DDR DDRA + #define RTL8019_DATA_PIN PINA + // RTL8019 control port + #define RTL8019_CONTROL_PORT PORTD + #define RTL8019_CONTROL_DDR DDRD + #define RTL8019_CONTROL_READPIN 6 + #define RTL8019_CONTROL_WRITEPIN 7 +#endif + +// RTL8019 RESET pin +#define RTL8019_RESET_PORT PORTD +#define RTL8019_RESET_DDR DDRD +#define RTL8019_RESET_PIN 4 + +// MAC address for this interface +#ifdef ETHADDR0 +#define RTL8019_MAC0 ETHADDR0 +#define RTL8019_MAC1 ETHADDR1 +#define RTL8019_MAC2 ETHADDR2 +#define RTL8019_MAC3 ETHADDR3 +#define RTL8019_MAC4 ETHADDR4 +#define RTL8019_MAC5 ETHADDR5 +#else +#define RTL8019_MAC0 '0' +#define RTL8019_MAC1 'F' +#define RTL8019_MAC2 'F' +#define RTL8019_MAC3 'I' +#define RTL8019_MAC4 'C' +#define RTL8019_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsp new file mode 100644 index 0000000..e0f8dee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pulsetest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/pulse/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/pulse/global.h b/3rd party/Procyuon avrlib/examples/pulse/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/pulse/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/pulse/makefile b/3rd party/Procyuon avrlib/examples/pulse/makefile new file mode 100644 index 0000000..82709b4 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/pulse/makefile @@ -0,0 +1,95 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = pulsetest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/pulse.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/pulse/pulsetest.c b/3rd party/Procyuon avrlib/examples/pulse/pulsetest.c new file mode 100644 index 0000000..c6bc049 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/pulse/pulsetest.c @@ -0,0 +1,103 @@ +//***************************************************************************** +// File Name : pulsetest.c +// +// Title : example usage of pulse library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 29-Apr-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "pulse.h" // include pulse output support + +void pulseTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(9600); + // initialize the timer system + timerInit(); + // initialize rprintf system + rprintfInit(uartSendByte); + + // run the test + pulseTest(); + + return 0; +} + +void pulseTest(void) +{ + u16 i; + + // print a little intro message so we know things are working + rprintf("\r\nWelcome to the pulse library test program!\r\n"); + + // set pulse pins as output + // ** these are the correct pins for most processors, but not all ** + sbi(DDRD, 4); + sbi(DDRD, 5); + + // initialize pulse library + pulseInit(); + + + // do logarithmic frequency sweep + rprintf("Running logarithmic frequency sweep...\r\n"); + for(i=1; i<4000; i+=((i/5)+1)) + { + // set the output frequency + pulseT1ASetFreq(i); + // - set the number of pulses to output + // - number of pulses will be set to make each + // frequency last 1/5 of a second in time + // ** make sure we don't request zero pulses + // ** because this means run indefinitely + pulseT1ARun( (i/5)+1 ); + // print a debug message + rprintf("Output Freq = %dHz\r\n", i); + // wait for pulses to finish being output + while(pulseT1ARemaining()); + } + + + // do simultaneous pulse output on OC1A and OC1B pins with different frequencies + rprintfCRLF(); + rprintf("Running simultaneous output on OC1A and OC1B with different frequencies\r\n"); + rprintf("OC1A will be at 50Hz for 2 seconds (100 pulses)\r\n"); + rprintf("OC1B will be at 175Hz for 4 seconds (700 pulses)\r\n"); + // start OC1A output + pulseT1ASetFreq(50); + pulseT1ARun(100); + // start OC1B output + pulseT1BSetFreq(175); + pulseT1BRun(700); + // enter a debug loop as long as there are pulses remaining + while(pulseT1ARemaining() | pulseT1BRemaining()) + { + rprintf("OC1A has %d pulses remaining, OC1B has %d pulses remaining\r\n", pulseT1ARemaining(), pulseT1BRemaining()); + timerPause(100); + } + rprintf("done!\r\n"); + +} + diff --git a/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsp new file mode 100644 index 0000000..9967377 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\rprintftest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/rprintf/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/rprintf/global.h b/3rd party/Procyuon avrlib/examples/rprintf/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/rprintf/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/rprintf/makefile b/3rd party/Procyuon avrlib/examples/rprintf/makefile new file mode 100644 index 0000000..cae01d0 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/rprintf/makefile @@ -0,0 +1,96 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = atmega8515 + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = rprintftest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/rprintf/rprintftest.c b/3rd party/Procyuon avrlib/examples/rprintf/rprintftest.c new file mode 100644 index 0000000..75cbc4c --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/rprintf/rprintftest.c @@ -0,0 +1,162 @@ +//***************************************************************************** +// File Name : rprintftest.c +// +// Title : example usage of rprintf library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 10-Sep-2002 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "vt100.h" // include VT100 terminal support + +void rprintfTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(9600); + // initialize the timer system + timerInit(); + + // initialize rprintf system + // - use uartSendByte as the output for all rprintf statements + // this will cause all rprintf library functions to direct their + // output to the uart + // - rprintf can be made to output to any device which takes characters. + // You must write a function which takes an unsigned char as an argument + // and then pass this to rprintfInit like this: rprintfInit(YOUR_FUNCTION); + rprintfInit(uartSendByte); + + // initialize vt100 library + vt100Init(); + + // clear the terminal screen + vt100ClearScreen(); + + // run the test + rprintfTest(); + + return 0; +} + +void rprintfTest(void) +{ + u16 val; + u08 mydata; + u08 mystring[10]; + float b; + u08 small; + u16 medium; + u32 big; + + // print a little intro message so we know things are working + rprintf("\r\nThis is my cool program!\r\n"); + + + rprintf("\r\nWelcome to rprintf Test!\r\n"); + + // print single characters + rprintfChar('H'); + rprintfChar('e'); + rprintfChar('l'); + rprintfChar('l'); + rprintfChar('o'); + // print a constant string stored in FLASH + rprintfProgStrM(" World!"); + // print a carriage return, line feed combination + rprintfCRLF(); + // note that using rprintfCRLF() is more memory-efficient than + // using rprintf("\r\n"), especially if you do it repeatedly + + mystring[0] = 'A'; + mystring[1] = ' '; + mystring[2] = 'S'; + mystring[3] = 't'; + mystring[4] = 'r'; + mystring[5] = 'i'; + mystring[6] = 'n'; + mystring[7] = 'g'; + mystring[8] = '!'; + mystring[9] = 0; // null termination + + // print a null-terminated string from RAM + rprintfStr(mystring); + rprintfCRLF(); + + // print a section of a string from RAM + // - start at index 2 + // - print 6 characters + rprintfStrLen(mystring, 2, 6); + rprintfCRLF(); + + + val = 24060; + mydata = 'L'; + + // print a decimal number + rprintf("This is a decimal number: %d\r\n", val); + + // print a hex number + rprintf("This is a hex number: %x\r\n", mydata); + + // print a character + rprintf("This is a character: %c\r\n", mydata); + + // print hex numbers + small = 0x12; // a char + medium = 0x1234; // a short + big = 0x12345678; // a long + + rprintf("This is a 2-digit hex number (char) : "); + rprintfu08(small); + rprintfCRLF(); + + rprintf("This is a 4-digit hex number (short): "); + rprintfu16(medium); + rprintfCRLF(); + + rprintf("This is a 8-digit hex number (long) : "); + rprintfu32(big); + rprintfCRLF(); + + // print a formatted decimal number + // - use base 10 + // - use 8 characters + // - the number is signed [TRUE] + // - pad with '.' periods + rprintf("This is a formatted decimal number: "); + rprintfNum(10, 8, TRUE, '.', val); + rprintfCRLF(); + + b = 1.23456; + + // print a floating point number + // use 10-digit precision + + // NOTE: TO USE rprintfFloat() YOU MUST ENABLE SUPPORT IN global.h + // use the following in your global.h: #define RPRINTF_FLOAT + + //rprintf("This is a floating point number: "); + //rprintfFloat(8, b); + //rprintfCRLF(); +} + diff --git a/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsp new file mode 100644 index 0000000..2ccef02 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\servotest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/servo/global.h b/3rd party/Procyuon avrlib/examples/servo/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/servo/makefile b/3rd party/Procyuon avrlib/examples/servo/makefile new file mode 100644 index 0000000..256efaa --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/makefile @@ -0,0 +1,94 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) + MCU = atmega163 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = servotest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/vt100.c $(AVRLIB)/servo.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h diff --git a/3rd party/Procyuon avrlib/examples/servo/servoconf.h b/3rd party/Procyuon avrlib/examples/servo/servoconf.h new file mode 100644 index 0000000..a930792 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/servoconf.h @@ -0,0 +1,82 @@ +/*! \file servoconf.h \brief Interrupt-driven RC Servo configuration. */ +//***************************************************************************** +// +// File Name : 'servoconf.h' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 07/31/2002 +// Revised : 09/30/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: you need the latest version (3.2+) of the AVR-GCC compiler to use this +// function library. Download it from http://www.avrfreaks.net/AVRGCC +// +// Description : This code allows you to drive up to 8 RC servos from any +// combination of ports and pins on the AVR processor. Using interrupts, +// this code continuously sends control signals to the servo to maintain +// position even while your code is doing other work. +// +// The servoInit and servoOff effectively turn on and turn off servo +// control. When you run ServoInit, it automatically assigns each +// "channel" of servo control to be output on the SERVO_DEFAULT_PORT. +// One "channel" of servo control can control one servo and must be +// assigned single I/O pin for output. +// +// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then +// then by default the code will use SERVO_DEFAULT_PORT pins 0-7. +// If you're only using four channels, then pins 0-3 will be used by +// default. +// +// The command servoSetChannelIO(channel, port, pin) allows you to +// reassign the output of any channel to any port and I/O pin you +// choose. For exampe, if you have an RC servo connected to PORTC, pin 6, +// and you wish to use channel 2 to control it, use: +// +// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6) +// +// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port) +// +// The servoSetPostion and servoGetPosition commands allow you to command +// a given servo to your desired position. The position you request must +// lie between the SERVO_MIN and SERVO_MAX limit you defined. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SERVOCONF_H +#define SERVOCONF_H + +// set number of servo channels (1 to 8) +// This is the number of servos you would like to drive +// Each "Channel" can control one servo and by default will +// map directly to the port pin of the same number on the +// SERVO_DEFAULT_PORT. You can change this default port/pin +// assignment for a given channel to any port/pin you like. +// See the "servoSetChannelIO" function. +#define SERVO_NUM_CHANNELS 4 +// set default SERVO output port +// This is the AVR port which you have connected to your servos +// See top of file for how servo "channels" map to port pins +#define SERVO_DEFAULT_PORT PORTB +// set servo characteristics (min and max raw position) +// You must find these by testing using your brand/type of servos. +// The min/max settings will change proportional to F_CPU, the CPU +// clock frequency. +// The numbers below good for parallax servos at an F_CPU of ~8MHz. +//#define SERVO_MAX 71 +//#define SERVO_MIN 17 +// The numbers below good for parallax servos at an F_CPU of ~14.745MHz. +#define SERVO_MAX 138 +#define SERVO_MIN 34 + +// set servo scaled range +// This sets the scaled position range of the servo. Allowed scaled +// positions are 0 -> SERVO_POSITION_MAX, and correspond to raw +// positions of SERVO_MIN -> SERVO_MAX. +#define SERVO_POSITION_MAX 255 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/servo/servotest.c b/3rd party/Procyuon avrlib/examples/servo/servotest.c new file mode 100644 index 0000000..0ee2466 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/servo/servotest.c @@ -0,0 +1,98 @@ +//***************************************************************************** +// File Name : servotest.c +// +// Title : example usage of RC servo library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 10-Sep-2002 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "a2d.h" // include A/D converter function library +#include "timer.h" // include timer function library (timing, PWM, etc) +#include "servo.h" // include RC servo driver library +#include "vt100.h" // include VT100 terminal library + +void servoTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(9600); + // set uartSendByte as the output for all rprintf statements + rprintfInit(uartSendByte); + // initialize the timer system + timerInit(); + // initialize vt100 library + vt100Init(); + vt100ClearScreen(); + // print a little intro message so we know things are working + rprintf("\r\nWelcome to Servo Test!\r\n"); + + // begin servo test + servoTest(); + + return 0; +} + +void servoTest(void) +{ + u08 pos; + u08 channel; + + // do some examples + // initialize RC servo system + servoInit(); + // setup servo output channel-to-I/Opin mapping + // format is servoSetChannelIO( CHANNEL#, PORT, PIN ); + servoSetChannelIO(0, _SFR_IO_ADDR(PORTC), PC0); + servoSetChannelIO(1, _SFR_IO_ADDR(PORTC), PC1); + servoSetChannelIO(2, _SFR_IO_ADDR(PORTC), PC2); + servoSetChannelIO(3, _SFR_IO_ADDR(PORTC), PC3); + + // set port pins to output + outb(DDRC, 0x0F); + + pos = 0; + +#define SPEED_SERVO 1 + + // spin servos sequentially back and forth between their limits + while(1) + { + for(channel=0; channel=1; pos--) + { + servoSetPosition(channel,pos); + timerPause(SPEED_SERVO); + } + } + } +} diff --git a/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsp new file mode 100644 index 0000000..e8db6e5 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsp @@ -0,0 +1,113 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\spyglasstest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\lcdconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/spyglass/global.h b/3rd party/Procyuon avrlib/examples/spyglass/global.h new file mode 100644 index 0000000..c82ea96 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/global.h @@ -0,0 +1,44 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 20000000 // 20MHz processor +//#define F_CPU 18432000 // 18.432MHz processor +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +// CYCLES_PER_US is used by some short delay loops +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/spyglass/i2cconf.h b/3rd party/Procyuon avrlib/examples/spyglass/i2cconf.h new file mode 100644 index 0000000..8152167 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2cconf.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/3rd party/Procyuon avrlib/examples/spyglass/lcdconf.h b/3rd party/Procyuon avrlib/examples/spyglass/lcdconf.h new file mode 100644 index 0000000..190f796 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/lcdconf.h @@ -0,0 +1,97 @@ +/*! \file lcdconf.h \brief Character LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'lcdconf.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCDCONF_H +#define LCDCONF_H + +// Define type of interface used to access the LCD +// LCD_MEMORY_INTERFACE: +// To use this mode you must supply the necessary hardware to connect the +// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD +// (HD44780 chip) must appear in the CPU's memory map. This mode is faster +// than the port interface but requires a little extra hardware to make it +// work. It is especially useful when your CPU is already configured to +// use an external memory bus for other purposes (like accessing memory). +// +// LCD_PORT_INTERFACE: +// This mode allows you to connect the control and data lines of the LCD +// directly to the I/O port pins (no interfacing hardware is needed), +// but it generally runs slower than the LCD_MEMORY_INTERFACE. +// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may +// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port +// (pins 0-7) is required for the LCD data lines, but transfers are faster. +// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD +// access is slower. In either mode, three additional port pins are +// required for the LCD interface control lines (RS, R/W, and E). + +// Enable one of the following interfaces to your LCD +//#define LCD_MEMORY_INTERFACE +#define LCD_PORT_INTERFACE + +// Enter the parameters for your chosen interface' +// if you chose the LCD_PORT_INTERFACE: +#ifdef LCD_PORT_INTERFACE + #ifndef LCD_CTRL_PORT + // port and pins you will use for control lines + #define LCD_CTRL_PORT PORTC + #define LCD_CTRL_DDR DDRC + #define LCD_CTRL_RS 2 + #define LCD_CTRL_RW 3 + #define LCD_CTRL_E 4 + #endif + #ifndef LCD_DATA_POUT + // port you will use for data lines + #define LCD_DATA_POUT PORTA + #define LCD_DATA_PIN PINA + #define LCD_DATA_DDR DDRA + // access mode you will use (default is 8bit unless 4bit is selected) + //#define LCD_DATA_4BIT + #endif +#endif + +// if you chose the LCD_MEMORY_INTERFACE: +#ifdef LCD_MEMORY_INTERFACE + #ifndef LCD_CTRL_ADDR + // CPU memory address of the LCD control register + #define LCD_CTRL_ADDR 0x1000 + #endif + #ifndef LCD_DATA_ADDR + // CPU memory address of the LCD data register + #define LCD_DATA_ADDR 0x1001 + #endif +#endif + + +// LCD display geometry +// change these definitions to adapt settings +#define LCD_LINES 4 // visible lines +#define LCD_LINE_LENGTH 20 // line length (in characters) +// cursor position to DDRAM mapping +#define LCD_LINE0_DDRAMADDR 0x00 +#define LCD_LINE1_DDRAMADDR 0x40 +#define LCD_LINE2_DDRAMADDR 0x14 +#define LCD_LINE3_DDRAMADDR 0x54 + +// LCD delay +// This delay affects how quickly accesses are made to the LCD controller. +// If your clock frequency is low, you can reduce the number of NOPs in the +// delay. If your clock frequency is high, you may need to add NOPs. +// The number of NOPs should be between at least 1 and up to 20. +//#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); + +#endif diff --git a/3rd party/Procyuon avrlib/examples/spyglass/makefile b/3rd party/Procyuon avrlib/examples/spyglass/makefile new file mode 100644 index 0000000..616faba --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/makefile @@ -0,0 +1,99 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the compile and link process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = at90s8515 + MCU = atmega163 +# MCU = atmega128 +# MCU = atmega16 +# MCU = atmega32 + +#put the name of the target file here (without .c extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = spyglasstest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + AVRLIB_SRC = buffer.c uart.c rprintf.c timer.c i2c.c spyglass.c + + SRC = $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# Use the -lm flag if you need the floating-point math library +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +uartsw.o : uartsw.c uartsw.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c makefile global.h diff --git a/3rd party/Procyuon avrlib/examples/spyglass/spyglasstest.c b/3rd party/Procyuon avrlib/examples/spyglass/spyglasstest.c new file mode 100644 index 0000000..f022cf6 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/spyglass/spyglasstest.c @@ -0,0 +1,228 @@ +//***************************************************************************** +// File Name : spyglasstest.c +// +// Title : example usage of the Spyglass I2C-controller user interface +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 28-Aug-2005 pstang Created the program +//***************************************************************************** + +#include + +#include "global.h" +#include "timer.h" +#include "uart.h" +#include "rprintf.h" +#include "vt100.h" +#include "lcd.h" +#include "debug.h" +#include "i2c.h" +#include "spyglass.h" + +// defines +#define TIMER_PRESCALE 1024 +#define TIMER_INTERVAL (F_CPU/TIMER_PRESCALE/100) + +// global variables +static volatile unsigned long UptimeMs; +u08 Contrast=0; + +// prototypes +void spyglassTest(void); +void systickHandler(void); +void i2cDeviceSearch(void); +void serviceLocal(void); + +int main(void) +{ + timerInit(); // initializing timers + uartInit(); // initializing serial port + uartSetBaudRate(115200); // set serial port baud rate + rprintfInit(uartSendByte); // direct rprintf() output to go to serial port + timerPause(100); // wait for a moment + + // print welcome message + rprintf("\r\n\n\nWelcome to the Spyglass UI test.\r\n"); + + // begin test application + spyglassTest(); + + return 0; +} + +void spyglassTest(void) +{ + // initializing Spyglass interface and I2C bus + rprintf("Initializing Spyglass communication..."); + spyglassInit(); + spyglassLcdInit(); + rprintf("Done!\r\n"); + rprintf("Printing 'Hello World!' message to spyglass LCD.\r\n"); + + rprintfInit(spyglassLcdWriteChar); + spyglassLcdGotoXY(0,0); + rprintfProgStrM("Hello World!"); + rprintfInit(uartSendByte); + + timerPause(1000); + + // initialize systick timer + rprintf("Initializing Periodic Timer\r\n"); + timer2SetPrescaler(TIMERRTC_CLK_DIV1024); + // attach the 'systickHandler' so that it gets called every time Timer2 overflows + timerAttach(TIMER2OVERFLOW_INT, systickHandler); + + rprintf("Starting local command prompt. Type '?' to get help.\r\n"); + rprintf("cmd>"); + + while(1) + { + serviceLocal(); + } +} + +void systickHandler(void) +{ + u16 tms; + u08 ts,tm,th; + u08 pb; + + // set timer for 10ms interval + TCNT2 = (unsigned char)-TIMER_INTERVAL; + // count up on uptime + UptimeMs += 10; + + // if we at a 100ths millisecond interval, update the display + if(!(UptimeMs % 100)) + { + // redirect rprintf() output to spyglass LCD + rprintfInit(spyglassLcdWriteChar); + + // print banner message + spyglassLcdGotoXY(0,0); + rprintfProgStrM("**** SpyglassUI ****"); + + // read pushbuttons and take appropriate action + pb = spyglassGetPushbuttons(); + spyglassLcdGotoXY(0,1); + rprintf("Buttons: "); + rprintfNum(2,8,FALSE,'0',pb); + + if((pb & 0x01) && (Contrast < 255)) + Contrast++; + if((pb & 0x02) && (Contrast > 0)) + Contrast--; + if(pb & 0x08) + spyglassSetLeds(0x01); + if(pb & 0x10) + spyglassSetLeds(0x02); + + // show display contrast + spyglassLcdGotoXY(0,2); + rprintf("LCD Contrast: "); + rprintfNum(10,3,FALSE,' ',Contrast); + spyglassSetLcdContrast(Contrast); + + // show time + tms = (UptimeMs)%1000; + ts = (UptimeMs/1000)%60; + tm = (UptimeMs/60000l)%60; + th = (UptimeMs/3600000l); + spyglassLcdGotoXY(0,3); + rprintf("Time:"); + rprintfNum(10,3,FALSE,' ',th); + rprintfChar(':'); + rprintfNum(10,2,FALSE,'0',tm); + rprintfChar(':'); + rprintfNum(10,2,FALSE,'0',ts); + rprintfChar('.'); + rprintfNum(10,3,FALSE,'0',tms); + rprintf("ms"); + + // return rprintf() output to serial port + rprintfInit(uartSendByte); + } +} + +void serviceLocal(void) +{ + int c; + + // a little command-prompt utility to play with the spyglass UI + // all commands are single characters + + if( (c = uartGetByte()) != -1) + { + // echo command to terminal + uartSendByte(c); + // process command + switch(c) + { + case 'i': spyglassLcdInit(); break; + case 'h': + rprintfInit(spyglassLcdWriteChar); + spyglassLcdGotoXY(0,0); + rprintf("*** HELLO WORLD ***"); + rprintfInit(uartSendByte); + break; + case 'p': + rprintf("Pushbutton State: 0x%x\r\n", spyglassGetPushbuttons()); + break; + case '+': if(Contrast<255) Contrast++; rprintf("\r\nLCD Contrast: %d\r\n", Contrast); spyglassSetLcdContrast(Contrast); break; + case '-': if(Contrast>0) Contrast--; rprintf("\r\nLCD Contrast: %d\r\n", Contrast); spyglassSetLcdContrast(Contrast); break; + case 'l': spyglassSetLeds(0x00); break; + case 'L': spyglassSetLeds(0xFF); break; + case 'b': spyglassSetBeeper(0); break; + case 'B': spyglassSetBeeper(1); break; + case 'x': + i2cDeviceSearch(); + break; + case '?': + rprintfProgStrM("\r\n"); + rprintfProgStrM("--- Spyglass Commands: ---\r\n"); + rprintfProgStrM("(i) Initialize Spyglass LCD\r\n"); + rprintfProgStrM("(h) Print 'Hello World' message to Spyglass LCD\r\n"); + rprintfProgStrM("(p) Get Spyglass pushbutton state\r\n"); + rprintfProgStrM("(+) Increase contrast number (lightens contrast)\r\n"); + rprintfProgStrM("(-) Decrease contrast number (darkens contrast)\r\n"); + rprintfProgStrM("(l) Set Spyglass User LEDs to OFF\r\n"); + rprintfProgStrM("(L) Set Spyglass User LEDs to ON\r\n"); + rprintfProgStrM("(b) Set Spyglass beeper to OFF\r\n"); + rprintfProgStrM("(B) Set Spyglass beeper to ON\r\n"); + rprintfProgStrM("--- General Commands: ---\r\n"); + rprintfProgStrM("(x) Search for I2C devices on the bus\r\n"); + rprintfProgStrM("(?) Help\r\n"); + break; + case '\r': + default: + break; + } + // print new prompt + rprintfProgStrM("\r\ncmd>"); + } +} + +void i2cDeviceSearch(void) +{ + u08 i2cAddr; + u08 i2cStat; + + // this function searches all device addresses on the I2C bus + // and returns addresses that are live (have a device) + + rprintf("\r\nSearching for I2c devices on bus\r\n"); + + for(i2cAddr = 0; i2cAddr<0x80; i2cAddr+=2) + { + i2cStat = i2cMasterSendNI(i2cAddr, 0, 0); + if(i2cStat == I2C_OK) + rprintf("Device present at address 0x%x\r\n", i2cAddr); + } + rprintf("Search complete.\r\n"); +} diff --git a/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsp new file mode 100644 index 0000000..0dc5604 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsp @@ -0,0 +1,82 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" +# Begin Target + +# Name "AVRProject - Win32 Release" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\stxetxtest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# Begin Source File + +SOURCE=.\lcdconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/stxetx/global.h b/3rd party/Procyuon avrlib/examples/stxetx/global.h new file mode 100644 index 0000000..da730c8 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/global.h @@ -0,0 +1,42 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor + +// CYCLES_PER_US is used by some short delay loops +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/stxetx/lcdconf.h b/3rd party/Procyuon avrlib/examples/stxetx/lcdconf.h new file mode 100644 index 0000000..92e2c34 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/lcdconf.h @@ -0,0 +1,97 @@ +/*! \file lcdconf.h \brief Character LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'lcdconf.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCDCONF_H +#define LCDCONF_H + +// Define type of interface used to access the LCD +// LCD_MEMORY_INTERFACE: +// To use this mode you must supply the necessary hardware to connect the +// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD +// (HD44780 chip) must appear in the CPU's memory map. This mode is faster +// than the port interface but requires a little extra hardware to make it +// work. It is especially useful when your CPU is already configured to +// use an external memory bus for other purposes (like accessing memory). +// +// LCD_PORT_INTERFACE: +// This mode allows you to connect the control and data lines of the LCD +// directly to the I/O port pins (no interfacing hardware is needed), +// but it generally runs slower than the LCD_MEMORY_INTERFACE. +// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may +// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port +// (pins 0-7) is required for the LCD data lines, but transfers are faster. +// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD +// access is slower. In either mode, three additional port pins are +// required for the LCD interface control lines (RS, R/W, and E). + +// Enable one of the following interfaces to your LCD +//#define LCD_MEMORY_INTERFACE +#define LCD_PORT_INTERFACE + +// Enter the parameters for your chosen interface' +// if you chose the LCD_PORT_INTERFACE: +#ifdef LCD_PORT_INTERFACE + #ifndef LCD_CTRL_PORT + // port and pins you will use for control lines + #define LCD_CTRL_PORT PORTC + #define LCD_CTRL_DDR DDRC + #define LCD_CTRL_RS 2 + #define LCD_CTRL_RW 3 + #define LCD_CTRL_E 4 + #endif + #ifndef LCD_DATA_POUT + // port you will use for data lines + #define LCD_DATA_POUT PORTA + #define LCD_DATA_PIN PINA + #define LCD_DATA_DDR DDRA + // access mode you will use (default is 8bit unless 4bit is selected) + //#define LCD_DATA_4BIT + #endif +#endif + +// if you chose the LCD_MEMORY_INTERFACE: +#ifdef LCD_MEMORY_INTERFACE + #ifndef LCD_CTRL_ADDR + // CPU memory address of the LCD control register + #define LCD_CTRL_ADDR 0x1000 + #endif + #ifndef LCD_DATA_ADDR + // CPU memory address of the LCD data register + #define LCD_DATA_ADDR 0x1001 + #endif +#endif + + +// LCD display geometry +// change these definitions to adapt settings +#define LCD_LINES 4 // visible lines +#define LCD_LINE_LENGTH 20 // line length (in characters) +// cursor position to DDRAM mapping +#define LCD_LINE0_DDRAMADDR 0x00 +#define LCD_LINE1_DDRAMADDR 0x40 +#define LCD_LINE2_DDRAMADDR 0x14 +#define LCD_LINE3_DDRAMADDR 0x54 + +// LCD delay +// This delay affects how quickly accesses are made to the LCD controller. +// If your clock frequency is low, you can reduce the number of NOPs in the +// delay. If your clock frequency is high, you may need to add NOPs. +// The number of NOPs should be between at least 1 and up to 20. +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n"); + +#endif diff --git a/3rd party/Procyuon avrlib/examples/stxetx/makefile b/3rd party/Procyuon avrlib/examples/stxetx/makefile new file mode 100644 index 0000000..2b512ea --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/makefile @@ -0,0 +1,97 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the compile and link process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = at90s8515 +# MCU = atmega161 + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega128 + +#put the name of the target file here (without .c extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = stxetxtest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/lcd.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/stxetx.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# Use the -lm flag if you need the floating-point math library +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +uartsw.o : uartsw.c uartsw.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c diff --git a/3rd party/Procyuon avrlib/examples/stxetx/stxetxconf.h b/3rd party/Procyuon avrlib/examples/stxetx/stxetxconf.h new file mode 100644 index 0000000..7e67166 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/stxetxconf.h @@ -0,0 +1,28 @@ +/*! \file stxetxconf.h \brief STX/ETX Packet Protocol Implementation Configuration. */ +//***************************************************************************** +// +// File Name : 'stxetx.h' +// Title : STX/ETX Packet Protocol Implementation Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 10/9/2002 +// Revised : 02/10/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef STXETXCONF_H +#define STXETXCONF_H + +// STX/ETX Configuration Options + +// This determines the size of the Packet Receive Buffer +// where whole verified packets are copied after being received +#define STXETX_MAXRXPACKETSIZE 20 // length of packet buffer + + +#endif diff --git a/3rd party/Procyuon avrlib/examples/stxetx/stxetxtest.c b/3rd party/Procyuon avrlib/examples/stxetx/stxetxtest.c new file mode 100644 index 0000000..ce13ec5 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/stxetx/stxetxtest.c @@ -0,0 +1,152 @@ +//***************************************************************************** +// File Name : stxetxtest.c +// Title : Example usage of STX/ETX packet protocol and library code +// Revision : 0.1 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 20-Nov-2002 pstang Created the program +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library +#include "lcd.h" // include LCD support +#include "stxetx.h" // include STX/ETX packet support + + +// make a transmitting packet buffer area in memory +// where we can assemble the data we wish to transmit +// using stx/etx +unsigned char TxPacket[20]; + +// function prototypes +void receiveStxEtx(void); +void transmitStxEtx(void); +u08 getSw(void); + +// main code +int main(void) +{ + // initialize the AVRlib libraries + timerInit(); // initialize the timer system + uartInit(); // initialize the UART (serial port) + lcdInit(); + rprintfInit(lcdDataWrite); // init rprintf + + // we will be using the AVR UART to communicate the + // STX/ETX protocol to another AVR board or to a PC + + // initialize stxetx to use the UART for sending data + stxetxInit(uartSendByte); + + // set baud rate to 4800 (less than 5000) if communicating using + // the Linx LC radio modules + uartSetBaudRate(4800); + + // choose to either transmit or receive + transmitStxEtx(); + //receiveStxEtx(); + + return 0; +} + +void transmitStxEtx(void) +{ + u16 packetNum=0; + + lcdClear(); + + while(1) + { + // assemble the data I wish to send inside a STX/ETX packet + // send the string "ALOHA" + TxPacket[0] = 'A'; + TxPacket[1] = 'L'; + TxPacket[2] = 'O'; + TxPacket[3] = 'H'; + TxPacket[4] = 'A'; + // send the packet number + TxPacket[5] = packetNum>>8; // high byte + TxPacket[6] = packetNum; // low byte + // send the current state of PORTA + TxPacket[7] = inb(PINA); + + // send the packet with: + // packet status = 0 + // packet type = 0x55 + // (the packet type and status may be, and mean, anything the user wishes) + // 8-bytes of user data + stxetxSend(0, 0x55, 8, TxPacket); + + // output our packet data to the LCD + lcdGotoXY(0,0); rprintf("Sending..."); + lcdGotoXY(20,0); rprintf("PORTA: "); rprintfu08(inb(PINA)); + lcdGotoXY(0,1); rprintf("String: ALOHA"); + lcdGotoXY(20,1); rprintf("PacketNum: "); rprintfu16(packetNum); + + // increment our packet number + packetNum++; + // pause for a moment + timerPause(10); + } +} + +void receiveStxEtx(void) +{ + u16 packetNum=0; + u08* dataPtr; + + lcdClear(); + + while(1) + { + lcdGotoXY(0,0); rprintf("Receiving..."); + + // here we get the UART's receive buffer and give it to the STX/ETX + // packet processing function. If the packet processor finds a valid + // packet in the buffer, it will return true. + if(stxetxProcess(uartGetRxBuffer())) + { + // sxtetxProcess has reported that it found a packet + // let's get the data... + + // (NOTE: although I discard the status, type, and datalength + // below, it would be important if I were sending more than one + // kind of packet) + + // get the packet's status + stxetxGetRxPacketStatus(); + // get the packet's type + stxetxGetRxPacketType(); + // get the packet's datalength + stxetxGetRxPacketDatalength(); + // get a pointer to the place where the received data is stored + dataPtr = stxetxGetRxPacketData(); + + // decode packet number + packetNum = (dataPtr[5]<<8) | dataPtr[6]; + + // output our packet data to the LCD + lcdGotoXY(20,0); rprintf("PORTA: "); rprintfu08( dataPtr[7] ); + lcdGotoXY(0,1); rprintf("String: "); + // print out the string + rprintfChar( dataPtr[0] ); + rprintfChar( dataPtr[1] ); + rprintfChar( dataPtr[2] ); + rprintfChar( dataPtr[3] ); + rprintfChar( dataPtr[4] ); + lcdGotoXY(20,1); rprintf("PacketNum: "); rprintfu16(packetNum); + } + } +} diff --git a/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsp b/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsp new file mode 100644 index 0000000..f1cf168 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="AVRProject" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=AVRProject - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AVRProject.mak" CFG="AVRProject - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AVRProject - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "AVRProject - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f AVRProject.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "AVRProject.exe" +# PROP BASE Bsc_Name "AVRProject.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make" +# PROP Rebuild_Opt "make clean" +# PROP Target_File "AVRProject.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "AVRProject - Win32 Release" +# Name "AVRProject - Win32 Debug" + +!IF "$(CFG)" == "AVRProject - Win32 Release" + +!ELSEIF "$(CFG)" == "AVRProject - Win32 Debug" + +!ENDIF + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\timertest.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\global.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Group +# End Target +# End Project diff --git a/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsw b/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsw new file mode 100644 index 0000000..fd116ee --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/timer/AVRProject.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AVRProject"=.\AVRProject.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/3rd party/Procyuon avrlib/examples/timer/global.h b/3rd party/Procyuon avrlib/examples/timer/global.h new file mode 100644 index 0000000..35a31f1 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/timer/global.h @@ -0,0 +1,40 @@ + +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVR project global include +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/3rd party/Procyuon avrlib/examples/timer/makefile b/3rd party/Procyuon avrlib/examples/timer/makefile new file mode 100644 index 0000000..905d5bc --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/timer/makefile @@ -0,0 +1,96 @@ +# Makefile for AVR function library development and examples +# Author: Pascal Stang +# +# For those who have never heard of makefiles: a makefile is essentially a +# script for compiling your code. Most C/C++ compilers in the world are +# command line programs and this is even true of programming environments +# which appear to be windows-based (like Microsoft Visual C++). Although +# you could use AVR-GCC directly from the command line and try to remember +# the compiler options each time, using a makefile keeps you free of this +# tedious task and automates the process. +# +# For those just starting with AVR-GCC and not used to using makefiles, +# I've added some extra comments above several of the makefile fields which +# you will have to deal with. + +########### change this lines according to your project ################## +#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.) +# MCU = at90s8515 + MCU = atmega163 +# MCU = atmega323 +# MCU = atmega161 +# MCU = atmega128 + +#put the name of the target file here (without extension) +# Your "target" file is your C source file that is at the top level of your code. +# In other words, this is the file which contains your main() function. + + TRG = timertest + +#put your C sourcefiles here +# Here you must list any C source files which are used by your target file. +# They will be compiled in the order you list them, so it's probably best +# to list $(TRG).c, your top-level target file, last. + + SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(TRG).c + +#put additional assembler source file here +# The ASRC line allows you to list files which contain assembly code/routines that +# you would like to use from within your C programs. The assembly code must be +# written in a special way to be usable as a function from your C code. + + ASRC = + +#additional libraries and object files to link +# Libraries and object files are collections of functions which have already been +# compiled. If you have such files, list them here, and you will be able to use +# use the functions they contain in your target program. + + LIB = + +#additional includes to compile + INC = + +#assembler flags + ASFLAGS = -Wa, -gstabs + +#compiler flags + CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst) + +#linker flags + LDFLAGS = -Wl,-Map=$(TRG).map,--cref +# LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm + + +########### you should not need to change the following line ############# +include $(AVRLIB)/make/avrproj_make + +###### dependecies, add any dependencies you need here ################### +# Dependencies tell the compiler which files in your code depend on which +# other files. When you change a piece of code, the dependencies allow +# the compiler to intelligently figure out which files are affected and +# need to be recompiled. You should only list the dependencies of *.o +# files. For example: uart.o is the compiled output of uart.c and uart.h +# and therefore, uart.o "depends" on uart.c and uart.h. But the code in +# uart.c also uses information from global.h, so that file should be listed +# in the dependecies too. That way, if you alter global.h, uart.o will be +# recompiled to take into account the changes. + +buffer.o : buffer.c buffer.h +uart.o : uart.c uart.h global.h +uart2.o : uart2.c uart2.h global.h +rprintf.o : rprintf.c rprintf.h +a2d.o : a2d.c a2d.h +timer.o : timer.c timer.h global.h +pulse.o : pulse.c pulse.h timer.h global.h +lcd.o : lcd.c lcd.h global.h +i2c.o : i2c.c i2c.h global.h +spi.o : spi.c spi.h global.h +swpwm.o : swpwm.c swpwm.h global.h +servo.o : servo.c servo.h global.h +swuart.o : swuart.c swuart.h global.h +tsip.o : tsip.c tsip.h global.h +nmea.o : nmea.c nmea.h global.h +vt100.o : vt100.c vt100.h global.h +gps.o : gps.c gps.h global.h +$(TRG).o : $(TRG).c global.h makefile diff --git a/3rd party/Procyuon avrlib/examples/timer/timertest.c b/3rd party/Procyuon avrlib/examples/timer/timertest.c new file mode 100644 index 0000000..ec55e95 --- /dev/null +++ b/3rd party/Procyuon avrlib/examples/timer/timertest.c @@ -0,0 +1,105 @@ +//***************************************************************************** +// File Name : timertest.c +// +// Title : example usage of timer library functions +// Revision : 1.0 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Description of change +// ----------- ----------- ----------------------- +// 30-Apr-2003 pstang Created the program +//***************************************************************************** + + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "uart.h" // include uart function library +#include "rprintf.h" // include printf function library +#include "timer.h" // include timer function library (timing, PWM, etc) + +void timerTest(void); + +//----- Begin Code ------------------------------------------------------------ +int main(void) +{ + // initialize our libraries + // initialize the UART (serial port) + uartInit(); + // set the baud rate of the UART for our debug/reporting output + uartSetBaudRate(9600); + // initialize rprintf system + rprintfInit(uartSendByte); + + // run the test + timerTest(); + + return 0; +} + +void timerTest(void) +{ + // print a little intro message so we know things are working + rprintf("\r\n\n\nWelcome to the timer library test program!\r\n"); + + // initialize the timer system + timerInit(); + + // to use the internal timers to produce a calibrated delay, + // use the timerPause() function. timerPause takes a 16-bit + // integer argument in milliseconds + + // example: wait for 1/2 of a second, or 500ms + rprintf("\r\nTest of timerPause() function\r\n"); + rprintf("Here comes a 1/2-second delay...\r\n"); + timerPause(500); + rprintf("Done!\r\n"); + + + // here's an example of using the timer library to do + // pulse-width modulation or PWM. PWM signals can be created on + // any output compare (OCx) pin. See your processor's data sheet + // for more information on which I/O pins have output compare + // capability. + rprintf("\r\nTest of timer1 PWM output\r\n"); + + // set the OC1x port pins to output + // We need to do this so we can see and use the PWM signal + // ** these settings are correct for most processors, but not for all + sbi(DDRD, PD4); + sbi(DDRD, PD5); + + // initialize timer1 for PWM output + // - you may use 8,9, or 10 bit PWM resolution + rprintf("Initializing timer1 for PWM\r\n"); + timer1PWMInit(8); + + // turn on the channel A PWM output of timer1 + // - this signal will come out on the OC1A I/O pin + rprintf("Turning on timer1 channel A PWM output\r\n"); + timer1PWMAOn(); + + // set the duty cycle of the channel A output + // - let's try 25% duty, or 256*25% = 64 + rprintf("Setting duty cycle to 25%%\r\n"); + timer1PWMASet(64); + + // turn on channel B and set it to 75% duty cycle + rprintf("Turning on channel B too, with 75%% duty\r\n"); + timer1PWMBOn(); + timer1PWMBSet(192); + + // wait for 5 seconds + rprintf("Pause for 5 seconds...\r\n"); + timerPause(5000); + + // now turn off all PWM on timer1 + rprintf("Turning off all PWM on timer1\r\n"); + timer1PWMOff(); +} + diff --git a/3rd party/Procyuon avrlib/extint.c b/3rd party/Procyuon avrlib/extint.c new file mode 100644 index 0000000..721f012 --- /dev/null +++ b/3rd party/Procyuon avrlib/extint.c @@ -0,0 +1,181 @@ +/*! \file extint.c \brief External-Interrupt function library. */ +//***************************************************************************** +// +// File Name : 'extint.c' +// Title : External-Interrupt function library +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 5/10/2002 +// Revised : 11/16/2004 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// Notes: This library provides convenient standardized configuration and +// access to external interrupts. The library is designed to make +// it possible to write code that uses external interrupts without +// digging into the processor datasheets to find register names and +// bit-defines. The library also strives to allow code which uses +// external interrupts to more easily cross-compile between different +// microcontrollers. +// +// NOTE: Using this library has certain advantages, but also adds +// overhead and latency to interrupt servicing. If the smallest +// code size or fastest possible latency is needed, do NOT use this +// library; link your interrupts directly. +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "extint.h" + +// Global variables +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr ExtIntFunc[EXTINT_NUM_INTERRUPTS]; + +// functions + +//! initializes extint library +void extintInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum +#include +#include + +#include "ata.h" +#include "rprintf.h" +#include "debug.h" + +#include "fat.h" +#include "fatconf.h" + +// globals +// buffers +unsigned char *SectorBuffer = (unsigned char *) FAT_SECTOR_BUFFER_ADDR; +unsigned char *FileNameBuffer = (unsigned char *) FAT_FILENAME_BUFFER_ADDR; +unsigned char *PathNameBuffer = (unsigned char *) FAT_PATHNAME_BUFFER_ADDR; + +// filesystem constants/metrics +struct partrecord PartInfo; +unsigned char Fat32Enabled; +unsigned long FirstDataSector; +unsigned short BytesPerSector; +unsigned short SectorsPerCluster; +unsigned long FirstFATSector; +unsigned long RootDirStartCluster; + +// operating variables +unsigned long CurrentDirStartCluster; //< current directory starting cluster +struct FileInfoStruct FileInfo; //< file information for last file accessed +unsigned long FatInCache = 0; + + +/*************************************************************************/ +/*************************************************************************/ + + +unsigned long fatClustToSect(unsigned long clust) +{ + return ((clust-2) * SectorsPerCluster) + FirstDataSector; +} + +unsigned int fatClusterSize(void) +{ + // return the number of sectors in a disk cluster + return SectorsPerCluster; +} + +unsigned char fatInit( unsigned char device) +{ + //struct partrecord *pr; + struct bpb710 *bpb; + + // read partition table + // TODO.... error checking + ataReadSectors(DRIVE0, 0, 1, SectorBuffer); + // map first partition record + // save partition information to global PartInfo + PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart); +// PartInfo = *pr; + + // Read the Partition BootSector + // **first sector of partition in PartInfo.prStartLBA + ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer ); + bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB; + + // setup global disk constants + FirstDataSector = PartInfo.prStartLBA; + if(bpb->bpbFATsecs) + { + // bpbFATsecs is non-zero and is therefore valid + FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs; + } + else + { + // bpbFATsecs is zero, real value is in bpbBigFATsecs + FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs; + } + SectorsPerCluster = bpb->bpbSecPerClust; + BytesPerSector = bpb->bpbBytesPerSec; + FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA; + + switch (PartInfo.prPartType) + { + case PART_TYPE_DOSFAT16: + case PART_TYPE_FAT16: + case PART_TYPE_FAT16LBA: + // first directory cluster is 2 by default (clusters range 2->big) + RootDirStartCluster = CLUST_FIRST; + // push data sector pointer to end of root directory area + //FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR; + Fat32Enabled = FALSE; + break; + case PART_TYPE_FAT32LBA: + case PART_TYPE_FAT32: + // bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's + RootDirStartCluster = bpb->bpbRootClust; + // push data sector pointer to end of root directory area + // need this? FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR; + Fat32Enabled = TRUE; + break; + default: + rprintfProgStrM("Found: No Partition!\r\n"); + //return 1; + break; + } + + // set current directory to root (\) + CurrentDirStartCluster = RootDirStartCluster; + PathNameBuffer[0] = '\\'; + PathNameBuffer[1] = 0; + + + // do debug +#ifdef DEBUG_FAT + switch (PartInfo.prPartType) + { + case PART_TYPE_DOSFAT16: + rprintfProgStrM("Found: DOSFAT 16\r\n"); + break; + case PART_TYPE_FAT16: + rprintfProgStrM("Found: FAT16\r\n"); + break; + case PART_TYPE_FAT16LBA: + rprintfProgStrM("Found: FAT16 LBA\r\n"); + break; + case PART_TYPE_FAT32LBA: + rprintfProgStrM("Found: FAT32 LBA\r\n"); + break; + case PART_TYPE_FAT32: + rprintfProgStrM("Found: FAT32\r\n"); + //return 1; + break; + default: + rprintfProgStrM("Found: No Partition!\r\n"); + //return 1; + break; + } + + rprintfProgStrM("First sector : "); rprintfu32(PartInfo.prStartLBA); rprintfCRLF(); + rprintfProgStrM("Size : "); rprintfu32(PartInfo.prSize); rprintfCRLF(); + rprintfProgStrM("bytes/sector : "); rprintfu16(bpb->bpbBytesPerSec); rprintfCRLF(); + rprintfProgStrM("sectors/cluster : "); rprintfu08(bpb->bpbSecPerClust); rprintfCRLF(); + rprintfProgStrM("reserved sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF(); + rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF(); + rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF(); + rprintfProgStrM("Number of Fats : "); rprintfu08(bpb->bpbFATs); rprintfCRLF(); + rprintfProgStrM("First Fat Sector: "); rprintfu32(FirstFATSector); rprintfCRLF(); + rprintfProgStrM("First Data Sect : "); rprintfu32(FirstDataSector); rprintfCRLF(); + rprintfProgStrM("RootDirStartClus: "); rprintfu32(RootDirStartCluster); rprintfCRLF(); +#endif + + return 0; +} + +////////////////////////////////////////////////////////////// + +unsigned char fatGetDirEntry(unsigned short entry) +{ + unsigned long sector; + struct direntry *de = 0; // avoid compiler warning by initializing + struct winentry *we; + unsigned char haveLongNameEntry; + unsigned char gotEntry; + unsigned short b; + int i,index; + char *fnbPtr; + unsigned short entrycount = 0; + + // read dir data + sector = fatClustToSect(CurrentDirStartCluster); + + haveLongNameEntry = 0; + gotEntry = 0; + + index = 16; // crank it up + + //while(entrycount < entry) + while(1) + { + if(index == 16) // time for next sector ? + { + ataReadSectors( DRIVE0, sector++, 1, SectorBuffer); + de = (struct direntry *) SectorBuffer; + index = 0; + } + + // check the status of this directory entry slot + if(de->deName[0] == 0x00) + { + // slot is empty and this is the end of directory + gotEntry = 0; + break; + } + else if(de->deName[0] == 0xE5) + { + // this is an empty slot + // do nothing and move to the next one + } + else + { + // this is a valid and occupied entry + // is it a part of a long file/dir name? + if(de->deAttributes == ATTR_LONG_FILENAME) + { + // we have a long name entry + // cast this directory entry as a "windows" (LFN: LongFileName) entry + we = (struct winentry *) de; + + b = WIN_ENTRY_CHARS*( (we->weCnt-1) & 0x0f); // index into string + fnbPtr = &FileNameBuffer[b]; + for (i=0;i<5;i++) *fnbPtr++ = we->wePart1[i*2]; // copy first part + for (i=0;i<6;i++) *fnbPtr++ = we->wePart2[i*2]; // second part + for (i=0;i<2;i++) *fnbPtr++ = we->wePart3[i*2]; // and third part + if (we->weCnt & WIN_LAST) *fnbPtr = 0; // in case dirnamelength is multiple of 13, add termination + if ((we->weCnt & 0x0f) == 1) haveLongNameEntry = 1; // flag that we have a complete long name entry set + } + else + { + // we have a short name entry + + // check if this is the short name entry corresponding + // to the end of a multi-part long name entry + if(haveLongNameEntry) + { + // a long entry name has been collected + if(entrycount == entry) + { + // desired entry has been found, break out + gotEntry = 1; + break; + } + // otherwise + haveLongNameEntry = 0; // clear long name flag + entrycount++; // increment entry counter + } + else + { + // entry is a short name (8.3 format) without a + // corresponding multi-part long name entry + fnbPtr = FileNameBuffer; + for (i=0;i<8;i++) *fnbPtr++ = de->deName[i]; // copy name + *fnbPtr++ = '.'; // insert '.' + for (i=0;i<3;i++) *fnbPtr++ = de->deExtension[i]; // copy extension + *fnbPtr = 0; // null-terminate + + if(entrycount == entry) + { + // desired entry has been found, break out + gotEntry = 1; + break; + } + // otherwise + entrycount++; // increment entry counter + } + } + } + // next directory entry + de++; + // next index + index++; + } + + // we have a file/dir to return + // store file/dir starting cluster (start of data) + FileInfo.StartCluster = (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster; + // store file/dir size + // (note: size field for subdirectory entries is always zero) + FileInfo.Size = de->deFileSize; + // store file/dir attributes + FileInfo.Attr = de->deAttributes; + // store file/dir creation time + FileInfo.CreateTime = de->deCTime[0] | de->deCTime[1]<<8; + // store file/dir creation date + FileInfo.CreateTime = de->deCDate[0] | de->deCDate[1]<<8; + + return gotEntry; +} + +// change directory into +unsigned char fatChangeDirectory(unsigned short entry) +{ + // get the requested directory entry + if( fatGetDirEntry(entry) ) + { + // make sure the entry is a directory + if(FileInfo.Attr & ATTR_DIRECTORY) + { + // change directories into this directory + // check to see if we are changing back to root directory + if(FileInfo.StartCluster) + { + // standard change directory + CurrentDirStartCluster = FileInfo.StartCluster; + } + else + { + // if startCluster pointer is zero, + // a change to the root directory is intended + // change directory to root + CurrentDirStartCluster = RootDirStartCluster; + } + // TODO: handle pathname properly for going up a directory + // set path string + strcat(PathNameBuffer, FileNameBuffer); + strcat(PathNameBuffer, "\\"); + // return success + return TRUE; + } + else + { + // not a directory, cannot CD into a file! + return FALSE; + } + } + else + { + // not a valid entry, cannot CD! + return FALSE; + } +} + +void fatPrintDirEntry(void) +{ + // print a formatted dir-style output for most recent file + // print date + rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_MONTH_MASK)>>DD_MONTH_SHIFT ); // month + rprintfChar('/'); + rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_DAY_MASK)>>DD_DAY_SHIFT ); // day + rprintfChar('/'); + rprintfNum(10, 4, FALSE, '0', (FileInfo.CreateDate&DD_YEAR_MASK)>>DD_YEAR_SHIFT ); // year + rprintfChar(' '); + + // print time + rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_HOURS_MASK)>>DT_HOURS_SHIFT ); // month + rprintfChar(':'); + rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_MINUTES_MASK)>>DT_MINUTES_SHIFT ); // day + rprintfChar(':'); + rprintfNum(10, 2, FALSE, '0', 2*(FileInfo.CreateTime&DT_2SECONDS_MASK)>>DT_2SECONDS_SHIFT ); // seconds + rprintfChar(' '); + + // print attributes + if(FileInfo.Attr & ATTR_VOLUME) rprintfChar('V'); else rprintfChar('-'); + if(FileInfo.Attr & ATTR_DIRECTORY) rprintfChar('D'); else rprintfChar('-'); + if(FileInfo.Attr & ATTR_READONLY) rprintfChar('R'); else rprintfChar('-'); + if(FileInfo.Attr & ATTR_HIDDEN) rprintfChar('H'); else rprintfChar('-'); + if(FileInfo.Attr & ATTR_SYSTEM) rprintfChar('S'); else rprintfChar('-'); + if(FileInfo.Attr & ATTR_ARCHIVE) rprintfChar('A'); else rprintfChar('-'); + rprintfChar(' '); + + // print filesize + rprintfNum(10, 8, FALSE, ' ', FileInfo.Size); // filesize + rprintfChar(' '); + + // print filename + rprintfStr(FileNameBuffer); +} + +void fatDumpDirSlot(unsigned short slot) +{ + unsigned long sector; + // load correct sector + sector = fatClustToSect(CurrentDirStartCluster); + sector += slot/DIRENTRIES_PER_SECTOR; + // print the entry as a hex table + debugPrintHexTable(32, SectorBuffer+(slot<<5) ); +} + +struct FileInfoStruct* fatGetFileInfo(void) +{ + return &FileInfo; +} + +// return the size of the last directory entry +unsigned long fatGetFilesize(void) +{ + return FileInfo.Size; +} + +// return the long name of the last directory entry +char* fatGetFilename(void) +{ + return FileNameBuffer; +} + +// return the directory of the last directory entry +char* fatGetDirname(void) +{ + return PathNameBuffer; +} + +// load a clusterfull of data +void fatLoadCluster(unsigned long cluster, unsigned char *buffer) +{ + register unsigned char i; + // read cluster + //while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0); + for(i=0; i"); + rprintfu32(nextCluster); + rprintfCRLF(); +#endif + + return nextCluster; +} diff --git a/3rd party/Procyuon avrlib/fat.h b/3rd party/Procyuon avrlib/fat.h new file mode 100644 index 0000000..84a540d --- /dev/null +++ b/3rd party/Procyuon avrlib/fat.h @@ -0,0 +1,404 @@ +/*! \file fat.h \brief FAT16/32 file system driver. */ +//***************************************************************************** +// +// File Name : 'fat.h' +// Title : FAT16/32 file system driver +// Author : Pascal Stang +// Date : 11/07/2000 +// Revised : 12/12/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup general +/// \defgroup fat FAT16/32 File System Interface (fat.c) +/// \code #include "fat.h" \endcode +/// \par Overview +/// This FAT16/32 interface allows you to detect and mount FAT16/32 +/// partitions, browse directories and files, and read file data. +/// The interface is designed to operate with the avrlib IDE/ATA driver. +/// Reading FAT efficiently requires at least 512+ bytes of RAM so this +/// interface may not be suitable for processors with less than 1K of RAM. +/// This interface will properly follow a file's cluster chain so files +/// need not be defragmented. +/// +/// \note This code is based in part on work done by Jesper Hansen for his +/// excellent YAMPP MP3 player project. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef FAT_H +#define FAT_H + +#include "global.h" + + +// Some useful cluster numbers +#define MSDOSFSROOT 0 // cluster 0 means the root dir +#define CLUST_FREE 0 // cluster 0 also means a free cluster +#define MSDOSFSFREE CLUST_FREE +#define CLUST_FIRST 2 // first legal cluster number +#define CLUST_RSRVD 0xfffffff6 // reserved cluster range +#define CLUST_BAD 0xfffffff7 // a cluster with a defect +#define CLUST_EOFS 0xfffffff8 // start of eof cluster range +#define CLUST_EOFE 0xffffffff // end of eof cluster range + +#define FAT12_MASK 0x00000fff // mask for 12 bit cluster numbers +#define FAT16_MASK 0x0000ffff // mask for 16 bit cluster numbers +#define FAT32_MASK 0x0fffffff // mask for FAT32 cluster numbers + + +// Partition Type used in the partition record +#define PART_TYPE_UNKNOWN 0x00 +#define PART_TYPE_FAT12 0x01 +#define PART_TYPE_XENIX 0x02 +#define PART_TYPE_DOSFAT16 0x04 +#define PART_TYPE_EXTDOS 0x05 +#define PART_TYPE_FAT16 0x06 +#define PART_TYPE_NTFS 0x07 +#define PART_TYPE_FAT32 0x0B +#define PART_TYPE_FAT32LBA 0x0C +#define PART_TYPE_FAT16LBA 0x0E +#define PART_TYPE_EXTDOSLBA 0x0F +#define PART_TYPE_ONTRACK 0x33 +#define PART_TYPE_NOVELL 0x40 +#define PART_TYPE_PCIX 0x4B +#define PART_TYPE_PHOENIXSAVE 0xA0 +#define PART_TYPE_CPM 0xDB +#define PART_TYPE_DBFS 0xE0 +#define PART_TYPE_BBT 0xFF + +struct partrecord // length 16 bytes +{ + BYTE prIsActive; // 0x80 indicates active partition + BYTE prStartHead; // starting head for partition + WORD prStartCylSect; // starting cylinder and sector + BYTE prPartType; // partition type (see above) + BYTE prEndHead; // ending head for this partition + WORD prEndCylSect; // ending cylinder and sector + DWORD prStartLBA; // first LBA sector for this partition + DWORD prSize; // size of this partition (bytes or sectors ?) +}; + + +struct partsector +{ + CHAR psPartCode[512-64-2]; // pad so struct is 512b + BYTE psPart[64]; // four partition records (64 bytes) + BYTE psBootSectSig0; // two signature bytes (2 bytes) + BYTE psBootSectSig1; +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + + + +// Format of a boot sector. This is the first sector on a DOS floppy disk +// or the first sector of a partition on a hard disk. But, it is not the +// first sector of a partitioned hard disk. +struct bootsector33 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOemName[8]; // OEM name and version + CHAR bsBPB[19]; // BIOS parameter block + CHAR bsDriveNumber; // drive number (0x80) + CHAR bsBootCode[479]; // pad so struct is 512b + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct extboot { + CHAR exDriveNumber; // drive number (0x80) + CHAR exReserved1; // reserved + CHAR exBootSignature; // ext. boot signature (0x29) +#define EXBOOTSIG 0x29 + CHAR exVolumeID[4]; // volume ID number + CHAR exVolumeLabel[11]; // volume label + CHAR exFileSysType[8]; // fs type (FAT12 or FAT16) +}; + +struct bootsector50 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOemName[8]; // OEM name and version + CHAR bsBPB[25]; // BIOS parameter block + CHAR bsExt[26]; // Bootsector Extension + CHAR bsBootCode[448]; // pad so structure is 512b + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct bootsector710 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOEMName[8]; // OEM name and version + CHAR bsBPB[53]; // BIOS parameter block + CHAR bsExt[26]; // Bootsector Extension + CHAR bsBootCode[418]; // pad so structure is 512b + BYTE bsBootSectSig2; // 2 & 3 are only defined for FAT32? + BYTE bsBootSectSig3; + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +#define BOOTSIG2 0 +#define BOOTSIG3 0 +}; + + +/***************************************************************/ +/***************************************************************/ + +// BIOS Parameter Block (BPB) for DOS 3.3 +struct bpb33 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + WORD bpbHiddenSecs; // number of hidden sectors +}; + +// BPB for DOS 5.0 +// The difference is bpbHiddenSecs is a short for DOS 3.3, +// and bpbHugeSectors is not present in the DOS 3.3 bpb. +struct bpb50 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + DWORD bpbHiddenSecs; // # of hidden sectors +// 3.3 compat ends here + DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0 +}; + +// BPB for DOS 7.10 (FAT32) +// This one has a few extensions to bpb50. +struct bpb710 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + DWORD bpbHiddenSecs; // # of hidden sectors +// 3.3 compat ends here + DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0 +// 5.0 compat ends here + DWORD bpbBigFATsecs;// like bpbFATsecs for FAT32 + WORD bpbExtFlags; // extended flags: +#define FATNUM 0xf // mask for numbering active FAT +#define FATMIRROR 0x80 // FAT is mirrored (like it always was) + WORD bpbFSVers; // filesystem version +#define FSVERS 0 // currently only 0 is understood + DWORD bpbRootClust; // start cluster for root directory + WORD bpbFSInfo; // filesystem info structure sector + WORD bpbBackup; // backup boot sector + // There is a 12 byte filler here, but we ignore it +}; + + + + +// *************************************************************** +// * byte versions of the above structs * +// *************************************************************** + + +// BIOS Parameter Block (BPB) for DOS 3.3 +struct byte_bpb33 { + CHAR bpbBytesPerSec[2]; // bytes per sector + CHAR bpbSecPerClust; // sectors per cluster + CHAR bpbResSectors[2]; // number of reserved sectors + CHAR bpbFATs; // number of FATs + CHAR bpbRootDirEnts[2]; // number of root directory entries + CHAR bpbSectors[2]; // total number of sectors + CHAR bpbMedia; // media descriptor + CHAR bpbFATsecs[2]; // number of sectors per FAT + CHAR bpbSecPerTrack[2]; // sectors per track + CHAR bpbHeads[2]; // number of heads + CHAR bpbHiddenSecs[2]; // number of hidden sectors +}; + +// BPB for DOS 5.0 +// The difference is bpbHiddenSecs is a short for DOS 3.3, +// and bpbHugeSectors is not in the 3.3 bpb. +struct byte_bpb50 { + CHAR bpbBytesPerSec[2]; // bytes per sector + CHAR bpbSecPerClust; // sectors per cluster + CHAR bpbResSectors[2]; // number of reserved sectors + CHAR bpbFATs; // number of FATs + CHAR bpbRootDirEnts[2]; // number of root directory entries + CHAR bpbSectors[2]; // total number of sectors + CHAR bpbMedia; // media descriptor + CHAR bpbFATsecs[2]; // number of sectors per FAT + CHAR bpbSecPerTrack[2]; // sectors per track + CHAR bpbHeads[2]; // number of heads + CHAR bpbHiddenSecs[4]; // number of hidden sectors + CHAR bpbHugeSectors[4]; // # of sectors if bpbSectors == 0 +}; + +// BPB for DOS 7.10 (FAT32). +// This one has a few extensions to bpb50. +struct byte_bpb710 { + BYTE bpbBytesPerSec[2]; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + BYTE bpbResSectors[2]; // number of reserved sectors + BYTE bpbFATs; // number of FATs + BYTE bpbRootDirEnts[2]; // number of root directory entries + BYTE bpbSectors[2]; // total number of sectors + BYTE bpbMedia; // media descriptor + BYTE bpbFATsecs[2]; // number of sectors per FAT + BYTE bpbSecPerTrack[2]; // sectors per track + BYTE bpbHeads[2]; // number of heads + BYTE bpbHiddenSecs[4]; // # of hidden sectors + BYTE bpbHugeSectors[4]; // # of sectors if bpbSectors == 0 + BYTE bpbBigFATsecs[4]; // like bpbFATsecs for FAT32 + BYTE bpbExtFlags[2]; // extended flags: + BYTE bpbFSVers[2]; // filesystem version + BYTE bpbRootClust[4]; // start cluster for root directory + BYTE bpbFSInfo[2]; // filesystem info structure sector + BYTE bpbBackup[2]; // backup boot sector + // There is a 12 byte filler here, but we ignore it +}; + +// FAT32 FSInfo block. +struct fsinfo { + BYTE fsisig1[4]; + BYTE fsifill1[480]; + BYTE fsisig2[4]; + BYTE fsinfree[4]; + BYTE fsinxtfree[4]; + BYTE fsifill2[12]; + BYTE fsisig3[4]; + BYTE fsifill3[508]; + BYTE fsisig4[4]; +}; + + +/***************************************************************/ +/***************************************************************/ + + +// Structure of a dos directory entry. +struct direntry { + BYTE deName[8]; // filename, blank filled +#define SLOT_EMPTY 0x00 // slot has never been used +#define SLOT_E5 0x05 // the real value is 0xE5 +#define SLOT_DELETED 0xE5 // file in this slot deleted + BYTE deExtension[3]; // extension, blank filled + BYTE deAttributes; // file attributes +#define ATTR_NORMAL 0x00 // normal file +#define ATTR_READONLY 0x01 // file is readonly +#define ATTR_HIDDEN 0x02 // file is hidden +#define ATTR_SYSTEM 0x04 // file is a system file +#define ATTR_VOLUME 0x08 // entry is a volume label +#define ATTR_LONG_FILENAME 0x0F // this is a long filename entry +#define ATTR_DIRECTORY 0x10 // entry is a directory name +#define ATTR_ARCHIVE 0x20 // file is new or modified + BYTE deLowerCase; // NT VFAT lower case flags (set to zero) +#define LCASE_BASE 0x08 // filename base in lower case +#define LCASE_EXT 0x10 // filename extension in lower case + BYTE deCHundredth; // hundredth of seconds in CTime + BYTE deCTime[2]; // create time + BYTE deCDate[2]; // create date + BYTE deADate[2]; // access date + WORD deHighClust; // high bytes of cluster number + BYTE deMTime[2]; // last update time + BYTE deMDate[2]; // last update date + WORD deStartCluster; // starting cluster of file + DWORD deFileSize; // size of file in bytes +}; + +// number of directory entries in one sector +#define DIRENTRIES_PER_SECTOR 0x10 + +// Structure of a Win95 long name directory entry +struct winentry { + BYTE weCnt; // +#define WIN_LAST 0x40 +#define WIN_CNT 0x3f + BYTE wePart1[10]; + BYTE weAttributes; +#define ATTR_WIN95 0x0f + BYTE weReserved1; + BYTE weChksum; + BYTE wePart2[12]; + WORD weReserved2; + BYTE wePart3[4]; +}; + +#define WIN_ENTRY_CHARS 13 // Number of chars per winentry + +// Maximum filename length in Win95 +// Note: Must be < sizeof(dirent.d_name) +#define WIN_MAXLEN 255 + +// This is the format of the contents of the deTime field in the direntry +// structure. +// We don't use bitfields because we don't know how compilers for +// arbitrary machines will lay them out. +#define DT_2SECONDS_MASK 0x1F // seconds divided by 2 +#define DT_2SECONDS_SHIFT 0 +#define DT_MINUTES_MASK 0x7E0 // minutes +#define DT_MINUTES_SHIFT 5 +#define DT_HOURS_MASK 0xF800 // hours +#define DT_HOURS_SHIFT 11 + +// This is the format of the contents of the deDate field in the direntry +// structure. +#define DD_DAY_MASK 0x1F // day of month +#define DD_DAY_SHIFT 0 +#define DD_MONTH_MASK 0x1E0 // month +#define DD_MONTH_SHIFT 5 +#define DD_YEAR_MASK 0xFE00 // year - 1980 +#define DD_YEAR_SHIFT 9 + +// Stuctures +struct FileInfoStruct +{ + unsigned long StartCluster; //< file starting cluster for last file accessed + unsigned long Size; //< file size for last file accessed + unsigned char Attr; //< file attr for last file accessed + unsigned short CreateTime; //< file creation time for last file accessed + unsigned short CreateDate; //< file creation date for last file accessed +}; + +// Prototypes +unsigned char fatInit( unsigned char device); +unsigned int fatClusterSize(void); +unsigned char fatGetDirEntry(unsigned short entry); +unsigned char fatChangeDirectory(unsigned short entry); +void fatPrintDirEntry(void); +void fatDumpDirSlot(unsigned short entry); +struct FileInfoStruct* fatGetFileInfo(void); +unsigned long fatGetFilesize(void); +char* fatGetFilename(void); +char* fatGetDirname(void); +void fatLoadCluster(unsigned long cluster, unsigned char *buffer); +unsigned long fatNextCluster(unsigned long cluster); + +#endif diff --git a/3rd party/Procyuon avrlib/fixedpt.c b/3rd party/Procyuon avrlib/fixedpt.c new file mode 100644 index 0000000..f6c60cc --- /dev/null +++ b/3rd party/Procyuon avrlib/fixedpt.c @@ -0,0 +1,85 @@ +/*! \file fixedpt.c \brief Fixed-point math function library. */ +//***************************************************************************** +// +// File Name : 'fixedpt.c' +// Title : Fixed-point math function library +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.01.26 +// Revised : 2003.02.02 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#include "fixedpt.h" + +// Program ROM constants + +// Global variables +u08 FixedPtBits; + +// Functions + +// fixedptInit() initializes fixed-point math function library +void fixedptInit(u08 fixedPtBits) +{ + // set the number of bits to use behind the point + FixedPtBits = fixedPtBits; +} + +s32 fixedptConvertFromInt(s32 int_number) +{ + // convert integer to fixed-point number + return (int_number<>FixedPtBits)+1; + } + else + { + // bit behind the point was a '0' + // round down (truncate) to next lower integer + return (fp_number>>FixedPtBits); + } +} + +s32 fixedptAdd(s32 a, s32 b) +{ + // add a and b (a+b) with fixed-point math + return a+b; +} + +s32 fixedptSubtract(s32 a, s32 b) +{ + // subtract a and b (a-b) with fixed-point math + return a-b; +} + +s32 fixedptMultiply(s32 a, s32 b) +{ + // multiply a and b (a*b) with fixed-point math + return (a*b)>>FixedPtBits; +} + +s32 fixedptDivide(s32 numer, s32 denom) +{ + // divide numer by denom (numer/denom) with fixed-point math + return (numer< + 0x02, 0x01, 0x51, 0x09, 0x06,// ? + 0x32, 0x49, 0x79, 0x41, 0x3E,// @ + 0x7E, 0x11, 0x11, 0x11, 0x7E,// A + 0x7F, 0x49, 0x49, 0x49, 0x36,// B + 0x3E, 0x41, 0x41, 0x41, 0x22,// C + 0x7F, 0x41, 0x41, 0x22, 0x1C,// D + 0x7F, 0x49, 0x49, 0x49, 0x41,// E + 0x7F, 0x09, 0x09, 0x01, 0x01,// F + 0x3E, 0x41, 0x41, 0x51, 0x32,// G + 0x7F, 0x08, 0x08, 0x08, 0x7F,// H + 0x00, 0x41, 0x7F, 0x41, 0x00,// I + 0x20, 0x40, 0x41, 0x3F, 0x01,// J + 0x7F, 0x08, 0x14, 0x22, 0x41,// K + 0x7F, 0x40, 0x40, 0x40, 0x40,// L + 0x7F, 0x02, 0x04, 0x02, 0x7F,// M + 0x7F, 0x04, 0x08, 0x10, 0x7F,// N + 0x3E, 0x41, 0x41, 0x41, 0x3E,// O + 0x7F, 0x09, 0x09, 0x09, 0x06,// P + 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q + 0x7F, 0x09, 0x19, 0x29, 0x46,// R + 0x46, 0x49, 0x49, 0x49, 0x31,// S + 0x01, 0x01, 0x7F, 0x01, 0x01,// T + 0x3F, 0x40, 0x40, 0x40, 0x3F,// U + 0x1F, 0x20, 0x40, 0x20, 0x1F,// V + 0x7F, 0x20, 0x18, 0x20, 0x7F,// W + 0x63, 0x14, 0x08, 0x14, 0x63,// X + 0x03, 0x04, 0x78, 0x04, 0x03,// Y + 0x61, 0x51, 0x49, 0x45, 0x43,// Z + 0x00, 0x00, 0x7F, 0x41, 0x41,// [ + 0x02, 0x04, 0x08, 0x10, 0x20,// "\" + 0x41, 0x41, 0x7F, 0x00, 0x00,// ] + 0x04, 0x02, 0x01, 0x02, 0x04,// ^ + 0x40, 0x40, 0x40, 0x40, 0x40,// _ + 0x00, 0x01, 0x02, 0x04, 0x00,// ` + 0x20, 0x54, 0x54, 0x54, 0x78,// a + 0x7F, 0x48, 0x44, 0x44, 0x38,// b + 0x38, 0x44, 0x44, 0x44, 0x20,// c + 0x38, 0x44, 0x44, 0x48, 0x7F,// d + 0x38, 0x54, 0x54, 0x54, 0x18,// e + 0x08, 0x7E, 0x09, 0x01, 0x02,// f + 0x08, 0x14, 0x54, 0x54, 0x3C,// g + 0x7F, 0x08, 0x04, 0x04, 0x78,// h + 0x00, 0x44, 0x7D, 0x40, 0x00,// i + 0x20, 0x40, 0x44, 0x3D, 0x00,// j + 0x00, 0x7F, 0x10, 0x28, 0x44,// k + 0x00, 0x41, 0x7F, 0x40, 0x00,// l + 0x7C, 0x04, 0x18, 0x04, 0x78,// m + 0x7C, 0x08, 0x04, 0x04, 0x78,// n + 0x38, 0x44, 0x44, 0x44, 0x38,// o + 0x7C, 0x14, 0x14, 0x14, 0x08,// p + 0x08, 0x14, 0x14, 0x18, 0x7C,// q + 0x7C, 0x08, 0x04, 0x04, 0x08,// r + 0x48, 0x54, 0x54, 0x54, 0x20,// s + 0x04, 0x3F, 0x44, 0x40, 0x20,// t + 0x3C, 0x40, 0x40, 0x20, 0x7C,// u + 0x1C, 0x20, 0x40, 0x20, 0x1C,// v + 0x3C, 0x40, 0x30, 0x40, 0x3C,// w + 0x44, 0x28, 0x10, 0x28, 0x44,// x + 0x0C, 0x50, 0x50, 0x50, 0x3C,// y + 0x44, 0x64, 0x54, 0x4C, 0x44,// z + 0x00, 0x08, 0x36, 0x41, 0x00,// { + 0x00, 0x00, 0x7F, 0x00, 0x00,// | + 0x00, 0x41, 0x36, 0x08, 0x00,// } + 0x08, 0x08, 0x2A, 0x1C, 0x08,// -> + 0x08, 0x1C, 0x2A, 0x08, 0x08 // <- +}; + +#endif diff --git a/3rd party/Procyuon avrlib/fontgr.h b/3rd party/Procyuon avrlib/fontgr.h new file mode 100644 index 0000000..5d88909 --- /dev/null +++ b/3rd party/Procyuon avrlib/fontgr.h @@ -0,0 +1,31 @@ +/*! \file fontgr.h \brief Graphic LCD Font (Graphic Characters). */ +//***************************************************************************** +// +// File Name : 'fontgr.h' +// Title : Graphic LCD Font (Graphic Charaters) +// Author : Pascal Stang +// Date : 10/19/2001 +// Revised : 10/19/2001 +// Version : 0.1 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +//***************************************************************************** + +#ifndef FONTGR_H +#define FONTGR_H + +#ifndef WIN32 +// AVR specific includes + #include +#endif + +static unsigned char __attribute__ ((progmem)) FontGr[] = +{ +// format is one character per line: +// length, byte array[length] + 0x0B,0x3E,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x3C,0x00,// 0. Folder Icon + 0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF // 1. Solid 6x8 block +}; + +#endif diff --git a/3rd party/Procyuon avrlib/glcd.c b/3rd party/Procyuon avrlib/glcd.c new file mode 100644 index 0000000..6e70b59 --- /dev/null +++ b/3rd party/Procyuon avrlib/glcd.c @@ -0,0 +1,164 @@ +/*! \file glcd.c \brief Graphic LCD API functions. */ +//***************************************************************************** +// +// File Name : 'glcd.c' +// Title : Graphic LCD API functions +// Author : Pascal Stang - Copyright (C) 2002 +// Date : 5/30/2002 +// Revised : 5/30/2002 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 +// AVR specific includes + #include + #include +#endif + +#include "glcd.h" + +// include hardware support +#include "ks0108.h" +// include fonts +#include "font5x7.h" +#include "fontgr.h" + +// graphic routines + +// set dot +void glcdSetDot(u08 x, u08 y) +{ + unsigned char temp; + + glcdSetAddress(x, y/8); + temp = glcdDataRead(); // dummy read + temp = glcdDataRead(); // read back current value + glcdSetAddress(x, y/8); + glcdDataWrite(temp | (1 << (y % 8))); + + glcdStartLine(0); +} + +// clear dot +void glcdClearDot(u08 x, u08 y) +{ + unsigned char temp; + + glcdSetAddress(x, y/8); + temp = glcdDataRead(); // dummy read + temp = glcdDataRead(); // read back current value + glcdSetAddress(x, y/8); + glcdDataWrite(temp & ~(1 << (y % 8))); + + glcdStartLine(0); +} + +// draw line +void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2) +{ +}; + +// draw rectangle +void glcdRectangle(u08 x, u08 y, u08 a, u08 b) +{ + unsigned char j; + + for (j = 0; j < a; j++) { + glcdSetDot(x, y + j); + glcdSetDot(x + b - 1, y + j); + } + for (j = 0; j < b; j++) { + glcdSetDot(x + j, y); + glcdSetDot(x + j, y + a - 1); + } +} + +// draw circle +void glcdCircle(u08 xcenter, u08 ycenter, u08 radius) +{ + int tswitch, y, x = 0; + unsigned char d; + + d = ycenter - xcenter; + y = radius; + tswitch = 3 - 2 * radius; + while (x <= y) { + glcdSetDot(xcenter + x, ycenter + y); glcdSetDot(xcenter + x, ycenter - y); + glcdSetDot(xcenter - x, ycenter + y); glcdSetDot(xcenter - x, ycenter - y); + glcdSetDot(ycenter + y - d, ycenter + x); glcdSetDot(ycenter + y - d, ycenter - x); + glcdSetDot(ycenter - y - d, ycenter + x); glcdSetDot(ycenter - y - d, ycenter - x); + + if (tswitch < 0) tswitch += (4 * x + 6); + else { + tswitch += (4 * (x - y) + 10); + y--; + } + x++; + } +} + +// text routines + +// write a character at the current position +void glcdWriteChar(unsigned char c) +{ + u08 i = 0; + + for(i=0; i<5; i++) + { + glcdDataWrite(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i])); + } + + // write a spacer line + glcdDataWrite(0x00); + // unless we're at the end of the display + //if(xx == 128) + // xx = 0; + //else + // glcdWriteData(0x00); + + //cbi(GLCD_Control, GLCD_CS1); + //cbi(GLCD_Control, GLCD_CS2); + glcdStartLine(0); +} + +void glcdWriteCharGr(u08 grCharIdx) +{ + u08 idx; + u08 grLength; + u08 grStartIdx = 0; + + // get starting index of graphic bitmap + for(idx=0; idx +#endif + +#include "global.h" + +#define LINE1 0 +#define LINE2 1 +#define LINE3 2 +#define LINE4 3 +#define LINE5 4 +#define LINE6 5 +#define LINE7 6 +#define LINE8 7 + +#define ON 1 +#define OFF 0 + +// API-level interface commands +// ***** Public Functions ***** + +//! set a dot on the display (x is horiz 0:127, y is vert 0:63) +void glcdSetDot(u08 x, u08 y); + +//! clear a dot on the display (x is horiz 0:127, y is vert 0:63) +void glcdClearDot(u08 x, u08 y); + +//! draw line +void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2); + +//! draw rectangle (coords????) +void glcdRectangle(u08 x, u08 y, u08 a, u08 b); + +//! draw circle of at +void glcdCircle(u08 xcenter, u08 ycenter, u08 radius); + +//! write a standard ascii charater (values 20-127) +// to the display at current position +void glcdWriteChar(unsigned char c); + +//! write a special graphic character/icon +// to the display at current position +void glcdWriteCharGr(u08 grCharIndex); + +// ***** Private Functions ***** (or depricated) +void glcdPutStr(u08 *data); + +#endif diff --git a/3rd party/Procyuon avrlib/gps.c b/3rd party/Procyuon avrlib/gps.c new file mode 100644 index 0000000..bf1fc74 --- /dev/null +++ b/3rd party/Procyuon avrlib/gps.c @@ -0,0 +1,83 @@ +/*! \file gps.c \brief GPS position storage and processing library. */ +//***************************************************************************** +// +// File Name : 'gps.c' +// Title : GPS position storage and processing function library +// Author : Pascal Stang - Copyright (C) 2002-2005 +// Created : 2005.01.14 +// Revised : 2002.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include + #include +#endif + +#include "global.h" +#include "rprintf.h" +#include "gps.h" + +// Global variables +GpsInfoType GpsInfo; + +// Functions +void gpsInit(void) +{ + +} + +GpsInfoType* gpsGetInfo(void) +{ + return &GpsInfo; +} + +void gpsInfoPrint(void) +{ + + rprintfProgStrM("TOW: "); rprintfFloat(8, GpsInfo.TimeOfWeek.f); rprintfCRLF(); + rprintfProgStrM("WkNum: "); rprintfNum(10,4,0,' ',GpsInfo.WeekNum); rprintfCRLF(); + rprintfProgStrM("UTCoffset:"); rprintfFloat(8, GpsInfo.UtcOffset.f); rprintfCRLF(); + rprintfProgStrM("Num SVs: "); rprintfNum(10,4,0,' ',GpsInfo.numSVs); rprintfCRLF(); + + rprintfProgStrM("X_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.x.f); rprintfCRLF(); + rprintfProgStrM("Y_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.y.f); rprintfCRLF(); + rprintfProgStrM("Z_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.z.f); rprintfCRLF(); + rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosECEF.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosECEF.updates); rprintfCRLF(); + + //u08 str[20]; + //rprintfProgStrM(" PosLat: "); rprintfStr(dtostrf(GpsInfo.PosLat.f, 10, 5, str)); + rprintfProgStrM("PosLat: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lat.f/PI)); rprintfCRLF(); + rprintfProgStrM("PosLon: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lon.f/PI)); rprintfCRLF(); + rprintfProgStrM("PosAlt: "); rprintfFloat(8, GpsInfo.PosLLA.alt.f); rprintfCRLF(); + rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosLLA.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosLLA.updates); rprintfCRLF(); + + rprintfProgStrM("Vel East: "); rprintfFloat(8, GpsInfo.VelENU.east.f); rprintfCRLF(); + rprintfProgStrM("Vel North:"); rprintfFloat(8, GpsInfo.VelENU.north.f); rprintfCRLF(); + rprintfProgStrM("Vel Up: "); rprintfFloat(8, GpsInfo.VelENU.up.f); rprintfCRLF(); +// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelENU.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelENU.updates); rprintfCRLF(); + + rprintfProgStrM("Vel Head: "); rprintfFloat(8, GpsInfo.VelHS.heading.f); rprintfCRLF(); + rprintfProgStrM("Vel Speed:"); rprintfFloat(8, GpsInfo.VelHS.speed.f); rprintfCRLF(); +// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelHS.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelHS.updates); rprintfCRLF(); + +} + + diff --git a/3rd party/Procyuon avrlib/gps.h b/3rd party/Procyuon avrlib/gps.h new file mode 100644 index 0000000..b42edda --- /dev/null +++ b/3rd party/Procyuon avrlib/gps.h @@ -0,0 +1,119 @@ +/*! \file gps.h \brief GPS position storage and processing library. */ +//***************************************************************************** +// +// File Name : 'gps.h' +// Title : GPS position storage and processing function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.29 +// Revised : 2002.08.29 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_hw +/// \defgroup gps GPS Positioning and Navigation Function Library (gps.c) +/// \code #include "gps.h" \endcode +/// \par Overview +/// This library provides a generic way to store and process information +/// received from a GPS receiver.  Currently the library only stores the most +/// recent set of GPS data (position, velocity, time) from a GPS receiver. +/// Future revisions will include navigation functions like calculate +/// heading/distance to a waypoint.  The processing of incoming serial data +/// packets from GPS hardware is not done in this library.  The libraries +/// tsip.c and nmea.c do the packet processing for Trimble Standard Interface +/// Protocol and NMEA-0813 repectively, and store the results in this library. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GPS_H +#define GPS_H + +#include "global.h" + +// constants/macros/typdefs +typedef union union_float_u32 +{ + float f; + unsigned long i; + unsigned char b[4]; +} float_u32; + +typedef union union_double_u64 +{ + double f; + unsigned long long i; + unsigned char b[8]; +} double_u64; + +struct PositionLLA +{ + float_u32 lat; + float_u32 lon; + float_u32 alt; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityENU +{ + float_u32 east; + float_u32 north; + float_u32 up; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityHS +{ + float_u32 heading; + float_u32 speed; + float_u32 TimeOfFix; + u16 updates; +}; + +struct PositionECEF +{ + float_u32 x; + float_u32 y; + float_u32 z; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityECEF +{ + float_u32 x; + float_u32 y; + float_u32 z; + float_u32 TimeOfFix; + u16 updates; +}; + +typedef struct struct_GpsInfo +{ + float_u32 TimeOfWeek; + u16 WeekNum; + float_u32 UtcOffset; + u08 numSVs; + + struct PositionLLA PosLLA; + struct PositionECEF PosECEF; + struct VelocityECEF VelECEF; + struct VelocityENU VelENU; + struct VelocityHS VelHS; + +} GpsInfoType; + +// functions +void gpsInit(void); +GpsInfoType* gpsGetInfo(void); +void gpsInfoPrint(void); + +#endif diff --git a/3rd party/Procyuon avrlib/i2c.c b/3rd party/Procyuon avrlib/i2c.c new file mode 100644 index 0000000..320dfc3 --- /dev/null +++ b/3rd party/Procyuon avrlib/i2c.c @@ -0,0 +1,600 @@ +/*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */ +//***************************************************************************** +// +// File Name : 'i2c.c' +// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.9 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "i2c.h" + +#include "rprintf.h" // include printf function library +#include "uart2.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +//#define I2C_DEBUG + +// I2C state and address variables +static volatile eI2cStateType I2cState; +static u08 I2cDeviceAddrRW; +// send/transmit buffer (outgoing data) +static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE]; +static u08 I2cSendDataIndex; +static u08 I2cSendDataLength; +// receive buffer (incoming data) +static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE]; +static u08 I2cReceiveDataIndex; +static u08 I2cReceiveDataLength; + +// function pointer to i2c receive routine +//! I2cSlaveReceive is called when this processor +// is addressed as a slave for writing +static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData); +//! I2cSlaveTransmit is called when this processor +// is addressed as a slave for reading +static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData); + +// functions +void i2cInit(void) +{ + // set pull-up resistors on I2C bus pins + // TODO: should #ifdef these + sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc + sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc + sbi(PORTD, 0); // i2c SCL on ATmega128,64 + sbi(PORTD, 1); // i2c SDA on ATmega128,64 + + // clear SlaveReceive and SlaveTransmit handler to null + i2cSlaveReceive = 0; + i2cSlaveTransmit = 0; + // set i2c bit rate to 100KHz + i2cSetBitrate(100); + // enable TWI (two-wire interface) + sbi(TWCR, TWEN); + // set state + I2cState = I2C_IDLE; + // enable TWI interrupt and slave address ACK + sbi(TWCR, TWIE); + sbi(TWCR, TWEA); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // enable interrupts + sei(); +} + +void i2cSetBitrate(u16 bitrateKHz) +{ + u08 bitrate_div; + // set i2c bitrate + // SCL freq = F_CPU/(16+2*TWBR)) + #ifdef TWPS0 + // for processors with additional bitrate division (mega128) + // SCL freq = F_CPU/(16+2*TWBR*4^TWPS) + // set TWPS to zero + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + #endif + // calculate bitrate division + bitrate_div = ((F_CPU/1000l)/bitrateKHz); + if(bitrate_div >= 16) + bitrate_div = (bitrate_div-16)/2; + outb(TWBR, bitrate_div); +} + +void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn) +{ + // set local device address (used in slave mode only) + outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) ); +} + +void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData)) +{ + i2cSlaveReceive = i2cSlaveRx_func; +} + +void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData)) +{ + i2cSlaveTransmit = i2cSlaveTx_func; +} + +inline void i2cSendStart(void) +{ + // send start condition + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA)); +} + +inline void i2cSendStop(void) +{ + // transmit stop condition + // leave with TWEA on for slave receiving + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO)); +} + +inline void i2cWaitForComplete(void) +{ + // wait for i2c interface to complete operation + while( !(inb(TWCR) & BV(TWINT)) ); +} + +inline void i2cSendByte(u08 data) +{ + // save data to the TWDR + outb(TWDR, data); + // begin send + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); +} + +inline void i2cReceiveByte(u08 ackFlag) +{ + // begin receive over i2c + if( ackFlag ) + { + // ackFlag = TRUE: ACK the recevied data + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + } + else + { + // ackFlag = FALSE: NACK the recevied data + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + } +} + +inline u08 i2cGetReceivedByte(void) +{ + // retieve received data byte from i2c TWDR + return( inb(TWDR) ); +} + +inline u08 i2cGetStatus(void) +{ + // retieve current i2c status from i2c TWSR + return( inb(TWSR) ); +} + +void i2cMasterSend(u08 deviceAddr, u08 length, u08* data) +{ + u08 i; + // wait for interface to be ready + while(I2cState); + // set state + I2cState = I2C_MASTER_TX; + // save data + I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation + for(i=0; i 1) + { + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *data++ = i2cGetReceivedByte(); + // decrement length + length--; + } + + // accept receive data and nack it (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *data++ = i2cGetReceivedByte(); + } + else + { + // device did not ACK it's address, + // data will not be transferred + // return error + retval = I2C_ERROR_NODEV; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return retval; +} +/* +void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata) +{ + // disable TWI interrupt + cbi(TWCR, TWIE); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + + // if there's data to be sent, do it + if(sendlength) + { + // send device address with write + i2cSendByte( deviceAddr & 0xFE ); + i2cWaitForComplete(); + + // send data + while(sendlength) + { + i2cSendByte( *senddata++ ); + i2cWaitForComplete(); + sendlength--; + } + } + + // if there's data to be received, do it + if(receivelength) + { + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr | 0x01 ); + i2cWaitForComplete(); + + // accept receive data and ack it + while(receivelength > 1) + { + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *receivedata++ = i2cGetReceivedByte(); + // decrement length + receivelength--; + } + + // accept receive data and nack it (last-byte signal) + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *receivedata++ = i2cGetReceivedByte(); + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + + // enable TWI interrupt + sbi(TWCR, TWIE); +} +*/ + +//! I2C (TWI) interrupt service routine +SIGNAL(SIG_2WIRE_SERIAL) +{ + // read status bits + u08 status = inb(TWSR) & TWSR_STATUS_MASK; + + switch(status) + { + // Master General + case TW_START: // 0x08: Sent start condition + case TW_REP_START: // 0x10: Sent repeated start condition + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: M->START\r\n"); + rprintfInit(uart1SendByte); + #endif + // send device address + i2cSendByte(I2cDeviceAddrRW); + break; + + // Master Transmitter & Receiver status codes + case TW_MT_SLA_ACK: // 0x18: Slave address acknowledged + case TW_MT_DATA_ACK: // 0x28: Data acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MT->SLA_ACK or DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + if(I2cSendDataIndex < I2cSendDataLength) + { + // send data + i2cSendByte( I2cSendData[I2cSendDataIndex++] ); + } + else + { + // transmit stop condition, enable SLA ACK + i2cSendStop(); + // set state + I2cState = I2C_IDLE; + } + break; + case TW_MR_DATA_NACK: // 0x58: Data received, NACK reply issued + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // store final received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // continue to transmit STOP condition + case TW_MR_SLA_NACK: // 0x48: Slave address not acknowledged + case TW_MT_SLA_NACK: // 0x20: Slave address not acknowledged + case TW_MT_DATA_NACK: // 0x30: Data not acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MTR->SLA_NACK or MT->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // transmit stop condition, enable SLA ACK + i2cSendStop(); + // set state + I2cState = I2C_IDLE; + break; + case TW_MT_ARB_LOST: // 0x38: Bus arbitration lost + //case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MT->ARB_LOST\r\n"); + rprintfInit(uart1SendByte); + #endif + // release bus + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + // set state + I2cState = I2C_IDLE; + // release bus and transmit start when bus is free + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA)); + break; + case TW_MR_DATA_ACK: // 0x50: Data acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // store received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // fall-through to see if more bytes will be received + case TW_MR_SLA_ACK: // 0x40: Slave address acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + if(I2cReceiveDataIndex < (I2cReceiveDataLength-1)) + // data byte will be received, reply with ACK (more bytes in transfer) + i2cReceiveByte(TRUE); + else + // data byte will be received, reply with NACK (final byte in transfer) + i2cReceiveByte(FALSE); + break; + + // Slave Receiver status codes + case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned + case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned + case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned + case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // we are being addressed as slave for writing (data will be received from master) + // set state + I2cState = I2C_SLAVE_RX; + // prepare buffer + I2cReceiveDataIndex = 0; + // receive data byte and return ACK + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + break; + case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned + case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // get previously received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // check receive buffer status + if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE) + { + // receive data byte and return ACK + i2cReceiveByte(TRUE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + } + else + { + // receive data byte and return NACK + i2cReceiveByte(FALSE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + } + break; + case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned + case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // receive data byte and return NACK + i2cReceiveByte(FALSE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + break; + case TW_SR_STOP: // 0xA0: STOP or REPEATED START has been received while addressed as slave + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->SR_STOP\r\n"); + rprintfInit(uart1SendByte); + #endif + // switch to SR mode with SLA ACK + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // i2c receive is complete, call i2cSlaveReceive + if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData); + // set state + I2cState = I2C_IDLE; + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // 0xA8: own SLA+R has been received, ACK has been returned + case TW_ST_ARB_LOST_SLA_ACK: // 0xB0: GCA+R has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // we are being addressed as slave for reading (data must be transmitted back to master) + // set state + I2cState = I2C_SLAVE_TX; + // request data from application + if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData); + // reset data index + I2cSendDataIndex = 0; + // fall-through to transmit first data byte + case TW_ST_DATA_ACK: // 0xB8: data byte has been transmitted, ACK has been received + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // transmit data byte + outb(TWDR, I2cSendData[I2cSendDataIndex++]); + if(I2cSendDataIndex < I2cSendDataLength) + // expect ACK to data byte + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + else + // expect NACK to data byte + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + break; + case TW_ST_DATA_NACK: // 0xC0: data byte has been transmitted, NACK has been received + case TW_ST_LAST_DATA: // 0xC8: + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->DATA_NACK or LAST_DATA\r\n"); + rprintfInit(uart1SendByte); + #endif + // all done + // switch to open slave + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // set state + I2cState = I2C_IDLE; + break; + + // Misc + case TW_NO_INFO: // 0xF8: No relevant state information + // do nothing + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: NO_INFO\r\n"); + rprintfInit(uart1SendByte); + #endif + break; + case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: BUS_ERROR\r\n"); + rprintfInit(uart1SendByte); + #endif + // reset internal hardware and release bus + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA)); + // set state + I2cState = I2C_IDLE; + break; + } +} + +eI2cStateType i2cGetState(void) +{ + return I2cState; +} diff --git a/3rd party/Procyuon avrlib/i2c.h b/3rd party/Procyuon avrlib/i2c.h new file mode 100644 index 0000000..1e0eb3a --- /dev/null +++ b/3rd party/Procyuon avrlib/i2c.h @@ -0,0 +1,176 @@ +/*! \file i2c.h \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */ +//***************************************************************************** +// +// File Name : 'i2c.h' +// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.03 +// Version : 0.9 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup driver_avr +/// \defgroup i2c I2C Serial Interface Function Library (i2c.c) +/// \code #include "i2c.h" \endcode +/// \par Overview +/// This library provides the high-level functions needed to use the I2C +/// serial interface supported by the hardware of several AVR processors. +/// The library is functional but has not been exhaustively tested yet and is +/// still expanding.  Thanks to the standardization of the I2C protocol and +/// register access, the send and receive commands are everything you need to +/// talk to thousands of different I2C devices including: EEPROMS, Flash memory, +/// MP3 players, A/D and D/A converters, electronic potentiometers, etc. +/// +/// \par About I2C +/// I2C (pronounced "eye-squared-see") is a two-wire bidirectional +/// network designed for easy transfer of information between a wide variety +/// of intelligent devices. Many of the Atmel AVR series processors have +/// hardware support for transmitting and receiving using an I2C-type bus. +/// In addition to the AVRs, there are thousands of other parts made by +/// manufacturers like Philips, Maxim, National, TI, etc that use I2C as +/// their primary means of communication and control. Common device types +/// are A/D & D/A converters, temp sensors, intelligent battery monitors, +/// MP3 decoder chips, EEPROM chips, multiplexing switches, etc. +/// +/// I2C uses only two wires (SDA and SCL) to communicate bidirectionally +/// between devices. I2C is a multidrop network, meaning that you can have +/// several devices on a single bus. Because I2C uses a 7-bit number to +/// identify which device it wants to talk to, you cannot have more than +/// 127 devices on a single bus. +/// +/// I2C ordinarily requires two 4.7K pull-up resistors to power (one each on +/// SDA and SCL), but for small numbers of devices (maybe 1-4), it is enough +/// to activate the internal pull-up resistors in the AVR processor. To do +/// this, set the port pins, which correspond to the I2C pins SDA/SCL, high. +/// For example, on the mega163, sbi(PORTC, 0); sbi(PORTC, 1);. +/// +/// For complete information about I2C, see the Philips Semiconductor +/// website. They created I2C and have the largest family of devices that +/// work with I2C. +/// +/// \Note: Many manufacturers market I2C bus devices under a different or generic +/// bus name like "Two-Wire Interface". This is because Philips still holds +/// "I2C" as a trademark. For example, SMBus and SMBus devices are hardware +/// compatible and closely related to I2C. They can be directly connected +/// to an I2C bus along with other I2C devices are are generally accessed in +/// the same way as I2C devices. SMBus is often found on modern motherboards +/// for temp sensing and other low-level control tasks. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2C_H +#define I2C_H + +#include "global.h" + +// include project-specific configuration +#include "i2cconf.h" + +// TWSR values (not bits) +// (taken from avr-libc twi.h - thank you Marek Michalkiewicz) +// Master +#define TW_START 0x08 +#define TW_REP_START 0x10 +// Master Transmitter +#define TW_MT_SLA_ACK 0x18 +#define TW_MT_SLA_NACK 0x20 +#define TW_MT_DATA_ACK 0x28 +#define TW_MT_DATA_NACK 0x30 +#define TW_MT_ARB_LOST 0x38 +// Master Receiver +#define TW_MR_ARB_LOST 0x38 +#define TW_MR_SLA_ACK 0x40 +#define TW_MR_SLA_NACK 0x48 +#define TW_MR_DATA_ACK 0x50 +#define TW_MR_DATA_NACK 0x58 +// Slave Transmitter +#define TW_ST_SLA_ACK 0xA8 +#define TW_ST_ARB_LOST_SLA_ACK 0xB0 +#define TW_ST_DATA_ACK 0xB8 +#define TW_ST_DATA_NACK 0xC0 +#define TW_ST_LAST_DATA 0xC8 +// Slave Receiver +#define TW_SR_SLA_ACK 0x60 +#define TW_SR_ARB_LOST_SLA_ACK 0x68 +#define TW_SR_GCALL_ACK 0x70 +#define TW_SR_ARB_LOST_GCALL_ACK 0x78 +#define TW_SR_DATA_ACK 0x80 +#define TW_SR_DATA_NACK 0x88 +#define TW_SR_GCALL_DATA_ACK 0x90 +#define TW_SR_GCALL_DATA_NACK 0x98 +#define TW_SR_STOP 0xA0 +// Misc +#define TW_NO_INFO 0xF8 +#define TW_BUS_ERROR 0x00 + +// defines and constants +#define TWCR_CMD_MASK 0x0F +#define TWSR_STATUS_MASK 0xF8 + +// return values +#define I2C_OK 0x00 +#define I2C_ERROR_NODEV 0x01 + +// types +typedef enum +{ + I2C_IDLE = 0, I2C_BUSY = 1, + I2C_MASTER_TX = 2, I2C_MASTER_RX = 3, + I2C_SLAVE_TX = 4, I2C_SLAVE_RX = 5 +} eI2cStateType; + +// functions + +//! Initialize I2C (TWI) interface +void i2cInit(void); + +//! Set the I2C transaction bitrate (in KHz) +void i2cSetBitrate(u16 bitrateKHz); + +// I2C setup and configurations commands +//! Set the local (AVR processor's) I2C device address +void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn); + +//! Set the user function which handles receiving (incoming) data as a slave +void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData)); +//! Set the user function which handles transmitting (outgoing) data as a slave +void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData)); + +// Low-level I2C transaction commands +//! Send an I2C start condition in Master mode +void i2cSendStart(void); +//! Send an I2C stop condition in Master mode +void i2cSendStop(void); +//! Wait for current I2C operation to complete +void i2cWaitForComplete(void); +//! Send an (address|R/W) combination or a data byte over I2C +void i2cSendByte(u08 data); +//! Receive a data byte over I2C +// ackFlag = TRUE if recevied data should be ACK'ed +// ackFlag = FALSE if recevied data should be NACK'ed +void i2cReceiveByte(u08 ackFlag); +//! Pick up the data that was received with i2cReceiveByte() +u08 i2cGetReceivedByte(void); +//! Get current I2c bus status from TWSR +u08 i2cGetStatus(void); + +// high-level I2C transaction commands + +//! send I2C data to a device on the bus +void i2cMasterSend(u08 deviceAddr, u08 length, u08 *data); +//! receive I2C data from a device on the bus +void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data); + +//! send I2C data to a device on the bus (non-interrupt based) +u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data); +//! receive I2C data from a device on the bus (non-interrupt based) +u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data); + +//! Get the current high-level state of the I2C interface +eI2cStateType i2cGetState(void); + +#endif diff --git a/3rd party/Procyuon avrlib/i2ceeprom.c b/3rd party/Procyuon avrlib/i2ceeprom.c new file mode 100644 index 0000000..dfbd0d9 --- /dev/null +++ b/3rd party/Procyuon avrlib/i2ceeprom.c @@ -0,0 +1,59 @@ +/*! \file i2ceeprom.c \brief Interface for standard I2C EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'i2ceeprom.c' +// Title : Interface for standard I2C EEPROM memories +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.04.23 +// Revised : 2003.04.23 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "i2c.h" +#include "i2ceeprom.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +// functions +void i2ceepromInit(void) +{ + // although there is no code here + // don't forget to initialize the I2C interface itself +} + +u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr) +{ + u08 packet[2]; + // prepare address + packet[0] = (memAddr>>8); + packet[1] = (memAddr&0x00FF); + // send memory address we wish to access to the memory chip + i2cMasterSendNI(i2cAddr, 2, packet); + // retrieve the data at this memory address + i2cMasterReceiveNI(i2cAddr, 1, packet); + // return data + return packet[0]; +} + +void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data) +{ + u08 packet[3]; + // prepare address + data + packet[0] = (memAddr>>8); + packet[1] = (memAddr&0x00FF); + packet[2] = data; + // send memory address we wish to access to the memory chip + // along with the data we wish to write + i2cMasterSendNI(i2cAddr, 3, packet); +} diff --git a/3rd party/Procyuon avrlib/i2ceeprom.h b/3rd party/Procyuon avrlib/i2ceeprom.h new file mode 100644 index 0000000..7943f23 --- /dev/null +++ b/3rd party/Procyuon avrlib/i2ceeprom.h @@ -0,0 +1,42 @@ +/*! \file i2ceeprom.h \brief Interface for standard I2C EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'i2ceeprom.h' +// Title : Interface for standard I2C EEPROM memories +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.04.23 +// Revised : 2003.04.23 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup driver_hw +/// \defgroup i2ceeprom Interface for standard I2C EEPROM memories (i2ceeprom.c) +/// \code #include "i2ceeprom.h" \endcode +/// \par Overview +/// This library provides functions for reading and writing standard +/// 24Cxxx/24LCxxx I2C EEPROM memories. Memory sizes up to 64Kbytes are +/// supported. Future revisions may include page-write support. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CEEPROM_H +#define I2CEEPROM_H + +#include "global.h" + +// functions + +//! Initialize I2C EEPROM interface +void i2ceepromInit(void); + +//! In the I2C EEPROM at [i2cAddr], read a byte from memory location [memAddr] +u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr); + +//! In the I2C EEPROM at [i2cAddr], write a byte [data] to the memory location [memAddr] +void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data); + +#endif diff --git a/3rd party/Procyuon avrlib/i2csw.c b/3rd party/Procyuon avrlib/i2csw.c new file mode 100644 index 0000000..4650a33 --- /dev/null +++ b/3rd party/Procyuon avrlib/i2csw.c @@ -0,0 +1,176 @@ +/*! \file i2csw.c \brief Software I2C interface using port pins. */ +//***************************************************************************** +// +// File Name : 'i2csw.c' +// Title : Software I2C interface using port pins +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 5/2/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include + +#include "i2csw.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +//#define QDEL delay(5) // i2c quarter-bit delay +//#define HDEL delay(10) // i2c half-bit delay + +// i2c quarter-bit delay +#define QDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); +// i2c half-bit delay +#define HDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); + +#define I2C_SDL_LO cbi( SDAPORT, SDA) +#define I2C_SDL_HI sbi( SDAPORT, SDA) + +#define I2C_SCL_LO cbi( SCLPORT, SCL); +#define I2C_SCL_HI sbi( SCLPORT, SCL); + +#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO; +#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO; +#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL; + +/* +void i2ct(void) +{ + HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO; +} + +void i2cstart(void) +{ + I2C_SDL_LO; QDEL; I2C_SCL_LO; +} + +void i2cstop(void) +{ + HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL; +} + + +#define I2C_SCL_TOGGLE i2ct(); +#define I2C_START i2cstart(); +#define I2C_STOP i2cstop(); +*/ + +UINT i2cPutbyte(u08 b) +{ + int i; + + for (i=7;i>=0;i--) + { + if ( b & (1<=0;i--) + { + HDEL; + I2C_SCL_HI; // clock HI + c = inb(SDAPIN) & (1< register +void i2cSend(BYTE device, BYTE sub, BYTE length, BYTE *data); + +// receive I2C data from register +void i2cReceive(BYTE device, BYTE sub, BYTE length, BYTE *data); + +#endif diff --git a/3rd party/Procyuon avrlib/index.html b/3rd party/Procyuon avrlib/index.html new file mode 100644 index 0000000..db76897 --- /dev/null +++ b/3rd party/Procyuon avrlib/index.html @@ -0,0 +1,152 @@ + + +Procyon AVRlib - C-Language Function Library for Atmel AVR Processors + + + + +

Procyon AVRlib
+
C-Language Function Library for + Atmel AVR Processors

+ +
+ Written by Pascal Stang | Updated: + +
+
+
    +
  • AVRlib is a library of easy-to-use C functions for a variety of common + and uncommon tasks using AVR processors.
  • +
  • The goal of AVRlib is to allow programmers to work quickly towards their + end goal by reducing the time needed to write basic support functions and + code.
  • +
  • Most AVRlib header (*.h) files have lengthy descriptions of how to use + the supplied library functions. All code (*.c) files are heavily commented + with additional information.
  • +
  • Documentation is still being improved and refined on many libraries. When + getting familiar with a library, look first at the HTML docs and any example + code that is available in the examples directory. Then look inside the *.h + and *conf.h files, and then the *.c file for that library for more details + and documentation.
  • +
  • Significant example code is included in avrlib.zip. The example + code is heavily commented and strives to illustrate how to use various AVRlib + function libraries.
  • +
  • Download AVRlib (with docs and code examples) + + +
  • +
  • On-line HTML Documentation
  • +
+ +
+ +
+

Procyon AVRlib Overview

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
GeneralAVR Built-In Peripheral + Drivers
    +
  • Byte Buffering (circular)
  • +
  • Bit Buffering (linear)
  • +
  • Printf and other formatted print functions
  • +
  • VT100 Terminal Output
  • +
  • Command Line Interface
  • +
  • FAT16/32 File System (support is read-only for now)
  • +
  • STX/ETX Packet Protocol
  • +
  • Fixed-Point Math Library (basic operations only)
  • +
    +
  • Timers (with PWM, interrupt management)
  • +
  • UART (interrupt driven)
  • +
  • A/D Converter
  • +
  • I2C Master/Slave (interrupt and non-intr)
  • +
  • SPI Interface
  • +
  • External Interrupts
  • +
External Hardware Device DriversAVR Software-Emulated Devices
    +
  • Character LCD Modules (HD44780-based)
  • +
  • I2C EEPROM Memories
  • +
  • SPI EEPROM Memories
  • +
  • MMC/SD Card Interface (SPI mode)
  • +
  • LIS3L02 ST Accelerometer
  • +
  • IDE/ATA Interface (for hard disks and CF cards)
  • +
  • Quadrature Encoders
  • +
  • RC-Servos (up to 8 channels)
  • +
  • STA013 MP3 Decoder Chip
  • +
  • GPS Receivers (via serial port) +
      +
    • NMEA-0813 Protocol
    • +
    • Trimble TSIP Protocol
    • +
    +
  • +
  • Graphic LCD Modules +
      +
    • KS0108/HD61202 Controller
    • +
    • T6963 Controller
    • +
    • LCD Fonts and Symbols
    • +
    +
  • +
    +
  • I2c Master (Bit-Bang)
  • +
  • UART (software-based, timer interrupt driven)
  • +
  • Pulse Output (timer-based, variable frequency)
  • +
  • Intel-type Memory Bus (Address & Data Buses + nRD,nWR)
  • +
Network Support 
    +
  • Device Drivers +
      +
    • RTL8019 Ethernet
    • +
    • AX88796 Ethernet
    • +
    • CS8900 Ethernet
    • +
    • Prism2 Wireless LAN
    • +
    +
  • +
  • Network Protocols +
      +
    • ARP
    • +
    • ICMP
    • +
    • IP
    • +
    • UDP
    • +
    • DHCP
    • +
    +
  • +
  • Network Stack infrastructure
  • +
 
+
+
+ Written by Pascal Stang | Updated: + +
+ + + + diff --git a/3rd party/Procyuon avrlib/ks0108.c b/3rd party/Procyuon avrlib/ks0108.c new file mode 100644 index 0000000..e1fec2c --- /dev/null +++ b/3rd party/Procyuon avrlib/ks0108.c @@ -0,0 +1,381 @@ +/*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */ +//***************************************************************************** +// +// File Name : 'ks0108.c' +// Title : Graphic LCD driver for HD61202/KS0108 displays +// Author : Pascal Stang - Copyright (C) 2001-2003 +// Date : 10/19/2002 +// Revised : 5/5/2003 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 +// AVR specific includes + #include + #include +#endif + +#include "global.h" +#include "ks0108.h" + +// global variables +GrLcdStateType GrLcdState; + +/*************************************************************/ +/********************** LOCAL FUNCTIONS **********************/ +/*************************************************************/ + +void glcdInitHW(void) +{ + // initialize I/O ports + // if I/O interface is in use +#ifdef GLCD_PORT_INTERFACE + + //TODO: make setup of chip select lines contingent on how + // many controllers are actually in the display + + // initialize LCD control lines levels + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); + // initialize LCD control port to output + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_E); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS2); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS3); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RESET); + // initialize LCD data + outb(GLCD_DATA_PORT, 0x00); + // initialize LCD data port to output + outb(GLCD_DATA_DDR, 0xFF); +#endif +} + +void glcdControllerSelect(u08 controller) +{ +#ifdef GLCD_PORT_INTERFACE + //TODO: make control of chip select lines contingent on how + // many controllers are actually in the display + + // unselect all controllers + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); + + // select requested controller + switch(controller) + { + case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); break; + case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); break; + case 2: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); break; + case 3: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); break; + default: break; + } +#endif +} + +void glcdBusyWait(u08 controller) +{ +#ifdef GLCD_PORT_INTERFACE + cli(); + // wait until LCD busy bit goes to zero + // select the controller chip + glcdControllerSelect(controller); + // do a read from control register + outb(GLCD_DATA_PORT, 0xFF); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + while(inb(GLCD_DATA_PIN) & GLCD_STATUS_BUSY) + { + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + } + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + outb(GLCD_DATA_DDR, 0xFF); + sei(); +#else + // sbi(MCUCR, SRW); // enable RAM waitstate + // wait until LCD busy bit goes to zero + while(*(volatile unsigned char *) + (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) & GLCD_STATUS_BUSY); + // cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +void glcdControlWrite(u08 controller, u08 data) +{ +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + outb(GLCD_DATA_DDR, 0xFF); + outb(GLCD_DATA_PORT, data); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +u08 glcdControlRead(u08 controller) +{ + register u08 data; +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + data = inb(GLCD_DATA_PIN); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + outb(GLCD_DATA_DDR, 0xFF); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + +void glcdDataWrite(u08 data) +{ + register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS); +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + outb(GLCD_DATA_DDR, 0xFF); + outb(GLCD_DATA_PORT, data); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + // increment our local address counter + GrLcdState.ctrlr[controller].xAddr++; + GrLcdState.lcdXAddr++; + if(GrLcdState.lcdXAddr >= GLCD_XPIXELS) + { + GrLcdState.lcdYAddr++; + glcdSetYAddress(GrLcdState.lcdYAddr); + glcdSetXAddress(0); + } +} + +u08 glcdDataRead(void) +{ + register u08 data; + register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS); +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + data = inb(GLCD_DATA_PIN); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + // increment our local address counter + GrLcdState.ctrlr[controller].xAddr++; + GrLcdState.lcdXAddr++; + if(GrLcdState.lcdXAddr >= GLCD_XPIXELS) + { + GrLcdState.lcdYAddr++; + glcdSetYAddress(GrLcdState.lcdYAddr); + glcdSetXAddress(0); + } + return data; +} + +void glcdReset(u08 resetState) +{ + // reset lcd if argument is true + // run lcd if argument is false +#ifdef GLCD_PORT_INTERFACE + if(resetState) + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); + else + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); +#endif +} + +void glcdSetXAddress(u08 xAddr) +{ + u08 i; + // record address change locally + GrLcdState.lcdXAddr = xAddr; + + // clear y (col) address on all controllers + for(i=0; i>3); pageAddr++) + { + // set page address + glcdSetAddress(0, pageAddr); + // clear all lines of this page of display memory + for(xAddr=0; xAddrLCD IS BUSY +#define GLCD_STATUS_ONOFF 0x20 // (0)->LCD IS ON +#define GLCD_STATUS_RESET 0x10 // (1)->LCD IS RESET + +// determine the number of controllers +// (make sure we round up for partial use of more than one controller) +#define GLCD_NUM_CONTROLLERS ((GLCD_XPIXELS+GLCD_CONTROLLER_XPIXELS-1)/GLCD_CONTROLLER_XPIXELS) + +// typedefs/structures +typedef struct struct_GrLcdCtrlrStateType +{ + unsigned char xAddr; + unsigned char yAddr; +} GrLcdCtrlrStateType; + +typedef struct struct_GrLcdStateType +{ + unsigned char lcdXAddr; + unsigned char lcdYAddr; + GrLcdCtrlrStateType ctrlr[GLCD_NUM_CONTROLLERS]; +} GrLcdStateType; + +// function prototypes +void glcdInitHW(void); +void glcdBusyWait(u08 controller); +void glcdControlWrite(u08 controller, u08 data); +u08 glcdControlRead(u08 controller); +void glcdDataWrite(u08 data); +u08 glcdDataRead(void); +void glcdSetXAddress(u08 xAddr); +void glcdSetYAddress(u08 yAddr); + + +//! Initialize the display, clear it, and prepare it for access +void glcdInit(void); +//! Clear the display +void glcdClearScreen(void); +//! Set display memory access point back to upper,left corner +void glcdHome(void); +//! Set display memory access point to row [line] and column [col] assuming 5x7 font +void glcdGotoChar(u08 line, u08 col); +//! Set display memory access point to [x] horizontal pixel and [y] vertical line +void glcdSetAddress(u08 x, u08 yLine); +//! Set display memory access point to row [line] and column [col] assuming 5x7 font +void glcdStartLine(u08 start); +//! Generic delay routine for timed glcd access +void glcdDelay(u16 p); +#endif diff --git a/3rd party/Procyuon avrlib/lcd.c b/3rd party/Procyuon avrlib/lcd.c new file mode 100644 index 0000000..cfe823e --- /dev/null +++ b/3rd party/Procyuon avrlib/lcd.c @@ -0,0 +1,469 @@ +/*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */ +//***************************************************************************** +// +// File Name : 'lcd.c' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer.h" + +#include "lcd.h" + +// custom LCD characters +unsigned char __attribute__ ((progmem)) LcdCustomChar[] = +{ + 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block + 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block + 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block + 0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block + 0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block + 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block + 0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow + 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block + 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars + 0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow + 0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow + 0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character + 0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00, // 13. animated play icon frame 0 + 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00, // 14. animated play icon frame 1 + 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00, // 15. animated play icon frame 2 + 0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00, // 16. animated play icon frame 3 +}; + +/*************************************************************/ +/********************** LOCAL FUNCTIONS **********************/ +/*************************************************************/ + +void lcdInitHW(void) +{ + // initialize I/O ports + // if I/O interface is in use +#ifdef LCD_PORT_INTERFACE + // initialize LCD control lines + cbi(LCD_CTRL_PORT, LCD_CTRL_RS); + cbi(LCD_CTRL_PORT, LCD_CTRL_RW); + cbi(LCD_CTRL_PORT, LCD_CTRL_E); + // initialize LCD control lines to output + sbi(LCD_CTRL_DDR, LCD_CTRL_RS); + sbi(LCD_CTRL_DDR, LCD_CTRL_RW); + sbi(LCD_CTRL_DDR, LCD_CTRL_E); + // initialize LCD data port to input + // initialize LCD data lines to pull-up + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif +#else + // enable external memory bus if not already enabled + sbi(MCUCR, SRE); // enable bus interface +#endif +} + +void lcdBusyWait(void) +{ + // wait until LCD busy bit goes to zero + // do a read from control register +#ifdef LCD_PORT_INTERFACE + cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control" + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif + sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read" + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + while(inb(LCD_DATA_PIN) & 1<>4; // input data, low 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN); // input data, 8bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + data = *((volatile unsigned char *) (LCD_CTRL_ADDR)); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + +void lcdDataWrite(u08 data) +{ +// write a data byte to the display +#ifdef LCD_PORT_INTERFACE + lcdBusyWait(); // wait until LCD not busy + sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data" + cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write" + #ifdef LCD_DATA_4BIT + // 4 bit write + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit) + outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) ); // output data, low 4 bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit write + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_DDR, 0xFF); // set data I/O lines to output (8bit) + outb(LCD_DATA_POUT, data); // output data, 8bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif +#else + // memory bus write + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + *((volatile unsigned char *) (LCD_DATA_ADDR)) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +u08 lcdDataRead(void) +{ +// read a data byte from the display + register u08 data; +#ifdef LCD_PORT_INTERFACE + lcdBusyWait(); // wait until LCD not busy + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif + sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data" + sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read" + #ifdef LCD_DATA_4BIT + // 4 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN); // input data, 8bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes +#else + // memory bus read + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + data = *((volatile unsigned char *) (LCD_DATA_ADDR)); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + + + +/*************************************************************/ +/********************* PUBLIC FUNCTIONS **********************/ +/*************************************************************/ + +void lcdInit() +{ + // initialize hardware + lcdInitHW(); + // LCD function set + lcdControlWrite(LCD_FUNCTION_DEFAULT); + // clear LCD + lcdControlWrite(1< pixelprogress ) + { + // this is a partial or empty block + if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)) > pixelprogress ) + { + // this is an empty block + // use space character? + c = 0; + } + else + { + // this is a partial block + c = pixelprogress % PROGRESSPIXELS_PER_CHAR; + } + } + else + { + // this is a full block + c = 5; + } + + // write character to display + lcdDataWrite(c); + } + +} + diff --git a/3rd party/Procyuon avrlib/lcd.h b/3rd party/Procyuon avrlib/lcd.h new file mode 100644 index 0000000..ea96f0b --- /dev/null +++ b/3rd party/Procyuon avrlib/lcd.h @@ -0,0 +1,183 @@ +/*! \file lcd.h \brief Character LCD driver for HD44780/SED1278 displays. */ +//***************************************************************************** +// +// File Name : 'lcd.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup driver_hw +/// \defgroup lcd Character LCD Driver for HD44780/SED1278-based displays (lcd.c) +/// \code #include "lcd.h" \endcode +/// \par Overview +/// This display driver provides an interface to the most common type of +/// character LCD, those based on the HD44780 or SED1278 controller chip +/// (about 90% of character LCDs use one of these chips).  The display driver +/// can interface to the display through the CPU memory bus, or directly via +/// I/O port pins.  When using the direct I/O port mode, no additional +/// interface hardware is needed except for a contrast potentiometer. +/// Supported functions include initialization, clearing, scrolling, cursor +/// positioning, text writing, and loading of custom characters or icons +/// (up to 8).  Although these displays are simple, clever use of the custom +/// characters can allow you to create animations or simple graphics.  The +/// "progress bar" function that is included in this driver is an example of +/// graphics using limited custom-chars. +/// +/// \Note The driver now supports both 8-bit and 4-bit interface modes. +/// +/// \Note For full text output functionality, you may wish to use the rprintf +/// functions along with this driver +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCD_H +#define LCD_H + +#include "global.h" + +// include project-dependent configurations +#include "lcdconf.h" + +// if LCD_DELAY is not defined, this definition sequence +// attempts to find a suitable LCD_DELAY given the F_CPU +#ifndef LCD_DELAY +#if F_CPU >= 16000000 +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); +#else +#if F_CPU >= 12000000 +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); +#else +#if F_CPU >= 8000000 +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); +#else +#if F_CPU >= 4000000 +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n nop\n"); +#else +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n"); +#endif +#endif +#endif +#endif +#endif + +// HD44780 LCD controller command set (do not modify these) +// writing: +#define LCD_CLR 0 // DB0: clear display +#define LCD_HOME 1 // DB1: return to home position +#define LCD_ENTRY_MODE 2 // DB2: set entry mode +#define LCD_ENTRY_INC 1 // DB1: increment +#define LCD_ENTRY_SHIFT 0 // DB2: shift +#define LCD_ON_CTRL 3 // DB3: turn lcd/cursor on +#define LCD_ON_DISPLAY 2 // DB2: turn display on +#define LCD_ON_CURSOR 1 // DB1: turn cursor on +#define LCD_ON_BLINK 0 // DB0: blinking cursor +#define LCD_MOVE 4 // DB4: move cursor/display +#define LCD_MOVE_DISP 3 // DB3: move display (0-> move cursor) +#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left) +#define LCD_FUNCTION 5 // DB5: function set +#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode) +#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line) +#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font) +#define LCD_CGRAM 6 // DB6: set CG RAM address +#define LCD_DDRAM 7 // DB7: set DD RAM address +// reading: +#define LCD_BUSY 7 // DB7: LCD is busy + +// Default LCD setup +// this default setup is loaded on LCD initialization +#ifdef LCD_DATA_4BIT + #define LCD_FDEF_1 (0< is a pointer to a ROM array containing custom characters +// is the index of the character to load from lcdCustomCharArray +// is the RAM location in the LCD (legal value: 0-7) +void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum); + +// prints a series of bytes/characters to the display +void lcdPrintData(char* data, u08 nBytes); + +// displays a horizontal progress bar at the current cursor location +// is the value the bargraph should indicate +// is the value at the end of the bargraph +// is the number of LCD characters that the bargraph should cover +void lcdProgressBar(u16 progress, u16 maxprogress, u08 length); + +#endif diff --git a/3rd party/Procyuon avrlib/lis3l02.c b/3rd party/Procyuon avrlib/lis3l02.c new file mode 100644 index 0000000..c0a621e --- /dev/null +++ b/3rd party/Procyuon avrlib/lis3l02.c @@ -0,0 +1,110 @@ +/*! \file lis3l02.c \brief ST LIS3L02 3-axis I2C Accelerometer Library. */ +//***************************************************************************** +// +// File Name : 'lis3l02.c' +// Title : ST LIS3L02 3-axis I2C Accelerometer Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.23 +// Revised : 2004.12.14 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "i2c.h" +#include "lis3l02.h" + +#include "rprintf.h" +#include "timer.h" + +// global variables + +// Functions +u08 lis3l02Init(void) +{ + // reset LIS3L02 chip + return lis3l02Reset(); +} + +u08 lis3l02Reset(void) +{ + // turn on device and enable X,Y,Z + lis3l02WriteReg(LIS3L02_REG_CTRLREG1, + LIS3L02_CTRLREG1_XEN | + LIS3L02_CTRLREG1_YEN | + LIS3L02_CTRLREG1_ZEN | + LIS3L02_CTRLREG1_PD0); + + // scale and justification options + lis3l02WriteReg(LIS3L02_REG_CTRLREG2, + LIS3L02_CTRLREG2_BOOT | + LIS3L02_CTRLREG2_DAS ); + + return 0; +} + +u08 lis3l02ReadReg(u08 reg) +{ + u08 data; + u08 i2cStat; + + // set register + i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 1, ®); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + // read register + i2cStat = i2cMasterReceiveNI(LIS3L02_I2C_ADDR, 1, &data); + + //rprintf("READ: Reg=0x%x Data=0x%x\r\n", reg, data); + + return data; +} + +u08 lis3l02WriteReg(u08 reg, u08 data) +{ + u08 packet[2]; + u08 i2cStat; + + // prepare packet + packet[0] = reg; + packet[1] = data; + // write register + i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 2, packet); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + + //rprintf("WRITE: Reg=0x%x Data=0x%x\r\n", reg, data); + + return (i2cStat == I2C_OK); +} + +s16 lis3l02GetAccel(u08 chxyz) +{ + s16 value; + + value = lis3l02ReadReg(LIS3L02_REG_OUTXL + (chxyz<<1)); + value |= lis3l02ReadReg(LIS3L02_REG_OUTXH + (chxyz<<1))<<8; + + return value; +} + + + diff --git a/3rd party/Procyuon avrlib/lis3l02.h b/3rd party/Procyuon avrlib/lis3l02.h new file mode 100644 index 0000000..de6d9e3 --- /dev/null +++ b/3rd party/Procyuon avrlib/lis3l02.h @@ -0,0 +1,127 @@ +/*! \file lis3l02.h \brief ST LIS3L02 3-axis I2C Accelerometer Library. */ +//***************************************************************************** +// +// File Name : 'lis3l02.h' +// Title : ST LIS3L02 3-axis I2C Accelerometer Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.23 +// Revised : 2004.12.14 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_hw +/// \defgroup lis3l02 ST LIS3L02 3-axis I2C Accelerometer Library (lis3l02.c) +/// \code #include "lis3l02.h" \endcode +/// \par Overview +/// This library provides an interface to the ST LIS3L02 integrated 3-axis +/// accelerometer. The LIS3L02 has a built-in A/D converter to capture analog +/// acceleration data and make it available over an I2C interface. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LIS3L02_H +#define LIS3L02_H + +#include "global.h" + +// constants/macros/typdefs +#define LIS3L02_I2C_ADDR 0x3A ///< Base I2C address of LIS3L02 device + +// LIS3L02 register address defines +#define LIS3L02_REG_OFFSETX 0x16 ///< LIS3L02 X-axis digital offset trim +#define LIS3L02_REG_OFFSETY 0x17 ///< LIS3L02 Y-axis digital offset trim +#define LIS3L02_REG_OFFSETZ 0x18 ///< LIS3L02 Z-axis digital offset trim +#define LIS3L02_REG_GAINX 0x19 ///< LIS3L02 X-axis digital gain trim +#define LIS3L02_REG_GAINY 0x1A ///< LIS3L02 Y-axis digital gain trim +#define LIS3L02_REG_GAINZ 0x1B ///< LIS3L02 Z-axis digital gain trim +#define LIS3L02_REG_CTRLREG1 0x20 ///< LIS3L02 interface/operation control +#define LIS3L02_REG_CTRLREG2 0x21 ///< LIS3L02 interface/operation control +#define LIS3L02_REG_WAKEUPCFG 0x23 ///< LIS3L02 interrupt/wakeup config +#define LIS3L02_REG_WAKEUPSRC 0x24 ///< LIS3L02 interrupt/wakeup source indicator +#define LIS3L02_REG_WAKEUPACK 0x25 ///< LIS3L02 wakeup source clear +#define LIS3L02_REG_STATUS 0x27 ///< LIS3L02 Accelerometer Status +#define LIS3L02_REG_OUTXL 0x28 ///< LIS3L02 Accelerometer X Output Low-byte +#define LIS3L02_REG_OUTXH 0x29 ///< LIS3L02 Accelerometer X Output High-byte +#define LIS3L02_REG_OUTYL 0x2A ///< LIS3L02 Accelerometer Y Output Low-byte +#define LIS3L02_REG_OUTYH 0x2B ///< LIS3L02 Accelerometer Y Output High-byte +#define LIS3L02_REG_OUTZL 0x2C ///< LIS3L02 Accelerometer Z Output Low-byte +#define LIS3L02_REG_OUTZH 0x2D ///< LIS3L02 Accelerometer Z Output High-byte +#define LIS3L02_REG_THSL 0x2E ///< LIS3L02 Accelerometer Threshold Low-byte +#define LIS3L02_REG_THSH 0x2F ///< LIS3L02 Accelerometer Threshold High-byte +#define LIS3L02_REG_MULTIREAD 0x80 ///< LIS3L02 Mutliple Read Bit + +// LIS3L02 control register 1 bit defines +#define LIS3L02_CTRLREG1_XEN 0x01 ///< LIS3L02 CtrlReg1 X-axis Enable +#define LIS3L02_CTRLREG1_YEN 0x02 ///< LIS3L02 CtrlReg1 Y-axis Enable +#define LIS3L02_CTRLREG1_ZEN 0x04 ///< LIS3L02 CtrlReg1 Z-axis Enable +#define LIS3L02_CTRLREG1_ST 0x08 ///< LIS3L02 CtrlReg1 Self-Test Enable +#define LIS3L02_CTRLREG1_DF0 0x10 ///< LIS3L02 CtrlReg1 Decimation Factor 0 +#define LIS3L02_CTRLREG1_DF1 0x20 ///< LIS3L02 CtrlReg1 Decimation Factor 0 +#define LIS3L02_CTRLREG1_PD0 0x40 ///< LIS3L02 CtrlReg1 Power-down Control 0 +#define LIS3L02_CTRLREG1_PD1 0x80 ///< LIS3L02 CtrlReg1 Power-down Control 1 + +// LIS3L02 control register 2 bit defines +#define LIS3L02_CTRLREG2_DAS 0x01 ///< LIS3L02 CtrlReg2 Data Alignment Selection +#define LIS3L02_CTRLREG2_SIM 0x02 ///< LIS3L02 CtrlReg2 SPI Mode Select +#define LIS3L02_CTRLREG2_DRDY 0x04 ///< LIS3L02 CtrlReg2 Enable Data-Ready generation +#define LIS3L02_CTRLREG2_IEN 0x08 ///< LIS3L02 CtrlReg2 Interrupt Enable +#define LIS3L02_CTRLREG2_BOOT 0x10 ///< LIS3L02 CtrlReg2 Reboot from memory +#define LIS3L02_CTRLREG2_FS 0x80 ///< LIS3L02 CtrlReg2 Full-scale Select (0=2g, 1=6g) + +// LIS3L02 WAKEUPCFG register bit defines +#define LIS3L02_WAKEUPCFG_MXL 0x01 ///< LIS3L02 WAKEUPCFG Mask X Low Interrupt +#define LIS3L02_WAKEUPCFG_MXH 0x02 ///< LIS3L02 WAKEUPCFG Mask X High Interrupt +#define LIS3L02_WAKEUPCFG_MYL 0x04 ///< LIS3L02 WAKEUPCFG Mask Y Low Interrupt +#define LIS3L02_WAKEUPCFG_MYH 0x08 ///< LIS3L02 WAKEUPCFG Mask Y High Interrupt +#define LIS3L02_WAKEUPCFG_MZL 0x10 ///< LIS3L02 WAKEUPCFG Mask Z Low Interrupt +#define LIS3L02_WAKEUPCFG_MZH 0x20 ///< LIS3L02 WAKEUPCFG Mask Z High Interrupt +#define LIS3L02_WAKEUPCFG_LIR 0x40 ///< LIS3L02 WAKEUPCFG Latch Intr Request + +// LIS3L02 WAKEUPSRC register bit defines +#define LIS3L02_WAKEUPSRC_XL 0x01 ///< LIS3L02 WAKEUPSRC X Low Interrupt +#define LIS3L02_WAKEUPSRC_XH 0x02 ///< LIS3L02 WAKEUPSRC X High Interrupt +#define LIS3L02_WAKEUPSRC_YL 0x04 ///< LIS3L02 WAKEUPSRC Y Low Interrupt +#define LIS3L02_WAKEUPSRC_YH 0x08 ///< LIS3L02 WAKEUPSRC Y High Interrupt +#define LIS3L02_WAKEUPSRC_ZL 0x10 ///< LIS3L02 WAKEUPSRC Z Low Interrupt +#define LIS3L02_WAKEUPSRC_ZH 0x20 ///< LIS3L02 WAKEUPSRC Z High Interrupt +#define LIS3L02_WAKEUPSRC_IA 0x40 ///< LIS3L02 WAKEUPSRC Interrupt Active + +// LIS3L02 WAKEUPSRC register bit defines +#define LIS3L02_STATUS_XDA 0x01 ///< LIS3L02 STATUS X New Data Available +#define LIS3L02_STATUS_YDA 0x02 ///< LIS3L02 STATUS Y New Data Available +#define LIS3L02_STATUS_ZDA 0x04 ///< LIS3L02 STATUS Z New Data Available +#define LIS3L02_STATUS_ZYXDA 0x08 ///< LIS3L02 STATUS XYZ New Data Available +#define LIS3L02_STATUS_XOR 0x10 ///< LIS3L02 STATUS X-axis Data Overrun +#define LIS3L02_STATUS_YOR 0x20 ///< LIS3L02 STATUS Y-axis Data Overrun +#define LIS3L02_STATUS_ZOR 0x40 ///< LIS3L02 STATUS Z-axis Data Overrun +#define LIS3L02_STATUS_ZYXOR 0x80 ///< LIS3L02 STATUS XYZ-axis Data Overrun + +// functions + +//! Initialize the LIS3L02 chip. +/// returns: +/// 0 if successful, +/// non-zero if unsuccessful (chip not present). +u08 lis3l02Init(void); + +//! Reset the LIS3L02 chip. +u08 lis3l02Reset(void); + +//! Read a LIS3L02 register. +u08 lis3l02ReadReg(u08 reg); + +//! Write a LIS3L02 register. +u08 lis3l02WriteReg(u08 reg, u08 data); + +//! Get an acceleration reading from the LIS3L02 sensor. +s16 lis3l02GetAccel(u08 chxyz); + +#endif diff --git a/3rd party/Procyuon avrlib/megaio/megaio.c b/3rd party/Procyuon avrlib/megaio/megaio.c new file mode 100644 index 0000000..5e7738b --- /dev/null +++ b/3rd party/Procyuon avrlib/megaio/megaio.c @@ -0,0 +1,175 @@ +/*! \file megaio.c \brief MegaIO Control/Access function library. */ +//***************************************************************************** +// +// File Name : 'megaio.c' +// Title : MegaIO Control/Access function library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 5/18/2004 +// Revised : 5/18/2004 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "buffer.h" // include buffer support +#include "i2c.h" // include I2C functions +#include "megaio/megaioreg.h" // include MegaIO register definitions + +#include "megaio.h" + +// MegaIO local receive buffer size +#define MEGAIO_UART_RX_BUFFER_SIZE 0x80 +// MegaIO local receive buffer data array +static char megaioUartRxData[MEGAIO_UART_RX_BUFFER_SIZE]; +// MegaIO local receive buffer +cBuffer megaioUartRxBuffer; + +//! initialize the MegaIO interface +u08 megaioInit(void) +{ + // initialize the UART receive buffer + bufferInit(&megaioUartRxBuffer, megaioUartRxData, MEGAIO_UART_RX_BUFFER_SIZE); + // initialize i2c interface + i2cInit(); + i2cSetBitrate(30); + // check for presence of megaio chip + if( megaioReadReg(MEGAIOREG_IDSTRING, 1) == 'M' ) + { + // megaio responded correctly + // initialization succeeded + return TRUE; + } + else + { + // megaio responded incorrectly + // initialization failed + return FALSE; + } +} + +//! write an 8-32 bit number to a MegaIO register +void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data) +{ + u08 packet[5]; + + // construct I2c data packet + // first byte is register address + // following bytes are the data that will be written to that register + packet[0] = regnum; + packet[1] = data; + packet[2] = data>>8; + packet[3] = data>>16; + packet[4] = data>>24; + // send 2 bytes (register and data) to MegaIO + i2cMasterSend(MEGAIO_I2C_ADDR, 1+nbytes, packet); +} + +//! read an 8-32 bit number from a MegaIO register +unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes) +{ + unsigned long data = 0; + + // first select the register by writing 1 byte (register) + i2cMasterSend(MEGAIO_I2C_ADDR, 1, ®num); + // then read n byte(s) from the selected MegaIO register + i2cMasterReceive(MEGAIO_I2C_ADDR, nbytes, (u08*)&data); + // return the results + return data; +} + +//! set the baudrate of the megaio serial port +void megaioSetBaudRate(u32 baudrate) +{ + megaioWriteReg(MEGAIOREG_UARTBAUD, 4, baudrate); +} + +//! send a byte out the megaio serial port +void megaioSendByte(u08 data) +{ + megaioWriteReg(MEGAIOREG_UARTDATA, 1, data); +} + +//! get a byte from the megaio serial port +int megaioGetByte(void) +{ + u08 data; + + // check the number of bytes in the megaio receive buffer + if( megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1) ) + { + // one or more bytes are available + // get first byte + data = megaioReadReg(MEGAIOREG_UARTDATA, 1); + return data; + } + else + { + // no bytes were available + // (no bytes have arrived and are waiting to be read) + return -1; + } +} + +//! returns the receive buffer structure +cBuffer* megaioGetRxBuffer(void) +{ + u08 nbytes; + // get the number of bytes waiting in the MegaIO buffer + nbytes = megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1); + // get all available bytes from the MegaIO chip + // and add them to the receive buffer + while(megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1)) + { + bufferAddToEnd(&megaioUartRxBuffer, megaioReadReg(MEGAIOREG_UARTDATA, 1)); + nbytes--; + } + // return rx buffer pointer + return &megaioUartRxBuffer; +} + +//! turn on megaio PWM and set for bitRes resolution +void megaioPWMInit(u08 bitRes) +{ + megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, bitRes); +} + +//! turn off megaio PWM +void megaioPWMOff(void) +{ + megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, 0); +} + +//! set megaio PWM1A duty cycle +void megaioPWMASet(u16 pwmDuty) +{ + megaioWriteReg(MEGAIOREG_PWM1ADUTY, 2, pwmDuty); +} + +//! set megaio PWM1B duty cycle +void megaioPWMBSet(u16 pwmDuty) +{ + megaioWriteReg(MEGAIOREG_PWM1BDUTY, 2, pwmDuty); +} + +//! set megaio prescaler division rate +void megaioSetPrescaler(u08 prescaleDiv) +{ + megaioWriteReg(MEGAIOREG_PWM1FREQ, 1, prescaleDiv); +} + +//! do A/D conversion on channel [ch] and return result +u16 megaioA2DConvert(u08 ch) +{ + // set channel + megaioWriteReg(MEGAIOREG_ADCCHSEL, 1, ch); + // start single conversion + megaioWriteReg(MEGAIOREG_ADCCTRL, 1, 0x01); + // wait for conversion to be complete + while( megaioReadReg(MEGAIOREG_ADCCTRL, 1) ); + // get result and return it + return megaioReadReg(MEGAIOREG_ADCRESULT, 2); +} diff --git a/3rd party/Procyuon avrlib/megaio/megaio.h b/3rd party/Procyuon avrlib/megaio/megaio.h new file mode 100644 index 0000000..3f2d2a2 --- /dev/null +++ b/3rd party/Procyuon avrlib/megaio/megaio.h @@ -0,0 +1,57 @@ +/*! \file megaio.h \brief MegaIO Control/Access function library. */ +//***************************************************************************** +// +// File Name : 'megaio.h' +// Title : MegaIO Control/Access function library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 5/18/2004 +// Revised : 5/18/2004 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MEGAIO_H +#define MEGAIO_H + +#include "megaio/megaioreg.h" // include MegaIO register definitions + +// defines + +// function prototypes + +//! initialize the MegaIO interface +u08 megaioInit(void); +//! write an 8-32 bit number to a MegaIO register +void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data); +//! read an 8-32 bit number from a MegaIO register +unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes); + +//! set the baudrate of the MegaIO serial port +void megaioSetBaudRate(u32 baudrate); +//! send a byte out the MegaIO serial port +void megaioSendByte(u08 data); +//! get a byte from the MegaIO serial port +int megaioGetByte(void); +//! get a complete receive buffer with data from MegaIO serial port +cBuffer* megaioGetRxBuffer(void); + +//! turn on MegaIO PWM and set for bitRes resolution +void megaioPWMInit(u08 bitRes); +//! turn off MegaIO PWM +void megaioPWMOff(void); +//! set MegaIO PWM1A duty cycle +void megaioPWMASet(u16 pwmDuty); +//! set MegaIO PWM1B duty cycle +void megaioPWMBSet(u16 pwmDuty); +//! set MegaIO prescaler division rate +void megaioSetPrescaler(u08 prescaleDiv); + +//! do A/D conversion on channel [ch] and return result +u16 megaioA2DConvert(u08 ch); + +#endif diff --git a/3rd party/Procyuon avrlib/megaio/megaioreg.h b/3rd party/Procyuon avrlib/megaio/megaioreg.h new file mode 100644 index 0000000..002b129 --- /dev/null +++ b/3rd party/Procyuon avrlib/megaio/megaioreg.h @@ -0,0 +1,96 @@ +/*! \file megaioreg.h \brief MegaIO register definitions. */ +//***************************************************************************** +// +// File Name : 'megaioreg.h' +// Title : MegaIO register definitions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.16 +// Revised : 2003.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MEGAIOREG_H +#define MEGAIOREG_H + +// define MEGAIO I2C address +#define MEGAIO_I2C_ADDR 0x4C + +// define MEGAIO registers +// General Registers +#define MEGAIOREG_IDSTRING 0x00 + +// UART Registers +#define MEGAIOREG_UARTDATA 0x10 +#define MEGAIOREG_UARTBAUD 0x14 +#define MEGAIOREG_UARTBAUDSEL 0x15 +#define MEGAIOREG_UARTRXBUFBYTES 0x18 +#define MEGAIOREG_UARTTXBUFBYTES 0x19 + +// PWM Registers +#define MEGAIOREG_PWM1CTRL 0x20 +#define MEGAIOREG_PWM1FREQ 0x21 +#define MEGAIOREG_PWM1ADUTY 0x24 +#define MEGAIOREG_PWM1BDUTY 0x25 + +// A/D Converter Registers +#define MEGAIOREG_ADCCTRL 0x30 +#define MEGAIOREG_ADCCHSEL 0x31 +#define MEGAIOREG_ADCRESULT 0x32 + +// PORT Access Registers +#define MEGAIOREG_PORTA 0x40 +#define MEGAIOREG_DDRA 0x41 +#define MEGAIOREG_PINA 0x42 +#define MEGAIOREG_PORTB 0x43 +#define MEGAIOREG_DDRB 0x44 +#define MEGAIOREG_PINB 0x45 +#define MEGAIOREG_PORTC 0x46 +#define MEGAIOREG_DDRC 0x47 +#define MEGAIOREG_PINC 0x48 +#define MEGAIOREG_PORTD 0x49 +#define MEGAIOREG_DDRD 0x4A +#define MEGAIOREG_PIND 0x4B +#define MEGAIOREG_PORTE 0x4C +#define MEGAIOREG_DDRE 0x4D +#define MEGAIOREG_PINE 0x4E +#define MEGAIOREG_PORTF 0x4F +#define MEGAIOREG_DDRF 0x50 +#define MEGAIOREG_PINF 0x51 + +// Direct Access Registers +#define MEGAIOREG_DIRECTIO 0x80 +#define MEGAIOREG_DIRECTMEM 0x81 + +// MegaIO configuration +#define MEGAIOREG_I2CADDR 0xF0 +#define MEGAIOREG_OSCCAL 0xF1 + +// MegaIO configuration cookie +// You must send this cookie to validate all configuration requests +#define MEGAIO_CONFIG_COOKIE 0xB4C3 + +// define MEGAIO register values +#define UARTBAUDSEL_300 0x00 +#define UARTBAUDSEL_600 0x01 +#define UARTBAUDSEL_1200 0x02 +#define UARTBAUDSEL_2400 0x03 +#define UARTBAUDSEL_4800 0x04 +#define UARTBAUDSEL_9600 0x05 +#define UARTBAUDSEL_19200 0x06 +#define UARTBAUDSEL_38400 0x07 +#define UARTBAUDSEL_115200 0x08 + +#define PWM1FREQ_STOP 0x00 +#define PWM1FREQ_MAX 0x01 +#define PWM1FREQ_DIV8 0x02 +#define PWM1FREQ_DIV64 0x03 +#define PWM1FREQ_DIV256 0x04 +#define PWM1FREQ_DIV1024 0x05 + +#endif diff --git a/3rd party/Procyuon avrlib/mmc.c b/3rd party/Procyuon avrlib/mmc.c new file mode 100644 index 0000000..24f189a --- /dev/null +++ b/3rd party/Procyuon avrlib/mmc.c @@ -0,0 +1,208 @@ +/*! \file mmc.c \brief MultiMedia and SD Flash Card Interface. */ +//***************************************************************************** +// +// File Name : 'mmc.c' +// Title : MultiMedia and SD Flash Card Interface +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2006.06.12 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "spi.h" // include spi bus support + +#include "rprintf.h" + +#include "mmc.h" + +// include project-specific hardware configuration +#include "mmcconf.h" + +// Global variables + +// Functions + +void mmcInit(void) +{ + // initialize SPI interface + spiInit(); + // release chip select + sbi(MMC_CS_DDR, MMC_CS_PIN); + sbi(MMC_CS_PORT,MMC_CS_PIN); +} + +u08 mmcReset(void) +{ + u08 i; + u08 retry; + u08 r1=0; + + retry = 0; + do + { + // send dummy bytes with CS high before accessing + for(i=0;i<10;i++) spiTransferByte(0xFF); + // resetting card, go to SPI mode + r1 = mmcSendCommand(MMC_GO_IDLE_STATE, 0); + #ifdef MMC_DEBUG + rprintf("MMC_GO_IDLE_STATE: R1=0x%x\r\n", r1); + #endif + // do retry counter + retry++; + if(retry>10) return -1; + } while(r1 != 0x01); + + // TODO: check card parameters for voltage compliance + // before issuing initialize command + + retry = 0; + do + { + // initializing card for operation + r1 = mmcSendCommand(MMC_SEND_OP_COND, 0); + #ifdef MMC_DEBUG + rprintf("MMC_SEND_OP_COND: R1=0x%x\r\n", r1); + #endif + // do retry counter + retry++; + if(retry>100) return -1; + } while(r1); + + // turn off CRC checking to simplify communication + r1 = mmcSendCommand(MMC_CRC_ON_OFF, 0); + #ifdef MMC_DEBUG + rprintf("MMC_CRC_ON_OFF: R1=0x%x\r\n", r1); + #endif + + // set block length to 512 bytes + r1 = mmcSendCommand(MMC_SET_BLOCKLEN, 512); + #ifdef MMC_DEBUG + rprintf("MMC_SET_BLOCKLEN: R1=0x%x\r\n", r1); + #endif + + // return success + return 0; +} + +u08 mmcSendCommand(u08 cmd, u32 arg) +{ + u08 r1; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue the command + r1 = mmcCommand(cmd, arg); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + + return r1; +} + +u08 mmcRead(u32 sector, u08* buffer) +{ + u08 r1; + u16 i; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue command + r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9); + #ifdef MMC_DEBUG + rprintf("MMC Read Block R1=0x%x\r\n", r1); + #endif + // check for valid response + if(r1 != 0x00) + return r1; + // wait for block start + while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ); + // read in data + for(i=0; i<0x200; i++) + { + *buffer++ = spiTransferByte(0xFF); + } + // read 16-bit CRC + spiTransferByte(0xFF); + spiTransferByte(0xFF); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + // return success + return 0; +} + +u08 mmcWrite(u32 sector, u08* buffer) +{ + u08 r1; + u16 i; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue command + r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9); + #ifdef MMC_DEBUG + rprintf("MMC Write Block R1=0x%x\r\n", r1); + #endif + // check for valid response + if(r1 != 0x00) + return r1; + // send dummy + spiTransferByte(0xFF); + // send data start token + spiTransferByte(MMC_STARTBLOCK_WRITE); + // write data + for(i=0; i<0x200; i++) + { + spiTransferByte(*buffer++); + } + // write 16-bit CRC (dummy values) + spiTransferByte(0xFF); + spiTransferByte(0xFF); + // read data response token + r1 = spiTransferByte(0xFF); + if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT) + return r1; + #ifdef MMC_DEBUG + rprintf("Data Response Token=0x%x\r\n", r1); + #endif + // wait until card not busy + while(!spiTransferByte(0xFF)); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + // return success + return 0; +} + +u08 mmcCommand(u08 cmd, u32 arg) +{ + u08 r1; + u08 retry=0; + // send command + spiTransferByte(cmd | 0x40); + spiTransferByte(arg>>24); + spiTransferByte(arg>>16); + spiTransferByte(arg>>8); + spiTransferByte(arg); + spiTransferByte(0x95); // crc valid only for MMC_GO_IDLE_STATE + // end command + // wait for response + // if more than 8 retries, card has timed-out + // return the received 0xFF + while((r1 = spiTransferByte(0xFF)) == 0xFF) + if(retry++ > 8) break; + // return response + return r1; +} diff --git a/3rd party/Procyuon avrlib/mmc.h b/3rd party/Procyuon avrlib/mmc.h new file mode 100644 index 0000000..b7ffd93 --- /dev/null +++ b/3rd party/Procyuon avrlib/mmc.h @@ -0,0 +1,138 @@ +/*! \file mmc.h \brief MultiMedia and SD Flash Card Interface. */ +//***************************************************************************** +// +// File Name : 'mmc.h' +// Title : MultiMedia and SD Flash Card Interface +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +/// \ingroup driver_hw +/// \defgroup mmc MultiMedia and SD Flash Card Interface (mmc.c) +/// \code #include "mmc.h" \endcode +/// \par Description +/// This library offers some simple functions which can be used +/// to read and write data on a MultiMedia or SecureDigital (SD) Flash +/// Card. Although MM and SD Cards are designed to operate with their own +/// special bus wiring and protocols, both types of cards also provide a +/// simple SPI-like interface mode which is exceptionally useful when +/// attempting to use the cards in embedded systems. +/// +/// \par Wiring +/// To work with this library, the card must be wired to the SPI port of +/// the Atmel microcontroller as described below. Typical cards can +/// operate at up to 25MHz maximum SPI clock rate (thus faster than most +/// AVR's maximum SPI clock rate). +///
+///	      _________________
+///	     /  1 2 3 4 5 6 78 |	<- view of MMC/SD card looking at contacts
+///	    / 9                |	Pins 8 and 9 are present only on SD cards
+///	    |    MMC/SD Card   |
+///	    |                  |
+///	    /\/\/\/\/\/\/\/\/\/\
+///	    1 - CS   (chip select)          - wire to any available I/O pin(*)
+///	    2 - DIN  (data in, card<-host)  - wire to SPI MOSI pin
+///	    3 - VSS  (ground)               - wire to ground
+///	    4 - VDD  (power, 3.3V only?)    - wire to power (MIGHT BE 3.3V ONLY!)
+///	    5 - SCLK (data clock)           - wire to SPI SCK pin
+///	    6 - VSS  (ground)               - wire to ground
+///	    7 - DOUT (data out, card->host) - wire to SPI MISO pin
+///
+///	    (*) you must define this chip select I/O pin in mmcconf.h
+/// 
+/// \note This code is currently below version 1.0, and therefore is considered +/// to be lacking in some functionality or documentation, or may not be fully +/// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef MMC_H +#define MMC_H + +#include "global.h" + +// constants/macros/typdefs +// MMC commands (taken from sandisk MMC reference) +#define MMC_GO_IDLE_STATE 0 ///< initialize card to SPI-type access +#define MMC_SEND_OP_COND 1 ///< set card operational mode +#define MMC_SEND_CSD 9 ///< get card's CSD +#define MMC_SEND_CID 10 ///< get card's CID +#define MMC_SEND_STATUS 13 +#define MMC_SET_BLOCKLEN 16 ///< Set number of bytes to transfer per block +#define MMC_READ_SINGLE_BLOCK 17 ///< read a block +#define MMC_WRITE_BLOCK 24 ///< write a block +#define MMC_PROGRAM_CSD 27 +#define MMC_SET_WRITE_PROT 28 +#define MMC_CLR_WRITE_PROT 29 +#define MMC_SEND_WRITE_PROT 30 +#define MMC_TAG_SECTOR_START 32 +#define MMC_TAG_SECTOR_END 33 +#define MMC_UNTAG_SECTOR 34 +#define MMC_TAG_ERASE_GROUP_START 35 ///< Sets beginning of erase group (mass erase) +#define MMC_TAG_ERARE_GROUP_END 36 ///< Sets end of erase group (mass erase) +#define MMC_UNTAG_ERASE_GROUP 37 ///< Untag (unset) erase group (mass erase) +#define MMC_ERASE 38 ///< Perform block/mass erase +#define MMC_CRC_ON_OFF 59 ///< Turns CRC check on/off +// R1 Response bit-defines +#define MMC_R1_BUSY 0x80 ///< R1 response: bit indicates card is busy +#define MMC_R1_PARAMETER 0x40 +#define MMC_R1_ADDRESS 0x20 +#define MMC_R1_ERASE_SEQ 0x10 +#define MMC_R1_COM_CRC 0x08 +#define MMC_R1_ILLEGAL_COM 0x04 +#define MMC_R1_ERASE_RESET 0x02 +#define MMC_R1_IDLE_STATE 0x01 +// Data Start tokens +#define MMC_STARTBLOCK_READ 0xFE ///< when received from card, indicates that a block of data will follow +#define MMC_STARTBLOCK_WRITE 0xFE ///< when sent to card, indicates that a block of data will follow +#define MMC_STARTBLOCK_MWRITE 0xFC +// Data Stop tokens +#define MMC_STOPTRAN_WRITE 0xFD +// Data Error Token values +#define MMC_DE_MASK 0x1F +#define MMC_DE_ERROR 0x01 +#define MMC_DE_CC_ERROR 0x02 +#define MMC_DE_ECC_FAIL 0x04 +#define MMC_DE_OUT_OF_RANGE 0x04 +#define MMC_DE_CARD_LOCKED 0x04 +// Data Response Token values +#define MMC_DR_MASK 0x1F +#define MMC_DR_ACCEPT 0x05 +#define MMC_DR_REJECT_CRC 0x0B +#define MMC_DR_REJECT_WRITE_ERROR 0x0D + +// functions + +//! Initialize AVR<->MMC hardware interface. +/// Prepares hardware for MMC access. +void mmcInit(void); + +//! Initialize the card and prepare it for use. +/// Returns zero if successful. +u08 mmcReset(void); + +//! Send card an MMC command. +/// Returns R1 result code. +u08 mmcSendCommand(u08 cmd, u32 arg); + +//! Read 512-byte sector from card to buffer +/// Returns zero if successful. +u08 mmcRead(u32 sector, u08* buffer); + +//! Write 512-byte sector from buffer to card +/// Returns zero if successful. +u08 mmcWrite(u32 sector, u08* buffer); + +//! Internal command function. +/// Issues a generic MMC command as specified by cmd and arg. +u08 mmcCommand(u08 cmd, u32 arg); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/arp.c b/3rd party/Procyuon avrlib/net/arp.c new file mode 100644 index 0000000..50aa00c --- /dev/null +++ b/3rd party/Procyuon avrlib/net/arp.c @@ -0,0 +1,227 @@ +/*! \file arp.c \brief ARP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'arp.c' +// Title : ARP Protocol Library +// Author : Pascal Stang +// Created : 9/7/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "global.h" +#include "net.h" +#include "nic.h" +#include "arp.h" + +#include "rprintf.h" + +// global variables + +/// Single ARP table entry/record +struct ArpEntry +{ + uint32_t ipaddr; ///< remote-note IP address + struct netEthAddr ethaddr; ///< remote-node ethernet (hardware/mac) address + uint8_t time; ///< time to live (in ARP table); this is decremented by arpTimer() +}; + +struct ArpEntry ArpMyAddr; ///< my local interface information (IP and MAC address) +struct ArpEntry ArpTable[ARP_TABLE_SIZE]; ///< ARP table of matched IP<->MAC associations + + +void arpInit(void) +{ + u08 i; + // initialize all ArpTable elements to unused + for(i=0; iarp ); + #endif + + // for now, we just reply to requests + // need to add ARP cache + if( (packet->arp.dipaddr == HTONL(ArpMyAddr.ipaddr)) && + (packet->arp.opcode == htons(ARP_OPCODE_REQUEST)) ) + { + // in ARP header + // copy sender's address info to dest. fields + packet->arp.dhwaddr = packet->arp.shwaddr; + packet->arp.dipaddr = packet->arp.sipaddr; + // fill in our information + packet->arp.shwaddr = ArpMyAddr.ethaddr; + packet->arp.sipaddr = HTONL(ArpMyAddr.ipaddr); + // change op to reply + packet->arp.opcode = htons(ARP_OPCODE_REPLY); + + // in ethernet header + packet->eth.dest = packet->eth.src; + packet->eth.src = ArpMyAddr.ethaddr; + + #ifdef ARP_DEBUG + rprintfProgStrM("Sending ARP Reply\r\n"); + arpPrintHeader( &packet->arp ); + #endif + + // send reply! + nicSend(len, (unsigned char*)packet); + } +} + +void arpIpIn(struct netEthIpHeader* packet) +{ + int8_t index; + + // check if sender is already present in arp table + index = arpMatchIp(HTONL(packet->ip.srcipaddr)); + if(index != -1) + { + // sender's IP address found, update ARP entry + ArpTable[index].ethaddr = packet->eth.src; + // and we're done + return; + } + + // sender was not present in table, + // must add in empty/expired slot + for(index=0; indexeth.src; + ArpTable[index].ipaddr = HTONL(packet->ip.srcipaddr); + ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + // and we're done + return; + } + } + + // no space in table, we give up +} + +void arpIpOut(struct netEthIpHeader* packet, uint32_t phyDstIp) +{ + int index; + // check if destination is already present in arp table + // use the physical dstIp if it's provided, otherwise the dstIp in packet + if(phyDstIp) + index = arpMatchIp(phyDstIp); + else + index = arpMatchIp(HTONL(packet->ip.destipaddr)); + // fill in ethernet info + if(index != -1) + { + // ARP entry present, fill eth address(es) + packet->eth.src = ArpMyAddr.ethaddr; + packet->eth.dest = ArpTable[index].ethaddr; + packet->eth.type = HTONS(ETHTYPE_IP); + } + else + { + // not in table, must send ARP request + packet->eth.src = ArpMyAddr.ethaddr; + // MUST CHANGE, but for now, send this one broadcast + packet->eth.dest.addr[0] = 0xFF; + packet->eth.dest.addr[1] = 0xFF; + packet->eth.dest.addr[2] = 0xFF; + packet->eth.dest.addr[3] = 0xFF; + packet->eth.dest.addr[4] = 0xFF; + packet->eth.dest.addr[5] = 0xFF; + packet->eth.type = HTONS(ETHTYPE_IP); + } +} + +void arpTimer(void) +{ + int index; + // this function meant to be called on a regular time interval + + // decrement time-to-live for all entries + for(index=0; indexopcode == htons(ARP_OPCODE_REQUEST)) + rprintfProgStrM("REQUEST"); + else if(packet->opcode == htons(ARP_OPCODE_REPLY)) + rprintfProgStrM("REPLY"); + else + rprintfProgStrM("UNKNOWN"); + rprintfCRLF(); + // print source hardware address + rprintfProgStrM("SrcHwAddr : "); netPrintEthAddr(&packet->shwaddr); rprintfCRLF(); + // print source protocol address + rprintfProgStrM("SrcProtoAddr: "); netPrintIPAddr(HTONL(packet->sipaddr)); rprintfCRLF(); + // print target hardware address + rprintfProgStrM("DstHwAddr : "); netPrintEthAddr(&packet->dhwaddr); rprintfCRLF(); + // print target protocol address + rprintfProgStrM("DstProtoAddr: "); netPrintIPAddr(HTONL(packet->dipaddr)); rprintfCRLF(); +} + + +void arpPrintTable(void) +{ + uint8_t i; + + // print ARP table + rprintfProgStrM("Time Eth Address IP Address\r\n"); + rprintfProgStrM("---------------------------------------\r\n"); + for(i=0; iMAC mapping is not in the table. +/// +/// \note This code is currently below version 1.0, and therefore is considered +/// to be lacking in some functionality or documentation, or may not be fully +/// tested. Nonetheless, you can expect most functions to work. +/// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef ARP_H +#define ARP_H + +#include "global.h" +#include "net.h" + +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 8 +#endif + +#ifndef ARP_CACHE_TIME_TO_LIVE +#define ARP_CACHE_TIME_TO_LIVE 100 +#endif + +//#define ARP_DEBUG_PRINT + + +/*! Initialize ARP system. + Clears ARP table and prepares it for use. This is typically done + once at program initialization. */ +void arpInit(void); + +/*! Set IP and Ethernet hardware/MAC address. + This must be done before valid replies can be generated for ARP + requests. Typically done once at program initialization. */ +void arpSetAddress(struct netEthAddr* myeth, uint32_t myip); + +/*! Processes incoming ARP packets. + This function is to be called when an ARP type packet has arrived + over the network. If the packet type is an ARP request for us, + an ARP reply will be generated and sent. */ +void arpArpIn(unsigned int len, struct netEthArpHeader* packet); + +/*! Process incoming IP packets to harvest IP<->MAC relationships. + This function should be called when IP packets are received over the + network. It does nothing more than harvest the IP<->MAC address + relationships from the ethernet and IP header of the packet. The + packet is not changed nor processed. Nothing is sent on the network. + Use of this command is not required, but it is a good way to + automatically fill the ARP table with information about nodes that are + active on the network. + + \warning On very busy or heavily populated netorks, this can quickly + fill the ARP table with unnecessary entries, and/or cause some CPU load. +*/ +void arpIpIn(struct netEthIpHeader* packet); + +/*! Process outgoing IP packet to fill in ethernet header information. + To be sent on a network, an IP packet must have the correct ethernet + header information appended to the front. This function will fill + in this information. + + A physical destination IP address argument is needed to support + sending to a gateway (i.e. when a packet is destined for a node that + is not on this network, IP addressing is as usual, but we phyiscally + send the packet to the gateway's ethernet address/interface). + + \warning Technically, if an IP<->MAC address mapping is not in the + ARP table, then the IP packet should be held while an ARP request is + made, and the reply received. However, in single-threaded ram-limited + embedded systems, such a holdup is unacceptable. This function instead + sends the packet as an ethernet broadcast if a mapping cannot be found. + + \todo Send the packet broadcast AND send an ARP request, if a mapping + is not found. +*/ +void arpIpOut(struct netEthIpHeader* packet, uint32_t phyDstIp); + +/*! Periodic ARP cache maintenance. + This function is to be called once per second and will slowly + expire old ARP cache entries. */ +void arpTimer(void); + + +/*! Check if this IP address is present in the ARP cache. Internal function. + If IP address is found, function returns index of entry. If not found, + returns -1. */ +int arpMatchIp(uint32_t ipaddr); + +//! Print diagnotic information about ARP packet. +void arpPrintHeader(struct netArpHeader* packet); +//! Print diagnotic information about ARP cache. +void arpPrintTable(void); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/ax88796.c b/3rd party/Procyuon avrlib/net/ax88796.c new file mode 100644 index 0000000..1c02667 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/ax88796.c @@ -0,0 +1,716 @@ +/*! \file ax88796.c \brief ASIX AX88796 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'ax88796.c' +// Title : ASIX AX88796 Ethernet Interface Driver +// Author : Pascal Stang +// Created : 10/22/2002 +// Revised : 8/21/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. +// +// Based in part on code by Louis Beaudoin (www.embedded-creations.com). +// Thanks to Adam Dunkels and Louis Beaudoin for providing the initial +// structure in which to write this driver. +// +//***************************************************************************** + +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "ax88796.h" + +// include configuration +#include "ax88796conf.h" + +// pointers to locations in the ax88796 receive buffer +static unsigned char NextPage; // page pointer to next Rx packet +static unsigned int CurrentRetreiveAddress; // DMA address for read Rx packet location + + +void nicInit(void) +{ + ax88796Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + ax88796BeginPacketSend(len); + ax88796SendPacketData(packet, len); + ax88796EndPacketSend(); +} + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + unsigned int packetLength; + + packetLength = ax88796BeginPacketRetreive(); + + // if there's no packet or an error - exit without ending the operation + if( !packetLength ) + return 0; + + // drop anything too big for the buffer + if( packetLength > maxlen ) + { + ax88796EndPacketRetreive(); + return 0; + } + + // copy the packet data into the uIP packet buffer + ax88796RetreivePacketData( packet, packetLength ); + ax88796EndPacketRetreive(); + + return packetLength; +} + +void nicGetMacAddress(u08* macaddr) +{ + u08 tempCR; + // switch register pages + tempCR = ax88796Read(CR); + ax88796Write(CR,tempCR|PS0); + // read MAC address registers + *macaddr++ = ax88796Read(PAR0); + *macaddr++ = ax88796Read(PAR1); + *macaddr++ = ax88796Read(PAR2); + *macaddr++ = ax88796Read(PAR3); + *macaddr++ = ax88796Read(PAR4); + *macaddr++ = ax88796Read(PAR5); + // switch register pages back + ax88796Write(CR,tempCR); +} + +void nicSetMacAddress(u08* macaddr) +{ + u08 tempCR; + // switch register pages + tempCR = ax88796Read(CR); + ax88796Write(CR,tempCR|PS0); + // write MAC address registers + ax88796Write(PAR0, *macaddr++); + ax88796Write(PAR1, *macaddr++); + ax88796Write(PAR2, *macaddr++); + ax88796Write(PAR3, *macaddr++); + ax88796Write(PAR4, *macaddr++); + ax88796Write(PAR5, *macaddr++); + // switch register pages back + ax88796Write(CR,tempCR); +} + +void nicRegDump(void) +{ + ax88796RegDump(); +} + + +void ax88796SetupPorts(void) +{ +#if NIC_CONNECTION == MEMORY_MAPPED + // enable external SRAM interface - no wait states + sbi(MCUCR, SRE); +// sbi(MCUCR, SRW10); +// sbi(XMCRA, SRW00); +// sbi(XMCRA, SRW01); +// sbi(XMCRA, SRW11); +#else + // set address port to output + AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK; + + // set data port to input with pull-ups + AX88796_DATA_DDR = 0x00; + AX88796_DATA_PORT = 0xFF; + + // initialize the control port read and write pins to de-asserted + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN ); + // set the read and write pins to output + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN ); +#endif + // set reset pin to output + sbi( AX88796_RESET_DDR, AX88796_RESET_PIN ); +} + + +#if NIC_CONNECTION == MEMORY_MAPPED +inline void ax88796Write(u08 address, u08 data) +{ + *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address) = data; +} +#else +void ax88796Write(u08 address, u08 data) +{ + // assert the address + AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK); + + // set data bus as output and place data on bus + AX88796_DATA_DDR = 0xFF; + AX88796_DATA_PORT = data; + + // clock write pin + cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN); + nop(); + nop(); + sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN); + + // set data bus back to input with pullups enabled + AX88796_DATA_DDR = 0x00; + AX88796_DATA_PORT = 0xFF; +} +#endif + + +#if NIC_CONNECTION == MEMORY_MAPPED +inline u08 ax88796Read(u08 address) +{ + return *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address); +} +#else +u08 ax88796Read(u08 address) +{ + u08 data; + + // assert the address + AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK); + + // assert read + cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN); + nop(); + nop(); + // read in the data + data = AX88796_DATA_PIN; + + // negate read + sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN); + + return data; +} +#endif + + +void ax88796Init(void) +{ + unsigned char tcrFduFlag; + + // initialize I/O ports + ax88796SetupPorts(); + + // do a hard reset + sbi(AX88796_RESET_PORT, AX88796_RESET_PIN); + delay_ms(100); + cbi(AX88796_RESET_PORT, AX88796_RESET_PIN); + + // do soft reset + ax88796Write(ISR, ax88796Read(ISR)); + delay_ms(50); + + // wait for PHY to come out of reset + ax88796Read(RSTPORT); + while(ax88796Read(TR) & RST_B); + + ax88796WriteMii(0x10,0x00,0x0800); + delay_ms(255); + ax88796WriteMii(0x10,0x00,0x1200); + + ax88796Write(CR,(RD2|STOP)); // stop the NIC, abort DMA, page 0 + delay_ms(5); // make sure nothing is coming in or going out + ax88796Write(DCR,DCR_INIT); + ax88796Write(RBCR0,0x00); + ax88796Write(RBCR1,0x00); + ax88796Write(IMR,0x00); + ax88796Write(ISR,0xFF); + ax88796Write(RCR,0x20); + ax88796Write(BNRY,RXSTART_INIT); + ax88796Write(PSTART,RXSTART_INIT); + ax88796Write(PSTOP,RXSTOP_INIT); + + // switch to page 1 + ax88796Write(CR,(PS0|RD2|STOP)); + // write mac address + ax88796Write(PAR0+0, AX88796_MAC0); + ax88796Write(PAR0+1, AX88796_MAC1); + ax88796Write(PAR0+2, AX88796_MAC2); + ax88796Write(PAR0+3, AX88796_MAC3); + ax88796Write(PAR0+4, AX88796_MAC4); + ax88796Write(PAR0+5, AX88796_MAC5); + // set start point + ax88796Write(CURR,RXSTART_INIT+1); + + ax88796Write(CR,(RD2|START)); + ax88796Write(RCR,RCR_INIT); + + if(ax88796Read(GPI) & I_SPD) // check PHY speed setting + tcrFduFlag = FDU; // if 100base, do full duplex + else + tcrFduFlag = 0; // if 10base, do half duplex + + ax88796Write(TCR,(tcrFduFlag|TCR_INIT)); + + ax88796Write(GPOC,MPSEL); // select media interface + + ax88796Write(TPSR,TXSTART_INIT); + + ax88796Write(CR,(RD2|STOP)); + ax88796Write(DCR,DCR_INIT); + ax88796Write(CR,(RD2|START)); + ax88796Write(ISR,0xFF); + ax88796Write(IMR,IMR_INIT); + ax88796Write(TCR,(tcrFduFlag|TCR_INIT)); + + //test +/* + while(1) + { + vt100SetCursorPos(18,0); + ax88796RegDump(); + } +*/ +} + + +void ax88796BeginPacketSend(unsigned int packetLength) +{ + unsigned int sendPacketLength; + sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)? + (packetLength):(ETHERNET_MIN_PACKET_LENGTH); + + //start the NIC + ax88796Write(CR,(RD2|START)); + + // still transmitting a packet - wait for it to finish + while( ax88796Read(CR) & TXP ); + + //load beginning page for transmit buffer + ax88796Write(TPSR,TXSTART_INIT); + + //set start address for remote DMA operation + ax88796Write(RSAR0,0x00); + ax88796Write(RSAR1,0x40); + + //clear the packet stored interrupt + ax88796Write(ISR, PTX); + + //load data byte count for remote DMA + ax88796Write(RBCR0, (unsigned char)(packetLength)); + ax88796Write(RBCR1, (unsigned char)(packetLength>>8)); + + ax88796Write(TBCR0, (unsigned char)(sendPacketLength)); + ax88796Write(TBCR1, (unsigned char)((sendPacketLength)>>8)); + + //do remote write operation + ax88796Write(CR,0x12); +} + + +void ax88796SendPacketData(unsigned char * localBuffer, unsigned int length) +{ + unsigned int i; + + for(i=0;i= RXSTOP_INIT) readPagePtr = RXSTART_INIT; + + // return if there is no packet in the buffer + if( readPagePtr == writePagePtr ) + { + return 0; + } + + // clear the packet received interrupt flag + ax88796Write(ISR, PRX); + + // if the boundary pointer is invalid, + // reset the contents of the buffer and exit + if( (bnryPagePtr < RXSTART_INIT) || (bnryPagePtr >= RXSTOP_INIT) ) + { + ax88796Write(BNRY, RXSTART_INIT); + ax88796Write(CR, (PS0|RD2|START)); + ax88796Write(CURR, RXSTART_INIT+1); + ax88796Write(CR, (RD2|START)); + +// rprintf("B"); + return 0; + } + + // initiate DMA to transfer the RTL8019 packet header + ax88796Write(RBCR0, 4); + ax88796Write(RBCR1, 0); + ax88796Write(RSAR0, 0); + ax88796Write(RSAR1, readPagePtr); + ax88796Write(CR, (RD0|START)); + for(i=0;i<4;i++) + pageheader[i] = ax88796Read(RDMAPORT); + + // end the DMA operation + ax88796Write(CR, (RD2|START)); + for(i = 0; i <= 20; i++) + if(ax88796Read(ISR) & RDC) + break; + ax88796Write(ISR, RDC); + + rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL]; + NextPage = pageheader[PKTHEADER_NEXTPAGE]; + + CurrentRetreiveAddress = (readPagePtr<<8) + 4; + + // if the NextPage pointer is invalid, the packet is not ready yet - exit + if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) ) + { +// rprintf("N"); +// rprintfu08(nextPage); + return 0; + } + + return rxlen-4; +} + + +void ax88796RetreivePacketData(unsigned char * localBuffer, unsigned int length) +{ + unsigned int i; + + // initiate DMA to transfer the data + ax88796Write(RBCR0, (unsigned char)length); + ax88796Write(RBCR1, (unsigned char)(length>>8)); + ax88796Write(RSAR0, (unsigned char)CurrentRetreiveAddress); + ax88796Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8)); + ax88796Write(CR, (RD0|START)); + for(i=0;i= 0x6000 ) + CurrentRetreiveAddress -= (0x6000-0x4600) ; +} + + +void ax88796EndPacketRetreive(void) +{ + unsigned char i; + unsigned char bnryPagePtr; + + // end the DMA operation + ax88796Write(CR, (RD2|START)); + for(i = 0; i <= 20; i++) + if(ax88796Read(ISR) & RDC) + break; + ax88796Write(ISR, RDC); + + // set the boundary register to point + // to the start of the next packet-1 + bnryPagePtr = NextPage-1; + if(bnryPagePtr < RXSTART_INIT) bnryPagePtr = RXSTOP_INIT-1; + + ax88796Write(BNRY, bnryPagePtr); +} + + +void ax88796ProcessInterrupt(void) +{ + unsigned char intr = ax88796Read(ISR); + + // check for receive overflow + if( intr & OVW ) + ax88796ReceiveOverflowRecover(); +} + + +void ax88796ReceiveOverflowRecover(void) +{ + // receive buffer overflow handling procedure + // as specified in the AX88796 datasheet + + unsigned char cmdReg; + unsigned char resend=0; + + // check if we were transmitting something + cmdReg = ax88796Read(CR); + // stop the interface + ax88796Write(CR, (RD2|STOP)); + // wait for timeout + delay_ms(2); + // clear remote byte count registers + ax88796Write(RBCR0, 0x00); + ax88796Write(RBCR1, 0x00); + + // if we were transmitting something + if(cmdReg & TXP) + { + // check if the transmit completed + cmdReg = ax88796Read(ISR); + if((cmdReg & PTX) || (cmdReg & TXE)) + resend = 0; // transmit completed + else + resend = 1; // transmit was interrupted, must resend + } + // switch to loopback mode + ax88796Write(TCR, LB0); + // start the interface + ax88796Write(CR, (RD2|START)); + // set boundary + ax88796Write(BNRY, RXSTART_INIT); + // go to page 1 + ax88796Write(CR, (PS0|RD2|START)); + // set current page register + ax88796Write(CPR, RXSTART_INIT+1); + // go to page 0 + ax88796Write(CR, (RD2|START)); + // clear the overflow int + ax88796Write(ISR, OVW); + // switch to normal (non-loopback mode) + ax88796Write(TCR, TCR_INIT); + + // if previous transmit was interrupted, then resend + if(resend) + ax88796Write(CR, (RD2|TXP|START)); + + // recovery completed +} + + +#define set_mdc ax88796Write(MEMR,ax88796Read(MEMR)|0x01); +#define clr_mdc ax88796Write(MEMR,ax88796Read(MEMR)&0xFE); + +#define mii_clk set_mdc; clr_mdc; + +#define set_mdir ax88796Write(MEMR,ax88796Read(MEMR)|0x02); +#define clr_mdir ax88796Write(MEMR,ax88796Read(MEMR)&0xFD); + +#define set_mdo ax88796Write(MEMR,ax88796Read(MEMR)|0x08) +#define clr_mdo ax88796Write(MEMR,ax88796Read(MEMR)&0xF7) + +#define mii_write clr_mdo; mii_clk; \ + set_mdo; mii_clk; \ + clr_mdo; mii_clk; \ + set_mdo; mii_clk; + +#define mii_read clr_mdo; mii_clk; \ + set_mdo; mii_clk; \ + set_mdo; mii_clk; \ + clr_mdo; mii_clk; + +#define mii_r_ta mii_clk; \ + +#define mii_w_ta set_mdo; mii_clk; \ + clr_mdo; mii_clk; + +void ax88796WriteMii(unsigned char phyad,unsigned char regad,unsigned int mii_data) +{ + unsigned char mask8; + unsigned int i,mask16; + + mii_write; + + mask8 = 0x10; + for(i=0;i<5;++i) + { + if(mask8 & phyad) + set_mdo; + else + clr_mdo; + mii_clk; + mask8 >>= 1; + } + mask8 = 0x10; + for(i=0;i<5;++i) + { + if(mask8 & regad) + set_mdo; + else + clr_mdo; + mii_clk; + mask8 >>= 1; + } + mii_w_ta; + + mask16 = 0x8000; + for(i=0;i<16;++i) + { + if(mask16 & mii_data) + set_mdo; + else + clr_mdo; + mii_clk; + mask16 >>= 1; + } +} + +unsigned int ax88796ReadMii(unsigned char phyad,unsigned char regad) +{ + unsigned char mask8,i; + unsigned int mask16,result16; + + mii_read; + + mask8 = 0x10; + for(i=0;i<5;++i) + { + if(mask8 & phyad) + set_mdo; + else + clr_mdo; + mii_clk; + mask8 >>= 1; + } + mask8 = 0x10; + for(i=0;i<5;++i) + { + if(mask8 & regad) + set_mdo; + else + clr_mdo; + mii_clk; + mask8 >>= 1; + } + + mii_r_ta; + + mask16 = 0x8000; + result16 = 0x0000; + for(i=0;i<16;++i) + { + mii_clk; + if(ax88796Read(MEMR) & 0x04) + { + result16 |= mask16; + } + else + { + asm volatile ("nop"); + break; + } + mask16 >>= 1; + } + return result16; +} + + +void ax88796RegDump(void) +{ + unsigned char result; + result = ax88796Read(TR); + + rprintf("Media State: "); + if(!(result & AUTOD)) + rprintf("Autonegotiation\r\n"); + else if(result & RST_B) + rprintf("PHY in Reset \r\n"); + else if(!(result & RST_10B)) + rprintf("10BASE-T \r\n"); + else if(!(result & RST_TXB)) + rprintf("100BASE-T \r\n"); + + //rprintf("TR regsiter : %x\r\n",result); + //result = read_mii(0x10,0); + //rprintf("MII regsiter 0x10: %x\r\n",result); + + rprintfProgStrM("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n"); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(CR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(BNRY)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(PSTART)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(PSTOP)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(ISR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(TSR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(RSR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(MEMR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(TR)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(GPI)); + rprintfCRLF(); + + ax88796Write(CR,ax88796Read(CR)|PS0); + + rprintf("Page1: CR PAR CPR\r\n"); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(CR)); + rprintfProgStrM(" "); + rprintfChar(ax88796Read(PAR0)); + rprintfChar(ax88796Read(PAR1)); + rprintfChar(ax88796Read(PAR2)); + rprintfChar(ax88796Read(PAR3)); + rprintfChar(ax88796Read(PAR4)); + rprintfChar(ax88796Read(PAR5)); + rprintfProgStrM(" "); + rprintfu08(ax88796Read(CPR)); + + ax88796Write(CR,ax88796Read(CR)&~PS0); + + delay_ms(25); +} + +/* +unsigned char ax88796ReceiveEmpty(void) +{ + unsigned char temp; + + // read CPR from page 1 + ax88796Write(CR,0x62); + temp = ax88796Read(CPR); + + // return to page 0 + ax88796Write(CR,0x22); + + return ( ax88796Read(BNRY) == temp ); + +}*/ + + + + diff --git a/3rd party/Procyuon avrlib/net/ax88796.h b/3rd party/Procyuon avrlib/net/ax88796.h new file mode 100644 index 0000000..73e1a46 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/ax88796.h @@ -0,0 +1,211 @@ +/*! \file ax88796.h \brief ASIX AX88796 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'ax88796.h' +// Title : ASIX AX88796 Ethernet Interface Driver +// Author : Pascal Stang +// Created : 10/22/2002 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup ax88796 ASIX AX88796 Ethernet Interface Driver (ax88796.c) +/// \code #include "net/ax88796.h" \endcode +/// \par Overview +/// This driver provides initialization and transmit/receive +/// functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. +/// +/// Based in part on code by Louis Beaudoin (www.embedded-creations.com). +/// Thanks to Adam Dunkels and Louis Beaudoin for providing the initial +/// structure in which to write this driver. +// +//***************************************************************************** +//@{ + +#ifndef AX88796_H +#define AX88796_H + +#include "global.h" + +#define nop() asm volatile ("nop") + +// AX88796/NE2000 Control Register Offsets +// Page 0 - Read/Write +#define CR 0x00 // Command Register +#define PSTART 0x01 // Page Start Register +#define PSTOP 0x02 // Page Stop Register +#define BNRY 0x03 // Boundary Pointer +#define RDMAPORT 0x10 // DMA Data Port +#define MEMR 0x14 // MII/EEPROM Access Register +#define TR 0x15 // Test Register +#define SPP_DPR 0x18 // Standard Printer Port Data +#define SSP_SPR 0x19 // Standard Printer Port Status +#define SSP_CPR 0x1A // Standard Printer Port Control +// Page 0 - Read +#define TSR 0x04 // Transmit Status Register +#define NCR 0x05 // Number of Collisions Register +#define ISR 0x07 // Interrupt Status Register +#define CRDA0 0x08 // Current Remote DMA Address 0 +#define CRDA1 0x09 // Current Remote DMA Address 1 +#define RSR 0x0C // Receive Status Register +#define CNTR0 0x0D +#define CNTR1 0x0E +#define CNTR2 0x0F +#define GPI 0x17 // General-Purpose Input +#define RSTPORT 0x1F // Reset +// Page 0 - Write +#define TPSR 0x04 // Transmit Page Start Address +#define TBCR0 0x05 // Transmit Byte Count Register 0 +#define TBCR1 0x06 // Transmit Byte Count Register 1 +#define RSAR0 0x08 // Remote Start Address Register 0 +#define RSAR1 0x09 // Remote Start Address Register 1 +#define RBCR0 0x0A // Remote Byte Count 0 +#define RBCR1 0x0B // Remote Byte Count 1 +#define RCR 0x0C // Receive Config Register +#define TCR 0x0D // Transmit Config Register +#define DCR 0x0E // Data Config Register +#define IMR 0x0F // Interrupt Mask Register +#define GPOC 0x17 // General-Purpose Output Control +// Page 1 - Read/Write +#define PAR0 0x01 // Physical Address Register 0 +#define PAR1 0x02 // Physical Address Register 0 +#define PAR2 0x03 // Physical Address Register 0 +#define PAR3 0x04 // Physical Address Register 0 +#define PAR4 0x05 // Physical Address Register 0 +#define PAR5 0x06 // Physical Address Register 0 +#define CURR 0x07 // Page 1 +#define CPR 0x07 // Current Page Register + +// AX88796 CR Register Bit Definitions +#define PS1 0x80 +#define PS0 0x40 +#define RD2 0x20 +#define RD1 0x10 +#define RD0 0x08 +#define TXP 0x04 +#define START 0x02 +#define STOP 0x01 +// AX88796 RCR Register Bit Definitions +#define INTT 0x40 +#define MON 0x20 +#define PRO 0x10 +#define AM 0x08 +#define AB 0x04 +#define AR 0x02 +#define SEP 0x01 +// AX88796 ISR Register Bit Definitions +#define RST 0x80 +#define RDC 0x40 +#define OVW 0x10 +#define RXE 0x08 +#define TXE 0x04 +#define PTX 0x02 +#define PRX 0x01 +// AX88796 TEST Register Bit Definitions +#define AUTOD 0x01 +#define RST_B 0x02 +#define RST_10B 0x04 +#define RST_TXB 0x08 +// AX88796 GPOC Register Bit Definitions +#define GPO0 0x01 +#define MPSEL 0x10 +#define MPSET 0x20 +#define PPDSET 0x40 +// AX88796 MEMR Register Bit Definitions +#define MDC 0x01 +#define MDIR 0x02 +#define MDI 0x04 +#define MDO 0x08 +#define EECS 0x10 +#define EEI 0x20 +#define EEO 0x40 +#define EECLK 0x80 +// AX88796 GPI Register Bit Definitions +#define GPI2 0x40 +#define GPI1 0x20 +#define GPI0 0x10 +#define I_SPD 0x04 +#define I_DPX 0x02 +#define I_LINK 0x01 +// AX88796 TCR Register Bit Definitions +#define FDU 0x80 // full duplex +#define PD 0x40 // pad disable +#define RLO 0x20 // retry of late collisions +#define LB1 0x04 // loopback 1 +#define LB0 0x02 // loopback 0 +#define CRC 0x01 // generate CRC + +// AX88796 Initial Register Values +// RCR : INT trigger active high and Accept Broadcast ENET packets +#define RCR_INIT (INTT | AB) +#define DCR_INIT 0x00 // was 0x58 for realtek RTL8019 +// TCR : default transmit operation - CRC is generated +#define TCR_INIT 0x00 +// IMR : interrupt enabled for receive and overrun events +#define IMR_INIT 0x11 // PRX and OVW interrupt enabled +// buffer boundaries +// transmit has 6 256-byte pages +// receive has 26 256-byte pages +// entire available packet buffer space is allocated +#define TXSTART_INIT 0x40 +#define RXSTART_INIT 0x46 +#define RXSTOP_INIT 0x60 + +// Ethernet constants +#define ETHERNET_MIN_PACKET_LENGTH 0x3C +//#define ETHERNET_HEADER_LENGTH 0x0E + +// offsets into ax88796 ethernet packet header +#define PKTHEADER_STATUS 0x00 // packet status +#define PKTHEADER_NEXTPAGE 0x01 // next buffer page +#define PKTHEADER_PKTLENL 0x02 // packet length low +#define PKTHEADER_PKTLENH 0x03 // packet length high + + +// functions +#include "nic.h" + +// setup ports for I/O +void ax88796SetupPorts(void); + +// read ax88796 register +u08 ax88796Read(u08 address); + +// write ax88796 register +void ax88796Write(u08 address, u08 data); + +// initialize the ethernet interface for transmit/receive +void ax88796Init(void); + +// packet transmit functions +void ax88796BeginPacketSend(unsigned int packetLength); +void ax88796SendPacketData(unsigned char * localBuffer, unsigned int length); +void ax88796EndPacketSend(void); + +// packet receive functions +unsigned int ax88796BeginPacketRetreive(void); +void ax88796RetreivePacketData(unsigned char *localBuffer, unsigned int length); +void ax88796EndPacketRetreive(void); + +// Processes AX88796 interrupts. +// Currently, this function looks only for a receive overflow condition. +// The function need not be called in response to an interrupt, +// but can be executed just before checking the receive buffer for incoming packets. +void ax88796ProcessInterrupt(void); + +// execute procedure for recovering from a receive overflow +// this should be done when the receive memory fills up with packets +void ax88796ReceiveOverflowRecover(void); + +// Write MII Registers +void ax88796WriteMii(unsigned char phyad,unsigned char regad,unsigned int mii_data); +// Read MII Registers +unsigned int ax88796ReadMii(unsigned char phyad,unsigned char regad); + +// formatted print of all important AX88796 registers +void ax88796RegDump(void); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/conf/ax88796conf.h b/3rd party/Procyuon avrlib/net/conf/ax88796conf.h new file mode 100644 index 0000000..f2f8c2a --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/ax88796conf.h @@ -0,0 +1,84 @@ +/*! \file ax88796conf.h \brief ASIX AX88796 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'ax88796conf.h' +// Title : ASIX AX88796 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/22/2002 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef AX88796CONF_H +#define AX88796CONF_H + +// This driver supports an AX88796 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the AX88796 address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// Memory-mapped mode assumes that the AX88796 is connected the processor via +// the external memory bus, and that the AX88796 address space starts at the +// memory location AX88796_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the AX88796's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define AX88796_MEMORY_MAPPED_OFFSET 0x2000 +#else // NIC Interface through General I/O + // AX88796 address port + #define AX88796_ADDRESS_PORT PORTB + #define AX88796_ADDRESS_DDR DDRB + #define AX88796_ADDRESS_MASK 0x1F + // AX88796 data port + #define AX88796_DATA_PORT PORTA + #define AX88796_DATA_DDR DDRA + #define AX88796_DATA_PIN PINA + // AX88796 control port + #define AX88796_CONTROL_PORT PORTD + #define AX88796_CONTROL_DDR DDRD + #define AX88796_CONTROL_READPIN PD5 + #define AX88796_CONTROL_WRITEPIN PD4 +#endif + +// AX88796 RESET pin +#define AX88796_RESET_PORT PORTD +#define AX88796_RESET_DDR DDRD +#define AX88796_RESET_PIN PD6 + +// MAC address for this interface +#ifdef ETHADDR0 +#define AX88796_MAC0 ETHADDR0 +#define AX88796_MAC1 ETHADDR1 +#define AX88796_MAC2 ETHADDR2 +#define AX88796_MAC3 ETHADDR3 +#define AX88796_MAC4 ETHADDR4 +#define AX88796_MAC5 ETHADDR5 +#else +#define AX88796_MAC0 '0' +#define AX88796_MAC1 'F' +#define AX88796_MAC2 'F' +#define AX88796_MAC3 'I' +#define AX88796_MAC4 'C' +#define AX88796_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/ax88796conf_easyethavrasix.h b/3rd party/Procyuon avrlib/net/conf/ax88796conf_easyethavrasix.h new file mode 100644 index 0000000..f2f8c2a --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/ax88796conf_easyethavrasix.h @@ -0,0 +1,84 @@ +/*! \file ax88796conf.h \brief ASIX AX88796 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'ax88796conf.h' +// Title : ASIX AX88796 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/22/2002 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef AX88796CONF_H +#define AX88796CONF_H + +// This driver supports an AX88796 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the AX88796 address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// Memory-mapped mode assumes that the AX88796 is connected the processor via +// the external memory bus, and that the AX88796 address space starts at the +// memory location AX88796_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the AX88796's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define AX88796_MEMORY_MAPPED_OFFSET 0x2000 +#else // NIC Interface through General I/O + // AX88796 address port + #define AX88796_ADDRESS_PORT PORTB + #define AX88796_ADDRESS_DDR DDRB + #define AX88796_ADDRESS_MASK 0x1F + // AX88796 data port + #define AX88796_DATA_PORT PORTA + #define AX88796_DATA_DDR DDRA + #define AX88796_DATA_PIN PINA + // AX88796 control port + #define AX88796_CONTROL_PORT PORTD + #define AX88796_CONTROL_DDR DDRD + #define AX88796_CONTROL_READPIN PD5 + #define AX88796_CONTROL_WRITEPIN PD4 +#endif + +// AX88796 RESET pin +#define AX88796_RESET_PORT PORTD +#define AX88796_RESET_DDR DDRD +#define AX88796_RESET_PIN PD6 + +// MAC address for this interface +#ifdef ETHADDR0 +#define AX88796_MAC0 ETHADDR0 +#define AX88796_MAC1 ETHADDR1 +#define AX88796_MAC2 ETHADDR2 +#define AX88796_MAC3 ETHADDR3 +#define AX88796_MAC4 ETHADDR4 +#define AX88796_MAC5 ETHADDR5 +#else +#define AX88796_MAC0 '0' +#define AX88796_MAC1 'F' +#define AX88796_MAC2 'F' +#define AX88796_MAC3 'I' +#define AX88796_MAC4 'C' +#define AX88796_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/cs8900conf.h b/3rd party/Procyuon avrlib/net/conf/cs8900conf.h new file mode 100644 index 0000000..7b15d05 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/cs8900conf.h @@ -0,0 +1,83 @@ +/*! \file cs8900conf.h \brief Crystal CS8900 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'cs8900conf.h' +// Title : Crystal CS8900 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 11/7/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +// +// Description : This driver provides initialization and transmit/receive +// functions for the Crystal CS8900 10Mb Ethernet Controller and PHY. +// +//***************************************************************************** + +#ifndef CS8900CONF_H +#define CS8900CONF_H + +// This driver supports a CS8900 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +//#define MEMORY_MAPPED 1 (*** MEMORY-MAPPED NOT YET IMPLEMENTED ***) +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location CS8900_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define CS8900_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // CS8900 address port + #define CS8900_ADDRESS_PORT PORTF + #define CS8900_ADDRESS_DDR DDRF + #define CS8900_ADDRESS_MASK 0x0F + // CS8900 data port + #define CS8900_DATA_PORT PORTA + #define CS8900_DATA_DDR DDRA + #define CS8900_DATA_PIN PINA + // CS8900 control port + #define CS8900_CONTROL_PORT PORTB + #define CS8900_CONTROL_DDR DDRB + #define CS8900_CONTROL_READPIN 4 + #define CS8900_CONTROL_WRITEPIN 3 +#endif + +// CS8900 RESET pin +#define CS8900_RESET_PORT PORTB +#define CS8900_RESET_DDR DDRB +#define CS8900_RESET_PIN 1 + +// MAC address for this interface +#ifdef ETHADDR0 +#define CS8900_MAC0 ETHADDR0 +#define CS8900_MAC1 ETHADDR1 +#define CS8900_MAC2 ETHADDR2 +#define CS8900_MAC3 ETHADDR3 +#define CS8900_MAC4 ETHADDR4 +#define CS8900_MAC5 ETHADDR5 +#else +#define CS8900_MAC0 '0' +#define CS8900_MAC1 'F' +#define CS8900_MAC2 'F' +#define CS8900_MAC3 'I' +#define CS8900_MAC4 'C' +#define CS8900_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/enc28j60conf.h b/3rd party/Procyuon avrlib/net/conf/enc28j60conf.h new file mode 100644 index 0000000..447504c --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/enc28j60conf.h @@ -0,0 +1,53 @@ +/*! \file enc28j60conf.h \brief Microchip ENC28J60 Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'enc28j60conf.h' +// Title : Microchip ENC28J60 Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/5/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the ENC28J60 10Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENC28J60CONF_H +#define ENC28J60CONF_H + +// ENC28J60 SPI port +#define ENC28J60_SPI_PORT PORTB +#define ENC28J60_SPI_DDR DDRB +#define ENC28J60_SPI_SCK 7 +#define ENC28J60_SPI_MOSI 5 +#define ENC28J60_SPI_MISO 6 +#define ENC28J60_SPI_SS 4 +// ENC28J60 control port +#define ENC28J60_CONTROL_PORT PORTB +#define ENC28J60_CONTROL_DDR DDRB +#define ENC28J60_CONTROL_CS 4 + +// MAC address for this interface +#ifdef ETHADDR0 +#define ENC28J60_MAC0 ETHADDR0 +#define ENC28J60_MAC1 ETHADDR1 +#define ENC28J60_MAC2 ETHADDR2 +#define ENC28J60_MAC3 ETHADDR3 +#define ENC28J60_MAC4 ETHADDR4 +#define ENC28J60_MAC5 ETHADDR5 +#else +#define ENC28J60_MAC0 '0' +#define ENC28J60_MAC1 'F' +#define ENC28J60_MAC2 'F' +#define ENC28J60_MAC3 'I' +#define ENC28J60_MAC4 'C' +#define ENC28J60_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/prism2conf.h b/3rd party/Procyuon avrlib/net/conf/prism2conf.h new file mode 100644 index 0000000..2e0ca64 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/prism2conf.h @@ -0,0 +1,97 @@ +/*! \file prism2conf.h \brief Prism2 802.11b Wireless-LAN Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'prism2conf.h' +// Title : Prism2 802.11b Wireless-LAN Interface Driver Configuration +// Author : Pascal Stang +// Created : 12/27/2004 +// Revised : 1/7/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +// +// Description : This is the configuration file for the Prism2 802.11b +// Wireless-LAN Controller Driver. +// +//***************************************************************************** + +#ifndef PRISM2CONF_H +#define PRISM2CONF_H + +// This driver supports a PRISM2 NIC connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// *** MEMORY-MAPPED NOT YET IMPLEMENTED *** +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location PRISM2_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define PRISM2_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // PRISM2 address port + #define PRISM2_ADDRESS_PORT PORTA + #define PRISM2_ADDRESS_DDR DDRA + #define PRISM2_ADDRESS_MASK 0xFF + // PRISM2 high address port + #define PRISM2_HADDRESS_PORT PORTF + #define PRISM2_HADDRESS_DDR DDRF + #define PRISM2_HADDRESS_MASK 0x07 + // PRISM2 data port + #define PRISM2_DATA_PORT PORTC + #define PRISM2_DATA_DDR DDRC + #define PRISM2_DATA_PIN PINC + // PRISM2 control port + #define PRISM2_CONTROL_PORT PORTG + #define PRISM2_CONTROL_DDR DDRG + #define PRISM2_CONTROL_IORD 1 + #define PRISM2_CONTROL_IOWR 2 + #define PRISM2_CONTROL_MEMRD 0 + #define PRISM2_CONTROL_MEMWR 3 + // Set PRISM2 memory and I/O bus access delay + // NOTE: PRISM2 cards may not respond correctly if access time is too short or too long + // Typically good settings: MEM = ~12us, I/O = ~1us + #define PRISM2_MEM_ACCESS_DELAY delay_us(12) + #define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } + //#define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } +#endif + +// PRISM2 RESET pin +#define PRISM2_RESET_PORT PORTG +#define PRISM2_RESET_DDR DDRG +#define PRISM2_RESET_PIN 4 + + + +// MAC address for this interface +#ifdef ETHADDR0 +#define PRISM2_MAC0 ETHADDR0 +#define PRISM2_MAC1 ETHADDR1 +#define PRISM2_MAC2 ETHADDR2 +#define PRISM2_MAC3 ETHADDR3 +#define PRISM2_MAC4 ETHADDR4 +#define PRISM2_MAC5 ETHADDR5 +#else +#define PRISM2_MAC0 '0' +#define PRISM2_MAC1 'F' +#define PRISM2_MAC2 'F' +#define PRISM2_MAC3 'I' +#define PRISM2_MAC4 'C' +#define PRISM2_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/prism2conf_airdrop.h b/3rd party/Procyuon avrlib/net/conf/prism2conf_airdrop.h new file mode 100644 index 0000000..2e0ca64 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/prism2conf_airdrop.h @@ -0,0 +1,97 @@ +/*! \file prism2conf.h \brief Prism2 802.11b Wireless-LAN Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'prism2conf.h' +// Title : Prism2 802.11b Wireless-LAN Interface Driver Configuration +// Author : Pascal Stang +// Created : 12/27/2004 +// Revised : 1/7/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +// +// Description : This is the configuration file for the Prism2 802.11b +// Wireless-LAN Controller Driver. +// +//***************************************************************************** + +#ifndef PRISM2CONF_H +#define PRISM2CONF_H + +// This driver supports a PRISM2 NIC connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// *** MEMORY-MAPPED NOT YET IMPLEMENTED *** +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location PRISM2_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define PRISM2_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // PRISM2 address port + #define PRISM2_ADDRESS_PORT PORTA + #define PRISM2_ADDRESS_DDR DDRA + #define PRISM2_ADDRESS_MASK 0xFF + // PRISM2 high address port + #define PRISM2_HADDRESS_PORT PORTF + #define PRISM2_HADDRESS_DDR DDRF + #define PRISM2_HADDRESS_MASK 0x07 + // PRISM2 data port + #define PRISM2_DATA_PORT PORTC + #define PRISM2_DATA_DDR DDRC + #define PRISM2_DATA_PIN PINC + // PRISM2 control port + #define PRISM2_CONTROL_PORT PORTG + #define PRISM2_CONTROL_DDR DDRG + #define PRISM2_CONTROL_IORD 1 + #define PRISM2_CONTROL_IOWR 2 + #define PRISM2_CONTROL_MEMRD 0 + #define PRISM2_CONTROL_MEMWR 3 + // Set PRISM2 memory and I/O bus access delay + // NOTE: PRISM2 cards may not respond correctly if access time is too short or too long + // Typically good settings: MEM = ~12us, I/O = ~1us + #define PRISM2_MEM_ACCESS_DELAY delay_us(12) + #define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } + //#define PRISM2_IO_ACCESS_DELAY { nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); } +#endif + +// PRISM2 RESET pin +#define PRISM2_RESET_PORT PORTG +#define PRISM2_RESET_DDR DDRG +#define PRISM2_RESET_PIN 4 + + + +// MAC address for this interface +#ifdef ETHADDR0 +#define PRISM2_MAC0 ETHADDR0 +#define PRISM2_MAC1 ETHADDR1 +#define PRISM2_MAC2 ETHADDR2 +#define PRISM2_MAC3 ETHADDR3 +#define PRISM2_MAC4 ETHADDR4 +#define PRISM2_MAC5 ETHADDR5 +#else +#define PRISM2_MAC0 '0' +#define PRISM2_MAC1 'F' +#define PRISM2_MAC2 'F' +#define PRISM2_MAC3 'I' +#define PRISM2_MAC4 'C' +#define PRISM2_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/conf/rtl8019conf.h b/3rd party/Procyuon avrlib/net/conf/rtl8019conf.h new file mode 100644 index 0000000..3922973 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/conf/rtl8019conf.h @@ -0,0 +1,84 @@ +/*! \file rtl8019conf.h \brief Realtek RTL8019AS Ethernet Interface Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'rtl8019conf.h' +// Title : Realtek RTL8019AS Ethernet Interface Driver Configuration +// Author : Pascal Stang +// Created : 10/5/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the RTL8019AS 10Mb Ethernet Controller and PHY. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RTL8019CONF_H +#define RTL8019CONF_H + +// This driver supports an RTL8019 connected in memory-mapped or direct I/O mode. +// +#define GENERAL_IO 0 +// Direct I/O mode assumes the NIC address, data, and control lines are +// connected directly to processor I/O pins. The memory-bus accesses are +// software emulated. +// +#define MEMORY_MAPPED 1 +// Memory-mapped mode assumes that the NIC is connected the processor via +// the external memory bus, and that the NIC address space starts at the +// memory location RTL8019_MEMORY_MAPPED_OFFSET. +// +// In either mode, a seperate I/O pins is required for control of the NIC's +// hardware RESET line. + +// set the connection type used to communicate with the NIC +#define NIC_CONNECTION GENERAL_IO + + +#if NIC_CONNECTION != GENERAL_IO + // NIC is memory-mapped starting at this address + #define RTL8019_MEMORY_MAPPED_OFFSET 0x8000 +#else // NIC Interface through General I/O + // RTL8019 address port + #define RTL8019_ADDRESS_PORT PORTB + #define RTL8019_ADDRESS_DDR DDRB + #define RTL8019_ADDRESS_MASK 0x1F + // RTL8019 data port + #define RTL8019_DATA_PORT PORTA + #define RTL8019_DATA_DDR DDRA + #define RTL8019_DATA_PIN PINA + // RTL8019 control port + #define RTL8019_CONTROL_PORT PORTD + #define RTL8019_CONTROL_DDR DDRD + #define RTL8019_CONTROL_READPIN 6 + #define RTL8019_CONTROL_WRITEPIN 7 +#endif + +// RTL8019 RESET pin +#define RTL8019_RESET_PORT PORTD +#define RTL8019_RESET_DDR DDRD +#define RTL8019_RESET_PIN 4 + +// MAC address for this interface +#ifdef ETHADDR0 +#define RTL8019_MAC0 ETHADDR0 +#define RTL8019_MAC1 ETHADDR1 +#define RTL8019_MAC2 ETHADDR2 +#define RTL8019_MAC3 ETHADDR3 +#define RTL8019_MAC4 ETHADDR4 +#define RTL8019_MAC5 ETHADDR5 +#else +#define RTL8019_MAC0 '0' +#define RTL8019_MAC1 'F' +#define RTL8019_MAC2 'F' +#define RTL8019_MAC3 'I' +#define RTL8019_MAC4 'C' +#define RTL8019_MAC5 'E' +#endif + +#endif diff --git a/3rd party/Procyuon avrlib/net/cs8900.c b/3rd party/Procyuon avrlib/net/cs8900.c new file mode 100644 index 0000000..4d3fce3 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/cs8900.c @@ -0,0 +1,339 @@ +/*! \file cs8900.c \brief Crystal CS8900 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'cs8900.c' +// Title : Crystal CS8900 Ethernet Interface Driver +// Author : Pascal Stang +// Created : 11/7/2004 +// Revised : 11/7/2004 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "cs8900.h" + +// include configuration +#include "cs8900conf.h" + +void nicInit(void) +{ + cs8900Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + u08 timeout = 15; + + // request space in CS8900's on-chip memory for storing an outgoing frame + cs8900Write16(CS8900_IO_TXCMD, TX_START_ALL_BYTES); + cs8900Write16(CS8900_IO_TXLENGTH, len); + // check if CS8900 is ready to accept the frame we want to send + // (timeout after 1.5ms since it should only take 1.25ms to + // finish sending previous frame. If we timeout, it's probably + // because there's no link, no ethernet cable.) + while(!(cs8900ReadReg(PP_BusST) & READY_FOR_TX_NOW) && timeout) + { + // wait 100us + delay_us(100); + timeout--; + } + // write packet data bytes + cs8900CopyToFrame(packet, len); + + // packet is automatically sent upon completion of above write +} + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + unsigned int packetLength; + + packetLength = cs8900BeginPacketRetreive(); + + // if there's no packet or an error - exit without ending the operation + if( !packetLength ) + return 0; + + // drop anything too big for the buffer + if( packetLength > maxlen ) + { + cs8900EndPacketRetreive(); + return 0; + } + + // copy the packet data into the packet buffer + cs8900RetreivePacketData( packet, packetLength ); + cs8900EndPacketRetreive(); + + return packetLength; +} + +void nicGetMacAddress(u08* macaddr) +{ + // read MAC address registers + // TODO: check byte order here! + *((unsigned short*)(macaddr+0)) = cs8900ReadReg(PP_IA+0); + *((unsigned short*)(macaddr+2)) = cs8900ReadReg(PP_IA+2); + *((unsigned short*)(macaddr+4)) = cs8900ReadReg(PP_IA+4); +} + +void nicSetMacAddress(u08* macaddr) +{ + // write MAC address registers + cs8900WriteReg(PP_IA+0, (macaddr[1]<<8) + macaddr[0] ); + cs8900WriteReg(PP_IA+2, (macaddr[3]<<8) + macaddr[2] ); + cs8900WriteReg(PP_IA+4, (macaddr[5]<<8) + macaddr[4] ); +} + +unsigned int cs8900BeginPacketRetreive(void) +{ + unsigned short status; + + // check RxEvent + status = cs8900ReadReg(PP_RxEvent); + + if( !((status&RX_OK)||(status&RX_IA)||(status&RX_BROADCAST)) ) + { + return 0; + } + +// return cs8900ReadReg(PP_RxFrameByteCnt); + // read RxStatus high-byte first + status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8; + status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0); + // read packet length high-byte first + status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8; + status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0); + + return status; +} + +void cs8900RetreivePacketData(u08* packet, unsigned int packetLength ) +{ + cs8900CopyFromFrame(packet, packetLength); +} + +void cs8900EndPacketRetreive(void) +{ + // dummy read first four bytes + //cs8900CopyFromFrame(packet, 4); +} + + + +void cs8900InitPorts(void) +{ +#if MEMORY_MAPPED_NIC == 1 + // enable external SRAM interface - no wait states + sbi(MCUSR, SRE); +#else + // set address port to output + outb(CS8900_ADDRESS_DDR, CS8900_ADDRESS_MASK); + + // set data port to input with pull-ups + outb(CS8900_DATA_DDR, 0x00); + outb(CS8900_DATA_PORT, 0xFF); + + // initialize the control port read and write pins to de-asserted + sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN ); + sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN ); + // set the read and write pins to output + sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_READPIN ); + sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_WRITEPIN ); +#endif + // set reset pin to output + sbi( CS8900_RESET_DDR, CS8900_RESET_PIN ); +} + +void cs8900Init(void) +{ + cs8900InitPorts(); + + // assert hardware reset + sbi( CS8900_RESET_PORT, CS8900_RESET_PIN ); + // wait + delay_ms(10); + // release hardware reset + cbi( CS8900_RESET_PORT, CS8900_RESET_PIN ); + delay_ms(10); + + // Reset the Ethernet-Controller + cs8900Write16(CS8900_IO_PP_PTR, PP_SelfCTL); + cs8900Write16(CS8900_IO_PP_DATA_PORT0, POWER_ON_RESET); + // wait until chip-reset is done + cs8900Write16(CS8900_IO_PP_PTR, PP_SelfST); + while(!(cs8900Read16(CS8900_IO_PP_DATA_PORT0) & INIT_DONE)); + + // set our MAC as Individual Address + cs8900WriteReg(PP_IA+0, (CS8900_MAC1<<8) + CS8900_MAC0 ); + cs8900WriteReg(PP_IA+2, (CS8900_MAC3<<8) + CS8900_MAC2 ); + cs8900WriteReg(PP_IA+4, (CS8900_MAC5<<8) + CS8900_MAC4 ); + // configure the Physical Interface + cs8900WriteReg(PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON); + cs8900WriteReg(PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT ); +} + +void cs8900Write(unsigned char address, unsigned char data) +{ + // assert the address + outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK)); + // set data bus as output + outb(CS8900_DATA_DDR, 0xFF); + // place data on bus + outb(CS8900_DATA_PORT, data); + // clock write pin + cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN); + nop(); + nop(); + nop(); + nop(); + sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN); + // set data bus back to input with pullups enabled + outb(CS8900_DATA_DDR, 0x00); + outb(CS8900_DATA_PORT, 0xFF); +} + +unsigned char cs8900Read(unsigned char address) +{ + unsigned char data; + // assert the address + outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK)); + // set data bus to input with pullups enabled + outb(CS8900_DATA_DDR, 0x00); + outb(CS8900_DATA_PORT, 0xFF); + // assert read + cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN); + nop(); + nop(); + nop(); + nop(); + // read in the data + data = inb( CS8900_DATA_PIN ); + // negate read + sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN); + // return data + return data; +} + +void cs8900Write16(unsigned char address, unsigned short data) +{ + cs8900Write(address+0, data); + cs8900Write(address+1, data>>8); +} + +unsigned short cs8900Read16(unsigned char address) +{ + unsigned short data; + data = cs8900Read(address+0); + data |= cs8900Read(address+1)<<8; + return data; +} + +// writes a word in little-endian byte order to a specified PacketPage address +void cs8900WriteReg(unsigned short address, unsigned short data) +{ + cs8900Write16(CS8900_IO_PP_PTR, address); + cs8900Write16(CS8900_IO_PP_DATA_PORT0, data); +} + +// reads a word in little-endian byte order from a specified PacketPage address +unsigned short cs8900ReadReg(unsigned short address) +{ + cs8900Write16(CS8900_IO_PP_PTR, address); + return cs8900Read16(CS8900_IO_PP_DATA_PORT0); +} + +// copies bytes from MCU-memory to frame port +// NOTES: * an odd number of byte may only be transfered +// if the frame is written to the end! +// * MCU-memory MUST start at word-boundary + +void cs8900CopyToFrame(unsigned char *source, unsigned short size) +{ + while(size>1) + { + cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *((unsigned short*)source)); + source += 2; + size -= 2; + } + // if odd num. of bytes... + // write leftover byte (the LAN-controller ignores the highbyte) + if(size) + cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *(unsigned char*)source); +} + +// copies bytes from frame port to MCU-memory +// NOTES: * an odd number of byte may only be transfered +// if the frame is read to the end! +// * MCU-memory MUST start at word-boundary + +void cs8900CopyFromFrame(unsigned char *dest, unsigned short size) +{ + while(size>1) + { + *((unsigned short *)dest) = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0); + dest += 2; + size -= 2; + } + + // check for leftover byte... + // the LAN-Controller will return 0 for the highbyte + if(size) + *(unsigned char *)dest = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0); +} + +void cs8900IORegDump(void) +{ + rprintfProgStrM("CS8900 I/O Registers\r\n"); + rprintfProgStrM(" FRAME ISQ ADDR DATA0 DATA1\r\n"); + rprintfProgStrM("-------------------------------\r\n"); + rprintfProgStrM(" "); + rprintfu16(cs8900Read16(CS8900_IO_RXTX_DATA_PORT0)); + rprintfProgStrM(" "); + rprintfu16(cs8900Read16(CS8900_IO_ISQ)); + rprintfProgStrM(" "); + rprintfu16(cs8900Read16(CS8900_IO_PP_PTR)); + rprintfProgStrM(" "); + rprintfu16(cs8900Read16(CS8900_IO_PP_DATA_PORT0)); + rprintfProgStrM(" "); + rprintfu16(cs8900Read16(CS8900_IO_PP_DATA_PORT1)); + rprintfCRLF(); +} + +void cs8900RegDump(void) +{ + rprintfProgStrM("CS8900 PacketPage Registers\r\n"); + rprintfProgStrM("CHIP ID: "); + rprintfu16(cs8900ReadReg(PP_ChipID)); + rprintfCRLF(); + + rprintfProgStrM("PP_ISAIOB: "); + rprintfu16(cs8900ReadReg(PP_ISAIOB)); + rprintfCRLF(); + + rprintfProgStrM("MAC addr: "); + rprintfu16(cs8900ReadReg(PP_IA+0)); + rprintfu16(cs8900ReadReg(PP_IA+2)); + rprintfu16(cs8900ReadReg(PP_IA+4)); + rprintfCRLF(); +} + +void nicRegDump(void) +{ + cs8900IORegDump(); + cs8900RegDump(); +} + + +u08 cs8900LinkStatus(void) +{ + if(cs8900ReadReg(PP_LineST) & LINK_OK) + return 1; + else + return 0; +} diff --git a/3rd party/Procyuon avrlib/net/cs8900.h b/3rd party/Procyuon avrlib/net/cs8900.h new file mode 100644 index 0000000..b596b79 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/cs8900.h @@ -0,0 +1,515 @@ +/*! \file cs8900.h \brief Crystal CS8900 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'cs8900.h' +// Title : Crystal CS8900 Ethernet Interface Driver +// Author : Pascal Stang +// Created : 11/7/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup cs8900 Crystal CS8900 Ethernet Interface Driver (cs8900.c) +/// \code #include "net/cs8900.h" \endcode +/// \par Overview +/// This driver provides initialization and transmit/receive +/// functions for the Crystal CS8900 10Mb Ethernet Controller and PHY. +// +//***************************************************************************** +//@{ + +#ifndef CS8900_H +#define CS8900_H + +#include "global.h" + +#define nop() asm volatile ("nop") + + +// Crystal ESIA product ID +#define CS8900_ESIA_ID (0x630e) + +// CS8900 IO Registers +#define CS8900_IO_RXTX_DATA_PORT0 (0x0000) +#define CS8900_IO_RXTX_DATA_PORT1 (0x0002) +#define CS8900_IO_TXCMD (0x0004) +#define CS8900_IO_TXLENGTH (0x0006) +#define CS8900_IO_ISQ (0x0008) +#define CS8900_IO_PP_PTR (0x000a) +#define CS8900_IO_PP_DATA_PORT0 (0x000c) +#define CS8900_IO_PP_DATA_PORT1 (0x000e) + +// definitions for Crystal CS8900 ethernet-controller +// based on linux-header by Russel Nelson + +#define PP_ChipID 0x0000 // offset 0h -> Corp-ID + // offset 2h -> Model/Product Number + // offset 3h -> Chip Revision Number + +#define PP_ISAIOB 0x0020 // IO base address +#define PP_CS8900_ISAINT 0x0022 // ISA interrupt select +#define PP_CS8900_ISADMA 0x0024 // ISA Rec DMA channel +#define PP_ISASOF 0x0026 // ISA DMA offset +#define PP_DmaFrameCnt 0x0028 // ISA DMA Frame count +#define PP_DmaByteCnt 0x002A // ISA DMA Byte count +#define PP_CS8900_ISAMemB 0x002C // Memory base +#define PP_ISABootBase 0x0030 // Boot Prom base +#define PP_ISABootMask 0x0034 // Boot Prom Mask +#define PP_RxFrameByteCnt 0x0050 + +// EEPROM data and command registers +#define PP_EECMD 0x0040 // NVR Interface Command register +#define PP_EEData 0x0042 // NVR Interface Data Register + +// Configuration and control registers +#define PP_RxCFG 0x0102 // Rx Bus config +#define PP_RxCTL 0x0104 // Receive Control Register +#define PP_TxCFG 0x0106 // Transmit Config Register +#define PP_TxCMD 0x0108 // Transmit Command Register +#define PP_BufCFG 0x010A // Bus configuration Register +#define PP_LineCTL 0x0112 // Line Config Register +#define PP_SelfCTL 0x0114 // Self Command Register +#define PP_BusCTL 0x0116 // ISA bus control Register +#define PP_TestCTL 0x0118 // Test Register + +// Status and Event Registers +#define PP_ISQ 0x0120 // Interrupt Status +#define PP_RxEvent 0x0124 // Rx Event Register +#define PP_TxEvent 0x0128 // Tx Event Register +#define PP_BufEvent 0x012C // Bus Event Register +#define PP_RxMiss 0x0130 // Receive Miss Count +#define PP_TxCol 0x0132 // Transmit Collision Count +#define PP_LineST 0x0134 // Line State Register +#define PP_SelfST 0x0136 // Self State register +#define PP_BusST 0x0138 // Bus Status +#define PP_TDR 0x013C // Time Domain Reflectometry + +// Initiate Transmit Registers +#define PP_TxCommand 0x0144 // Tx Command +#define PP_TxLength 0x0146 // Tx Length + +// Address Filter Registers +#define PP_LAF 0x0150 // Hash Table +#define PP_IA 0x0158 // Physical Address Register + +// Frame Location +#define PP_RxStatus 0x0400 // Receive start of frame +#define PP_RxLength 0x0402 // Receive Length of frame +#define PP_RxFrame 0x0404 // Receive frame pointer +#define PP_TxFrame 0x0A00 // Transmit frame pointer + +// Primary I/O Base Address. If no I/O base is supplied by the user, then this +// can be used as the default I/O base to access the PacketPage Area. +#define DEFAULTIOBASE 0x0300 + +// PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write +#define SKIP_1 0x0040 +#define RX_STREAM_ENBL 0x0080 +#define RX_OK_ENBL 0x0100 +#define RX_DMA_ONLY 0x0200 +#define AUTO_RX_DMA 0x0400 +#define BUFFER_CRC 0x0800 +#define RX_CRC_ERROR_ENBL 0x1000 +#define RX_RUNT_ENBL 0x2000 +#define RX_EXTRA_DATA_ENBL 0x4000 + +// PP_RxCTL - Receive Control bit definition - Read/write +#define RX_IA_HASH_ACCEPT 0x0040 +#define RX_PROM_ACCEPT 0x0080 +#define RX_OK_ACCEPT 0x0100 +#define RX_MULTCAST_ACCEPT 0x0200 +#define RX_IA_ACCEPT 0x0400 +#define RX_BROADCAST_ACCEPT 0x0800 +#define RX_BAD_CRC_ACCEPT 0x1000 +#define RX_RUNT_ACCEPT 0x2000 +#define RX_EXTRA_DATA_ACCEPT 0x4000 + +// PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write +#define TX_LOST_CRS_ENBL 0x0040 +#define TX_SQE_ERROR_ENBL 0x0080 +#define TX_OK_ENBL 0x0100 +#define TX_LATE_COL_ENBL 0x0200 +#define TX_JBR_ENBL 0x0400 +#define TX_ANY_COL_ENBL 0x0800 +#define TX_16_COL_ENBL 0x8000 + +// PP_TxCMD - Transmit Command bit definition - Read-only and +// PP_TxCommand - Write-only +#define TX_START_5_BYTES 0x0000 +#define TX_START_381_BYTES 0x0040 +#define TX_START_1021_BYTES 0x0080 +#define TX_START_ALL_BYTES 0x00C0 +#define TX_FORCE 0x0100 +#define TX_ONE_COL 0x0200 +#define TX_NO_CRC 0x1000 +#define TX_RUNT 0x2000 + +// PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write +#define GENERATE_SW_INTERRUPT 0x0040 +#define RX_DMA_ENBL 0x0080 +#define READY_FOR_TX_ENBL 0x0100 +#define TX_UNDERRUN_ENBL 0x0200 +#define RX_MISS_ENBL 0x0400 +#define RX_128_BYTE_ENBL 0x0800 +#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000 +#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000 +#define RX_DEST_MATCH_ENBL 0x8000 + +// PP_LineCTL - Line Control bit definition - Read/write +#define SERIAL_RX_ON 0x0040 +#define SERIAL_TX_ON 0x0080 +#define AUI_ONLY 0x0100 +#define AUTO_AUI_10BASET 0x0200 +#define MODIFIED_BACKOFF 0x0800 +#define NO_AUTO_POLARITY 0x1000 +#define TWO_PART_DEFDIS 0x2000 +#define LOW_RX_SQUELCH 0x4000 + +// PP_SelfCTL - Software Self Control bit definition - Read/write +#define POWER_ON_RESET 0x0040 +#define SW_STOP 0x0100 +#define SLEEP_ON 0x0200 +#define AUTO_WAKEUP 0x0400 +#define HCB0_ENBL 0x1000 +#define HCB1_ENBL 0x2000 +#define HCB0 0x4000 +#define HCB1 0x8000 + +// PP_BusCTL - ISA Bus Control bit definition - Read/write +#define RESET_RX_DMA 0x0040 +#define MEMORY_ON 0x0400 +#define DMA_BURST_MODE 0x0800 +#define IO_CHANNEL_READY_ON 0x1000 +#define RX_DMA_SIZE_64K 0x2000 +#define ENABLE_IRQ 0x8000 + +// PP_TestCTL - Test Control bit definition - Read/write +#define LINK_OFF 0x0080 +#define ENDEC_LOOPBACK 0x0200 +#define AUI_LOOPBACK 0x0400 +#define BACKOFF_OFF 0x0800 +#define FDX_8900 0x4000 + +// PP_RxEvent - Receive Event Bit definition - Read-only +#define RX_IA_HASHED 0x0040 +#define RX_DRIBBLE 0x0080 +#define RX_OK 0x0100 +#define RX_HASHED 0x0200 +#define RX_IA 0x0400 +#define RX_BROADCAST 0x0800 +#define RX_CRC_ERROR 0x1000 +#define RX_RUNT 0x2000 +#define RX_EXTRA_DATA 0x4000 +#define HASH_INDEX_MASK 0xFC00 // Hash-Table Index Mask (6 Bit) + +// PP_TxEvent - Transmit Event Bit definition - Read-only +#define TX_LOST_CRS 0x0040 +#define TX_SQE_ERROR 0x0080 +#define TX_OK 0x0100 +#define TX_LATE_COL 0x0200 +#define TX_JBR 0x0400 +#define TX_16_COL 0x8000 +#define TX_COL_COUNT_MASK 0x7800 + +// PP_BufEvent - Buffer Event Bit definition - Read-only +#define SW_INTERRUPT 0x0040 +#define RX_DMA 0x0080 +#define READY_FOR_TX 0x0100 +#define TX_UNDERRUN 0x0200 +#define RX_MISS 0x0400 +#define RX_128_BYTE 0x0800 +#define TX_COL_OVRFLW 0x1000 +#define RX_MISS_OVRFLW 0x2000 +#define RX_DEST_MATCH 0x8000 + +// PP_LineST - Ethernet Line Status bit definition - Read-only +#define LINK_OK 0x0080 +#define AUI_ON 0x0100 +#define TENBASET_ON 0x0200 +#define POLARITY_OK 0x1000 +#define CRS_OK 0x4000 + +// PP_SelfST - Chip Software Status bit definition +#define ACTIVE_33V 0x0040 +#define INIT_DONE 0x0080 +#define SI_BUSY 0x0100 +#define EEPROM_PRESENT 0x0200 +#define EEPROM_OK 0x0400 +#define EL_PRESENT 0x0800 +#define EE_SIZE_64 0x1000 + +// PP_BusST - ISA Bus Status bit definition +#define TX_BID_ERROR 0x0080 +#define READY_FOR_TX_NOW 0x0100 + +// The following block defines the ISQ event types +#define ISQ_RX_EVENT 0x0004 +#define ISQ_TX_EVENT 0x0008 +#define ISQ_BUFFER_EVENT 0x000C +#define ISQ_RX_MISS_EVENT 0x0010 +#define ISQ_TX_COL_EVENT 0x0012 + +#define ISQ_EVENT_MASK 0x003F // ISQ mask to find out type of event + +#define AUTOINCREMENT 0x8000 // Bit mask to set Bit-15 for autoincrement + +// EEProm Commands +#define EEPROM_WRITE_EN 0x00F0 +#define EEPROM_WRITE_DIS 0x0000 +#define EEPROM_WRITE_CMD 0x0100 +#define EEPROM_READ_CMD 0x0200 + +// Receive Header of each packet in receive area of memory for DMA-Mode +#define RBUF_EVENT_LOW 0x0000 // Low byte of RxEvent +#define RBUF_EVENT_HIGH 0x0001 // High byte of RxEvent +#define RBUF_LEN_LOW 0x0002 // Length of received data - low byte +#define RBUF_LEN_HI 0x0003 // Length of received data - high byte +#define RBUF_HEAD_LEN 0x0004 // Length of this header + +// typedefs + +// constants + +// prototypes + +#include "nic.h" + +unsigned int cs8900BeginPacketRetreive(void); +void cs8900RetreivePacketData(u08* packet, unsigned int packetLength); +void cs8900EndPacketRetreive(void); + + +void cs8900Init(void); +void cs8900Write(unsigned char address, unsigned char data); +unsigned char cs8900Read(unsigned char address); + +void cs8900Write16(unsigned char address, unsigned short data); +unsigned short cs8900Read16(unsigned char address); + +void cs8900WriteReg(unsigned short address, unsigned short data); +unsigned short cs8900ReadReg(unsigned short address); + +void cs8900CopyToFrame(unsigned char *source, unsigned short size); +void cs8900CopyFromFrame(unsigned char *dest, unsigned short size); + +u08 cs8900LinkStatus(void); + +void cs8900IORegDump(void); +void cs8900RegDump(void); + +#endif +//@} + + +/**************** + +// CS8900 device register definitions + +// Crystal ESIA product id. + +#define CS8900_ESIA_ID (0x630e) + +//IO Registers. +#define CS8900_IO_RX_TX_DATA_PORT0 (0x0000) +#define CS8900_IO_TX_TX_DATA_PORT1 (0x0002) +#define CS8900_IO_TxCMD (0x0004) +#define CS8900_IO_TxLength (0x0006) +#define CS8900_IO_ISQ (0x0008) +#define CS8900_IO_PACKET_PAGE_PTR (0x000a) +#define CS8900_IO_PP_DATA_PORT0 (0x000c) +#define CS8900_IO_PP_DATA_PORT1 (0x000e) + + * Packet Page Registers. + + * Bus Interface Registers. + +#define CS8900_PP_PROD_ID (0x0000) +#define CS8900_PP_IO_BASE (0x0020) +#define CS8900_PP_INT (0x0022) +#define CS8900_PP_DMA_CHANNEL (0x0024) +#define CS8900_PP_DMA_SOF (0x0026) +#define CS8900_PP_DMA_FRM_CNT (0x0028) +#define CS8900_PP_DMA_RX_BCNT (0x002a) +#define CS8900_PP_MEM_BASE (0x002c) +#define CS8900_PP_BPROM_BASE (0x0030) +#define CS8900_PP_BPROM_AMASK (0x0034) +#define CS8900_PP_EEPROM_CMD (0x0040) +#define CS8900_PP_EEPROM_DATA (0x0042) +#define CS8900_PP_RX_FRAME_BCNT (0x0050) + + * Configuration and Control Registers. + +#define CS8900_PP_RxCFG (0x0102) +#define CS8900_PP_RxCTL (0x0104) +#define CS8900_PP_TxCFG (0x0106) +#define CS8900_PP_TxCMD_READ (0x0108) +#define CS8900_PP_BufCFG (0x010a) +#define CS8900_PP_LineCFG (0x0112) +#define CS8900_PP_SelfCTL (0x0114) +#define CS8900_PP_BusCTL (0x0116) +#define CS8900_PP_TestCTL (0x0118) + + * Status and Event Registers. + +#define CS8900_PP_ISQ (0x0120) +#define CS8900_PP_RxEvent (0x0124) +#define CS8900_PP_TxEvent (0x0128) +#define CS8900_PP_BufEvent (0x012c) +#define CS8900_PP_RxMISS (0x0130) +#define CS8900_PP_TxCol (0x0132) +#define CS8900_PP_LineST (0x0134) +#define CS8900_PP_SelfST (0x0136) +#define CS8900_PP_BusST (0x0138) +#define CS8900_PP_TDR (0x013c) + + * Initiate Transmit Registers. +#define CS8900_PP_TxCMD (0x0144) +#define CS8900_PP_TxLength (0x0146) + +* Address Filter Registers. +#define CS8900_PP_LAF (0x0150) +#define CS8900_PP_IA (0x0158) + + * Frame Location. +#define CS8900_PP_RxStatus (0x0400) +#define CS8900_PP_RxLength (0x0402) +#define CS8900_PP_RxFrameLoc (0x0404) +#define CS8900_PP_TxFrameLoc (0x0a00) + + * Bit Definitions of Registers. + * IO Packet Page Pointer. +#define CS8900_PPP_AUTO_INCREMENT (0x8000) + + * Reg 3. Receiver Configuration. +#define CS8900_RX_CONFIG_SKIP_1 (1 << 6) +#define CS8900_RX_CONFIG_STREAM_ENABLE (1 << 7) +#define CS8900_RX_CONFIG_RX_OK (1 << 8) +#define CS8900_RX_CONFIG_RX_DMA (1 << 9) +#define CS8900_RX_CONFIG_RX_AUTO_DMA (1 << 10) +#define CS8900_RX_CONFIG_BUFFER_CRC (1 << 11) +#define CS8900_RX_CONFIG_CRC_ERROR (1 << 12) +#define CS8900_RX_CONFIG_RUNT (1 << 13) +#define CS8900_RX_CONFIG_EXTRA_DATA (1 << 14) + + * Reg 4. Receiver Event. +#define CS8900_RX_EVENT_HASH_IA_MATCH (1 << 6) +#define CS8900_RX_EVENT_DRIBBLE_BITS (1 << 7) +#define CS8900_RX_EVENT_RX_OK (1 << 8) +#define CS8900_RX_EVENT_HASHED (1 << 9) +#define CS8900_RX_EVENT_IA (1 << 10) +#define CS8900_RX_EVENT_BROADCAST (1 << 11) +#define CS8900_RX_EVENT_CRC_ERROR (1 << 12) +#define CS8900_RX_EVENT_RUNT (1 << 13) +#define CS8900_RX_EVENT_EXTRA_DATA (1 << 14) + + * Reg 5. Receiver Control. +#define CS8900_RX_CTRL_HASH_IA_MATCH (1 << 6) +#define CS8900_RX_CTRL_PROMISCUOUS (1 << 7) +#define CS8900_RX_CTRL_RX_OK (1 << 8) +#define CS8900_RX_CTRL_MULTICAST (1 << 9) +#define CS8900_RX_CTRL_INDIVIDUAL (1 << 10) +#define CS8900_RX_CTRL_BROADCAST (1 << 11) +#define CS8900_RX_CTRL_CRC_ERROR (1 << 12) +#define CS8900_RX_CTRL_RUNT (1 << 13) +#define CS8900_RX_CTRL_EXTRA_DATA (1 << 14) + + * Reg 7. Transmit Configuration. +#define CS8900_TX_CONFIG_LOSS_OF_CARRIER (1 << 6) +#define CS8900_TX_CONFIG_SQ_ERROR (1 << 7) +#define CS8900_TX_CONFIG_TX_OK (1 << 8) +#define CS8900_TX_CONFIG_OUT_OF_WINDOW (1 << 9) +#define CS8900_TX_CONFIG_JABBER (1 << 10) +#define CS8900_TX_CONFIG_ANY_COLLISION (1 << 11) +#define CS8900_TX_CONFIG_16_COLLISION (1 << 15) + + * Reg 8. Transmit Event. +#define CS8900_TX_EVENT_LOSS_OF_CARRIER (1 << 6) +#define CS8900_TX_EVENT_SQ_ERROR (1 << 7) +#define CS8900_TX_EVENT_TX_OK (1 << 8) +#define CS8900_TX_EVENT_OUT_OF_WINDOW (1 << 9) +#define CS8900_TX_EVENT_JABBER (1 << 10) +#define CS8900_TX_EVENT_16_COLLISIONS (1 << 15) + + * Reg 9. Transmit Command Status. +#define CS8900_TX_CMD_STATUS_TX_START_5 (0 << 6) +#define CS8900_TX_CMD_STATUS_TX_START_381 (1 << 6) +#define CS8900_TX_CMD_STATUS_TX_START_1021 (2 << 6) +#define CS8900_TX_CMD_STATUS_TX_START_ENTIRE (3 << 6) +#define CS8900_TX_CMD_STATUS_FORCE (1 << 8) +#define CS8900_TX_CMD_STATUS_ONE_COLLISION (1 << 9) +#define CS8900_TX_CMD_STATUS_INHIBIT_CRC (1 << 12) +#define CS8900_TX_CMD_STATUS_TX_PAD_DISABLED (1 << 13) + + * Reg B. Buffer Configuration. +#define CS8900_BUFFER_CONFIG_SW_INT (1 << 6) +#define CS8900_BUFFER_CONFIG_RX_DMA_DONE (1 << 7) +#define CS8900_BUFFER_CONFIG_RDY_FOR_TX (1 << 8) +#define CS8900_BUFFER_CONFIG_TX_UNDERRUN (1 << 9) +#define CS8900_BUFFER_CONFIG_RX_MISSED (1 << 10) +#define CS8900_BUFFER_CONFIG_RX_128_BYTES (1 << 11) +#define CS8900_BUFFER_CONFIG_TX_COL_OVF (1 << 12) +#define CS8900_BUFFER_CONFIG_RX_MISSED_OVF (1 << 13) +#define CS8900_BUFFER_CONFIG_RX_DEST_MATCH (1 << 15) + + * Reg C. Buffer Event. +#define CS8900_BUFFER_EVENT_SW_INT (1 << 6) +#define CS8900_BUFFER_EVENT_RX_DMA_DONE (1 << 7) +#define CS8900_BUFFER_EVENT_RDY_FOR_TX (1 << 8) +#define CS8900_BUFFER_EVENT_TX_UNDERRUN (1 << 9) +#define CS8900_BUFFER_EVENT_RX_MISSED (1 << 10) +#define CS8900_BUFFER_EVENT_RX_128_BYTES (1 << 11) +#define CS8900_BUFFER_EVENT_RX_DEST_MATCH (1 << 15) + + * Reg 13. Line Control. +#define CS8900_LINE_CTRL_RX_ON (1 << 6) +#define CS8900_LINE_CTRL_TX_ON (1 << 7) +#define CS8900_LINE_CTRL_AUI (1 << 8) +#define CS8900_LINE_CTRL_10BASET (0 << 9) +#define CS8900_LINE_CTRL_AUTO_AUI_10BASET (1 << 9) +#define CS8900_LINE_CTRL_MOD_BACKOFF (1 << 11) +#define CS8900_LINE_CTRL_POLARITY_DISABLED (1 << 12) +#define CS8900_LINE_CTRL_2_PART_DEF_DISABLED (1 << 13) +#define CS8900_LINE_CTRL_LO_RX_SQUELCH (1 << 14) + + * Reg 14. Line Status. +#define CS8900_LINE_STATUS_LINK_OK (1 << 7) +#define CS8900_LINE_STATUS_AUI (1 << 8) +#define CS8900_LINE_STATUS_10_BASE_T (1 << 9) +#define CS8900_LINE_STATUS_POLARITY_OK (1 << 12) +#define CS8900_LINE_STATUS_CRS (1 << 14) + + * Reg 15. Self Control. +#define CS8900_SELF_CTRL_RESET (1 << 6) +#define CS8900_SELF_CTRL_SW_SUSPEND (1 << 8) +#define CS8900_SELF_CTRL_HW_SLEEP (1 << 9) +#define CS8900_SELF_CTRL_HW_STANDBY (1 << 10) +#define CS8900_SELF_CTRL_HC0E (1 << 12) +#define CS8900_SELF_CTRL_HC1E (1 << 13) +#define CS8900_SELF_CTRL_HCB0 (1 << 14) +#define CS8900_SELF_CTRL_HCB1 (1 << 15) + + * Reg 16. Self Status. +#define CS8900_SELF_STATUS_3_3_V (1 << 6) +#define CS8900_SELF_STATUS_INITD (1 << 7) +#define CS8900_SELF_STATUS_SIBUST (1 << 8) +#define CS8900_SELF_STATUS_EEPROM_PRESENT (1 << 9) +#define CS8900_SELF_STATUS_EEPROM_OK (1 << 10) +#define CS8900_SELF_STATUS_EL_PRESENT (1 << 11) +#define CS8900_SELF_STATUS_EE_SIZE (1 << 12) + + * Reg 17. Bus Control. +#define CS8900_BUS_CTRL_RESET_RX_DMA (1 << 6) +#define CS8900_BUS_CTRL_USE_SA (1 << 9) +#define CS8900_BUS_CTRL_MEMORY_ENABLE (1 << 10) +#define CS8900_BUS_CTRL_DMA_BURST (1 << 11) +#define CS8900_BUS_CTRL_IOCHRDYE (1 << 12) +#define CS8900_BUS_CTRL_RX_DMA_SIZE (1 << 13) +#define CS8900_BUS_CTRL_ENABLE_INT (1 << 15) + + * Reg 18. Bus Status. +#define CS8900_BUS_STATUS_TX_BID_ERROR (1 << 7) +#define CS8900_BUS_STATUS_RDY_FOR_TX_NOW (1 << 8) + +*/ diff --git a/3rd party/Procyuon avrlib/net/dhcp.c b/3rd party/Procyuon avrlib/net/dhcp.c new file mode 100644 index 0000000..b3dd774 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/dhcp.c @@ -0,0 +1,300 @@ +/*! \file dhcp.c \brief DHCP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'dhcp.c' +// Title : DHCP Protocol Library +// Author : Pascal Stang +// Created : 9/17/2005 +// Revised : 9/17/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "global.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "netstack.h" + +#include "dhcp.h" + +#include "rprintf.h" + +// global variables +uint32_t DhcpServerIP; ///< IP address of the DHCP server that offered lease +uint32_t DhcpTransactID; ///< Unique transaction ID that identifies DHCP request/replies +uint32_t DhcpLeaseTime; ///< Number of seconds left in DHCP lease + +void dhcpInit(void) +{ + uint8_t macaddr[6]; + + // get interface mac address + nicGetMacAddress(macaddr); + // set transaction ID based on mac address + DhcpTransactID = *((uint32_t*)&macaddr); + // reset lease time + DhcpLeaseTime = 0; +} + +void dhcpIn(unsigned int len, struct netDhcpHeader* packet) +{ + uint8_t msgtype; + uint32_t sid; + uint8_t* optptr; + uint32_t val; + uint32_t netmask; + uint32_t gateway; + + #if NET_DEBUG >= 3 + dhcpPrintHeader(packet); + #endif + + // check that this is a reply, and for me + if((packet->bootp.op != BOOTP_OP_BOOTREPLY) || (packet->bootp.xid != DhcpTransactID)) + return; + + // process incoming packet + // check reply type + dhcpGetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &msgtype); + #if NET_DEBUG >= 2 + rprintf("DHCP: Received msgtype = %d\r\n", msgtype); + #endif + + if(msgtype == DHCP_MSG_DHCPOFFER) + { + // get DHCP server ID + dhcpGetOption(packet->options, DHCP_OPT_SERVERID, 4, &sid); + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Got offer from server "); netPrintIPAddr(htonl(sid)); rprintfCRLF(); + #endif + + // build DHCP request (on top of this reply) + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + // set operation + val = DHCP_MSG_DHCPREQUEST; + optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + // set the server ID + optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &sid); + // request the IP previously offered + optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.yiaddr); + // request additional information + ((uint8_t*)&val)[0] = DHCP_OPT_NETMASK; + ((uint8_t*)&val)[1] = DHCP_OPT_ROUTERS; + ((uint8_t*)&val)[2] = DHCP_OPT_DNSSERVERS; + ((uint8_t*)&val)[3] = DHCP_OPT_DOMAINNAME; + optptr = dhcpSetOption(optptr, DHCP_OPT_PARAMREQLIST, 4, &val); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending request in response to offer\r\n"); + #endif + // send DHCP request + DhcpServerIP = htonl(sid); + udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+6+6+6+1, (uint8_t*)packet); + + } + else if(msgtype == DHCP_MSG_DHCPACK) + { + // get netmask + dhcpGetOption(packet->options, DHCP_OPT_NETMASK, 4, &val); + netmask = htonl(val); + // get gateway + dhcpGetOption(packet->options, DHCP_OPT_ROUTERS, 4, &val); + gateway = htonl(val); + // get gateway + dhcpGetOption(packet->options, DHCP_OPT_LEASETIME, 4, &val); + DhcpLeaseTime = htonl(val); + + // assign new network info + ipSetConfig(htonl(packet->bootp.yiaddr), netmask, gateway); + + #ifdef DHCP_DEBUG + rprintf("DHCP: Got request ACK, bind complete\r\n"); + //debugPrintHexTable(len-DHCP_HEADER_LEN, (packet->options)); + // print info + ipPrintConfig(ipGetConfig()); + rprintfProgStrM("LeaseTm : "); rprintfNum(10,8,FALSE,' ',DhcpLeaseTime); rprintfCRLF(); + #endif + } +} + +void dhcpRequest(void) +{ + struct netDhcpHeader* packet; + uint32_t val; + + packet = (struct netDhcpHeader*)&netstackGetBuffer()[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]; + + // build BOOTP/DHCP header + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + packet->bootp.htype = BOOTP_HTYPE_ETHERNET; + packet->bootp.hlen = BOOTP_HLEN_ETHERNET; + packet->bootp.ciaddr = htonl(ipGetConfig()->ip); + packet->bootp.yiaddr = HTONL(0l); + packet->bootp.siaddr = HTONL(0l); + packet->bootp.giaddr = HTONL(0l); + nicGetMacAddress(&packet->bootp.chaddr[0]); // fill client hardware address + packet->bootp.xid = DhcpTransactID; + packet->bootp.flags = HTONS(1); + + // build DHCP request + // begin with magic cookie + packet->cookie = 0x63538263; + // set operation + val = DHCP_MSG_DHCPDISCOVER; + dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending Query\r\n"); + //dhcpPrintHeader(packet); + #endif + + // send request + udpSend(0xFFFFFFFF, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+1, (uint8_t*)packet); +} + +void dhcpRelease(void) +{ + struct netDhcpHeader* packet; + uint32_t val; + uint8_t* optptr; + + packet = (struct netDhcpHeader*)&netstackGetBuffer()[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]; + + // build BOOTP/DHCP header + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + packet->bootp.htype = BOOTP_HTYPE_ETHERNET; + packet->bootp.hlen = BOOTP_HLEN_ETHERNET; + packet->bootp.ciaddr = htonl(ipGetConfig()->ip); + packet->bootp.yiaddr = HTONL(0l); + packet->bootp.siaddr = HTONL(0l); + packet->bootp.giaddr = HTONL(0l); + nicGetMacAddress(&packet->bootp.chaddr[0]); // fill client hardware address + packet->bootp.xid = DhcpTransactID; // set trans ID (use part of MAC address) + packet->bootp.flags = HTONS(1); + + // build DHCP request + // begin with magic cookie + packet->cookie = 0x63538263; + // set operation + val = DHCP_MSG_DHCPRELEASE; + optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + // set the server ID + val = htonl(DhcpServerIP); + optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &val); + // request the IP previously offered + optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.ciaddr); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending Release to "); netPrintIPAddr(DhcpServerIP); rprintfCRLF(); + //dhcpPrintHeader(packet); + #endif + + // send release + udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+6+6+1, (uint8_t*)packet); + + // deconfigure ip addressing + ipSetConfig(0,0,0); + DhcpLeaseTime = 0; +} + +void dhcpTimer(void) +{ + // this function to be called once per second + + // decrement lease time + if(DhcpLeaseTime) + DhcpLeaseTime--; +} + +uint8_t dhcpGetOption(uint8_t* options, uint8_t optcode, uint8_t optlen, void* optvalptr) +{ + uint8_t i; + + // parse for desired option + for (;;) + { + // skip pad characters + if(*options == DHCP_OPT_PAD) + options++; + // break if end reached + else if(*options == DHCP_OPT_END) + break; + // check for desired option + else if(*options == optcode) + { + // found desired option + // limit size to actual option length + optlen = MIN(optlen, *(options+1)); + //if(*(options+1) < optlen) + // optlen = *(options+1); + + // copy contents of option + for(i=0; ibootp.op) + { + case BOOTP_OP_BOOTREQUEST: rprintfProgStrM("BOOTREQUEST"); break; + case BOOTP_OP_BOOTREPLY: rprintfProgStrM("BOOTREPLY"); break; + default: rprintfProgStrM("UNKNOWN"); break; + } + rprintfCRLF(); + // print transaction ID + rprintfProgStrM("XID : 0x"); rprintfu32(packet->bootp.xid); rprintfCRLF(); + // print client IP address + rprintfProgStrM("ClIpAddr: "); netPrintIPAddr(htonl(packet->bootp.ciaddr)); rprintfCRLF(); + // print 'your' IP address + rprintfProgStrM("YrIpAddr: "); netPrintIPAddr(htonl(packet->bootp.yiaddr)); rprintfCRLF(); + // print server IP address + rprintfProgStrM("SvIpAddr: "); netPrintIPAddr(htonl(packet->bootp.siaddr)); rprintfCRLF(); + // print gateway IP address + rprintfProgStrM("GwIpAddr: "); netPrintIPAddr(htonl(packet->bootp.giaddr)); rprintfCRLF(); + // print client hardware address + rprintfProgStrM("ClHwAddr: "); netPrintEthAddr((struct netEthAddr*)packet->bootp.chaddr); rprintfCRLF(); +} +#endif diff --git a/3rd party/Procyuon avrlib/net/dhcp.h b/3rd party/Procyuon avrlib/net/dhcp.h new file mode 100644 index 0000000..dfa344d --- /dev/null +++ b/3rd party/Procyuon avrlib/net/dhcp.h @@ -0,0 +1,156 @@ +/*! \file dhcp.h \brief DHCP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'dhcp.h' +// Title : DHCP Protocol Library +// Author : Pascal Stang +// Created : 9/17/2005 +// Revised : 9/17/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup dhcp DHCP Protocol Library (dhcp.c) +/// \code #include "net/dhcp.h" \endcode +/// \par Description +/// This library provides a limited implementation of DHCP (Dynamic Host +/// Configuration Protocol) as described in RFC2131. DHCP allows a +/// network device to automatically obtain an IP address and other network +/// configuration settings from a DHCP server. +/// +/// \note This code is currently below version 1.0, and therefore is considered +/// to be lacking in some functionality or documentation, or may not be fully +/// tested. Nonetheless, you can expect most functions to work. +/// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef DHCP_H +#define DHCP_H + +#include "global.h" +#include "net.h" + +//#define DHCP_DEBUG_PRINT +//#define DHCP_DEBUG + +/// Bootp Header (DHCP is transported by BOOTP/UDP/IP) +struct netBootpHeader +{ + uint8_t op; ///< Message op-code / message type + uint8_t htype; ///< Hardware address type (Ethernet=1) + uint8_t hlen; ///< Hardware address length (Ethernet=6 byte MAC addr) + uint8_t hops; ///< hop count (client set to zero) + uint32_t xid; ///< Transaction ID (randomly chosen by client, must remain same) + uint16_t secs; ///< Seconds elapsed since DHCP negotiation began (filled by client) + uint16_t flags; ///< Flags + uint32_t ciaddr; ///< Client IP address (filled only if already bound, renewing, or rebinding) + uint32_t yiaddr; ///< 'Your' IP address (client) + uint32_t siaddr; ///< Server IP address + uint32_t giaddr; ///< Gateway IP address + uint8_t chaddr[16]; ///< Client Hardware Address + uint8_t sname[64]; ///< Server Host Name + uint8_t file[128]; ///< Boot file name (null-term string) +} GNUC_PACKED; + +#define BOOTP_HEADER_LEN 236 ///< length of BOOTP header not including options + +#define BOOTP_OP_BOOTREQUEST 1 ///< BOOTP Request operation (message from client to server) +#define BOOTP_OP_BOOTREPLY 2 ///< BOOTP Reply operation (message from server to client) + +#define BOOTP_HTYPE_ETHERNET 1 +#define BOOTP_HLEN_ETHERNET 6 + +/// DHCP Header +struct netDhcpHeader +{ + struct netBootpHeader bootp; ///< BOOTP header + uint32_t cookie; ///< magic cookie value + uint8_t options[]; ///< DHCP options +} GNUC_PACKED; + +#define DHCP_HEADER_LEN 240 ///< length of DHCP header not including options + +#define DHCP_UDP_SERVER_PORT 67 ///< UDP port where DHCP requests should be sent +#define DHCP_UDP_CLIENT_PORT 68 ///< UDP port clients will receive DHCP replies + + +#define DHCP_OPT_PAD 0 ///< token padding value (make be skipped) +#define DHCP_OPT_NETMASK 1 ///< subnet mask client should use (4 byte mask) +#define DHCP_OPT_ROUTERS 3 ///< routers client should use (IP addr list) +#define DHCP_OPT_TIMESERVERS 4 ///< time servers client should use (IP addr list) +#define DHCP_OPT_NAMESERVERS 5 ///< name servers client should use (IP addr list) +#define DHCP_OPT_DNSSERVERS 6 ///< DNS servers client should use (IP addr list) +#define DHCP_OPT_HOSTNAME 12 ///< host name client should use (string) +#define DHCP_OPT_DOMAINNAME 15 ///< domain name client should use (string) +#define DHCP_OPT_REQUESTEDIP 50 ///< IP address requested by client (IP address) +#define DHCP_OPT_LEASETIME 51 ///< DHCP Lease Time (uint32 seconds) +#define DHCP_OPT_DHCPMSGTYPE 53 ///< DHCP message type (1 byte) +#define DHCP_OPT_SERVERID 54 ///< Server Identifier (IP address) +#define DHCP_OPT_PARAMREQLIST 55 ///< Paramerter Request List (n OPT codes) +#define DHCP_OPT_RENEWALTIME 58 ///< DHCP Lease Renewal Time (uint32 seconds) +#define DHCP_OPT_REBINDTIME 59 ///< DHCP Lease Rebinding Time (uint32 seconds) +#define DHCP_OPT_END 255 ///< token end value (marks end of options list) + +#define DHCP_MSG_DHCPDISCOVER 1 ///< DISCOVER is broadcast by client to solicit OFFER from any/all DHCP servers. +#define DHCP_MSG_DHCPOFFER 2 ///< OFFER(s) are made to client by server to offer IP address and config info. +#define DHCP_MSG_DHCPREQUEST 3 ///< REQUEST is made my client in response to best/favorite OFFER message. +#define DHCP_MSG_DHCPDECLINE 4 ///< DECLINE may be sent by client to server to indicate IP already in use. +#define DHCP_MSG_DHCPACK 5 ///< ACK is sent to client by server in confirmation of REQUEST, contains config and IP. +#define DHCP_MSG_DHCPNAK 6 ///< NAK is sent to client by server to indicate problem with REQUEST. +#define DHCP_MSG_DHCPRELEASE 7 ///< RELEASE is sent by client to server to relinquish DHCP lease on IP address, etc. +#define DHCP_MSG_DHCPINFORM 8 ///< INFORM is sent by client to server to request config info, IP address configured locally. + + +/*! Initialize DHCP system. + Prepares DHCP for use and initializes lease time to zero. */ +void dhcpInit(void); + +/*! Processes incoming DHCP packets from UDP port 68. + This function is to be called by the stack when a DHCP packet + arrives over the network. The DHCP packet will be parsed, handled, + and a response will be generated and sent if needed. When the DHCP + process completes, the IP addressing will be automatically updated. */ +void dhcpIn(unsigned int len, struct netDhcpHeader* packet); + +/*! Request DHCP assigned network parameters. + This function begins the DHCP process. The remainder of operations + are handled in dhcpIn(). */ +void dhcpRequest(void); + +/*! Release DHCP lease and assigned network parameters. + This function releases the DHCP assigned address and allows the + DHCP server to reallocate it. */ +void dhcpRelease(void); + +/*! Periodic DHCP maintenance. + This function is to be called once per second and will + expire the DHCP lease. */ +void dhcpTimer(void); + +/*! Get a DHCP option from the option list. + \param options is a pointer to the options field of a DHCP packet. + \param optcode is the desired option number to retrieve. + \param optlen is the maximum data length that should be retrieved (less data will be retrieved if option is shorter). + \param optvalptr is a pointer to where the option value will be stored. + \return actual length of the option data, as stored in the options list. */ +uint8_t dhcpGetOption(uint8_t* options, uint8_t optcode, uint8_t optlen, void* optvalptr); + +/*! Set a DHCP option in the option list. + \param options is a pointer to the options field of a DHCP packet. + \param optcode is the option number to write. + \param optlen is the data length of the option value. + \param optvalptr is a pointer to the option data to be read. + \return pointer to write location of the next option. */ +uint8_t* dhcpSetOption(uint8_t* options, uint8_t optcode, uint8_t optlen, void* optvalptr); + +/*! Print diagnotic information about BOOTP/DHCP packet. +*/ +void dhcpPrintHeader(struct netDhcpHeader* packet); + +#endif +//@} + diff --git a/3rd party/Procyuon avrlib/net/enc28j60.c b/3rd party/Procyuon avrlib/net/enc28j60.c new file mode 100644 index 0000000..cd14cb1 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/enc28j60.c @@ -0,0 +1,545 @@ +/*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'enc28j60.c' +// Title : Microchip ENC28J60 Ethernet Interface Driver +// Author : Pascal Stang (c)2005 +// Created : 9/22/2005 +// Revised : 9/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. +// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin +// chip, using an SPI interface to the host processor. +// +//***************************************************************************** + +#include "avr/io.h" + +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "enc28j60.h" + +#ifdef SPDR0 + #define SPDR SPDR0 + #define SPCR SPCR0 + #define SPSR SPSR0 + + #define SPIF SPIF0 + #define MSTR MSTR0 + #define CPOL CPOL0 + #define DORD DORD0 + #define SPR0 SPR00 + #define SPR1 SPR01 + #define SPI2X SPI2X0 + #define SPE SPE0 +#endif + +// include configuration +#include "enc28j60conf.h" + +u08 Enc28j60Bank; +u16 NextPacketPtr; + +void nicInit(void) +{ + enc28j60Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + enc28j60PacketSend(len, packet); +} + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + return enc28j60PacketReceive(maxlen, packet); +} + +void nicGetMacAddress(u08* macaddr) +{ + // read MAC address registers + // NOTE: MAC address in ENC28J60 is byte-backward + *macaddr++ = enc28j60Read(MAADR5); + *macaddr++ = enc28j60Read(MAADR4); + *macaddr++ = enc28j60Read(MAADR3); + *macaddr++ = enc28j60Read(MAADR2); + *macaddr++ = enc28j60Read(MAADR1); + *macaddr++ = enc28j60Read(MAADR0); +} + +void nicSetMacAddress(u08* macaddr) +{ + // write MAC address + // NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, *macaddr++); + enc28j60Write(MAADR4, *macaddr++); + enc28j60Write(MAADR3, *macaddr++); + enc28j60Write(MAADR2, *macaddr++); + enc28j60Write(MAADR1, *macaddr++); + enc28j60Write(MAADR0, *macaddr++); +} + +void nicRegDump(void) +{ + enc28j60RegDump(); +} + +/* +void ax88796SetupPorts(void) +{ +#if NIC_CONNECTION == MEMORY_MAPPED + // enable external SRAM interface - no wait states + sbi(MCUCR, SRE); +// sbi(MCUCR, SRW10); +// sbi(XMCRA, SRW00); +// sbi(XMCRA, SRW01); +// sbi(XMCRA, SRW11); +#else + // set address port to output + AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK; + + // set data port to input with pull-ups + AX88796_DATA_DDR = 0x00; + AX88796_DATA_PORT = 0xFF; + + // initialize the control port read and write pins to de-asserted + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN ); + // set the read and write pins to output + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN ); + sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN ); +#endif + // set reset pin to output + sbi( AX88796_RESET_DDR, AX88796_RESET_PIN ); +} +*/ + +u08 enc28j60ReadOp(u08 op, u08 address) +{ + u08 data; + + // assert CS + ENC28J60_CONTROL_PORT &= ~(1<>5); + Enc28j60Bank = (address & BANK_MASK); + } +} + +u08 enc28j60Read(u08 address) +{ + // set the bank + enc28j60SetBank(address); + // do the read + return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); +} + +void enc28j60Write(u08 address, u08 data) +{ + // set the bank + enc28j60SetBank(address); + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +} + +u16 enc28j60PhyRead(u08 address) +{ + u16 data; + + // Set the right address and start the register read operation + enc28j60Write(MIREGADR, address); + enc28j60Write(MICMD, MICMD_MIIRD); + + // wait until the PHY read completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY); + + // quit reading + enc28j60Write(MICMD, 0x00); + + // get data value + data = enc28j60Read(MIRDL); + data |= enc28j60Read(MIRDH); + // return the data + return data; +} + +void enc28j60PhyWrite(u08 address, u16 data) +{ + // set the PHY register address + enc28j60Write(MIREGADR, address); + + // write the PHY data + enc28j60Write(MIWRL, data); + enc28j60Write(MIWRH, data>>8); + + // wait until the PHY write completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY); +} + +void enc28j60Init(void) +{ + // initialize I/O + sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS); + sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); + + // setup SPI I/O pins + sbi(ENC28J60_SPI_PORT, ENC28J60_SPI_SCK); // set SCK hi + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SCK); // set SCK as output + cbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MISO); // set MISO as input + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MOSI); // set MOSI as output + sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SS); // SS must be output for Master mode to work + // initialize SPI interface + // master mode + sbi(SPCR, MSTR); + // select clock phase positive-going in middle of data + cbi(SPCR, CPOL); + // Data order MSB first + cbi(SPCR,DORD); + // switch to f/4 2X = f/2 bitrate + cbi(SPCR, SPR0); + cbi(SPCR, SPR1); + sbi(SPSR, SPI2X); + // enable SPI + sbi(SPCR, SPE); + + // perform system reset + enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); + // check CLKRDY bit to see if reset is complete + delay_us(50); + while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); + + // do bank 0 stuff + // initialize receive buffer + // 16-bit transfers, must write low byte first + // set receive buffer start address + NextPacketPtr = RXSTART_INIT; + enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXSTH, RXSTART_INIT>>8); + // set receive pointer address + enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + // set receive buffer end + // ERXND defaults to 0x1FFF (end of ram) + enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + // set transmit buffer start + // ETXST defaults to 0x0000 (beginnging of ram) + enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + enc28j60Write(ETXSTH, TXSTART_INIT>>8); + + // do bank 2 stuff + // enable MAC receive + enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + // bring MAC out of reset + enc28j60Write(MACON2, 0x00); + // enable automatic padding and CRC operations + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); +// enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + // set inter-frame gap (non-back-to-back) + enc28j60Write(MAIPGL, 0x12); + enc28j60Write(MAIPGH, 0x0C); + // set inter-frame gap (back-to-back) + enc28j60Write(MABBIPG, 0x12); + // Set the maximum packet size which the controller will accept + enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + + // do bank 3 stuff + // write MAC address + // NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, ENC28J60_MAC0); + enc28j60Write(MAADR4, ENC28J60_MAC1); + enc28j60Write(MAADR3, ENC28J60_MAC2); + enc28j60Write(MAADR2, ENC28J60_MAC3); + enc28j60Write(MAADR1, ENC28J60_MAC4); + enc28j60Write(MAADR0, ENC28J60_MAC5); + + // no loopback of transmitted frames + enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + + // switch to bank 0 + enc28j60SetBank(ECON1); + // enable interrutps + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + // enable packet reception + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +/* + enc28j60PhyWrite(PHLCON, 0x0AA2); + + // setup duplex ---------------------- + + // Disable receive logic and abort any packets currently being transmitted + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN); + + { + u16 temp; + // Set the PHY to the proper duplex mode + temp = enc28j60PhyRead(PHCON1); + temp &= ~PHCON1_PDPXMD; + enc28j60PhyWrite(PHCON1, temp); + // Set the MAC to the proper duplex mode + temp = enc28j60Read(MACON3); + temp &= ~MACON3_FULDPX; + enc28j60Write(MACON3, temp); + } + + // Set the back-to-back inter-packet gap time to IEEE specified + // requirements. The meaning of the MABBIPG value changes with the duplex + // state, so it must be updated in this function. + // In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex + //enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12); + + // Reenable receive logic + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); + + // setup duplex ---------------------- +*/ +} + +void enc28j60PacketSend(unsigned int len, unsigned char* packet) +{ + // Set the write pointer to start of transmit buffer area + enc28j60Write(EWRPTL, TXSTART_INIT); + enc28j60Write(EWRPTH, TXSTART_INIT>>8); + // Set the TXND pointer to correspond to the packet size given + enc28j60Write(ETXNDL, (TXSTART_INIT+len)); + enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + + // write per-packet control byte + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, packet); + + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); +} + +unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet) +{ + u16 rxstat; + u16 len; + + // check if a packet has been received and buffered +// if( !(enc28j60Read(EIR) & EIR_PKTIF) ) + if( !enc28j60Read(EPKTCNT) ) + return 0; + + // Make absolutely certain that any previous packet was discarded + //if( WasDiscarded == FALSE) + // MACDiscardRx(); + + // Set the read pointer to the start of the received packet + enc28j60Write(ERDPTL, (NextPacketPtr)); + enc28j60Write(ERDPTH, (NextPacketPtr)>>8); + // read the next packet pointer + NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the packet length + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the receive status + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + + // limit retrieve length + // (we reduce the MAC-reported length by 4 to remove the CRC) + len = MIN(len, maxlen); + + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, packet); + + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out + enc28j60Write(ERXRDPTL, (NextPacketPtr)); + enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8); + + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + + return len; +} + +void enc28j60ReceiveOverflowRecover(void) +{ + // receive buffer overflow handling procedure + + // recovery completed +} + +void enc28j60RegDump(void) +{ +// unsigned char macaddr[6]; +// result = ax88796Read(TR); + +// rprintf("Media State: "); +// if(!(result & AUTOD)) +// rprintf("Autonegotiation\r\n"); +// else if(result & RST_B) +// rprintf("PHY in Reset \r\n"); +// else if(!(result & RST_10B)) +// rprintf("10BASE-T \r\n"); +// else if(!(result & RST_TXB)) +// rprintf("100BASE-T \r\n"); + + rprintf("RevID: 0x%x\r\n", enc28j60Read(EREVID)); + + rprintfProgStrM("Cntrl: ECON1 ECON2 ESTAT EIR EIE\r\n"); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ECON1)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ECON2)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(ESTAT)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(EIR)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(EIE)); + rprintfCRLF(); + + rprintfProgStrM("MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON1)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON2)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON3)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACON4)); + rprintfProgStrM(" "); + rprintfu08(enc28j60Read(MAADR5)); + rprintfu08(enc28j60Read(MAADR4)); + rprintfu08(enc28j60Read(MAADR3)); + rprintfu08(enc28j60Read(MAADR2)); + rprintfu08(enc28j60Read(MAADR1)); + rprintfu08(enc28j60Read(MAADR0)); + rprintfCRLF(); + + rprintfProgStrM("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXSTH)); + rprintfu08(enc28j60Read(ERXSTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXNDH)); + rprintfu08(enc28j60Read(ERXNDL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXWRPTH)); + rprintfu08(enc28j60Read(ERXWRPTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXRDPTH)); + rprintfu08(enc28j60Read(ERXRDPTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ERXFCON)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(EPKTCNT)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MAMXFLH)); + rprintfu08(enc28j60Read(MAMXFLL)); + rprintfCRLF(); + + rprintfProgStrM("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\r\n"); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ETXSTH)); + rprintfu08(enc28j60Read(ETXSTL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(ETXNDH)); + rprintfu08(enc28j60Read(ETXNDL)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACLCON1)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MACLCON2)); + rprintfProgStrM(" 0x"); + rprintfu08(enc28j60Read(MAPHSUP)); + rprintfCRLF(); + + delay_ms(25); +} + + + diff --git a/3rd party/Procyuon avrlib/net/enc28j60.h b/3rd party/Procyuon avrlib/net/enc28j60.h new file mode 100644 index 0000000..0c679dd --- /dev/null +++ b/3rd party/Procyuon avrlib/net/enc28j60.h @@ -0,0 +1,306 @@ +/*! \file enc28j60.h \brief Microchip ENC28J60 Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'enc28j60.h' +// Title : Microchip ENC28J60 Ethernet Interface Driver +// Author : Pascal Stang (c)2005 +// Created : 9/22/2005 +// Revised : 9/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup enc28j60 Microchip ENC28J60 Ethernet Interface Driver (enc28j60.c) +/// \code #include "net/enc28j60.h" \endcode +/// \par Overview +/// This driver provides initialization and transmit/receive +/// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. +/// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin +/// chip, using an SPI interface to the host processor. +/// +// +//***************************************************************************** +//@{ + +#ifndef ENC28J60_H +#define ENC28J60_H + +#include "global.h" + +#define nop() asm volatile ("nop") + +// ENC28J60 Control Registers +// Control register definitions are a combination of address, +// bank number, and Ethernet/MAC/PHY indicator bits. +// - Register address (bits 0-4) +// - Bank number (bits 5-6) +// - MAC/PHY indicator (bit 7) +#define ADDR_MASK 0x1F +#define BANK_MASK 0x60 +#define SPRD_MASK 0x80 +// All-bank registers +#define EIE 0x1B +#define EIR 0x1C +#define ESTAT 0x1D +#define ECON2 0x1E +#define ECON1 0x1F +// Bank 0 registers +#define ERDPTL (0x00|0x00) +#define ERDPTH (0x01|0x00) +#define EWRPTL (0x02|0x00) +#define EWRPTH (0x03|0x00) +#define ETXSTL (0x04|0x00) +#define ETXSTH (0x05|0x00) +#define ETXNDL (0x06|0x00) +#define ETXNDH (0x07|0x00) +#define ERXSTL (0x08|0x00) +#define ERXSTH (0x09|0x00) +#define ERXNDL (0x0A|0x00) +#define ERXNDH (0x0B|0x00) +#define ERXRDPTL (0x0C|0x00) +#define ERXRDPTH (0x0D|0x00) +#define ERXWRPTL (0x0E|0x00) +#define ERXWRPTH (0x0F|0x00) +#define EDMASTL (0x10|0x00) +#define EDMASTH (0x11|0x00) +#define EDMANDL (0x12|0x00) +#define EDMANDH (0x13|0x00) +#define EDMADSTL (0x14|0x00) +#define EDMADSTH (0x15|0x00) +#define EDMACSL (0x16|0x00) +#define EDMACSH (0x17|0x00) +// Bank 1 registers +#define EHT0 (0x00|0x20) +#define EHT1 (0x01|0x20) +#define EHT2 (0x02|0x20) +#define EHT3 (0x03|0x20) +#define EHT4 (0x04|0x20) +#define EHT5 (0x05|0x20) +#define EHT6 (0x06|0x20) +#define EHT7 (0x07|0x20) +#define EPMM0 (0x08|0x20) +#define EPMM1 (0x09|0x20) +#define EPMM2 (0x0A|0x20) +#define EPMM3 (0x0B|0x20) +#define EPMM4 (0x0C|0x20) +#define EPMM5 (0x0D|0x20) +#define EPMM6 (0x0E|0x20) +#define EPMM7 (0x0F|0x20) +#define EPMCSL (0x10|0x20) +#define EPMCSH (0x11|0x20) +#define EPMOL (0x14|0x20) +#define EPMOH (0x15|0x20) +#define EWOLIE (0x16|0x20) +#define EWOLIR (0x17|0x20) +#define ERXFCON (0x18|0x20) +#define EPKTCNT (0x19|0x20) +// Bank 2 registers +#define MACON1 (0x00|0x40|0x80) +#define MACON2 (0x01|0x40|0x80) +#define MACON3 (0x02|0x40|0x80) +#define MACON4 (0x03|0x40|0x80) +#define MABBIPG (0x04|0x40|0x80) +#define MAIPGL (0x06|0x40|0x80) +#define MAIPGH (0x07|0x40|0x80) +#define MACLCON1 (0x08|0x40|0x80) +#define MACLCON2 (0x09|0x40|0x80) +#define MAMXFLL (0x0A|0x40|0x80) +#define MAMXFLH (0x0B|0x40|0x80) +#define MAPHSUP (0x0D|0x40|0x80) +#define MICON (0x11|0x40|0x80) +#define MICMD (0x12|0x40|0x80) +#define MIREGADR (0x14|0x40|0x80) +#define MIWRL (0x16|0x40|0x80) +#define MIWRH (0x17|0x40|0x80) +#define MIRDL (0x18|0x40|0x80) +#define MIRDH (0x19|0x40|0x80) +// Bank 3 registers +#define MAADR1 (0x00|0x60|0x80) +#define MAADR0 (0x01|0x60|0x80) +#define MAADR3 (0x02|0x60|0x80) +#define MAADR2 (0x03|0x60|0x80) +#define MAADR5 (0x04|0x60|0x80) +#define MAADR4 (0x05|0x60|0x80) +#define EBSTSD (0x06|0x60) +#define EBSTCON (0x07|0x60) +#define EBSTCSL (0x08|0x60) +#define EBSTCSH (0x09|0x60) +#define MISTAT (0x0A|0x60|0x80) +#define EREVID (0x12|0x60) +#define ECOCON (0x15|0x60) +#define EFLOCON (0x17|0x60) +#define EPAUSL (0x18|0x60) +#define EPAUSH (0x19|0x60) +// PHY registers +#define PHCON1 0x00 +#define PHSTAT1 0x01 +#define PHHID1 0x02 +#define PHHID2 0x03 +#define PHCON2 0x10 +#define PHSTAT2 0x11 +#define PHIE 0x12 +#define PHIR 0x13 +#define PHLCON 0x14 + +// ENC28J60 EIE Register Bit Definitions +#define EIE_INTIE 0x80 +#define EIE_PKTIE 0x40 +#define EIE_DMAIE 0x20 +#define EIE_LINKIE 0x10 +#define EIE_TXIE 0x08 +#define EIE_WOLIE 0x04 +#define EIE_TXERIE 0x02 +#define EIE_RXERIE 0x01 +// ENC28J60 EIR Register Bit Definitions +#define EIR_PKTIF 0x40 +#define EIR_DMAIF 0x20 +#define EIR_LINKIF 0x10 +#define EIR_TXIF 0x08 +#define EIR_WOLIF 0x04 +#define EIR_TXERIF 0x02 +#define EIR_RXERIF 0x01 +// ENC28J60 ESTAT Register Bit Definitions +#define ESTAT_INT 0x80 +#define ESTAT_LATECOL 0x10 +#define ESTAT_RXBUSY 0x04 +#define ESTAT_TXABRT 0x02 +#define ESTAT_CLKRDY 0x01 +// ENC28J60 ECON2 Register Bit Definitions +#define ECON2_AUTOINC 0x80 +#define ECON2_PKTDEC 0x40 +#define ECON2_PWRSV 0x20 +#define ECON2_VRPS 0x08 +// ENC28J60 ECON1 Register Bit Definitions +#define ECON1_TXRST 0x80 +#define ECON1_RXRST 0x40 +#define ECON1_DMAST 0x20 +#define ECON1_CSUMEN 0x10 +#define ECON1_TXRTS 0x08 +#define ECON1_RXEN 0x04 +#define ECON1_BSEL1 0x02 +#define ECON1_BSEL0 0x01 +// ENC28J60 MACON1 Register Bit Definitions +#define MACON1_LOOPBK 0x10 +#define MACON1_TXPAUS 0x08 +#define MACON1_RXPAUS 0x04 +#define MACON1_PASSALL 0x02 +#define MACON1_MARXEN 0x01 +// ENC28J60 MACON2 Register Bit Definitions +#define MACON2_MARST 0x80 +#define MACON2_RNDRST 0x40 +#define MACON2_MARXRST 0x08 +#define MACON2_RFUNRST 0x04 +#define MACON2_MATXRST 0x02 +#define MACON2_TFUNRST 0x01 +// ENC28J60 MACON3 Register Bit Definitions +#define MACON3_PADCFG2 0x80 +#define MACON3_PADCFG1 0x40 +#define MACON3_PADCFG0 0x20 +#define MACON3_TXCRCEN 0x10 +#define MACON3_PHDRLEN 0x08 +#define MACON3_HFRMLEN 0x04 +#define MACON3_FRMLNEN 0x02 +#define MACON3_FULDPX 0x01 +// ENC28J60 MICMD Register Bit Definitions +#define MICMD_MIISCAN 0x02 +#define MICMD_MIIRD 0x01 +// ENC28J60 MISTAT Register Bit Definitions +#define MISTAT_NVALID 0x04 +#define MISTAT_SCAN 0x02 +#define MISTAT_BUSY 0x01 +// ENC28J60 PHY PHCON1 Register Bit Definitions +#define PHCON1_PRST 0x8000 +#define PHCON1_PLOOPBK 0x4000 +#define PHCON1_PPWRSV 0x0800 +#define PHCON1_PDPXMD 0x0100 +// ENC28J60 PHY PHSTAT1 Register Bit Definitions +#define PHSTAT1_PFDPX 0x1000 +#define PHSTAT1_PHDPX 0x0800 +#define PHSTAT1_LLSTAT 0x0004 +#define PHSTAT1_JBSTAT 0x0002 +// ENC28J60 PHY PHCON2 Register Bit Definitions +#define PHCON2_FRCLINK 0x4000 +#define PHCON2_TXDIS 0x2000 +#define PHCON2_JABBER 0x0400 +#define PHCON2_HDLDIS 0x0100 + +// ENC28J60 Packet Control Byte Bit Definitions +#define PKTCTRL_PHUGEEN 0x08 +#define PKTCTRL_PPADEN 0x04 +#define PKTCTRL_PCRCEN 0x02 +#define PKTCTRL_POVERRIDE 0x01 + +// SPI operation codes +#define ENC28J60_READ_CTRL_REG 0x00 +#define ENC28J60_READ_BUF_MEM 0x3A +#define ENC28J60_WRITE_CTRL_REG 0x40 +#define ENC28J60_WRITE_BUF_MEM 0x7A +#define ENC28J60_BIT_FIELD_SET 0x80 +#define ENC28J60_BIT_FIELD_CLR 0xA0 +#define ENC28J60_SOFT_RESET 0xFF + + +// buffer boundaries applied to internal 8K ram +// entire available packet buffer space is allocated +#define TXSTART_INIT 0x0000 // start TX buffer at 0 +#define RXSTART_INIT 0x0600 // give TX buffer space for one full ethernet frame (~1500 bytes) +#define RXSTOP_INIT 0x1FFF // receive buffer gets the rest + +#define MAX_FRAMELEN 1518 // maximum ethernet frame length + +// Ethernet constants +#define ETHERNET_MIN_PACKET_LENGTH 0x3C +//#define ETHERNET_HEADER_LENGTH 0x0E + +// functions +#include "nic.h" + +// setup ports for I/O +//void ax88796SetupPorts(void); + +//! do a ENC28J60 read operation +u08 enc28j60ReadOp(u08 op, u08 address); +//! do a ENC28J60 write operation +void enc28j60WriteOp(u08 op, u08 address, u08 data); +//! read the packet buffer memory +void enc28j60ReadBuffer(u16 len, u08* data); +//! write the packet buffer memory +void enc28j60WriteBuffer(u16 len, u08* data); +//! set the register bank for register at address +void enc28j60SetBank(u08 address); +//! read ax88796 register +u08 enc28j60Read(u08 address); +//! write ax88796 register +void enc28j60Write(u08 address, u08 data); +//! read a PHY register +u16 enc28j60PhyRead(u08 address); +//! write a PHY register +void enc28j60PhyWrite(u08 address, u16 data); + +//! initialize the ethernet interface for transmit/receive +void enc28j60Init(void); + +//! Packet transmit function. +/// Sends a packet on the network. It is assumed that the packet is headed by a valid ethernet header. +/// \param len Length of packet in bytes. +/// \param packet Pointer to packet data. +void enc28j60PacketSend(unsigned int len, unsigned char* packet); + +//! Packet receive function. +/// Gets a packet from the network receive buffer, if one is available. +/// The packet will by headed by an ethernet header. +/// \param maxlen The maximum acceptable length of a retrieved packet. +/// \param packet Pointer where packet data should be stored. +/// \return Packet length in bytes if a packet was retrieved, zero otherwise. +unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet); + +//! execute procedure for recovering from a receive overflow +/// this should be done when the receive memory fills up with packets +void enc28j60ReceiveOverflowRecover(void); + +//! formatted print of important ENC28J60 registers +void enc28j60RegDump(void); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/icmp.c b/3rd party/Procyuon avrlib/net/icmp.c new file mode 100644 index 0000000..7680240 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/icmp.c @@ -0,0 +1,94 @@ +/*! \file icmp.c \brief ICMP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'icmp.c' +// Title : ICMP (Internet Control Message Protocol) Protocol Library +// Author : Pascal Stang +// Created : 9/10/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "global.h" +#include "net.h" +#include "nic.h" +#include "arp.h" +#include "icmp.h" + +#include "rprintf.h" +#include "debug.h" + +//extern void nicSend(unsigned int len, unsigned char* packet); + +// global variables + + +// functions +void icmpInit(void) +{ +} + +void icmpIpIn(icmpip_hdr* packet) +{ + // check ICMP type + switch(packet->icmp.type) + { + case ICMP_TYPE_ECHOREQUEST: + // echo request + icmpEchoRequest(packet); + break; + default: + break; + } +} + +void icmpEchoRequest(icmpip_hdr* packet) +{ + uint32_t tempIp; + + // change type to reply + packet->icmp.type = ICMP_TYPE_ECHOREPLY; + // recalculate checksum + packet->icmp.icmpchksum = 0; + packet->icmp.icmpchksum = netChecksum((u08*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN); + // return to sender + tempIp = packet->ip.destipaddr; + packet->ip.destipaddr = packet->ip.srcipaddr; + packet->ip.srcipaddr = tempIp; + // add ethernet routing + arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0); + + // debugging + #if NET_DEBUG >= 2 + icmpPrintHeader(packet); + //debugPrintHexTable(htons(packet->ip.len), (u08*)packet); + #endif + + // send it (packet->ip.len+ETH_HEADER_LEN + nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((u08*)packet)-ETH_HEADER_LEN)); +} + +#ifdef ICMP_DEBUG_PRINT +void icmpPrintHeader(icmpip_hdr* packet) +{ + rprintfProgStrM("ICMP Packet:\r\n"); + // print source IP address + rprintfProgStrM("SrcIpAddr: "); netPrintIPAddr(htonl(packet->ip.srcipaddr)); rprintfCRLF(); + // print dest IP address + rprintfProgStrM("DstIpAddr: "); netPrintIPAddr(htonl(packet->ip.destipaddr)); rprintfCRLF(); + // print type + rprintfProgStrM("Type : "); + switch(packet->icmp.type) + { + case ICMP_TYPE_ECHOREQUEST: rprintfProgStrM("ECHO REQUEST"); break; + case ICMP_TYPE_ECHOREPLY: rprintfProgStrM("ECHO REPLY"); break; + default: rprintfProgStrM("UNKNOWN"); break; + } + rprintfCRLF(); + // print code + rprintfProgStrM("Code : 0x"); rprintfu08(packet->icmp.icode); rprintfCRLF(); +} +#endif diff --git a/3rd party/Procyuon avrlib/net/icmp.h b/3rd party/Procyuon avrlib/net/icmp.h new file mode 100644 index 0000000..3a58ac8 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/icmp.h @@ -0,0 +1,50 @@ +/*! \file icmp.h \brief ICMP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'icmp.h' +// Title : ICMP (Internet Control Message Protocol) Protocol Library +// Author : Pascal Stang +// Created : 9/10/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup icmp ICMP Protocol Library (icmp.c) +/// \code #include "net/icmp.h" \endcode +/// \par Description +/// ICMP (Internet Control Message Protocol) has many functions on the +/// internet, including the handling of ECHO (ping) requests, relaying +/// network route status, passing connection status messages, etc. +/// +/// This library currently handles only ICMP ECHO requests (ping), but +/// may be expanded to include other useful ICMP operations as needed. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef ICMP_H +#define ICMP_H + +#include "global.h" +#include "net.h" + +//#define ICMP_DEBUG_PRINT + +//! Initialize ICMP protocol library. +void icmpInit(void); + +//! Incoming IP packets of protocol ICMP should be passed to this function. +void icmpIpIn(icmpip_hdr* packet); + +//! Forms and sends a reply in response to an ICMP ECHO request. +void icmpEchoRequest(icmpip_hdr* packet); + +//! Print ICMP packet information. +void icmpPrintHeader(icmpip_hdr* packet); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/ip.c b/3rd party/Procyuon avrlib/net/ip.c new file mode 100644 index 0000000..215badf --- /dev/null +++ b/3rd party/Procyuon avrlib/net/ip.c @@ -0,0 +1,134 @@ +/*! \file ip.c \brief IP (Internet Protocol) Library. */ +//***************************************************************************** +// +// File Name : 'ip.c' +// Title : IP (Internet Protocol) Library +// Author : Pascal Stang +// Created : 8/30/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + + +#include +#include "global.h" +#include "rprintf.h" + +#include "net.h" +#include "nic.h" +#include "arp.h" +#include "ip.h" + +struct ipConfig IpMyConfig; ///< Local IP address/config structure + + +void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp) +{ + struct netEthAddr ethaddr; + + // set local addressing + IpMyConfig.ip = myIp; + IpMyConfig.netmask = netmask; + IpMyConfig.gateway = gatewayIp; + + // set ARP association + nicGetMacAddress(ethaddr.addr); + arpSetAddress(ðaddr, myIp); +} + +struct ipConfig* ipGetConfig(void) +{ + return &IpMyConfig; +} + +// deprecated +/* +uint32_t ipGetMyAddress(void) +{ + return IpMyConfig.ip; +} +*/ + +void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len, uint8_t* data) +{ + // make pointer to ethernet/IP header + struct netEthIpHeader* ethIpHeader; + + // move data pointer to make room for headers + data -= ETH_HEADER_LEN+IP_HEADER_LEN; + ethIpHeader = (struct netEthIpHeader*)data; + +// debugPrintHexTable(len+ETH_HEADER_LEN+IP_HEADER_LEN, data); + + // adjust length to add IP header + len += IP_HEADER_LEN; + + // fill IP header + ethIpHeader->ip.destipaddr = HTONL(dstIp); + ethIpHeader->ip.srcipaddr = HTONL(IpMyConfig.ip); + ethIpHeader->ip.proto = protocol; + ethIpHeader->ip.len = htons(len); + ethIpHeader->ip.vhl = 0x45; + ethIpHeader->ip.tos = 0; + ethIpHeader->ip.ipid = 0; + ethIpHeader->ip.ipoffset = 0; + ethIpHeader->ip.ttl = IP_TIME_TO_LIVE; + ethIpHeader->ip.ipchksum = 0; + + // calculate and apply IP checksum + // DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER + ethIpHeader->ip.ipchksum = netChecksum(ðIpHeader->ip, IP_HEADER_LEN); + + // add ethernet routing + // check if we need to send to gateway + if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) + { + arpIpOut(ethIpHeader,0); // local send + //rprintf("Sending IP packet on local net\r\n"); + } + else + { + arpIpOut(ethIpHeader,IpMyConfig.gateway); // gateway send + //rprintf("Sending IP packet to gateway\r\n"); + } + + // adjust length to add ethernet header + len += ETH_HEADER_LEN; + + // debug + //debugPrintHexTable(ETH_HEADER_LEN, &data[0]); + //debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]); + + // send it + nicSend(len, data); +} + +void udpSend(uint32_t dstIp, uint16_t dstPort, uint16_t len, uint8_t* data) +{ + // make pointer to UDP header + struct netUdpHeader* udpHeader; + // move data pointer to make room for UDP header + data -= UDP_HEADER_LEN; + udpHeader = (struct netUdpHeader*)data; + // adjust length to add UDP header + len += UDP_HEADER_LEN; + // fill UDP header + udpHeader->destport = HTONS(dstPort); + udpHeader->srcport = HTONS(dstPort); + udpHeader->udplen = htons(len); + udpHeader->udpchksum = 0; + +// debugPrintHexTable(UDP_HEADER_LEN, (uint8_t*)udpPacket); + + ipSend(dstIp, IP_PROTO_UDP, len, (uint8_t*)udpHeader); +} + +void ipPrintConfig(struct ipConfig* config) +{ + rprintfProgStrM("IP Addr : "); netPrintIPAddr(config->ip); rprintfCRLF(); + rprintfProgStrM("Netmask : "); netPrintIPAddr(config->netmask); rprintfCRLF(); + rprintfProgStrM("Gateway : "); netPrintIPAddr(config->gateway); rprintfCRLF(); +} diff --git a/3rd party/Procyuon avrlib/net/ip.h b/3rd party/Procyuon avrlib/net/ip.h new file mode 100644 index 0000000..6a90b41 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/ip.h @@ -0,0 +1,70 @@ +/*! \file ip.h \brief IP (Internet Protocol) Library. */ +//***************************************************************************** +// +// File Name : 'ip.h' +// Title : IP (Internet Protocol) Library +// Author : Pascal Stang +// Created : 8/30/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup ip IP (Internet Protocol) Library (ip.c) +/// \code #include "net/ip.h" \endcode +/// \par Description +/// The IP (Internet Protocol) library provide support for sending IP and +/// IP-related packets. It's not clear if additional features are needed +/// or will be added, or even if this is the proper way to facilitate IP +/// packet operations. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef IP_H +#define IP_H + +#include "net.h" +#include "arp.h" + +#include + +struct ipConfig ///< IP addressing/configuration structure +{ + uint32_t ip; ///< IP address + uint32_t netmask; ///< netmask + uint32_t gateway; ///< gateway IP address +}; + +#define IP_TIME_TO_LIVE 128 ///< default Time-To-Live (TTL) value to use in IP headers + +//! Set our IP address and routing information. +/// The myIp value will be used in the source field of IP packets. +/// Use this function to set and reset the system IP address. +void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp); + +//! Get our local IP address. +/// Returns current IP address value. +//uint32_t ipGetMyAddress(void); + +//! Get our local IP configuration. +/// Returns pointer to current IP address/configuration. +struct ipConfig* ipGetConfig(void); + +//! Print IP configuration +/// +void ipPrintConfig(struct ipConfig* config); + + +//! Send an IP packet. +void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len, uint8_t* data); + +//! Send a UDP/IP packet. +void udpSend(uint32_t dstIp, uint16_t dstPort, uint16_t len, uint8_t* data); + +#endif +//@} + diff --git a/3rd party/Procyuon avrlib/net/net.c b/3rd party/Procyuon avrlib/net/net.c new file mode 100644 index 0000000..cfb4b1d --- /dev/null +++ b/3rd party/Procyuon avrlib/net/net.c @@ -0,0 +1,131 @@ +/*! \file net.c \brief Network support library. */ +//***************************************************************************** +// +// File Name : 'net.c' +// Title : Network support library +// Author : Pascal Stang +// Created : 8/30/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include +#include "global.h" +#include "rprintf.h" + +#include "net.h" + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); +} + +uint32_t htonl(uint32_t val) +{ + return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); +} + + +uint16_t netChecksum(void *data, uint16_t len) +{ + register uint32_t sum = 0; + + for (;;) { + if (len < 2) + break; + //sum += *((uint16_t *)data)++; + sum += *((uint16_t *)data); + data+=2; + len -= 2; + } + if (len) + sum += *(uint8_t *) data; + + while ((len = (uint16_t) (sum >> 16)) != 0) + sum = (uint16_t) sum + len; + + return (uint16_t) sum ^ 0xFFFF; +} + +void netPrintEthAddr(struct netEthAddr* ethaddr) +{ + rprintfu08(ethaddr->addr[0]); + rprintfChar(':'); + rprintfu08(ethaddr->addr[1]); + rprintfChar(':'); + rprintfu08(ethaddr->addr[2]); + rprintfChar(':'); + rprintfu08(ethaddr->addr[3]); + rprintfChar(':'); + rprintfu08(ethaddr->addr[4]); + rprintfChar(':'); + rprintfu08(ethaddr->addr[5]); +} + +void netPrintIPAddr(uint32_t ipaddr) +{ + rprintf("%d.%d.%d.%d", + ((unsigned char*)&ipaddr)[3], + ((unsigned char*)&ipaddr)[2], + ((unsigned char*)&ipaddr)[1], + ((unsigned char*)&ipaddr)[0]); +} + +/* +void netPrintEthHeader(struct netEthHeader* eth_hdr) +{ + rprintfProgStrM("Eth Packet Type: 0x"); + rprintfu16(eth_hdr->type); + + rprintfProgStrM(" SRC:"); + netPrintEthAddr(ð_hdr->src); + rprintfProgStrM("->DST:"); + netPrintEthAddr(ð_hdr->dest); + rprintfCRLF(); +} + +void netPrintIpHeader(struct netIpHeader* ipheader) +{ + rprintfProgStrM("IP Header\r\n"); + rprintf("Ver : %d\r\n", (ipheader->vhl)>>4); + rprintf("Length : %d\r\n", htons(ipheader->len)); + if(ipheader->proto == IP_PROTO_ICMP) + rprintfProgStrM("Protocol: ICMP\r\n"); + else if(ipheader->proto == IP_PROTO_TCP) + rprintfProgStrM("Protocol: TCP\r\n"); + else if(ipheader->proto == IP_PROTO_UDP) + rprintfProgStrM("Protocol: UDP\r\n"); + else + rprintf("Protocol: %d\r\n", ipheader->proto); + + rprintfProgStrM("SourceIP: "); netPrintIPAddr(htonl(ipheader->srcipaddr)); rprintfCRLF(); + rprintfProgStrM("Dest IP: "); netPrintIPAddr(htonl(ipheader->destipaddr)); rprintfCRLF(); +} + +void netPrintTcpHeader(struct netTcpHeader* tcpheader) +{ + rprintfProgStrM("TCP Header\r\n"); + rprintf("Src Port: %d\r\n", htons(tcpheader->srcport)); + rprintf("Dst Port: %d\r\n", htons(tcpheader->destport)); + rprintfProgStrM("Seq Num : 0x"); rprintfu32(htonl(tcpheader->seqno)); rprintfCRLF(); + rprintfProgStrM("Ack Num : 0x"); rprintfu32(htonl(tcpheader->ackno)); rprintfCRLF(); + rprintfProgStrM("Flags : "); + if(tcpheader->flags & TCP_FLAGS_FIN) + rprintfProgStrM("FIN "); + if(tcpheader->flags & TCP_FLAGS_SYN) + rprintfProgStrM("SYN "); + if(tcpheader->flags & TCP_FLAGS_RST) + rprintfProgStrM("RST "); + if(tcpheader->flags & TCP_FLAGS_PSH) + rprintfProgStrM("PSH "); + if(tcpheader->flags & TCP_FLAGS_ACK) + rprintfProgStrM("ACK "); + if(tcpheader->flags & TCP_FLAGS_URG) + rprintfProgStrM("URG "); + rprintfCRLF(); +} +*/ + diff --git a/3rd party/Procyuon avrlib/net/net.h b/3rd party/Procyuon avrlib/net/net.h new file mode 100644 index 0000000..baea9c9 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/net.h @@ -0,0 +1,206 @@ +/*! \file net.h \brief Network support library. */ +//***************************************************************************** +// +// File Name : 'net.h' +// Title : Network support library +// Author : Pascal Stang +// Created : 8/30/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup net Network support library (net.c) +/// \code #include "net/net.h" \endcode +/// \par Description +/// This is a general network support library including a multitude of +/// structure definitions for various types of network packets, functions +/// and macros for switching byte order, and an RFC-compliant function +/// for calculating checksums. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef NET_H +#define NET_H + +#include +#include "global.h" + +// Representation of a 48-bit Ethernet address. +struct netEthAddr +{ + uint8_t addr[6]; +} GNUC_PACKED; + +// The Ethernet header +struct netEthHeader +{ + struct netEthAddr dest; + struct netEthAddr src; + uint16_t type; +} GNUC_PACKED; + +#define ETH_HEADER_LEN 14 + +#define ETHTYPE_ARP 0x0806 +#define ETHTYPE_IP 0x0800 +#define ETHTYPE_IP6 0x86dd + +// The ARP header +struct netArpHeader +{ + uint16_t hwtype; + uint16_t protocol; + uint8_t hwlen; + uint8_t protolen; + uint16_t opcode; + struct netEthAddr shwaddr; + uint32_t sipaddr; + struct netEthAddr dhwaddr; + uint32_t dipaddr; +} GNUC_PACKED; + +#define ARP_OPCODE_REQUEST 1 +#define ARP_OPCODE_REPLY 2 +#define ARP_HWTYPE_ETH 1 + +// The IP header +struct netIpHeader +{ + uint8_t vhl; + uint8_t tos; + uint16_t len; + uint16_t ipid; + uint16_t ipoffset; + uint8_t ttl; + uint8_t proto; + uint16_t ipchksum; + uint32_t srcipaddr; + uint32_t destipaddr; +} GNUC_PACKED; +#define IP_HEADER_LEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 + +// The ICMP header +struct netIcmpHeader +{ + uint8_t type; + uint8_t icode; + uint16_t icmpchksum; + uint16_t id; + uint16_t seqno; +} GNUC_PACKED; +#define ICMP_HEADER_LEN 8 + +#define ICMP_TYPE_ECHOREPLY 0 +#define ICMP_TYPE_ECHOREQUEST 8 + +// The UDP header +struct netUdpHeader +{ + uint16_t srcport; + uint16_t destport; + uint16_t udplen; + uint16_t udpchksum; +} GNUC_PACKED; +#define UDP_HEADER_LEN 8 + +// The TCP header +struct netTcpHeader +{ + uint16_t srcport; + uint16_t destport; + uint32_t seqno; + uint32_t ackno; + uint8_t tcpoffset; + uint8_t flags; + uint16_t wnd; + uint16_t tcpchksum; + uint16_t urgp; +// uint8_t optdata[4]; +} GNUC_PACKED; +#define TCP_HEADER_LEN 20 + +#define TCP_FLAGS_FIN 0x01 +#define TCP_FLAGS_SYN 0x02 +#define TCP_FLAGS_RST 0x04 +#define TCP_FLAGS_PSH 0x08 +#define TCP_FLAGS_ACK 0x10 +#define TCP_FLAGS_URG 0x20 + +// Ethernet/ARP header +struct netEthArpHeader +{ + struct netEthHeader eth; + struct netArpHeader arp; +} GNUC_PACKED; + +// Ethernet/IP header +struct netEthIpHeader +{ + struct netEthHeader eth; + struct netIpHeader ip; +} GNUC_PACKED; + +// The IP header +typedef struct netIpHeader ip_hdr; + +// The IP/TCP headers +typedef struct +{ + struct netIpHeader ip; + struct netTcpHeader tcp; +} tcpip_hdr; + +// The IP/ICMP headers +typedef struct { + struct netIpHeader ip; + struct netIcmpHeader icmp; +} icmpip_hdr; + + +// The UDP and IP headers +typedef struct { + struct netIpHeader ip; + struct netUdpHeader udp; +} udpip_hdr; + + +//! Convert dot-notation IP address into 32-bit word. +/// Example: IPDOT(192l,168l,1l,1l) +#define IPDOT(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d)) + +//! Host-to-Network SHORT (16-bit) byte-order swap (macro). +#define HTONS(s) ((s<<8) | (s>>8)) +//! Host-to-Network LONG (32-bit) byte-order swap (macro). +#define HTONL(l) ((l<<24) | ((l&0x00FF0000l)>>8) | ((l&0x0000FF00l)<<8) | (l>>24)) + +//! Host-to-Network SHORT (16-bit) byte-order swap (function). +uint16_t htons(uint16_t val); +//! Host-to-Network LONG (32-bit) byte-order swap (function). +uint32_t htonl(uint32_t val); + +//! Calculate IP-style checksum from data. +uint16_t netChecksum(void *data, uint16_t len); + +//! Print Ethernet address in XX:XX:XX:XX:XX:XX format. +void netPrintEthAddr(struct netEthAddr* ethaddr); +//! Print IP address in dot notation. +void netPrintIPAddr(uint32_t ipaddr); +//! Print Ethernet header information. +void netPrintEthHeader(struct netEthHeader* eth_hdr); +//! Print IP header information. +void netPrintIpHeader(struct netIpHeader* ipheader); +//! Print TCP header information. +void netPrintTcpHeader(struct netTcpHeader* tcpheader); + +#endif +//@} + diff --git a/3rd party/Procyuon avrlib/net/netstack.c b/3rd party/Procyuon avrlib/net/netstack.c new file mode 100644 index 0000000..085c70e --- /dev/null +++ b/3rd party/Procyuon avrlib/net/netstack.c @@ -0,0 +1,143 @@ +/*! \file netstack.c \brief Network Stack. */ +//***************************************************************************** +// +// File Name : 'netstack.c' +// Title : Network Stack +// Author : Pascal Stang +// Created : 6/28/2005 +// Revised : 9/20/2005 +// Version : 0.3 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "rprintf.h" +#include "debug.h" + +#include "netstack.h" + +unsigned char NetBuffer[NETSTACK_BUFFERSIZE]; + +void netstackInit(uint32_t ipaddress, uint32_t netmask, uint32_t gatewayip) +{ + // init network device driver + #ifdef NETSTACK_DEBUG + rprintf("Initializing Network Device\r\n"); + #endif + nicInit(); + // init ARP + #ifdef NETSTACK_DEBUG + rprintf("Initializing ARP cache\r\n"); + #endif + arpInit(); + // init addressing + #ifdef NETSTACK_DEBUG + rprintf("Initializing Addressing\r\n"); + #endif + ipSetConfig(ipaddress, netmask, gatewayip); +} + +u08* netstackGetBuffer(void) +{ + return NetBuffer; +} + +int netstackService(void) +{ + int len; + struct netEthHeader* ethPacket; + + // look for a packet + len = nicPoll(NETSTACK_BUFFERSIZE, NetBuffer); + + if(len) + { + ethPacket = (struct netEthHeader*)&NetBuffer[0]; + + #if NET_DEBUG >= 5 + rprintf("Received packet len: %d, type:", len); + rprintfu16(htons(ethPacket->type)); + rprintfCRLF(); + rprintf("Packet Contents\r\n"); + debugPrintHexTable(len, NetBuffer); + #endif + + if(ethPacket->type == htons(ETHTYPE_IP)) + { + // process an IP packet + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: IP packet\r\n"); + #endif + // add the source to the ARP cache + // also correctly set the ethernet packet length before processing? + arpIpIn((struct netEthIpHeader*)&NetBuffer[0]); + //arpPrintTable(); + + netstackIPProcess( len-ETH_HEADER_LEN, (ip_hdr*)&NetBuffer[ETH_HEADER_LEN] ); + } + else if(ethPacket->type == htons(ETHTYPE_ARP)) + { + // process an ARP packet + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: ARP packet\r\n"); + #endif + arpArpIn(len, ((struct netEthArpHeader*)&NetBuffer[0]) ); + } + } + return len; +} + +void netstackIPProcess(unsigned int len, ip_hdr* packet) +{ + // check IP addressing, stop processing if not for me and not a broadcast + if( (htonl(packet->destipaddr) != ipGetConfig()->ip) && + (htonl(packet->destipaddr) != (ipGetConfig()->ip|ipGetConfig()->netmask)) && + (htonl(packet->destipaddr) != 0xFFFFFFFF) ) + return; + + // handle ICMP packet + if( packet->proto == IP_PROTO_ICMP ) + { + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: ICMP/IP packet\r\n"); + //icmpPrintHeader((icmpip_hdr*)packet); + #endif + icmpIpIn((icmpip_hdr*)packet); + } + else if( packet->proto == IP_PROTO_UDP ) + { + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: UDP/IP packet\r\n"); + //debugPrintHexTable(NetBufferLen-14, &NetBuffer[14]); + #endif + netstackUDPIPProcess(len, ((udpip_hdr*)packet) ); + } + else if( packet->proto == IP_PROTO_TCP ) + { + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: TCP/IP packet\r\n"); + #endif + netstackTCPIPProcess(len, ((tcpip_hdr*)packet) ); + } + else + { + #ifdef NETSTACK_DEBUG + rprintfProgStrM("NET Rx: IP packet\r\n"); + #endif + } +} + +void netstackUDPIPProcess(unsigned int len, udpip_hdr* packet) +{ + #ifdef NETSTACK_DEBUG + rprintf("NetStack UDP/IP Rx Dummy Handler\r\n"); + #endif +} + +void netstackTCPIPProcess(unsigned int len, tcpip_hdr* packet) +{ + #ifdef NETSTACK_DEBUG + rprintf("NetStack TCP/IP Rx Dummy Handler\r\n"); + #endif +} diff --git a/3rd party/Procyuon avrlib/net/netstack.h b/3rd party/Procyuon avrlib/net/netstack.h new file mode 100644 index 0000000..a82cbc6 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/netstack.h @@ -0,0 +1,85 @@ +/*! \file netstack.h \brief Network Stack. */ +//***************************************************************************** +// +// File Name : 'netstack.h' +// Title : Network Stack +// Author : Pascal Stang +// Created : 6/28/2005 +// Revised : 9/20/2005 +// Version : 0.3 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup netstack Network Stack (netstack.c) +/// \code #include "net/netstack.h" \endcode +/// \par Description +/// This library co-ordinates the various pieces of a typical IP network +/// stack into one unit. Included are handling for ARP, ICMP, and IP +/// packets. UDP and TCP packets are processed and passed to the user. +/// +/// This is an example of how to use the various network libraries, and +/// is meant to be useful out-of-the-box for most users. However, some +/// users may find it restrictive and write their own handlers instead. +/// This stack implementation is by no means the only way to use the various +/// network libraries. +/// +/// \note This is NOT a full-blown TCP/IP stack. It merely handles lower +/// level stack functions so that UDP and TCP packets can be sent +/// and received easily. End-to-end TCP functionality may be added +/// in a future version. Until then, I can recommend using other embedded +/// TCP/IP stacks like Adam Dunkel's uIP. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef NETSTACK_H +#define NETSTACK_H + +#include "net.h" +#include "arp.h" +#include "icmp.h" +#include "ip.h" +#include "nic.h" + +//#define NETSTACK_DEBUG + +/// NET_BUFFERSIZE is the common receive/process/transmit buffer. +/// - You may override the default NET_BUFFERSIZE by defining an alternate value in global.h. +/// - Network packets larger than NET_BUFFERSIZE will not be accepted. +#ifndef NETSTACK_BUFFERSIZE +#define NETSTACK_BUFFERSIZE (576+ETH_HEADER_LEN) +#endif + +/// netstackInit prepares the network interface for use and should be called +/// once at the beginning of the user program. +/// \note Use ipSetAddress() to change network parameters in mid-run. +void netstackInit(uint32_t ipaddress, uint32_t netmask, uint32_t gatewayip); + +/// netstackGetBuffer returns a pointer to the common receive/process/transmit buffer. +u08* netstackGetBuffer(void); + +/// netstackService should be called in the main loop of the user program. +/// The function will process one received network packet per call. +/// The return value is the length of the packet processed, or zero if no +/// packet was processed. +int netstackService(void); + +/// netstackIPProcess handles distribution of IP received packets. +/// +void netstackIPProcess(unsigned int len, ip_hdr* packet); + +/// This weakly-defined function is the default handler for incoming UDP/IP packets. +/// Users should define this same function in user code (same name and arguments) to +/// override this default handler and get access to the received packets. +void netstackUDPIPProcess(unsigned int len, udpip_hdr* packet) __attribute__ ((weak)); + +/// This weakly-defined function is the default handler for incoming TCP/IP packets. +/// Users should define this same function in user code (same name and arguments) to +/// override this default handler and get access to the received packets. +void netstackTCPIPProcess(unsigned int len, tcpip_hdr* packet) __attribute__ ((weak)); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/nic.h b/3rd party/Procyuon avrlib/net/nic.h new file mode 100644 index 0000000..cc03a02 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/nic.h @@ -0,0 +1,71 @@ +/*! \file nic.h \brief Network Interface Card (NIC) software definition. */ +//***************************************************************************** +// +// File Name : 'nic.h' +// Title : Network Interface Card (NIC) software definition +// Author : Pascal Stang +// Created : 8/22/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup nic Network Interface Card (NIC) software definition (nic.h) +/// \code #include "net/nic.h" \endcode +/// \par Description +/// This is the software interface standard for network interface hardware +/// as used by AVRlib. Drivers for network hardware must implement these +/// functions to allow upper network layers to initialize the interface, +/// and send and receive net traffic. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +//***************************************************************************** +//@{ + +#ifndef NIC_H +#define NIC_H + +#include + +//! Initialize network interface hardware. +/// Reset and bring up network interface hardware. This function should leave +/// the network interface ready to handle \c nicSend() and \c nicPoll() requests. +/// \note For some hardware, this command will take a non-negligible amount of +/// time (1-2 seconds). +void nicInit(void); + +//! Send packet on network interface. +/// Function accepts the length (in bytes) of the data to be sent, and a pointer +/// to the data. This send command may assume an ethernet-like 802.3 header is at the +/// beginning of the packet, and contains the packet addressing information. +/// See net.h documentation for ethernet header format. +void nicSend(unsigned int len, unsigned char* packet); + +//! Check network interface; return next received packet if avaialable. +/// Function accepts the maximum allowable packet length (in bytes), and a +/// pointer to the received packet buffer. Return value is the length +/// (in bytes) of the packet recevied, or zero if no packet is available. +/// Upper network layers may assume that an ethernet-like 802.3 header is at +/// the beginning of the packet, and contains the packet addressing information. +/// See net.h documentation for ethernet header format. +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet); + +//! Return the 48-bit hardware node (MAC) address of this network interface. +/// This function can return a MAC address read from the NIC hardware, if available. +/// If the hardware does not provide a MAC address, a software-defined address may be +/// returned. It may be acceptable to return an address that is less than 48-bits. +void nicGetMacAddress(uint8_t* macaddr); + +//! Set the 48-bit hardware node (MAC) address of this network interface. +/// This function may not be supported on all hardware. +void nicSetMacAddress(uint8_t* macaddr); + +//! Print network interface hardware registers. +/// Prints a formatted list of names and values of NIC registers for debugging +/// purposes. +inline void nicRegDump(void); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/net/prism2.c b/3rd party/Procyuon avrlib/net/prism2.c new file mode 100644 index 0000000..d69344d --- /dev/null +++ b/3rd party/Procyuon avrlib/net/prism2.c @@ -0,0 +1,651 @@ +/*! \file prism2.c \brief Prism2 802.11b Wireless-LAN Interface Driver. */ +//***************************************************************************** +// +// File Name : 'prism2.c' +// Title : Prism2 802.11b Wireless-LAN Interface Driver +// Author : Pascal Stang +// Created : 12/27/2004 +// Revised : 1/7/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This driver provides initialization and transmit/receive +// functions for the Prism2 802.11b Wireless-LAN Controller. +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "timer.h" +#include "rprintf.h" +#include "debug.h" + +#include "net.h" +#include "prism2.h" + +// include configuration +#include "prism2conf.h" + +u16 TxHeader[34]; + +void nicInit(void) +{ + prism2Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + u16 i; + u16 txfid; + u08 stat; + // request free buffer space to store outgoing frame + prism2Command(PRISM2_CMD_ALLOC, len+44+14+6); + // wait for buffer to be allocated + while( !(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_ALLOC) ); + // get the buffer FID + txfid = prism2Read16(PRISM2_REG_ALLOCFID); + // ACK the alloc event + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_ALLOC); + +// rprintf("PRISM2: TxFID=0x"); +// rprintfu16(txfid); +// rprintfCRLF(); + + // adjust packet length because MAC addresses and type + // will be written seperately from packet payload + len-=14; + + // write the outgoing frame to BAP + // begin with control structure + prism2SetupTxHeader(TxHeader); + + // write dest and src MAC addresses + for(i=0;i<6;++i) + TxHeader[23+i] = packet[i*2+1]<<8 | packet[i*2]; + // write length + TxHeader[29] = htons(len+8); + // write type + TxHeader[33] = packet[13]<<8 | packet[12]; + +// debugPrintHexTable(34*2, (u08*)TxHeader); +// rprintfCRLF(); +// debugPrintHexTable(len, &packet[14]); + + // write Tx header out to BAP + prism2WriteBAP0(txfid, 0, TxHeader, 34); + // write packet out to BAP + prism2WriteBAP0(txfid, 68, (u16*)&packet[14], (len+1)>>1); + // issue transmit command + stat = prism2Command(PRISM2_CMD_TX, txfid); + if(stat) + rprintf("Transmit failed: 0x%x\r\n", stat); + // do cleanup + prism2EventCheck(); +} + +void nicGetMacAddress(u08* macaddr) +{ + prism2GetMacAddress(macaddr); +} + +void nicSetMacAddress(u08* macaddr) +{ + // not yet supported +} + +void nicRegDump(void) +{ + prism2CardRegDump(); + prism2RegDump(); +} + +void prism2SetupTxHeader(u16* header) +{ + u16 i; + + // clear out header + for(i=0;i<22;i++) + header[i] = 0x00; + + // set TxRate and retry count + header[5] = (0<<8) | 0; + // 0x00 = automatic selection + // 0x0A = 10 = 1.0Mbit/s + // 0x14 = 20 = 2.0Mbit/s + // 0x37 = 55 = 5.5Mbit/s + // 0x6E = 110 = 11 Mbit/s + + // set TxControl + header[6] = 0x0004; + + // write length + // (not really needed since card will pull info from 802.3 header) + //TxHeader[22] = len+8; + + // fill in 802.3 header fields + TxHeader[30] = 0xAAAA; + TxHeader[31] = 0x0003; + TxHeader[32] = 0x0000; + + // src mac address @ byte offset 52 +} + +void prism2EventCheck(void) +{ + unsigned int evstat_data; + + evstat_data = prism2Read16(PRISM2_REG_EVSTAT); + + if(evstat_data & PRISM2_EVENT_TX) + { + prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TX); + } + + if(evstat_data & PRISM2_EVENT_TXEXEC) + { + prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TXEXEC); + } + + if(evstat_data & PRISM2_EVENT_ALLOC) + { + prism2Write16(PRISM2_REG_EVACK, 0x0002); + } + + if(evstat_data & PRISM2_EVENT_CMD) + { + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD); + } + + if(evstat_data & PRISM2_EVENT_INFO) + { + prism2Read16(PRISM2_REG_INFOFID); + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFO); + } + + if(evstat_data & PRISM2_EVENT_INFDROP) + { + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFDROP); + } + + if(evstat_data & PRISM2_EVENT_WTERR) + { + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_WTERR); + } +} + + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + u16 rxfid=0; + u16 packetLength=0; + + // check if packets have been received + if(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_RX) + { + // we have a receive event + // get RxFID + rxfid = prism2Read16(PRISM2_REG_RXFID); + // read the packet length + prism2ReadBAP0(rxfid, 44, &packetLength, 1); + } + + // if there's no packet or an error - exit + if( !packetLength ) + return 0; + + // drop anything too big for the buffer + if( packetLength > maxlen ) + { + // ACK the receive event to finish up + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX); + return 0; + } + + // packet is available, retrieve data + // this is a hack: while reading in data, + // convert 802.2/3 header to ethernet header + // first get dest and src MAC addresses + prism2ReadBAP0(rxfid, 46, (u16*)&packet[0], 6); + // skip length, snap, and ctrl fields + // begin data copy again at type field + prism2ReadBAP0(rxfid, 46+12+8, (u16*)&packet[12], packetLength-6); + // ACK the receive event to finish up + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX); + + return packetLength; +} + +void prism2InitPorts(void) +{ +#if NIC_CONNECTION == MEMORY_MAPPED + // enable external SRAM interface - no wait states + sbi(MCUSR, SRE); +#else + // set address port to output + outb(PRISM2_ADDRESS_DDR, PRISM2_ADDRESS_MASK); + outb(PRISM2_HADDRESS_DDR, PRISM2_HADDRESS_MASK); + + // set data port to input with pull-ups + outb(PRISM2_DATA_DDR, 0x00); + outb(PRISM2_DATA_PORT, 0xFF); + + // initialize the control port read and write pins to de-asserted + sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD ); + sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR ); + sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD ); + sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR ); + // set the read and write pins to output + sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IORD ); + sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IOWR ); + sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMRD ); + sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMWR ); +#endif + // set reset pin to output + sbi( PRISM2_RESET_DDR, PRISM2_RESET_PIN ); + + // clear -REG pin + sbi(DDRB, 6); + cbi(PORTB, 6); + // setup IREQ pin + cbi(DDRB, 7); + sbi(PORTB, 7); +} + +void prism2Init(void) +{ + u08 result; + u16 buffer[20]; + +// rprintf("Init ports\r\n"); + prism2InitPorts(); + + // assert hardware reset + sbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN ); + // wait + delay_ms(10); + // release hardware reset + cbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN ); + delay_ms(100); + +/* + // soft-reset card + prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, 0x80); + delay_ms(10); + prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, 0x00); + // wait until soft-reset is done + delay_ms(500); + + // set 8-bit PCMCIA I/O mode + prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x20); + + prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x04); + timerPause(1000); + prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x00); +*/ + // enable PCMCIA I/O mode + prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, prism2ReadMem(0x3E0+PCMCIA_ATTR_COR) | 0x01); +// prism2CardRegDump(); + + rprintf("Prism2 Initializing...\r\n"); + if( (result = prism2Command(PRISM2_CMD_INIT,0)) ) + { + rprintf("Prism2 Initialization Failure\r\n"); + rprintf("Result Code = %x\r\n",result); + } + + rprintf("Prism2 Initialized\r\n"); + + // set SSID + prism2SetSSID("airdrop"); + + // set max packet size + buffer[0] = 0x0002; + buffer[1] = PRISM2_RID_CNFMAXDATALEN; + buffer[2] = 0x05DC; + prism2WriteRID(PRISM2_RID_CNFMAXDATALEN, 0, buffer, 3); + + // set operating mode / port type + buffer[0] = 0x0002; + buffer[1] = PRISM2_RID_CNFPORTTYPE; + //buffer[2] = 0x0000; // IBSS + buffer[2] = 0x0001; // BSS + prism2WriteRID(PRISM2_RID_CNFPORTTYPE, 0, buffer, 3); + + // set channel +// buffer[0] = 0x0002; +// buffer[1] = 0xFC03; +// buffer[2] = 0x0001; +// prism2WriteRID(0xFC00, 0, buffer, 3); + + // enable the interface + prism2Command(PRISM2_CMD_ENABLE_MAC0,0); +} + +void prism2Off(void) +{ + // turn off communication + prism2Command(PRISM2_CMD_DISABLE_MAC0,0); + // wait for all events to complete + delay_ms(100); + // reset card + prism2Command(PRISM2_CMD_INIT,0); +} + +void prism2GetMacAddress(u08* macaddr) +{ + u16 buffer[5]; + + // read MAC address register + prism2ReadRID(PRISM2_RID_CNFOWNMACADDR, 0, buffer, 5); + + *macaddr++ = buffer[2]; + *macaddr++ = buffer[2]>>8; + *macaddr++ = buffer[3]; + *macaddr++ = buffer[3]>>8; + *macaddr++ = buffer[4]; + *macaddr++ = buffer[4]>>8; +} + +void prism2SetSSID(u08* ssid) +{ + u16 buffer[12]; + + // prepare buffer for SSID write + buffer[0] = 0x0012; + buffer[1] = PRISM2_RID_CNFDESIREDSSID; + buffer[2] = strlen(ssid); + // copy ssid string to buffer + strcpy((unsigned char*)&buffer[3], ssid); + // write SSID + prism2WriteRID(PRISM2_RID_CNFDESIREDSSID, 0, buffer, buffer[0]); +} + +void prism2SetWEPKey(u08* wepkey) +{ + u16 buffer[9]; + + // prepare buffer for SSID write + buffer[0] = 0x0008; + buffer[1] = PRISM2_RID_CNFWEPDEFAULTKEY0; + // copy ssid string to buffer + strncpy((unsigned char*)&buffer[2], wepkey, 13); + buffer[8] &= 0x00FF; + // write SSID + prism2WriteRID(PRISM2_RID_CNFWEPDEFAULTKEY0, 0, buffer, buffer[0]); + + // set WEP active + buffer[0] = 0x0002; + buffer[1] = PRISM2_RID_CNFWEPFLAGS; + buffer[2] = 0x0001; + prism2WriteRID(PRISM2_RID_CNFWEPFLAGS, 0, buffer, buffer[0]); + // set WEP active + buffer[0] = 0x0002; + buffer[1] = 0xfc2a; + buffer[2] = 0x0001; + prism2WriteRID(0xfc2a, 0, buffer, buffer[0]); + // set WEP active + buffer[0] = 0x0002; + buffer[1] = 0xfc23; + buffer[2] = 0x0000; + prism2WriteRID(0xfc23, 0, buffer, buffer[0]); + +} + +u08 prism2Command(u16 cmd, u16 param0) +{ + u16 result; + + // wait until card not busy +// rprintf("PRISM_CMD: Wait until card ready\r\n"); + while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY); + +// rprintf("PRISM_CMD: Issue Command = 0x%x\r\n", cmd); + prism2Write16(PRISM2_REG_PARAM0, param0); + prism2Write16(PRISM2_REG_CMD, cmd); + + // wait until card not busy +// rprintf("PRISM_CMD: Wait until card ready\r\n"); + while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY); + + // read event register - wait for command to complete +// rprintf("PRISM_CMD: Wait for command to complete\r\n"); + while(!(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_CMD)); + + // read status register + result = prism2Read16(PRISM2_REG_STATUS)>>8; +// rprintf("PRISM_CMD: Result = 0x%x\r\n", result>>8); +// rprintf("PRISM_CMD: CmdCode = 0x%x\r\n", result); + + // acknowledge event +// rprintf("PRISM_CMD: Ack command event\r\n"); + prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD); + + // return command result + return result; +} + +u08 prism2ReadRID(u16 id, u16 offset, u16* data, u16 len) +{ + prism2Command(PRISM2_CMD_ACCESS_RD, id); + return prism2ReadBAP0(id, offset, data, len); +} + +u08 prism2WriteRID(u16 id, u16 offset, u16* data, u16 len) +{ + u08 result; + result = prism2WriteBAP0(id, offset, data, len); + prism2Command(PRISM2_CMD_ACCESS_WR, id); + return result; +} + +u08 prism2ReadBAP0(u16 id, u16 offset, u16* data, u16 len) +{ + // wait for BAP to be ready + //rprintf("PRISM_BAP: Wait1\r\n"); + while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY); + // set ID + prism2Write16(PRISM2_REG_BAP0SEL, id); + // set offset + prism2Write16(PRISM2_REG_BAP0OFFSET, offset); + // wait for BAP to be ready + //rprintf("PRISM_BAP: Wait2\r\n"); + while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY); + // check for error + if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR) + return -1; + // read data + //rprintf("PRISM_BAP: Read\r\n"); + while(len--) + *data++ = prism2Read16(PRISM2_REG_BAP0DATA); + // return success + return 0; +} + +u08 prism2WriteBAP0(u16 id, u16 offset, u16* data, u16 len) +{ + // wait for BAP to be ready + //rprintf("PRISM_BAP: Wait1\r\n"); + while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY); + // set ID + prism2Write16(PRISM2_REG_BAP0SEL, id); + // set offset + prism2Write16(PRISM2_REG_BAP0OFFSET, offset); + // wait for BAP to be ready + //rprintf("PRISM_BAP: Wait2\r\n"); + while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY); + // check for error + if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR) + return -1; + // write data + //rprintf("PRISM_BAP: Write\r\n"); + while(len--) + prism2Write16(PRISM2_REG_BAP0DATA, *data++); + // return success + return 0; +} + +void prism2Write(unsigned short address, unsigned char data) +{ + cli(); + // assert the address + outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK)); + outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK)); + // set data bus as output + outb(PRISM2_DATA_DDR, 0xFF); + // place data on bus + outb(PRISM2_DATA_PORT, data); + // assert write + cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR); + // delay + PRISM2_IO_ACCESS_DELAY; + // negate write + sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR); + // set data bus back to input with pullups enabled + outb(PRISM2_DATA_DDR, 0x00); + outb(PRISM2_DATA_PORT, 0xFF); + sei(); +} + +unsigned char prism2Read(unsigned short address) +{ + unsigned char data; + cli(); + // assert the address + outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK)); + outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK)); + // set data bus to input with pullups enabled + outb(PRISM2_DATA_DDR, 0x00); + outb(PRISM2_DATA_PORT, 0xFF); + // assert read + cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD); + // delay + PRISM2_IO_ACCESS_DELAY; + // read in the data + data = inb( PRISM2_DATA_PIN ); + // negate read + sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD); + // return data + sei(); + return data; +} + +void prism2Write16(unsigned short address, unsigned short data) +{ + prism2Write(address, data); + prism2Write(address+1, data>>8); +} + +unsigned short prism2Read16(unsigned short address) +{ + return prism2Read(address) | (prism2Read(address+1)<<8); +} + +void prism2WriteMem(unsigned short address, unsigned short data) +{ + cli(); + // assert the address + outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK)); + outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK)); + // set data bus as output + outb(PRISM2_DATA_DDR, 0xFF); + // place data on bus + outb(PRISM2_DATA_PORT, data); + // assert write + cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR); + // delay + PRISM2_MEM_ACCESS_DELAY; + // negate write + sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR); + // set data bus back to input with pullups enabled + outb(PRISM2_DATA_DDR, 0x00); + outb(PRISM2_DATA_PORT, 0xFF); + sei(); +} + +unsigned short prism2ReadMem(unsigned short address) +{ + unsigned char data; + cli(); + // assert the address + outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK)); + outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK)); + // set data bus to input with pullups enabled + outb(PRISM2_DATA_DDR, 0x00); + outb(PRISM2_DATA_PORT, 0xFF); + // assert read + cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD); + // delay + PRISM2_MEM_ACCESS_DELAY; + // read in the data + data = inb( PRISM2_DATA_PIN ); + // negate read + sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD); + sei(); + // return data + return data; +} + +void prism2CardRegDump(void) +{ + u16 i; + u08 buffer[0x100]; + + rprintfProgStrM("Card Config Registers\r\n"); + rprintfProgStrM("-------------------------------\r\n"); + // read card CIS (16 bytes) + rprintf("CIS : \r\n"); + for(i=0; i<0x100; i++) + buffer[i] = prism2ReadMem(i<<1); + debugPrintHexTable(0x100, buffer); + + rprintfCRLF(); + + rprintf("COR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_COR)); rprintfCRLF(); + rprintf("CSR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_CSR)); rprintfCRLF(); + rprintf("PRR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_PRR)); rprintfCRLF(); + rprintf("SCR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_SCR)); rprintfCRLF(); +} + +void prism2RegDump(void) +{ + rprintfProgStrM("Prism2 Registers\r\n"); + rprintfProgStrM("CMD : "); rprintfu16(prism2Read16(PRISM2_REG_CMD)); rprintfCRLF(); + rprintfProgStrM("PARAM0 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM0)); rprintfCRLF(); + rprintfProgStrM("PARAM1 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM1)); rprintfCRLF(); + rprintfProgStrM("PARAM2 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM2)); rprintfCRLF(); + rprintfProgStrM("STATUS : "); rprintfu16(prism2Read16(PRISM2_REG_STATUS)); rprintfCRLF(); + rprintfProgStrM("RESP0 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP0)); rprintfCRLF(); + rprintfProgStrM("RESP1 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP1)); rprintfCRLF(); + rprintfProgStrM("RESP2 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP2)); rprintfCRLF(); + + rprintfProgStrM("INFOFID : "); rprintfu16(prism2Read16(PRISM2_REG_INFOFID)); rprintfCRLF(); + rprintfProgStrM("RXFID : "); rprintfu16(prism2Read16(PRISM2_REG_RXFID)); rprintfCRLF(); + rprintfProgStrM("ALLOCFID: "); rprintfu16(prism2Read16(PRISM2_REG_ALLOCFID)); rprintfCRLF(); + rprintfProgStrM("TXFID : "); rprintfu16(prism2Read16(PRISM2_REG_TXFID)); rprintfCRLF(); + + rprintfProgStrM("BAP0SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP0SEL)); rprintfCRLF(); + rprintfProgStrM("BAP0OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0OFFSET)); rprintfCRLF(); + rprintfProgStrM("BAP0DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0DATA)); rprintfCRLF(); + + rprintfProgStrM("BAP1SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP1SEL)); rprintfCRLF(); + rprintfProgStrM("BAP1OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1OFFSET)); rprintfCRLF(); + rprintfProgStrM("BAP1DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1DATA)); rprintfCRLF(); + + rprintfProgStrM("EVSTAT : "); rprintfu16(prism2Read16(PRISM2_REG_EVSTAT)); rprintfCRLF(); + rprintfProgStrM("INTEN : "); rprintfu16(prism2Read16(PRISM2_REG_INTEN)); rprintfCRLF(); + rprintfProgStrM("EVACK : "); rprintfu16(prism2Read16(PRISM2_REG_EVACK)); rprintfCRLF(); + + rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP0)); rprintfCRLF(); + rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP1)); rprintfCRLF(); + rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP2)); rprintfCRLF(); + + rprintfProgStrM("AUXPAGE : "); rprintfu16(prism2Read16(PRISM2_REG_AUXPAGE)); rprintfCRLF(); + rprintfProgStrM("AUXOFFS : "); rprintfu16(prism2Read16(PRISM2_REG_AUXOFFSET)); rprintfCRLF(); + rprintfProgStrM("AUXDATA : "); rprintfu16(prism2Read16(PRISM2_REG_AUXDATA)); rprintfCRLF(); + + delay_ms(25); +} diff --git a/3rd party/Procyuon avrlib/net/prism2.h b/3rd party/Procyuon avrlib/net/prism2.h new file mode 100644 index 0000000..dd63d0a --- /dev/null +++ b/3rd party/Procyuon avrlib/net/prism2.h @@ -0,0 +1,229 @@ +/*! \file prism2.h \brief Prism2 802.11b Wireless-LAN Interface Driver. */ +//***************************************************************************** +// +// File Name : 'prism2.h' +// Title : Prism2 802.11b Wireless-LAN Interface Driver +// Author : Pascal Stang +// Created : 12/27/2004 +// Revised : 1/7/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup prism2 PrismII 802.11b WLAN Interface Driver (prism2.c) +/// \code #include "net/prism2.h" \endcode +/// \par Overview +/// This driver provides initialization and transmit/receive +/// functions for the Prism2 802.11b Wireless-LAN Controller. +/// +/// \note This driver works but is still in development. +// +//***************************************************************************** +//@{ + +#ifndef PRISM2_H +#define PRISM2_H + +#include "global.h" + +#define nop() asm volatile ("nop") + +// PRISM2 I/O register defines +#define PRISM2_REG_CMD 0x00 +#define PRISM2_REG_PARAM0 0x02 +#define PRISM2_REG_PARAM1 0x04 +#define PRISM2_REG_PARAM2 0x06 +#define PRISM2_REG_STATUS 0x08 +#define PRISM2_REG_RESP0 0x0A +#define PRISM2_REG_RESP1 0x0C +#define PRISM2_REG_RESP2 0x0E + +#define PRISM2_REG_INFOFID 0x10 +#define PRISM2_REG_RXFID 0x20 +#define PRISM2_REG_ALLOCFID 0x22 +#define PRISM2_REG_TXFID 0x24 + +#define PRISM2_REG_BAP0SEL 0x18 +#define PRISM2_REG_BAP0OFFSET 0x1C +#define PRISM2_REG_BAP0DATA 0x36 + +#define PRISM2_REG_BAP1SEL 0x1A +#define PRISM2_REG_BAP1OFFSET 0x1E +#define PRISM2_REG_BAP1DATA 0x38 + +#define PRISM2_REG_EVSTAT 0x30 +#define PRISM2_REG_INTEN 0x32 +#define PRISM2_REG_EVACK 0x34 + +#define PRISM2_REG_SWSUP0 0x28 +#define PRISM2_REG_SWSUP1 0x2A +#define PRISM2_REG_SWSUP2 0x2C + +#define PRISM2_REG_AUXPAGE 0x3A +#define PRISM2_REG_AUXOFFSET 0x3C +#define PRISM2_REG_AUXDATA 0x3E + + +// PRISM2 commands defines +#define PRISM2_CMD_INIT 0x0000 +#define PRISM2_CMD_ENABLE_MAC0 0x0001 +#define PRISM2_CMD_DISABLE_MAC0 0x0002 +#define PRISM2_CMD_DIAG 0x0003 +#define PRISM2_CMD_ALLOC 0x000A +#define PRISM2_CMD_TX 0x000B +#define PRISM2_CMD_TX_RECL 0x010B +#define PRISM2_CMD_NOTIFY 0x0010 +#define PRISM2_CMD_INQUIRE 0x0011 +#define PRISM2_CMD_ACCESS_RD 0x0021 +#define PRISM2_CMD_ACCESS_WR 0x0121 +#define PRISM2_CMD_BUSY 0x8000 +#define PRISM2_CMD_NORESP 0xFFFF + +// PRISM2 command result codes +#define PRISM2_RESULT_SUCCESS 0x00 +#define PRISM2_RESULT_CARDFAIL 0x01 +#define PRISM2_RESULT_NOBUFFER 0x05 +#define PRISM2_RESULT_CMDERROR 0x7F + +// PRISM2 BAP Offset defines +#define PRISM2_BAPOFFSET_ERROR 0x4000 +#define PRISM2_BAPOFFSET_BUSY 0x8000 + +// PRISM2 event bit defines +#define PRISM2_EVENT_RX 0x0001 +#define PRISM2_EVENT_TX 0x0002 +#define PRISM2_EVENT_TXEXEC 0x0004 +#define PRISM2_EVENT_ALLOC 0x0008 +#define PRISM2_EVENT_CMD 0x0010 +#define PRISM2_EVENT_DTIM 0x0020 +#define PRISM2_EVENT_INFO 0x0080 +#define PRISM2_EVENT_INFDROP 0x2000 +#define PRISM2_EVENT_WTERR 0x4000 +#define PRISM2_EVENT_TICK 0x8000 +#define PRISM2_EVENT_ALL 0xFFFF + +// PRISM2 Record ID defines (RIDs) +#define PRISM2_RID_CNFPORTTYPE 0xFC00 +#define PRISM2_RID_CNFOWNMACADDR 0xFC01 +#define PRISM2_RID_CNFDESIREDSSID 0xFC02 +#define PRISM2_RID_CNFOWNCHANNEL 0xFC03 +#define PRISM2_RID_CNFOWNSSID 0xFC04 +#define PRISM2_RID_CNFOWNATIMWIN 0xFC05 +#define PRISM2_RID_CNFSYSSCALE 0xFC06 +#define PRISM2_RID_CNFMAXDATALEN 0xFC07 +#define PRISM2_RID_CNFWDSADDR 0xFC08 +#define PRISM2_RID_CNFPMENABLED 0xFC09 +#define PRISM2_RID_CNFPMEPS 0xFC0A +#define PRISM2_RID_CNFMULTICASTRX 0xFC0B +#define PRISM2_RID_CNFMAXSLEEPDUR 0xFC0C +#define PRISM2_RID_CNFPMHOLDDUR 0xFC0D +#define PRISM2_RID_CNFOWNNAME 0xFC0E +#define PRISM2_RID_CNFOWNDTIMPER 0xFC10 +#define PRISM2_RID_CNFWDSADDR1 0xFC11 +#define PRISM2_RID_CNFWDSADDR2 0xFC12 +#define PRISM2_RID_CNFWDSADDR3 0xFC13 +#define PRISM2_RID_CNFWDSADDR4 0xFC14 +#define PRISM2_RID_CNFWDSADDR5 0xFC15 +#define PRISM2_RID_CNFWDSADDR6 0xFC16 +#define PRISM2_RID_CNFMCASTPMBUFF 0xFC17 +#define PRISM2_RID_CNFWEPDEFAULTKEYID 0xFC23 +#define PRISM2_RID_CNFWEPDEFAULTKEY0 0xFC24 +#define PRISM2_RID_CNFWEPDEFAULTKEY1 0xFC25 +#define PRISM2_RID_CNFWEPDEFAULTKEY2 0xFC26 +#define PRISM2_RID_CNFWEPDEFAULTKEY3 0xFC27 +#define PRISM2_RID_CNFWEPFLAGS 0xFC28 +#define PRISM2_RID_CNFWEPKEYMAPTABLE 0xFC29 +#define PRISM2_RID_CNFAUTHENTICATION 0xFC2A +#define PRISM2_RID_CNFMAXASSOCSTATIONS 0xFC2B +#define PRISM2_RID_CNFTXCONTROL 0xFC2C +#define PRISM2_RID_CNFROAMINGMODE 0xFC2D +#define PRISM2_RID_CNFHOSTAUTH 0xFC2E +#define PRISM2_RID_CNFRCVCRCERROR 0xFC30 +#define PRISM2_RID_CNFALTRETRYCNT 0xFC32 +#define PRISM2_RID_CNFAPBCNINT 0xFC33 +#define PRISM2_RID_CNFAPPCFINFO 0xFC34 +#define PRISM2_RID_CNFSTAPCFINFO 0xFC35 +#define PRISM2_RID_CNFPRIORITYQUSAGE 0xFC37 +#define PRISM2_RID_CNFTIMCTRL 0xFC40 +#define PRISM2_RID_CNFTHIRTY2TALLY 0xFC42 +#define PRISM2_RID_CNFENHSECURITY 0xFC43 +#define PRISM2_RID_CNFDBMADJUST 0xFC46 +#define PRISM2_RID_SSNGENERICELEMENT 0xFC48 +#define PRISM2_RID_CNFSHORTPREAMBLE 0xFCB0 +#define PRISM2_RID_CNFEXCLONGPREAMBLE 0xFCB1 +#define PRISM2_RID_CNFAUTHRSPTIMEOUT 0xFCB2 +#define PRISM2_RID_CNFBASICRATES 0xFCB3 +#define PRISM2_RID_CNFSUPPRATES 0xFCB4 +#define PRISM2_RID_CNFFALLBACKCTRL 0xFCB5 +#define PRISM2_RID_WEPKEYDISABLE 0xFCB6 +#define PRISM2_RID_WEPKEYMAPINDEX 0xFCB7 +#define PRISM2_RID_BROADCASTKEYID 0xFCB8 +#define PRISM2_RID_ENTSECFLAGEYID 0xFCB9 +#define PRISM2_RID_CNFPASSIVESCANCTRL 0xFCBA +#define PRISM2_RID_SSNHANDLINGMODE 0xFCBB +#define PRISM2_RID_MDCCONTROL 0xFCBC +#define PRISM2_RID_MDCCOUNTRY 0xFCBD +#define PRISM2_RID_TXPOWERMAX 0xFCBE +#define PRISM2_RID_CNFLFOENBLED 0xFCBF +#define PRISM2_RID_CAPINFO 0xFCC0 +#define PRISM2_RID_LISTENINTERVAL 0xFCC1 +#define PRISM2_RID_SCANREQUEST 0xFCE1 +#define PRISM2_RID_JOINREQUEST 0xFCE2 +#define PRISM2_RID_AUTHENTICATESTA 0xFCE3 +#define PRISM2_RID_CHANNELINFOREQUEST 0xFCE4 +#define PRISM2_RID_HOSTSCAN 0xFCE5 + +#define PCMCIA_ATTR_COR 0x0000 +#define PCMCIA_ATTR_CSR 0x0002 +#define PCMCIA_ATTR_PRR 0x0004 +#define PCMCIA_ATTR_SCR 0x0006 +#define PCMCIA_ATTR_IOBASE0 0x0010 +#define PCMCIA_ATTR_IOBASE1 0x0012 +#define PCMCIA_ATTR_IOLIMIT 0x0018 + +// typedefs + +// constants + +// prototypes +#include "nic.h" + + +unsigned int prism2BeginPacketRetreive(void); +void prism2RetreivePacketData(u08* packet, unsigned int packetLength); +void prism2EndPacketRetreive(void); + +void prism2SetupTxHeader(u16* header); +void prism2EventCheck(void); + +// initialize the network interface for transmit/receive +void prism2Init(void); + +void prism2GetMacAddress(u08* macaddr); +void prism2SetSSID(u08* ssid); +void prism2SetWEPKey(u08* wepkey); + +u08 prism2Command(u16 cmd, u16 param0); +u08 prism2WriteBAP0(u16 id, u16 offset, u16* data, u16 len); +u08 prism2ReadBAP0(u16 id, u16 offset, u16* data, u16 len); + +u08 prism2ReadRID(u16 id, u16 offset, u16* data, u16 len); +u08 prism2WriteRID(u16 id, u16 offset, u16* data, u16 len); + + +// hardware access commands +void prism2Write(unsigned short address, unsigned char data); +unsigned char prism2Read(unsigned short address); +void prism2Write16(unsigned short address, unsigned short data); +unsigned short prism2Read16(unsigned short address); +void prism2WriteMem(unsigned short address, unsigned short data); +unsigned short prism2ReadMem(unsigned short address); + +// debugging commands +void prism2CardRegDump(void); +void prism2RegDump(void); + +#endif +//@} + diff --git a/3rd party/Procyuon avrlib/net/prism2rids.h b/3rd party/Procyuon avrlib/net/prism2rids.h new file mode 100644 index 0000000..2520d04 --- /dev/null +++ b/3rd party/Procyuon avrlib/net/prism2rids.h @@ -0,0 +1,330 @@ + +// The contents of this file are believed to come from a linux PRISM2 driver, +// with some changes made by Pascal Stang. + +/*--- Record ID Constants --------------------------*/ +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Static Configuration Entities +--------------------------------------------------------------------*/ +#define PRISM2_RID_CNFPORTTYPE ((UINT16)0xFC00) +#define PRISM2_RID_CNFOWNMACADDR ((UINT16)0xFC01) +#define PRISM2_RID_CNFDESIREDSSID ((UINT16)0xFC02) +#define PRISM2_RID_CNFOWNCHANNEL ((UINT16)0xFC03) +#define PRISM2_RID_CNFOWNSSID ((UINT16)0xFC04) +#define PRISM2_RID_CNFOWNATIMWIN ((UINT16)0xFC05) +#define PRISM2_RID_CNFSYSSCALE ((UINT16)0xFC06) +#define PRISM2_RID_CNFMAXDATALEN ((UINT16)0xFC07) +#define PRISM2_RID_CNFWDSADDR ((UINT16)0xFC08) +#define PRISM2_RID_CNFPMENABLED ((UINT16)0xFC09) +#define PRISM2_RID_CNFPMEPS ((UINT16)0xFC0A) +#define PRISM2_RID_CNFMULTICASTRX ((UINT16)0xFC0B) +#define PRISM2_RID_CNFMAXSLEEPDUR ((UINT16)0xFC0C) +#define PRISM2_RID_CNFPMHOLDDUR ((UINT16)0xFC0D) +#define PRISM2_RID_CNFOWNNAME ((UINT16)0xFC0E) +#define PRISM2_RID_CNFOWNDTIMPER ((UINT16)0xFC10) +#define PRISM2_RID_CNFWDSADDR1 ((UINT16)0xFC11) +#define PRISM2_RID_CNFWDSADDR2 ((UINT16)0xFC12) +#define PRISM2_RID_CNFWDSADDR3 ((UINT16)0xFC13) +#define PRISM2_RID_CNFWDSADDR4 ((UINT16)0xFC14) +#define PRISM2_RID_CNFWDSADDR5 ((UINT16)0xFC15) +#define PRISM2_RID_CNFWDSADDR6 ((UINT16)0xFC16) +#define PRISM2_RID_CNFMCASTPMBUFF ((UINT16)0xFC17) + +/*-------------------------------------------------------------------- +Configuration RID lengths: Network Params, Static Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define PRISM2_RID_CNFPORTTYPE_LEN ((UINT16)2) +#define PRISM2_RID_CNFOWNMACADDR_LEN ((UINT16)6) +#define PRISM2_RID_CNFDESIREDSSID_LEN ((UINT16)34) +#define PRISM2_RID_CNFOWNCHANNEL_LEN ((UINT16)2) +#define PRISM2_RID_CNFOWNSSID_LEN ((UINT16)34) +#define PRISM2_RID_CNFOWNATIMWIN_LEN ((UINT16)2) +#define PRISM2_RID_CNFSYSSCALE_LEN ((UINT16)0) +#define PRISM2_RID_CNFMAXDATALEN_LEN ((UINT16)0) +#define PRISM2_RID_CNFWDSADDR_LEN ((UINT16)6) +#define PRISM2_RID_CNFPMENABLED_LEN ((UINT16)0) +#define PRISM2_RID_CNFPMEPS_LEN ((UINT16)0) +#define PRISM2_RID_CNFMULTICASTRX_LEN ((UINT16)0) +#define PRISM2_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) +#define PRISM2_RID_CNFPMHOLDDUR_LEN ((UINT16)0) +#define PRISM2_RID_CNFOWNNAME_LEN ((UINT16)34) +#define PRISM2_RID_CNFOWNDTIMPER_LEN ((UINT16)0) +#define PRISM2_RID_CNFWDSADDR1_LEN ((UINT16)6) +#define PRISM2_RID_CNFWDSADDR2_LEN ((UINT16)6) +#define PRISM2_RID_CNFWDSADDR3_LEN ((UINT16)6) +#define PRISM2_RID_CNFWDSADDR4_LEN ((UINT16)6) +#define PRISM2_RID_CNFWDSADDR5_LEN ((UINT16)6) +#define PRISM2_RID_CNFWDSADDR6_LEN ((UINT16)6) +#define PRISM2_RID_CNFMCASTPMBUFF_LEN ((UINT16)0) +#define PRISM2_RID_CNFAUTHENTICATION_LEN ((UINT16)sizeof(UINT16)) +#define PRISM2_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Dynamic Configuration Entities +--------------------------------------------------------------------*/ +#define PRISM2_RID_GROUPADDR ((UINT16)0xFC80) +#define PRISM2_RID_CREATEIBSS ((UINT16)0xFC81) +#define PRISM2_RID_FRAGTHRESH ((UINT16)0xFC82) +#define PRISM2_RID_RTSTHRESH ((UINT16)0xFC83) +#define PRISM2_RID_TXRATECNTL ((UINT16)0xFC84) +#define PRISM2_RID_PROMISCMODE ((UINT16)0xFC85) +#define PRISM2_RID_FRAGTHRESH0 ((UINT16)0xFC90) +#define PRISM2_RID_FRAGTHRESH1 ((UINT16)0xFC91) +#define PRISM2_RID_FRAGTHRESH2 ((UINT16)0xFC92) +#define PRISM2_RID_FRAGTHRESH3 ((UINT16)0xFC93) +#define PRISM2_RID_FRAGTHRESH4 ((UINT16)0xFC94) +#define PRISM2_RID_FRAGTHRESH5 ((UINT16)0xFC95) +#define PRISM2_RID_FRAGTHRESH6 ((UINT16)0xFC96) +#define PRISM2_RID_RTSTHRESH0 ((UINT16)0xFC97) +#define PRISM2_RID_RTSTHRESH1 ((UINT16)0xFC98) +#define PRISM2_RID_RTSTHRESH2 ((UINT16)0xFC99) +#define PRISM2_RID_RTSTHRESH3 ((UINT16)0xFC9A) +#define PRISM2_RID_RTSTHRESH4 ((UINT16)0xFC9B) +#define PRISM2_RID_RTSTHRESH5 ((UINT16)0xFC9C) +#define PRISM2_RID_RTSTHRESH6 ((UINT16)0xFC9D) +#define PRISM2_RID_TXRATECNTL0 ((UINT16)0xFC9E) +#define PRISM2_RID_TXRATECNTL1 ((UINT16)0xFC9F) +#define PRISM2_RID_TXRATECNTL2 ((UINT16)0xFCA0) +#define PRISM2_RID_TXRATECNTL3 ((UINT16)0xFCA1) +#define PRISM2_RID_TXRATECNTL4 ((UINT16)0xFCA2) +#define PRISM2_RID_TXRATECNTL5 ((UINT16)0xFCA3) +#define PRISM2_RID_TXRATECNTL6 ((UINT16)0xFCA4) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Network Param, Dynamic Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define PRISM2_RID_GROUPADDR_LEN ((UINT16)16 * WLAN_ADDR_LEN) +#define PRISM2_RID_CREATEIBSS_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL_LEN ((UINT16)4) +#define PRISM2_RID_PROMISCMODE_LEN ((UINT16)2) +#define PRISM2_RID_FRAGTHRESH0_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH1_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH2_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH3_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH4_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH5_LEN ((UINT16)0) +#define PRISM2_RID_FRAGTHRESH6_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH0_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH1_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH2_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH3_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH4_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH5_LEN ((UINT16)0) +#define PRISM2_RID_RTSTHRESH6_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL0_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL1_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL2_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL3_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL4_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL5_LEN ((UINT16)0) +#define PRISM2_RID_TXRATECNTL6_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Behavior Parameters +--------------------------------------------------------------------*/ +#define PRISM2_RID_ITICKTIME ((UINT16)0xFCE0) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Behavior Parameters + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define PRISM2_RID_ITICKTIME_LEN ((UINT16)2) + +/*---------------------------------------------------------------------- +Information RIDs: NIC Information +--------------------------------------------------------------------*/ +#define PRISM2_RID_MAXLOADTIME ((UINT16)0xFD00) +#define PRISM2_RID_DOWNLOADBUFFER ((UINT16)0xFD01) +#define PRISM2_RID_PRIIDENTITY ((UINT16)0xFD02) +#define PRISM2_RID_PRISUPRANGE ((UINT16)0xFD03) +#define PRISM2_RID_PRI_CFIACTRANGES ((UINT16)0xFD04) +#define PRISM2_RID_NICSERIALNUMBER ((UINT16)0xFD0A) +#define PRISM2_RID_NICIDENTITY ((UINT16)0xFD0B) +#define PRISM2_RID_MFISUPRANGE ((UINT16)0xFD0C) +#define PRISM2_RID_CFISUPRANGE ((UINT16)0xFD0D) +#define PRISM2_RID_CHANNELLIST ((UINT16)0xFD10) +#define PRISM2_RID_REGULATORYDOMAINS ((UINT16)0xFD11) +#define PRISM2_RID_TEMPTYPE ((UINT16)0xFD12) +#define PRISM2_RID_CIS ((UINT16)0xFD13) +#define PRISM2_RID_STAIDENTITY ((UINT16)0xFD20) +#define PRISM2_RID_STASUPRANGE ((UINT16)0xFD21) +#define PRISM2_RID_STA_MFIACTRANGES ((UINT16)0xFD22) +#define PRISM2_RID_STA_CFIACTRANGES ((UINT16)0xFD23) +#define PRISM2_RID_BUILDSEQ ((UINT16)0xFFFE) +#define PRISM2_RID_FWID ((UINT16)0xFFFF) + +/*---------------------------------------------------------------------- +Information RID Lengths: NIC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define PRISM2_RID_MAXLOADTIME_LEN ((UINT16)0) +#define PRISM2_RID_DOWNLOADBUFFER_LEN ((UINT16)sizeof(PRISM2_downloadbuffer_t)) +#define PRISM2_RID_PRIIDENTITY_LEN ((UINT16)8) +#define PRISM2_RID_PRISUPRANGE_LEN ((UINT16)10) +#define PRISM2_RID_CFIACTRANGES_LEN ((UINT16)10) +#define PRISM2_RID_NICSERIALNUMBER_LEN ((UINT16)12) +#define PRISM2_RID_NICIDENTITY_LEN ((UINT16)8) +#define PRISM2_RID_MFISUPRANGE_LEN ((UINT16)10) +#define PRISM2_RID_CFISUPRANGE_LEN ((UINT16)10) +#define PRISM2_RID_CHANNELLIST_LEN ((UINT16)0) +#define PRISM2_RID_REGULATORYDOMAINS_LEN ((UINT16)12) +#define PRISM2_RID_TEMPTYPE_LEN ((UINT16)0) +#define PRISM2_RID_CIS_LEN ((UINT16)480) +#define PRISM2_RID_STAIDENTITY_LEN ((UINT16)8) +#define PRISM2_RID_STASUPRANGE_LEN ((UINT16)10) +#define PRISM2_RID_MFIACTRANGES_LEN ((UINT16)10) +#define PRISM2_RID_CFIACTRANGES2_LEN ((UINT16)10) +#define PRISM2_RID_BUILDSEQ_LEN ((UINT16)sizeof(PRISM2_BuildSeq_t)) +#define PRISM2_RID_FWID_LEN ((UINT16)sizeof(PRISM2_FWID_t)) + +/*-------------------------------------------------------------------- +Information RIDs: MAC Information +--------------------------------------------------------------------*/ +#define PRISM2_RID_PORTSTATUS ((UINT16)0xFD40) +#define PRISM2_RID_CURRENTSSID ((UINT16)0xFD41) +#define PRISM2_RID_CURRENTBSSID ((UINT16)0xFD42) +#define PRISM2_RID_COMMSQUALITY ((UINT16)0xFD43) +#define PRISM2_RID_CURRENTTXRATE ((UINT16)0xFD44) +#define PRISM2_RID_CURRENTBCNINT ((UINT16)0xFD45) +#define PRISM2_RID_CURRENTSCALETHRESH ((UINT16)0xFD46) +#define PRISM2_RID_PROTOCOLRSPTIME ((UINT16)0xFD47) +#define PRISM2_RID_SHORTRETRYLIMIT ((UINT16)0xFD48) +#define PRISM2_RID_LONGRETRYLIMIT ((UINT16)0xFD49) +#define PRISM2_RID_MAXTXLIFETIME ((UINT16)0xFD4A) +#define PRISM2_RID_MAXRXLIFETIME ((UINT16)0xFD4B) +#define PRISM2_RID_CFPOLLABLE ((UINT16)0xFD4C) +#define PRISM2_RID_AUTHALGORITHMS ((UINT16)0xFD4D) +#define PRISM2_RID_PRIVACYOPTIMP ((UINT16)0xFD4F) +#define PRISM2_RID_DBMCOMMSQUALITY ((UINT16)0xFD51) +#define PRISM2_RID_CURRENTTXRATE1 ((UINT16)0xFD80) +#define PRISM2_RID_CURRENTTXRATE2 ((UINT16)0xFD81) +#define PRISM2_RID_CURRENTTXRATE3 ((UINT16)0xFD82) +#define PRISM2_RID_CURRENTTXRATE4 ((UINT16)0xFD83) +#define PRISM2_RID_CURRENTTXRATE5 ((UINT16)0xFD84) +#define PRISM2_RID_CURRENTTXRATE6 ((UINT16)0xFD85) +#define PRISM2_RID_OWNMACADDRESS ((UINT16)0xFD86) +// #define PRISM2_RID_PCFINFO ((UINT16)0xFD87) +#define PRISM2_RID_SCANRESULTS ((UINT16)0xFD88) // NEW +#define PRISM2_RID_HOSTSCANRESULTS ((UINT16)0xFD89) // NEW +#define PRISM2_RID_AUTHENTICATIONUSED ((UINT16)0xFD8A) // NEW + +/*-------------------------------------------------------------------- +Information RID Lengths: MAC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define PRISM2_RID_PORTSTATUS_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTSSID_LEN ((UINT16)34) +#define PRISM2_RID_CURRENTBSSID_LEN ((UINT16)WLAN_BSSID_LEN) +#define PRISM2_RID_COMMSQUALITY_LEN ((UINT16)sizeof(PRISM2_commsquality_t)) +#define PRISM2_RID_DBMCOMMSQUALITY_LEN ((UINT16)sizeof(PRISM2_dbmcommsquality_t)) +#define PRISM2_RID_CURRENTTXRATE_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTBCNINT_LEN ((UINT16)0) +#define PRISM2_RID_STACURSCALETHRESH_LEN ((UINT16)12) +#define PRISM2_RID_APCURSCALETHRESH_LEN ((UINT16)6) +#define PRISM2_RID_PROTOCOLRSPTIME_LEN ((UINT16)0) +#define PRISM2_RID_SHORTRETRYLIMIT_LEN ((UINT16)0) +#define PRISM2_RID_LONGRETRYLIMIT_LEN ((UINT16)0) +#define PRISM2_RID_MAXTXLIFETIME_LEN ((UINT16)0) +#define PRISM2_RID_MAXRXLIFETIME_LEN ((UINT16)0) +#define PRISM2_RID_CFPOLLABLE_LEN ((UINT16)0) +#define PRISM2_RID_AUTHALGORITHMS_LEN ((UINT16)4) +#define PRISM2_RID_PRIVACYOPTIMP_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE1_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE2_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE3_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE4_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE5_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTTXRATE6_LEN ((UINT16)0) +#define PRISM2_RID_OWNMACADDRESS_LEN ((UINT16)6) +#define PRISM2_RID_PCFINFO_LEN ((UINT16)6) +#define PRISM2_RID_CNFAPPCFINFO_LEN ((UINT16)sizeof(PRISM2_PCFInfo_data_t)) +#define PRISM2_RID_SCANREQUEST_LEN ((UINT16)sizeof(PRISM2_ScanRequest_data_t)) +#define PRISM2_RID_JOINREQUEST_LEN ((UINT16)sizeof(PRISM2_JoinRequest_data_t)) +#define PRISM2_RID_AUTHENTICATESTA_LEN ((UINT16)sizeof(PRISM2_authenticateStation_data_t)) +#define PRISM2_RID_CHANNELINFOREQUEST_LEN ((UINT16)sizeof(PRISM2_ChannelInfoRequest_data_t)) +/*-------------------------------------------------------------------- +Information RIDs: Modem Information +--------------------------------------------------------------------*/ +#define PRISM2_RID_PHYTYPE ((UINT16)0xFDC0) +#define PRISM2_RID_CURRENTCHANNEL ((UINT16)0xFDC1) +#define PRISM2_RID_CURRENTPOWERSTATE ((UINT16)0xFDC2) +#define PRISM2_RID_CCAMODE ((UINT16)0xFDC3) +#define PRISM2_RID_SUPPORTEDDATARATES ((UINT16)0xFDC6) +#define PRISM2_RID_LFOSTATUS ((UINT16)0xFDC7) // 1.7.1 + +/*-------------------------------------------------------------------- +Information RID Lengths: Modem Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define PRISM2_RID_PHYTYPE_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTCHANNEL_LEN ((UINT16)0) +#define PRISM2_RID_CURRENTPOWERSTATE_LEN ((UINT16)0) +#define PRISM2_RID_CCAMODE_LEN ((UINT16)0) +#define PRISM2_RID_SUPPORTEDDATARATES_LEN ((UINT16)10) + +/*-------------------------------------------------------------------- +API ENHANCEMENTS (NOT ALREADY IMPLEMENTED) +--------------------------------------------------------------------*/ +#define PRISM2_RID_CNFWEPDEFAULTKEYID ((UINT16)0xFC23) +#define PRISM2_RID_CNFWEPDEFAULTKEY0 ((UINT16)0xFC24) +#define PRISM2_RID_CNFWEPDEFAULTKEY1 ((UINT16)0xFC25) +#define PRISM2_RID_CNFWEPDEFAULTKEY2 ((UINT16)0xFC26) +#define PRISM2_RID_CNFWEPDEFAULTKEY3 ((UINT16)0xFC27) +#define PRISM2_RID_CNFWEPFLAGS ((UINT16)0xFC28) +#define PRISM2_RID_CNFWEPKEYMAPTABLE ((UINT16)0xFC29) +#define PRISM2_RID_CNFAUTHENTICATION ((UINT16)0xFC2A) +#define PRISM2_RID_CNFMAXASSOCSTATIONS ((UINT16)0xFC2B) +#define PRISM2_RID_CNFTXCONTROL ((UINT16)0xFC2C) +#define PRISM2_RID_CNFROAMINGMODE ((UINT16)0xFC2D) +#define PRISM2_RID_CNFHOSTAUTH ((UINT16)0xFC2E) +#define PRISM2_RID_CNFRCVCRCERROR ((UINT16)0xFC30) +// #define PRISM2_RID_CNFMMLIFE ((UINT16)0xFC31) +#define PRISM2_RID_CNFALTRETRYCNT ((UINT16)0xFC32) +#define PRISM2_RID_CNFAPBCNINT ((UINT16)0xFC33) +#define PRISM2_RID_CNFAPPCFINFO ((UINT16)0xFC34) +#define PRISM2_RID_CNFSTAPCFINFO ((UINT16)0xFC35) +#define PRISM2_RID_CNFPRIORITYQUSAGE ((UINT16)0xFC37) +#define PRISM2_RID_CNFTIMCTRL ((UINT16)0xFC40) +#define PRISM2_RID_CNFTHIRTY2TALLY ((UINT16)0xFC42) +#define PRISM2_RID_CNFENHSECURITY ((UINT16)0xFC43) +#define PRISM2_RID_CNFDBMADJUST ((UINT16)0xFC46) // NEW +#define PRISM2_RID_SSNGENERICELEMENT ((UINT16)0xFC48) // 1.7.0 +#define PRISM2_RID_CNFSHORTPREAMBLE ((UINT16)0xFCB0) +#define PRISM2_RID_CNFEXCLONGPREAMBLE ((UINT16)0xFCB1) +#define PRISM2_RID_CNFAUTHRSPTIMEOUT ((UINT16)0xFCB2) +#define PRISM2_RID_CNFBASICRATES ((UINT16)0xFCB3) +#define PRISM2_RID_CNFSUPPRATES ((UINT16)0xFCB4) +#define PRISM2_RID_CNFFALLBACKCTRL ((UINT16)0xFCB5) // NEW +#define PRISM2_RID_WEPKEYDISABLE ((UINT16)0xFCB6) // NEW +#define PRISM2_RID_WEPKEYMAPINDEX ((UINT16)0xFCB7) // NEW +#define PRISM2_RID_BROADCASTKEYID ((UINT16)0xFCB8) // NEW +#define PRISM2_RID_ENTSECFLAGEYID ((UINT16)0xFCB9) // NEW +#define PRISM2_RID_CNFPASSIVESCANCTRL ((UINT16)0xFCBA) // NEW STA +#define PRISM2_RID_SSNHANDLINGMODE ((UINT16)0xFCBB) // 1.7.0 +#define PRISM2_RID_MDCCONTROL ((UINT16)0xFCBC) // 1.7.0/1.4.0 +#define PRISM2_RID_MDCCOUNTRY ((UINT16)0xFCBD) // 1.7.0/1.4.0 +#define PRISM2_RID_TXPOWERMAX ((UINT16)0xFCBE) // 1.7.0/1.4.0 +#define PRISM2_RID_CNFLFOENBLED ((UINT16)0xFCBF) // 1.6.3 +#define PRISM2_RID_CAPINFO ((UINT16)0xFCC0) // 1.7.0/1.3.7 +#define PRISM2_RID_LISTENINTERVAL ((UINT16)0xFCC1) // 1.7.0/1.3.7 +#define PRISM2_RID_SCANREQUEST (UINT16)0xFCE1) +#define PRISM2_RID_JOINREQUEST ((UINT16)0xFCE2) +#define PRISM2_RID_AUTHENTICATESTA ((UINT16)0xFCE3) +#define PRISM2_RID_CHANNELINFOREQUEST ((UINT16)0xFCE4) +#define PRISM2_RID_HOSTSCAN ((UINT16)0xFCE5) // NEW STA + +#define PRISM2_RID_CNFWEPDEFAULTKEY_LEN ((UINT16)6) +#define PRISM2_RID_CNFWEP128DEFAULTKEY_LEN ((UINT16)14) +#define PRISM2_RID_CNFPRIOQUSAGE_LEN ((UINT16)4) diff --git a/3rd party/Procyuon avrlib/net/rtl8019.c b/3rd party/Procyuon avrlib/net/rtl8019.c new file mode 100644 index 0000000..fe4fcbf --- /dev/null +++ b/3rd party/Procyuon avrlib/net/rtl8019.c @@ -0,0 +1,523 @@ +/*! \file rtl8019.c \brief Realtek RTL8019AS Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'rtl8019.c' +// Title : Realtek RTL8019AS Ethernet Interface Driver +// Author : Pascal Stang +// Created : 7/6/2004 +// Revised : 10/1/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Based in part on code by Louis Beaudoin (www.embedded-creations.com). +// Thanks to Adam Dunkels and Louis Beaudoin for providing the initial +// structure in which to write this driver. +//***************************************************************************** + +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "rtl8019.h" + +// include configuration +#include "rtl8019conf.h" + +// pointers to locations in the RTL8019 receive buffer +static unsigned char NextPage; // page pointer to next Rx packet +static unsigned int CurrentRetreiveAddress; // DMA address for read Rx packet location + + +void nicInit(void) +{ + rtl8019Init(); +} + +void nicSend(unsigned int len, unsigned char* packet) +{ + rtl8019BeginPacketSend(len); + rtl8019SendPacketData(packet, len); + rtl8019EndPacketSend(); +} + +unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) +{ + unsigned int packetLength; + + packetLength = rtl8019BeginPacketRetreive(); + + // if there's no packet or an error - exit without ending the operation + if( !packetLength ) + return 0; + + // drop anything too big for the buffer + if( packetLength > maxlen ) + { + rtl8019EndPacketRetreive(); + return 0; + } + + // copy the packet data into the packet buffer + rtl8019RetreivePacketData( packet, packetLength ); + rtl8019EndPacketRetreive(); + + return packetLength; +} + +void nicGetMacAddress(u08* macaddr) +{ + u08 tempCR; + // switch register pages + tempCR = rtl8019Read(CR); + rtl8019Write(CR,tempCR|PS0); + // read MAC address registers + *macaddr++ = rtl8019Read(PAR0); + *macaddr++ = rtl8019Read(PAR1); + *macaddr++ = rtl8019Read(PAR2); + *macaddr++ = rtl8019Read(PAR3); + *macaddr++ = rtl8019Read(PAR4); + *macaddr++ = rtl8019Read(PAR5); + // switch register pages back + rtl8019Write(CR,tempCR); +} + +void nicSetMacAddress(u08* macaddr) +{ + u08 tempCR; + // switch register pages + tempCR = rtl8019Read(CR); + rtl8019Write(CR,tempCR|PS0); + // write MAC address registers + rtl8019Write(PAR0, *macaddr++); + rtl8019Write(PAR1, *macaddr++); + rtl8019Write(PAR2, *macaddr++); + rtl8019Write(PAR3, *macaddr++); + rtl8019Write(PAR4, *macaddr++); + rtl8019Write(PAR5, *macaddr++); + // switch register pages back + rtl8019Write(CR,tempCR); +} + +void nicRegDump(void) +{ + rtl8019RegDump(); +} + + +void rtl8019SetupPorts(void) +{ +#if NIC_CONNECTION == MEMORY_MAPPED + // enable external SRAM interface - no wait states + sbi(MCUCR, SRE); +// sbi(MCUCR, SRW10); +// sbi(XMCRA, SRW00); +// sbi(XMCRA, SRW01); +// sbi(XMCRA, SRW11); +#else + // make the address port output + RTL8019_ADDRESS_DDR |= RTL8019_ADDRESS_MASK; + // make the data port input with pull-ups + RTL8019_DATA_PORT = 0xFF; + + // initialize the control port read and write pins to de-asserted + RTL8019_CONTROL_DDR |= (1<=ETHERNET_MIN_PACKET_LENGTH)? + (packetLength):ETHERNET_MIN_PACKET_LENGTH; + + //start the NIC + rtl8019Write(CR, (RD2|START)); + + // still transmitting a packet - wait for it to finish + while( rtl8019Read(CR) & TXP ); + + // load beginning page for transmit buffer + rtl8019Write(TPSR,TXSTART_INIT); + + // set start address for remote DMA operation + rtl8019Write(RSAR0,0x00); + rtl8019Write(RSAR1,0x40); + + // clear the packet stored interrupt + rtl8019Write(ISR,PTX); + + // load data byte count for remote DMA + rtl8019Write(RBCR0, (unsigned char)(packetLength)); + rtl8019Write(RBCR1, (unsigned char)(packetLength>>8)); + + rtl8019Write(TBCR0, (unsigned char)(sendPacketLength)); + rtl8019Write(TBCR1, (unsigned char)((sendPacketLength)>>8)); + + // do remote write operation + rtl8019Write(CR,(RD1|START)); +} + + +void rtl8019SendPacketData(unsigned char *localBuffer, unsigned int length) +{ + unsigned int i; + + // write data to DMA port + for(i=0;i= RXSTOP_INIT) || (bnry < RXSTART_INIT) ) + { + // reset the contents of the buffer and exit + rtl8019Write(BNRY, RXSTART_INIT); + rtl8019Write(CR, (PS0|RD2|START)); + rtl8019Write(CPR, RXSTART_INIT); + rtl8019Write(CR, (RD2|START)); + return 0; + } + + // initiate DMA to transfer the RTL8019 packet header + rtl8019Write(RBCR0, 4); + rtl8019Write(RBCR1, 0); + rtl8019Write(RSAR0, 0); + rtl8019Write(RSAR1, bnry); + rtl8019Write(CR, (RD0|START)); + // transfer packet header + for(i=0;i<4;i++) + pageheader[i] = rtl8019Read(RDMAPORT); + // end the DMA operation + rtl8019Write(CR, (RD2|START)); + // wait for remote DMA complete + for(i = 0; i < 20; i++) + if(rtl8019Read(ISR) & RDC) + break; + rtl8019Write(ISR, RDC); + + rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL]; + NextPage = pageheader[PKTHEADER_NEXTPAGE]; + + CurrentRetreiveAddress = (bnry<<8) + 4; + + // if the NextPage pointer is invalid, the packet is not ready yet - exit + if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) ) + return 0; + + return rxlen-4; +} + + +void rtl8019RetreivePacketData(unsigned char * localBuffer, unsigned int length) +{ + unsigned int i; + + // initiate DMA to transfer the data + rtl8019Write(RBCR0, (unsigned char)length); + rtl8019Write(RBCR1, (unsigned char)(length>>8)); + rtl8019Write(RSAR0, (unsigned char)CurrentRetreiveAddress); + rtl8019Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8)); + rtl8019Write(CR, (RD0|START)); + // transfer packet data + for(i=0;i= 0x6000 ) + CurrentRetreiveAddress = CurrentRetreiveAddress - (0x6000-0x4600) ; +} + + +void rtl8019EndPacketRetreive(void) +{ + unsigned char i; + + // end the DMA operation + rtl8019Write(CR, (RD2|START)); + // wait for remote DMA complete + for(i=0; i<20; i++) + if(rtl8019Read(ISR) & RDC) + break; + rtl8019Write(ISR, RDC); + + // set the boundary register to point to the start of the next packet + rtl8019Write(BNRY, NextPage); +} + + +void rtl8019ProcessInterrupt(void) +{ + unsigned char byte = rtl8019Read(ISR); + + if( byte & OVW ) + rtl8019ReceiveOverflowRecover(); +} + +void rtl8019ReceiveOverflowRecover(void) +{ + unsigned char data_L, resend; + + data_L = rtl8019Read(CR); + rtl8019Write(CR, 0x21); + delay_ms(2); + rtl8019Write(RBCR0, 0x00); + rtl8019Write(RBCR1, 0x00); + if(!(data_L & 0x04)) + resend = 0; + else if(data_L & 0x04) + { + data_L = rtl8019Read(ISR); + if((data_L & 0x02) || (data_L & 0x08)) + resend = 0; + else + resend = 1; + } + + rtl8019Write(TCR, 0x02); + rtl8019Write(CR, 0x22); + rtl8019Write(BNRY, RXSTART_INIT); + rtl8019Write(CR, 0x62); + rtl8019Write(CPR, RXSTART_INIT); + rtl8019Write(CR, 0x22); + rtl8019Write(ISR, 0x10); + rtl8019Write(TCR, TCR_INIT); + + if(resend) + rtl8019Write(CR, 0x26); + + rtl8019Write(ISR, 0xFF); +} + + +void rtl8019RegDump(void) +{ +// unsigned char result; +// result = rtl8019Read(TR); + +// rprintf("Media State: "); +// if(!(result & AUTOD)) +// rprintf("Autonegotiation\r\n"); +// else if(result & RST_B) +// rprintf("PHY in Reset \r\n"); +// else if(!(result & RST_10B)) +// rprintf("10BASE-T \r\n"); +// else if(!(result & RST_TXB)) +// rprintf("100BASE-T \r\n"); + + //rprintf("TR regsiter : %x\r\n",result); + //result = read_mii(0x10,0); + //rprintf("MII regsiter 0x10: %x\r\n",result); + + rprintf("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n"); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(CR)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(BNRY)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(PSTART)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(PSTOP)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(ISR)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(TSR)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(RSR)); + rprintfProgStrM(" "); +// rprintfu08(rtl8019Read(MEMR)); + rprintfProgStrM(" "); +// rprintfu08(rtl8019Read(TR)); + rprintfProgStrM(" "); +// rprintfu08(rtl8019Read(GPI)); + rprintfCRLF(); + + rtl8019Write(CR,rtl8019Read(CR)|PS0); + + rprintf("Page1: CR PAR CPR\r\n"); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(CR)); + rprintfProgStrM(" "); + rprintfChar(rtl8019Read(PAR0)); + rprintfChar(rtl8019Read(PAR1)); + rprintfChar(rtl8019Read(PAR2)); + rprintfChar(rtl8019Read(PAR3)); + rprintfChar(rtl8019Read(PAR4)); + rprintfChar(rtl8019Read(PAR5)); + rprintfProgStrM(" "); + rprintfu08(rtl8019Read(CPR)); + + rtl8019Write(CR,rtl8019Read(CR)&~PS0); + + delay_ms(25); +} + diff --git a/3rd party/Procyuon avrlib/net/rtl8019.h b/3rd party/Procyuon avrlib/net/rtl8019.h new file mode 100644 index 0000000..4e7cc3c --- /dev/null +++ b/3rd party/Procyuon avrlib/net/rtl8019.h @@ -0,0 +1,190 @@ +/*! \file rtl8019.h \brief Realtek RTL8019AS Ethernet Interface Driver. */ +//***************************************************************************** +// +// File Name : 'rtl8019.h' +// Title : Realtek RTL8019AS Ethernet Interface Driver +// Author : Pascal Stang +// Created : 7/6/2004 +// Revised : 8/22/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup network +/// \defgroup rtl8019 Realtek RTL8019AS Ethernet Interface Driver (rtl8019.c) +/// \code #include "net/rtl8019.h" \endcode +/// \par Overview +/// This driver provides initialization and transmit/receive +/// functions for the Realtek RTL8019AS 10Mb Ethernet Controller and PHY. +/// +/// Based in part on code by Louis Beaudoin (www.embedded-creations.com). +/// Thanks to Adam Dunkels and Louis Beaudoin for providing the initial +/// structure in which to write this driver. +// +//***************************************************************************** +//@{ + +#ifndef RTL8019_H +#define RTL8019_H + +#define nop() asm volatile ("nop") + +// RTL8019 Control Register Offsets +// Page 0 - Read/Write +#define CR 0x00 // Command Register +#define PSTART 0x01 // Page Start Register +#define PSTOP 0x02 // Page Stop Register +#define BNRY 0x03 // Boundary Pointer +#define RDMAPORT 0x10 // DMA Data Port +#define MEMR 0x14 // MII/EEPROM Access Register +#define TR 0x15 // Test Register +#define SPP_DPR 0x18 // Standard Printer Port Data +#define SSP_SPR 0x19 // Standard Printer Port Status +#define SSP_CPR 0x1A // Standard Printer Port Control +// Page 0 - Read +#define TSR 0x04 // Transmit Status Register +#define NCR 0x05 // Number of Collisions Register +#define ISR 0x07 // Interrupt Status Register +#define CRDA0 0x08 // Current Remote DMA Address 0 +#define CRDA1 0x09 // Current Remote DMA Address 1 +#define RSR 0x0C // Receive Status Register +#define CNTR0 0x0D +#define CNTR1 0x0E +#define CNTR2 0x0F +#define GPI 0x17 // General-Purpose Input +#define RSTPORT 0x1F // Reset +// Page 0 - Write +#define TPSR 0x04 // Transmit Page Start Address +#define TBCR0 0x05 // Transmit Byte Count Register 0 +#define TBCR1 0x06 // Transmit Byte Count Register 1 +#define RSAR0 0x08 // Remote Start Address Register 0 +#define RSAR1 0x09 // Remote Start Address Register 1 +#define RBCR0 0x0A // Remote Byte Count 0 +#define RBCR1 0x0B // Remote Byte Count 1 +#define RCR 0x0C // Receive Config Register +#define TCR 0x0D // Transmit Config Register +#define DCR 0x0E // Data Config Register +#define IMR 0x0F // Interrupt Mask Register +#define GPOC 0x17 // General-Purpose Output Control +// Page 1 - Read/Write +#define PAR0 0x01 // Physical Address Register 0 +#define PAR1 0x02 // Physical Address Register 1 +#define PAR2 0x03 // Physical Address Register 2 +#define PAR3 0x04 // Physical Address Register 3 +#define PAR4 0x05 // Physical Address Register 4 +#define PAR5 0x06 // Physical Address Register 5 +#define CURR 0x07 // Page 1 +#define CPR 0x07 // Current Page Register + +#define RTL_EECR 0x01 // page 3 +#define CR9346 0x01 // Page 3 +#define CONFIG2 0x05 // page 3 +#define CONFIG3 0x06 // page 3 + +// RTL8019/NE2000 CR Register Bit Definitions +#define PS1 0x80 +#define PS0 0x40 +#define RD2 0x20 +#define RD1 0x10 +#define RD0 0x08 +#define TXP 0x04 +#define START 0x02 +#define STOP 0x01 +// RTL8019/NE2000 ISR Register Bit Definitions +#define RST 0x80 +#define RDC 0x40 +#define OVW 0x10 +#define RXE 0x08 +#define TXE 0x04 +#define PTX 0x02 +#define PRX 0x01 +// RTL8019/NE2000 RCR Register Bit Definitions +#define MON 0x20 +#define PRO 0x10 +#define AM 0x08 +#define AB 0x04 +#define AR 0x02 +#define SEP 0x01 +// RTL8019/NE2000 TCR Register Bit Definitions +#define FDU 0x80 // full duplex +#define PD 0x40 // pad disable +#define RLO 0x20 // retry of late collisions +#define LB1 0x04 // loopback 1 +#define LB0 0x02 // loopback 0 +#define CRC 0x01 // generate CRC +// RTL8019 EECR Register Bit Definitions +#define EEM1 0x80 +#define EEM0 0x40 +#define EECS 0x08 +#define EESK 0x04 +#define EEDI 0x02 +#define EEDO 0x01 + + +// RTL8019 Initial Register Values +// RCR : INT trigger active high and Accept Broadcast ENET packets +#define RCR_INIT (AB) +#define DCR_INIT 0x58 // FIFO thrsh. 8bits, 8bit DMA transfer +// TCR : default transmit operation - CRC is generated +#define TCR_INIT 0x00 +// IMR : interrupt enabled for receive and overrun events +#define IMR_INIT 0x11 // PRX and OVW interrupt enabled +// buffer boundaries +// transmit has 6 256-byte pages +// receive has 26 256-byte pages +// entire available packet buffer space is allocated +#define TXSTART_INIT 0x40 +#define RXSTART_INIT 0x46 +#define RXSTOP_INIT 0x60 + +// Ethernet constants +#define ETHERNET_MIN_PACKET_LENGTH 0x3C +//#define ETHERNET_HEADER_LENGTH 0x0E + +// offsets into ax88796 ethernet packet header +#define PKTHEADER_STATUS 0x00 // packet status +#define PKTHEADER_NEXTPAGE 0x01 // next buffer page +#define PKTHEADER_PKTLENL 0x02 // packet length low +#define PKTHEADER_PKTLENH 0x03 // packet length high + + +// functions +#include "nic.h" + +// setup ports for I/O +void rtl8019SetupPorts(void); + +// read ax88796 register +unsigned char rtl8019Read(unsigned char address); + +// write ax88796 register +void rtl8019Write(unsigned char address, unsigned char data); + +// initialize the ethernet interface for transmit/receive +void rtl8019Init(void); + +// packet transmit functions +void rtl8019BeginPacketSend(unsigned int packetLength); +void rtl8019SendPacketData(unsigned char * localBuffer, unsigned int length); +void rtl8019EndPacketSend(void); + +// packet receive functions +unsigned int rtl8019BeginPacketRetreive(void); +void rtl8019RetreivePacketData(unsigned char * localBuffer, unsigned int length); +void rtl8019EndPacketRetreive(void); + +// Processes RTL8019 interrupts. +// Currently, this function looks only for a receive overflow condition. +// The function need not be called in response to an interrupt, +// but can be executed just before checking the receive buffer for incoming packets. +void rtl8019ProcessInterrupt(void); + +// execute procedure for recovering from a receive overflow +// this should be done when the receive memory fills up with packets +void rtl8019ReceiveOverflowRecover(void); + +// formatted print of all important RTL8019 registers +void rtl8019RegDump(void); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/nmea.c b/3rd party/Procyuon avrlib/nmea.c new file mode 100644 index 0000000..23c070f --- /dev/null +++ b/3rd party/Procyuon avrlib/nmea.c @@ -0,0 +1,259 @@ +/*! \file nmea.c \brief NMEA protocol function library. */ +//***************************************************************************** +// +// File Name : 'nmea.c' +// Title : NMEA protocol function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include +#endif +#include +#include +#include + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "gps.h" + +#include "nmea.h" + +// Program ROM constants + +// Global variables +extern GpsInfoType GpsInfo; +u08 NmeaPacket[NMEA_BUFFERSIZE]; + +void nmeaInit(void) +{ +} + +u08* nmeaGetPacketBuffer(void) +{ + return NmeaPacket; +} + +u08 nmeaProcess(cBuffer* rxBuffer) +{ + u08 foundpacket = NMEA_NODATA; + u08 startFlag = FALSE; + //u08 data; + u16 i,j; + + // process the receive buffer + // go through buffer looking for packets + while(rxBuffer->datalength) + { + // look for a start of NMEA packet + if(bufferGetAtIndex(rxBuffer,0) == '$') + { + // found start + startFlag = TRUE; + // when start is found, we leave it intact in the receive buffer + // in case the full NMEA string is not completely received. The + // start will be detected in the next nmeaProcess iteration. + + // done looking for start + break; + } + else + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength)-1; i++) + { + // check for end of NMEA packet + if((bufferGetAtIndex(rxBuffer,i) == '\r') && (bufferGetAtIndex(rxBuffer,i+1) == '\n')) + { + // have a packet end + // dump initial '$' + bufferGetFromFront(rxBuffer); + // copy packet to NmeaPacket + for(j=0; j<(i-1); j++) + { + // although NMEA strings should be 80 characters or less, + // receive buffer errors can generate erroneous packets. + // Protect against packet buffer overflow + if(j<(NMEA_BUFFERSIZE-1)) + NmeaPacket[j] = bufferGetFromFront(rxBuffer); + else + bufferGetFromFront(rxBuffer); + } + // null terminate it + NmeaPacket[j] = 0; + // dump from rxBuffer + bufferGetFromFront(rxBuffer); + bufferGetFromFront(rxBuffer); + + #ifdef NMEA_DEBUG_PKT + rprintf("Rx NMEA packet type: "); + rprintfStrLen(NmeaPacket, 0, 5); + rprintfStrLen(NmeaPacket, 5, (i-1)-5); + rprintfCRLF(); + #endif + // found a packet + // done with this processing session + foundpacket = NMEA_UNKNOWN; + break; + } + } + } + + if(foundpacket) + { + // check message type and process appropriately + if(!strncmp(NmeaPacket, "GPGGA", 5)) + { + // process packet of this type + nmeaProcessGPGGA(NmeaPacket); + // report packet type + foundpacket = NMEA_GPGGA; + } + else if(!strncmp(NmeaPacket, "GPVTG", 5)) + { + // process packet of this type + nmeaProcessGPVTG(NmeaPacket); + // report packet type + foundpacket = NMEA_GPVTG; + } + } + else if(rxBuffer->datalength >= rxBuffer->size) + { + // if we found no packet, and the buffer is full + // we're logjammed, flush entire buffer + bufferFlush(rxBuffer); + } + return foundpacket; +} + +void nmeaProcessGPGGA(u08* packet) +{ + u08 i; + char* endptr; + double degrees, minutesfrac; + + #ifdef NMEA_DEBUG_GGA + rprintf("NMEA: "); + rprintfStr(packet); + rprintfCRLF(); + #endif + + // start parsing just after "GPGGA," + i = 6; + // attempt to reject empty packets right away + if(packet[i]==',' && packet[i+1]==',') + return; + + // get UTC time [hhmmss.sss] + GpsInfo.PosLLA.TimeOfFix.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: latitude + + // get latitude [ddmm.mmmmm] + GpsInfo.PosLLA.lat.f = strtod(&packet[i], &endptr); + // convert to pure degrees [dd.dddd] format + minutesfrac = modf(GpsInfo.PosLLA.lat.f/100, °rees); + GpsInfo.PosLLA.lat.f = degrees + (minutesfrac*100)/60; + // convert to radians + GpsInfo.PosLLA.lat.f *= (M_PI/180); + while(packet[i++] != ','); // next field: N/S indicator + + // correct latitute for N/S + if(packet[i] == 'S') GpsInfo.PosLLA.lat.f = -GpsInfo.PosLLA.lat.f; + while(packet[i++] != ','); // next field: longitude + + // get longitude [ddmm.mmmmm] + GpsInfo.PosLLA.lon.f = strtod(&packet[i], &endptr); + // convert to pure degrees [dd.dddd] format + minutesfrac = modf(GpsInfo.PosLLA.lon.f/100, °rees); + GpsInfo.PosLLA.lon.f = degrees + (minutesfrac*100)/60; + // convert to radians + GpsInfo.PosLLA.lon.f *= (M_PI/180); + while(packet[i++] != ','); // next field: E/W indicator + + // correct latitute for E/W + if(packet[i] == 'W') GpsInfo.PosLLA.lon.f = -GpsInfo.PosLLA.lon.f; + while(packet[i++] != ','); // next field: position fix status + + // position fix status + // 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPS + // check for good position fix + if( (packet[i] != '0') && (packet[i] != ',') ) + GpsInfo.PosLLA.updates++; + while(packet[i++] != ','); // next field: satellites used + + // get number of satellites used in GPS solution + GpsInfo.numSVs = atoi(&packet[i]); + while(packet[i++] != ','); // next field: HDOP (horizontal dilution of precision) + while(packet[i++] != ','); // next field: altitude + + // get altitude (in meters) + GpsInfo.PosLLA.alt.f = strtod(&packet[i], &endptr); + + while(packet[i++] != ','); // next field: altitude units, always 'M' + while(packet[i++] != ','); // next field: geoid seperation + while(packet[i++] != ','); // next field: seperation units + while(packet[i++] != ','); // next field: DGPS age + while(packet[i++] != ','); // next field: DGPS station ID + while(packet[i++] != '*'); // next field: checksum +} + +void nmeaProcessGPVTG(u08* packet) +{ + u08 i; + char* endptr; + + #ifdef NMEA_DEBUG_VTG + rprintf("NMEA: "); + rprintfStr(packet); + rprintfCRLF(); + #endif + + // start parsing just after "GPVTG," + i = 6; + // attempt to reject empty packets right away + if(packet[i]==',' && packet[i+1]==',') + return; + + // get course (true north ref) in degrees [ddd.dd] + GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'T' + while(packet[i++] != ','); // next field: course (magnetic north) + + // get course (magnetic north ref) in degrees [ddd.dd] + //GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'M' + while(packet[i++] != ','); // next field: speed (knots) + + // get speed in knots + //GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'N' + while(packet[i++] != ','); // next field: speed (km/h) + + // get speed in km/h + GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'K' + while(packet[i++] != '*'); // next field: checksum + + GpsInfo.VelHS.updates++; +} + diff --git a/3rd party/Procyuon avrlib/nmea.h b/3rd party/Procyuon avrlib/nmea.h new file mode 100644 index 0000000..8b0ab00 --- /dev/null +++ b/3rd party/Procyuon avrlib/nmea.h @@ -0,0 +1,61 @@ +/*! \file nmea.h \brief NMEA protocol function library. */ +//***************************************************************************** +// +// File Name : 'nmea.h' +// Title : NMEA protocol function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_hw +/// \defgroup nmea NMEA Packet Interface for GPS Receivers (nmea.c) +/// \code #include "nmea.h" \endcode +/// \par Overview +/// This library parses and decodes the standard NMEA data stream from a +/// GPS and stores the position, velocity, and time solutions in the gps.c +/// library. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef NMEA_H +#define NMEA_H + +#include "global.h" +#include "buffer.h" + +// constants/macros/typdefs +#define NMEA_BUFFERSIZE 80 + +// Message Codes +#define NMEA_NODATA 0 // No data. Packet not available, bad, or not decoded +#define NMEA_GPGGA 1 // Global Positioning System Fix Data +#define NMEA_GPVTG 2 // Course over ground and ground speed +#define NMEA_GPGLL 3 // Geographic position - latitude/longitude +#define NMEA_GPGSV 4 // GPS satellites in view +#define NMEA_GPGSA 5 // GPS DOP and active satellites +#define NMEA_GPRMC 6 // Recommended minimum specific GPS data +#define NMEA_UNKNOWN 0xFF// Packet received but not known + +// Debugging +//#define NMEA_DEBUG_PKT ///< define to enable debug of all NMEA messages +//#define NMEA_DEBUG_GGA ///< define to enable debug of GGA messages +//#define NMEA_DEBUG_VTG ///< define to enable debug of VTG messages + +// functions +void nmeaInit(void); +u08* nmeaGetPacketBuffer(void); +u08 nmeaProcess(cBuffer* rxBuffer); +void nmeaProcessGPGGA(u08* packet); +void nmeaProcessGPVTG(u08* packet); + +#endif diff --git a/3rd party/Procyuon avrlib/param.c b/3rd party/Procyuon avrlib/param.c new file mode 100644 index 0000000..15589a8 --- /dev/null +++ b/3rd party/Procyuon avrlib/param.c @@ -0,0 +1,56 @@ +/*! \file param.c \brief EEPROM Parameter Storage Library. */ +//***************************************************************************** +// +// File Name : 'param.c' +// Title : EEPROM Parameter Storage Library +// Author : Pascal Stang (c)2005 +// Created : 9/16/2005 +// Revised : 9/20/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include + +#include "global.h" + +u08 paramLoad(u08* parameters, u08* memaddr, u16 sizebytes) +{ + u16 i; + u08 checksum_stored=0; + u08 checksum=0; + + // load parameters + eeprom_read_block(parameters, memaddr, sizebytes); + // load checksum + eeprom_read_block(&checksum_stored, memaddr+sizebytes, sizeof(u08)); + + // calculate own checksum + for(i=0;i +#include +#include + +#include "global.h" +#include "timer.h" +#include "pulse.h" + +// Global variables +// pulse generation registers +volatile static unsigned char PulseT1AMode; +volatile static unsigned short PulseT1ACount; +volatile static unsigned short PulseT1APeriodTics; +volatile static unsigned char PulseT1BMode; +volatile static unsigned short PulseT1BCount; +volatile static unsigned short PulseT1BPeriodTics; + +// pulse mode bit definitions +// PULSE_MODE_COUNTED +// if true, the requested number of pulses are output, then output is turned off +// if false, pulses are output continuously +#define PULSE_MODE_CONTINUOUS 0x00 +#define PULSE_MODE_COUNTED 0x01 + +// functions + +void pulseInit(void) +{ + // initialize timer1 for pulse operation + pulseT1Init(); +} + +void pulseT1Init(void) +{ + // try to make sure that timer1 is in "normal" mode + // most importantly, turn off PWM mode + timer1PWMOff(); + + // set some reasonable initial values + // in case the user forgets to + PulseT1AMode = 0; + PulseT1BMode = 0; + PulseT1ACount = 0; + PulseT1BCount = 0; + PulseT1APeriodTics = 0x8000; + PulseT1BPeriodTics = 0x8000; + + // attach the pulse service routines to + // the timer 1 output compare A and B interrupts + timerAttach(TIMER1OUTCOMPAREA_INT,pulseT1AService); + timerAttach(TIMER1OUTCOMPAREB_INT,pulseT1BService); +} + +void pulseT1Off(void) +{ + // turns pulse outputs off immediately + + // set pulse counters to zero (finished) + PulseT1ACount = 0; + PulseT1BCount = 0; + // disconnect OutputCompare action from OC1A pin + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); + // disconnect OutputCompare action from OC1B pin + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); + // detach the pulse service routines + timerDetach(TIMER1OUTCOMPAREA_INT); + timerDetach(TIMER1OUTCOMPAREB_INT); +} + +void pulseT1ASetFreq(u16 freqHz) +{ + // set the frequency of the pulse output + // we need to find the requested period/2 (in timer tics) + // from the frequency (in hertz) + + // calculate how many tics in period/2 + // this is the (timer tic rate)/(2*requested freq) + PulseT1APeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz)); +} + +void pulseT1BSetFreq(u16 freqHz) +{ + // set the frequency of the pulse output + // we need to find the requested period/2 (in timer tics) + // from the frequency (in hertz) + + // calculate how many tics in period/2 + // this is the (timer tic rate)/(2*requested freq) + PulseT1BPeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz)); +} + +void pulseT1ARun(u16 nPulses) +{ + // set the number of pulses we want and the mode + if(nPulses) + { + // if the nPulses is non-zero, use "counted" mode + PulseT1AMode |= PULSE_MODE_COUNTED; + PulseT1ACount = nPulses<<1; + } + else + { + // if nPulses is zero, run forever + PulseT1AMode &= ~PULSE_MODE_COUNTED; + PulseT1ACount = 1<<1; + } + // set OutputCompare action to toggle OC1A pin + cbi(TCCR1A,COM1A1); + sbi(TCCR1A,COM1A0); + + // now the "enabling" stuff + + // set the output compare one pulse cycle ahead of current timer position + // to make sure we don't have to wait until the timer overflows and comes + // back to the current value + // set future output compare time to TCNT1 + PulseT1APeriodTics + //outw(OCR1A, inw(TCNT1) + PulseT1APeriodTics); + OCR1A += PulseT1APeriodTics; + + // enable OutputCompare interrupt + sbi(TIMSK, OCIE1A); +} + +void pulseT1BRun(u16 nPulses) +{ + // set the number of pulses we want and the mode + if(nPulses) + { + // if the nPulses is non-zero, use "counted" mode + PulseT1BMode |= PULSE_MODE_COUNTED; + PulseT1BCount = nPulses<<1; + } + else + { + // if nPulses is zero, run forever + PulseT1BMode &= ~PULSE_MODE_COUNTED; + PulseT1BCount = 1<<1; + } + // set OutputCompare action to toggle OC1B pin + // (note: with all the A's and B's flying around, TCCR1A is not a bug) + cbi(TCCR1A,COM1B1); + sbi(TCCR1A,COM1B0); + + // now the "enabling" stuff + + // set the output compare one pulse cycle ahead of current timer position + // to make sure we don't have to wait until the timer overflows and comes + // back to the current value + // set future output compare time to TCNT1 + PulseT1APeriodTics + //outw(OCR1B, inw(TCNT1) + PulseT1BPeriodTics); + OCR1B += PulseT1BPeriodTics; + + // enable OutputCompare interrupt + sbi(TIMSK, OCIE1B); +} + +void pulseT1AStop(void) +{ + // stop output regardless of remaining pulses or mode + // go to "counted" mode + PulseT1AMode |= PULSE_MODE_COUNTED; + // set pulses to zero + PulseT1ACount = 0; +} + +void pulseT1BStop(void) +{ + // stop output regardless of remaining pulses or mode + // go to "counted" mode + PulseT1BMode |= PULSE_MODE_COUNTED; + // set pulses to zero + PulseT1BCount = 0; +} + +u16 pulseT1ARemaining(void) +{ + // return the number of pulses remaining for channel A + // add 1 to make sure we round up, >>1 equivalent to /2 + return (PulseT1ACount+1)>>1; +} + +u16 pulseT1BRemaining(void) +{ + // return the number of pulses remaining for channel A + // add 1 to make sure we round up, >>1 equivalent to /2 + return (PulseT1BCount+1)>>1; +} + +void pulseT1AService(void) +{ + // check if TimerPulseACount is non-zero + // (i.e. pulses are still requested) + if(PulseT1ACount) + { + //u16 OCValue; + // read in current value of output compare register OCR1A + //OCValue = inp(OCR1AL); // read low byte of OCR1A + //OCValue += inp(OCR1AH)<<8; // read high byte of OCR1A + // increment OCR1A value by PulseT1APeriodTics + //OCValue += PulseT1APeriodTics; + // set future output compare time to this new value + //outp((OCValue>>8), OCR1AH); // write high byte + //outp((OCValue & 0x00FF),OCR1AL); // write low byte + + // the following line should be identical in operation + // to the lines above, but for the moment, I'm not convinced + // this method is bug-free. At least it's simpler! + //outw(OCR1A, inw(OCR1A) + PulseT1APeriodTics); + // change again + OCR1A += PulseT1APeriodTics; + + // decrement the number of pulses executed + if(PulseT1AMode & PULSE_MODE_COUNTED) + PulseT1ACount--; + } + else + { + // pulse count has reached zero + // disable the output compare's action on OC1A pin + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); + // and disable the output compare's interrupt to stop pulsing + cbi(TIMSK, OCIE1A); + } +} + +void pulseT1BService(void) +{ + // check if TimerPulseACount is non-zero + // (i.e. pulses are still requested) + if(PulseT1BCount) + { + //u16 OCValue; + // read in current value of output compare register OCR1B + //OCValue = inp(OCR1BL); // read low byte of OCR1B + //OCValue += inp(OCR1BH)<<8; // read high byte of OCR1B + // increment OCR1B value by PulseT1BPeriodTics + //OCValue += PulseT1BPeriodTics; + // set future output compare time to this new value + //outp((OCValue>>8), OCR1BH); // write high byte + //outp((OCValue & 0x00FF),OCR1BL); // write low byte + + // the following line should be identical in operation + // to the lines above, but for the moment, I'm not convinced + // this method is bug-free. At least it's simpler! + //outw(OCR1B, inw(OCR1B) + PulseT1BPeriodTics); + // change again + OCR1B += PulseT1BPeriodTics; + + + // decrement the number of pulses executed + if(PulseT1BMode & PULSE_MODE_COUNTED) + PulseT1BCount--; + } + else + { + // pulse count has reached zero + // disable the output compare's action on OC1B pin + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); + // and disable the output compare's interrupt to stop pulsing + cbi(TIMSK, OCIE1B); + } +} diff --git a/3rd party/Procyuon avrlib/pulse.h b/3rd party/Procyuon avrlib/pulse.h new file mode 100644 index 0000000..d3136ec --- /dev/null +++ b/3rd party/Procyuon avrlib/pulse.h @@ -0,0 +1,108 @@ +/*! \file pulse.h \brief Pulse/frequency generation function library. */ +//***************************************************************************** +// +// File Name : 'pulse.h' +// Title : Pulse/frequency generation function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2002-08-19 +// Revised : 2003-05-29 +// Version : 0.7 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +/// \ingroup driver_avr +/// \defgroup pulse Pulse/Frequency Generation Function Library (pulse.c) +/// \code +/// #include "timer.h" +/// #include "pulse.h" +/// \endcode +/// \par Overview +/// This library is designed to facilitate the output of square wave pulses +/// at a frequency determined by the user. The user may specify a continuous +/// stream of pulses, or a certain fixed number. Common uses include stepper +/// motor speed control, tone generation, communications, etc. The library +/// uses the AVR processor built-in timers and pulse output is on the timer +/// Output Compare (OC) pins. This library requires the timer function +/// library to work. +/// +/// The allowable range of frequencies which can be generated is governed +/// by the tic rate of the timer (therefore the CPU clock rate and the +/// timer prescaler), and the computing speed of the processor itself. See +/// the SetFreq commands for more details. +/// +/// \Note In order for the pulse library to work, pulseInit() will attach +/// the pulse service routines to the timer interrupts using the +/// timerAttach function. You must not detach the service routines during +/// pulse library operation. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef PULSE_H +#define PULSE_H + +#include "global.h" + +// constants/macros/typdefs + +// functions + +// Master Pulse Commands +// pulseInit() +// Initializes the pulse system/library. +void pulseInit(void); + +// Pulse commands for timer1 +// pulseT1Init() +// configures the timer1 hardware to produce pulses on pins OC1A and OC1B. +// A "pulse" is considered to be one high and low period of a square wave. +void pulseT1Init(void); + +// pulseT1Off() +// Turns pulse output off immediately (cancels running pulse operations). +// Unconfigures hardware and interrupts. +void pulseT1Off(void); + +// pulseT1ASetFreq() and pulseT1BSetFreq() +// sets the frequency in hertz for each channel of square-wave pulse output +// Note1: the freqency must always be greater than zero +// Note2: both channels share the same frequency range which is governed +// by the timer1 prescaler setting. A prescaler setting of DIV/8 allows +// frequencies of a few hertz through a few kilohertz. +// +// Lower frequency bound = overflow rate of timer1 at current prescaling +// Upper frequency bound = the tics rate of timer1 at current prescaling, +// or approx. the (clock rate of the processor)/50, +// whichever is smaller +void pulseT1ASetFreq(u16 freqHz); +void pulseT1BSetFreq(u16 freqHz); + +// pulseT1ARun() and pulseT1BRun(); +// Sets the number of square-wave pulses to be output on the given channel. +// For continuous (unlimited) pulse output, use nPulses = 0. Pulses begin +// coming out immediately. +// Note: must be between 0 and 32767 +void pulseT1ARun(u16 nPulses); +void pulseT1BRun(u16 nPulses); + +// pulseT1AStop() and pulseT1BStop(); +// Stop pulse output at the next cycle (regardless of the number of +// remaining pulses). +void pulseT1AStop(void); +void pulseT1BStop(void); + +// pulseT1ARemaining() and pulseT1BRemaining() +// Returns the number of pulses remaining to be output for each channel. +// This function is useful for figuring out if the pulses are done. +u16 pulseT1ARemaining(void); +u16 pulseT1BRemaining(void); + +// pulseT1AService() and pulseT1BService() +// Interrupt service routines for pulse output (do not call these functions directly) +void pulseT1AService(void); +void pulseT1BService(void); + + +#endif diff --git a/3rd party/Procyuon avrlib/rprintf.c b/3rd party/Procyuon avrlib/rprintf.c new file mode 100644 index 0000000..55c8baf --- /dev/null +++ b/3rd party/Procyuon avrlib/rprintf.c @@ -0,0 +1,782 @@ +/*! \file rprintf.c \brief printf routine and associated routines. */ +//***************************************************************************** +// +// File Name : 'rprintf.c' +// Title : printf routine and associated routines +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2000.12.26 +// Revised : 2003.5.1 +// Version : 1.0 +// Target MCU : Atmel AVR series and other targets +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +//#include +//#include +#include +#include "global.h" +#include "rprintf.h" + +#ifndef TRUE + #define TRUE -1 + #define FALSE 0 +#endif + +#define INF 32766 // maximum field size to print +#define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr)) + +#ifdef RPRINTF_COMPLEX + static unsigned char buf[128]; +#endif + +// use this to store hex conversion in RAM +//static char HexChars[] = "0123456789ABCDEF"; +// use this to store hex conversion in program memory +//static prog_char HexChars[] = "0123456789ABCDEF"; +static char __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF"; + +#define hexchar(x) pgm_read_byte( HexChars+((x)&0x0f) ) +//#define hexchar(x) ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0')) + +// function pointer to single character output routine +static void (*rputchar)(unsigned char c); + +// *** rprintf initialization *** +// you must call this function once and supply the character output +// routine before using other functions in this library +void rprintfInit(void (*putchar_func)(unsigned char c)) +{ + rputchar = putchar_func; +} + +// *** rprintfChar *** +// send a character/byte to the current output device +void rprintfChar(unsigned char c) +{ + // do LF -> CR/LF translation + if(c == '\n') + rputchar('\r'); + // send character + rputchar(c); +} + +// *** rprintfStr *** +// prints a null-terminated string stored in RAM +void rprintfStr(char str[]) +{ + // send a string stored in RAM + // check to make sure we have a good pointer + if (!str) return; + + // print the string until a null-terminator + while (*str) + rprintfChar(*str++); +} + +// *** rprintfStrLen *** +// prints a section of a string stored in RAM +// begins printing at position indicated by +// prints number of characters indicated by +void rprintfStrLen(char str[], unsigned int start, unsigned int len) +{ + register int i=0; + + // check to make sure we have a good pointer + if (!str) return; + // spin through characters up to requested start + // keep going as long as there's no null + while((i++ CR/LF translation built-in to rprintfChar() + rprintfChar('\n'); +} + +// *** rprintfu04 *** +// prints an unsigned 4-bit number in hex (1 digit) +void rprintfu04(unsigned char data) +{ + // print 4-bit hex value +// char Character = data&0x0f; +// if (Character>9) +// Character+='A'-10; +// else +// Character+='0'; + rprintfChar(hexchar(data)); +} + +// *** rprintfu08 *** +// prints an unsigned 8-bit number in hex (2 digits) +void rprintfu08(unsigned char data) +{ + // print 8-bit hex value + rprintfu04(data>>4); + rprintfu04(data); +} + +// *** rprintfu16 *** +// prints an unsigned 16-bit number in hex (4 digits) +void rprintfu16(unsigned short data) +{ + // print 16-bit hex value + rprintfu08(data>>8); + rprintfu08(data); +} + +// *** rprintfu32 *** +// prints an unsigned 32-bit number in hex (8 digits) +void rprintfu32(unsigned long data) +{ + // print 32-bit hex value + rprintfu16(data>>16); + rprintfu16(data); +} + +// *** rprintfNum *** +// special printf for numbers only +// see formatting information below +// Print the number "n" in the given "base" +// using exactly "numDigits" +// print +/- if signed flag "isSigned" is TRUE +// use the character specified in "padchar" to pad extra characters +// +// Examples: +// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234" +// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234" +// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5" +void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n) +{ + // define a global HexChars or use line below + //static char HexChars[16] = "0123456789ABCDEF"; + char *p, buf[32]; + unsigned long x; + unsigned char count; + + // prepare negative number + if( isSigned && (n < 0) ) + { + x = -n; + } + else + { + x = n; + } + + // setup little string buffer + count = (numDigits-1)-(isSigned?1:0); + p = buf + sizeof (buf); + *--p = '\0'; + + // force calculation of first digit + // (to prevent zero from not printing at all!!!) + *--p = hexchar(x%base); x /= base; + // calculate remaining digits + while(count--) + { + if(x != 0) + { + // calculate next digit + *--p = hexchar(x%base); x /= base; + } + else + { + // no more digits left, pad out to desired length + *--p = padchar; + } + } + + // apply signed notation if requested + if( isSigned ) + { + if(n < 0) + { + *--p = '-'; + } + else if(n > 0) + { + *--p = '+'; + } + else + { + *--p = ' '; + } + } + + // print the string right-justified + count = numDigits; + while(count--) + { + rprintfChar(*p++); + } +} + +#ifdef RPRINTF_FLOAT +// *** rprintfFloat *** +// floating-point print +void rprintfFloat(char numDigits, double x) +{ + unsigned char firstplace = FALSE; + unsigned char negative; + unsigned char i, digit; + double place = 1.0; + + // save sign + negative = (x<0); + // convert to absolute value + x = (x>0)?(x):(-x); + + // find starting digit place + for(i=0; i<15; i++) + { + if((x/place) < 10.0) + break; + else + place *= 10.0; + } + // print polarity character + if(negative) + rprintfChar('-'); + else + rprintfChar('+'); + + // print digits + for(i=0; i 1 && div_val > u_val) div_val /= 10; + } + do + { + //rprintfChar(pgm_read_byte(HexChars+(u_val/div_val))); + rprintfu04(u_val/div_val); + u_val %= div_val; + div_val /= base; + } while (div_val); + } + } + va_end(ap); +} +#endif + + +#ifdef RPRINTF_COMPLEX +// *** rprintf2RamRom *** +// called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s) +// Supports: +// %d - decimal +// %u - unsigned decimal +// %o - octal +// %x - hex +// %c - character +// %s - strings +// and the width,precision,padding modifiers +// **this printf does not support floating point numbers +int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...) +{ + register unsigned char *f, *bp; + register long l; + register unsigned long u; + register int i; + register int fmt; + register unsigned char pad = ' '; + int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + int sign = 0; + + va_list ap; + va_start(ap, sfmt); + + f = (unsigned char *) sfmt; + + for (; READMEMBYTE(stringInRom,f); f++) + { + if (READMEMBYTE(stringInRom,f) != '%') + { // not a format character + // then just output the char + rprintfChar(READMEMBYTE(stringInRom,f)); + } + else + { + f++; // if we have a "%" then skip it + if (READMEMBYTE(stringInRom,f) == '-') + { + flush_left = 1; // minus: flush left + f++; + } + if (READMEMBYTE(stringInRom,f) == '0' + || READMEMBYTE(stringInRom,f) == '.') + { + // padding with 0 rather than blank + pad = '0'; + f++; + } + if (READMEMBYTE(stringInRom,f) == '*') + { // field width + f_width = va_arg(ap, int); + f++; + } + else if (Isdigit(READMEMBYTE(stringInRom,f))) + { + f_width = atoiRamRom(stringInRom, (char *) f); + while (Isdigit(READMEMBYTE(stringInRom,f))) + f++; // skip the digits + } + if (READMEMBYTE(stringInRom,f) == '.') + { // precision + f++; + if (READMEMBYTE(stringInRom,f) == '*') + { + prec = va_arg(ap, int); + f++; + } + else if (Isdigit(READMEMBYTE(stringInRom,f))) + { + prec = atoiRamRom(stringInRom, (char *) f); + while (Isdigit(READMEMBYTE(stringInRom,f))) + f++; // skip the digits + } + } + if (READMEMBYTE(stringInRom,f) == '#') + { // alternate form + hash = 1; + f++; + } + if (READMEMBYTE(stringInRom,f) == 'l') + { // long format + do_long = 1; + f++; + } + + fmt = READMEMBYTE(stringInRom,f); + bp = buf; + switch (fmt) { // do the formatting + case 'd': // 'd' signed decimal + if (do_long) + l = va_arg(ap, long); + else + l = (long) (va_arg(ap, int)); + if (l < 0) + { + sign = 1; + l = -l; + } + do { + *bp++ = l % 10 + '0'; + } while ((l /= 10) > 0); + if (sign) + *bp++ = '-'; + f_width = f_width - (bp - buf); + if (!flush_left) + while (f_width-- > 0) + rprintfChar(pad); + for (bp--; bp >= buf; bp--) + rprintfChar(*bp); + if (flush_left) + while (f_width-- > 0) + rprintfChar(' '); + break; + case 'o': // 'o' octal number + case 'x': // 'x' hex number + case 'u': // 'u' unsigned decimal + if (do_long) + u = va_arg(ap, unsigned long); + else + u = (unsigned long) (va_arg(ap, unsigned)); + if (fmt == 'u') + { // unsigned decimal + do { + *bp++ = u % 10 + '0'; + } while ((u /= 10) > 0); + } + else if (fmt == 'o') + { // octal + do { + *bp++ = u % 8 + '0'; + } while ((u /= 8) > 0); + if (hash) + *bp++ = '0'; + } + else if (fmt == 'x') + { // hex + do { + i = u % 16; + if (i < 10) + *bp++ = i + '0'; + else + *bp++ = i - 10 + 'a'; + } while ((u /= 16) > 0); + if (hash) + { + *bp++ = 'x'; + *bp++ = '0'; + } + } + i = f_width - (bp - buf); + if (!flush_left) + while (i-- > 0) + rprintfChar(pad); + for (bp--; bp >= buf; bp--) + rprintfChar((int) (*bp)); + if (flush_left) + while (i-- > 0) + rprintfChar(' '); + break; + case 'c': // 'c' character + i = va_arg(ap, int); + rprintfChar((int) (i)); + break; + case 's': // 's' string + bp = va_arg(ap, unsigned char *); + if (!bp) + bp = (unsigned char *) "(nil)"; + f_width = f_width - strlen((char *) bp); + if (!flush_left) + while (f_width-- > 0) + rprintfChar(pad); + for (i = 0; *bp && i < prec; i++) + { + rprintfChar(*bp); + bp++; + } + if (flush_left) + while (f_width-- > 0) + rprintfChar(' '); + break; + case '%': // '%' character + rprintfChar('%'); + break; + } + flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + sign = 0; + pad = ' '; + } + } + + va_end(ap); + return 0; +} + +unsigned char Isdigit(char c) +{ + if((c >= 0x30) && (c <= 0x39)) + return TRUE; + else + return FALSE; +} + +int atoiRamRom(unsigned char stringInRom, char *str) +{ + int num = 0;; + + while(Isdigit(READMEMBYTE(stringInRom,str))) + { + num *= 10; + num += ((READMEMBYTE(stringInRom,str++)) - 0x30); + } + return num; +} + +#endif + +//****************************************************************************** +// code below this line is commented out and can be ignored +//****************************************************************************** +/* +char* sprintf(const char *sfmt, ...) +{ + register unsigned char *f, *bp, *str; + register long l; + register unsigned long u; + register int i; + register int fmt; + register unsigned char pad = ' '; + int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + int sign = 0; + + va_list ap; + va_start(ap, sfmt); + + str = bufstring; + f = (unsigned char *) sfmt; + + for (; *f; f++) + { + if (*f != '%') + { // not a format character + *str++ = (*f); // then just output the char + } + else + { + f++; // if we have a "%" then skip it + if (*f == '-') + { + flush_left = 1; // minus: flush left + f++; + } + if (*f == '0' || *f == '.') + { + // padding with 0 rather than blank + pad = '0'; + f++; + } + if (*f == '*') + { // field width + f_width = va_arg(ap, int); + f++; + } + else if (Isdigit(*f)) + { + f_width = atoi((char *) f); + while (Isdigit(*f)) + f++; // skip the digits + } + if (*f == '.') + { // precision + f++; + if (*f == '*') + { + prec = va_arg(ap, int); + f++; + } + else if (Isdigit(*f)) + { + prec = atoi((char *) f); + while (Isdigit(*f)) + f++; // skip the digits + } + } + if (*f == '#') + { // alternate form + hash = 1; + f++; + } + if (*f == 'l') + { // long format + do_long = 1; + f++; + } + + fmt = *f; + bp = buf; + switch (fmt) { // do the formatting + case 'd': // 'd' signed decimal + if (do_long) + l = va_arg(ap, long); + else + l = (long) (va_arg(ap, int)); + if (l < 0) + { + sign = 1; + l = -l; + } + do { + *bp++ = l % 10 + '0'; + } while ((l /= 10) > 0); + if (sign) + *bp++ = '-'; + f_width = f_width - (bp - buf); + if (!flush_left) + while (f_width-- > 0) + *str++ = (pad); + for (bp--; bp >= buf; bp--) + *str++ = (*bp); + if (flush_left) + while (f_width-- > 0) + *str++ = (' '); + break; + case 'o': // 'o' octal number + case 'x': // 'x' hex number + case 'u': // 'u' unsigned decimal + if (do_long) + u = va_arg(ap, unsigned long); + else + u = (unsigned long) (va_arg(ap, unsigned)); + if (fmt == 'u') + { // unsigned decimal + do { + *bp++ = u % 10 + '0'; + } while ((u /= 10) > 0); + } + else if (fmt == 'o') + { // octal + do { + *bp++ = u % 8 + '0'; + } while ((u /= 8) > 0); + if (hash) + *bp++ = '0'; + } + else if (fmt == 'x') + { // hex + do { + i = u % 16; + if (i < 10) + *bp++ = i + '0'; + else + *bp++ = i - 10 + 'a'; + } while ((u /= 16) > 0); + if (hash) + { + *bp++ = 'x'; + *bp++ = '0'; + } + } + i = f_width - (bp - buf); + if (!flush_left) + while (i-- > 0) + *str++ = (pad); + for (bp--; bp >= buf; bp--) + *str++ = ((int) (*bp)); + if (flush_left) + while (i-- > 0) + *str++ = (' '); + break; + case 'c': // 'c' character + i = va_arg(ap, int); + *str++ = ((int) (i)); + break; + case 's': // 's' string + bp = va_arg(ap, unsigned char *); + if (!bp) + bp = (unsigned char *) "(nil)"; + f_width = f_width - strlen((char *) bp); + if (!flush_left) + while (f_width-- > 0) + *str++ = (pad); + for (i = 0; *bp && i < prec; i++) + { + *str++ = (*bp); + bp++; + } + if (flush_left) + while (f_width-- > 0) + *str++ = (' '); + break; + case '%': // '%' character + *str++ = ('%'); + break; + } + flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + sign = 0; + pad = ' '; + } + } + + va_end(ap); + // terminate string with null + *str++ = '\0'; + return bufstring; +} + +*/ diff --git a/3rd party/Procyuon avrlib/rprintf.h b/3rd party/Procyuon avrlib/rprintf.h new file mode 100644 index 0000000..e5ac043 --- /dev/null +++ b/3rd party/Procyuon avrlib/rprintf.h @@ -0,0 +1,191 @@ +/*! \file rprintf.h \brief printf routine and associated routines. */ +//**************************************************************************** +// +// File Name : 'rprintf.h' +// Title : printf routine and associated routines +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2000.12.26 +// Revised : 2003.5.1 +// Version : 1.0 +// Target MCU : Atmel AVR series and other targets +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup general +/// \defgroup rprintf printf() Function Library (rprintf.c) +/// \code #include "rprintf.h" \endcode +/// \par Overview +/// The rprintf function library provides a simplified (reduced) version of +/// the common C printf() function.  See the code files for details about +/// which printf features are supported.  Also in this library are a +/// variety of functions for fast printing of certain common data types +/// (variable types).  Functions include print string from RAM, print +/// string from ROM, print string snippet, print hex byte/short/long, and +/// a custom-formatted number print, as well as an optional floating-point +/// print routine. +/// +/// \note All output from the rprintf library can be directed to any device +/// or software which accepts characters.  This means that rprintf output +/// can be sent to the UART (serial port) or can be used with the LCD +/// display libraries to print formatted text on the screen. +// +//**************************************************************************** +//@{ + +#ifndef RPRINTF_H +#define RPRINTF_H + +// needed for use of PSTR below +#include + +// configuration +// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function +// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function +#ifndef RPRINTF_COMPLEX + #define RPRINTF_SIMPLE +#endif + +// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat() +// (adds +4600bytes or 2.2Kwords of code) + +// defines/constants +#define STRING_IN_RAM 0 +#define STRING_IN_ROM 1 + +// make a putchar for those that are used to using it +//#define putchar(c) rprintfChar(c); + +// functions + +//! Initializes the rprintf library for an output stream. +/// You must call this initializer once before using any other rprintf function. +/// The argument must be a character stream output function. +void rprintfInit(void (*putchar_func)(unsigned char c)); + +//! prints a single character to the current output device +void rprintfChar(unsigned char c); + +//! prints a null-terminated string stored in RAM +void rprintfStr(char str[]); + +//! Prints a section of a string stored in RAM. +/// Begins printing at position indicated by , +/// and prints number of characters indicated by . +void rprintfStrLen(char str[], unsigned int start, unsigned int len); + +//! prints a string stored in program rom +/// \note This function does not actually store your string in +/// program rom, but merely reads it assuming you stored it properly. +void rprintfProgStr(const prog_char str[]); + +//! Using the function rprintfProgStrM(...) automatically causes +/// your string to be stored in ROM, thereby not wasting precious RAM. +/// Example usage: +/// \code +/// rprintfProgStrM("Hello, this string is stored in program rom"); +/// \endcode +#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string))) + +//! Prints a carriage-return and line-feed. +/// Useful when printing to serial ports/terminals. +void rprintfCRLF(void); + +// Prints the number contained in "data" in hex format +// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively +void rprintfu04(unsigned char data); ///< Print 4-bit hex number. Outputs a single hex character. +void rprintfu08(unsigned char data); ///< Print 8-bit hex number. Outputs two hex characters. +void rprintfu16(unsigned short data); ///< Print 16-bit hex number. Outputs four hex characters. +void rprintfu32(unsigned long data); ///< Print 32-bit hex number. Outputs eight hex characters. + +//! A flexible integer-number printing routine. +/// Print the number "n" in the given "base", using exactly "numDigits". +/// Print +/- if signed flag "isSigned" is TRUE. +/// The character specified in "padchar" will be used to pad extra characters. +/// +/// Examples: +/// \code +/// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234" +/// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234" +/// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5" +/// \endcode +void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n); + +#ifdef RPRINTF_FLOAT + //! floating-point print routine + void rprintfFloat(char numDigits, double x); +#endif + +// NOTE: Below you'll see the function prototypes of rprintf1RamRom and +// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions +// of the regular C printf() command. However, they are modified to be able +// to read their text/format strings from RAM or ROM in the Atmel microprocessors. +// Unless you really intend to, do not use the "RamRom" versions of the functions +// directly. Instead use the #defined function versions: +// +// printfx("text/format",args) ...to keep your text/format string stored in RAM +// - or - +// printfxROM("text/format",args) ...to keep your text/format string stored in ROM +// +// where x is either 1 or 2 for the simple or more powerful version of printf() +// +// Since there is much more ROM than RAM available in the Atmel microprocessors, +// and nearly all text/format strings are constant (never change in the course +// of the program), you should try to use the ROM printf version exclusively. +// This will ensure you leave as much RAM as possible for program variables and +// data. + +//! \fn int rprintf(const char *format, ...); +/// A reduced substitute for the usual C printf() function. +/// This function actually points to either rprintf1RamRom or rprintf2RamRom +/// depending on the user's selection. Rprintf1 is a simple small fast print +/// routine while rprintf2 is larger and slower but more capable. To choose +/// the routine you would like to use, define either RPRINTF_SIMPLE or +/// RPRINTF_COMPLEX in global.h. + +#ifdef RPRINTF_SIMPLE + //! A simple printf routine. + /// Called by rprintf() - does a simple printf (supports %d, %x, %c). + /// Supports: + /// - %d - decimal + /// - %x - hex + /// - %c - character + int rprintf1RamRom(unsigned char stringInRom, const char *format, ...); + // #defines for RAM or ROM operation + #define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) + #define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args) + + // *** Default rprintf(...) *** + // this next line determines what the the basic rprintf() defaults to: + #define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) +#endif + +#ifdef RPRINTF_COMPLEX + //! A more powerful printf routine. + /// Called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s). + /// Supports: + /// - %d - decimal + /// - %u - unsigned decimal + /// - %o - octal + /// - %x - hex + /// - %c - character + /// - %s - strings + /// - and the width,precision,padding modifiers + /// \note This printf does not support floating point numbers. + int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...); + // #defines for RAM or ROM operation + #define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args) + #define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args) + + // *** Default rprintf(...) *** + // this next line determines what the the basic rprintf() defaults to: + #define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args) +#endif + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/rsl/avrcore.c b/3rd party/Procyuon avrlib/rsl/avrcore.c new file mode 100644 index 0000000..8ce6f0b --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/avrcore.c @@ -0,0 +1,101 @@ +/*! \file avrcore.c \brief AVR-Core Board Driver Functions. */ +//***************************************************************************** +// +// File Name : 'avrcore.c' +// Title : AVR-Core Board Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.1 +// Revised : 2004.10.1 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "avrcore.h" + +// globals +u08 AvrcoreLatch; + +// functions +void avrcoreInit(void) +{ + // initialize ports to input with pullup + // (this is done to avoid contentions and input-pin oscillation) + outb(DDRA, 0x00); + outb(DDRB, 0x00); + outb(DDRC, 0x00); + outb(DDRD, 0x00); + outb(DDRE, 0x00); + outb(DDRF, 0x00); + outb(PORTA, 0xFF); + outb(PORTB, 0xFF); + outb(PORTC, 0xFF); + outb(PORTD, 0xFF); + outb(PORTE, 0xFF); + outb(PORTF, 0xFF); + // turn on RAM interface + sbi(MCUCR, SRE); + // initialize RAM page + avrcoreSetRamPage(0); + // initialize LEDs + avrcoreSetLeds(0); + // set serial power to on by default + avrcoreSetSerialPortPower(1); +} + +void avrcoreSetRamPage(u08 page) +{ + // update latch state + AvrcoreLatch &= ~AVRCORELATCH_ADDRMASK; + AvrcoreLatch |= page & AVRCORELATCH_ADDRMASK; + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLeds(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state + AvrcoreLatch |= AVRCORELATCH_LEDMASK; + AvrcoreLatch &= ~(leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLedsOn(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state to turn on inidicated leds + AvrcoreLatch &= ~(leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLedsOff(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state to turn off inidicated leds + AvrcoreLatch |= (leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetSerialPortPower(u08 on) +{ + // this function simply manipulates LED3/power control + if(on) + AvrcoreLatch &= ~(0x80); + else + AvrcoreLatch |= (0x80); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} diff --git a/3rd party/Procyuon avrlib/rsl/avrcore.h b/3rd party/Procyuon avrlib/rsl/avrcore.h new file mode 100644 index 0000000..3fc1882 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/avrcore.h @@ -0,0 +1,72 @@ +/*! \file avrcore.h \brief AVR-Core Board Driver Functions. */ +//***************************************************************************** +// +// File Name : 'avrcore.h' +// Title : AVR-Core Board Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.01 +// Revised : 2005.10.24 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef AVRCORE_H +#define AVRCORE_H + +// defines and typedefs +#define AVRCORELATCH (*((unsigned char*)0x4000)) +#define AVRCORELATCH_ADDRMASK 0x0F +#define AVRCORELATCH_LEDMASK 0xF0 + +// SAT-MB serial port control +// CTS is an output signal +#define AVRCORE_SER_CTS_PORT PORTB +#define AVRCORE_SER_CTS_DDR DDRB +#define AVRCORE_SER_CTS_PORTIN PINB +#define AVRCORE_SER_CTS_PIN PB5 +// RTS is an input signal +#define AVRCORE_SER_RTS_PORT PORTB +#define AVRCORE_SER_RTS_DDR DDRB +#define AVRCORE_SER_RTS_PORTIN PINB +#define AVRCORE_SER_RTS_PIN PB6 + +// functions + +//! Initialize AVRCore hardware +void avrcoreInit(void); + +//! Set the current external RAM page +// The AVRCore on-board external RAM is typically 512KBytes. +// The RAM is memory-mapped into the 32KByte address space from +// 0x8000-0xFFFF, and must therefore be accessed in pages (32KB chunks). +// Use this function to select which of the 16 (0-15) 32KByte pages +// you wish to access. +void avrcoreSetRamPage(u08 page); + +//! Set the state of the four LEDs on AVRCore +// leds bit0 => LED1 (0=off, 1=on) +// leds bit1 => LED2 (0=off, 1=on) +// leds bit2 => LED3 (0=off, 1=on) +// leds bit3 => LED4 (0=off, 1=on) +void avrcoreSetLeds(u08 leds); + +//! Turn on selected LEDs +// '0' bit = no change +// '1' bit = turn on +void avrcoreSetLedsOn(u08 leds); + +//! Turn off selected LEDs +// '0' bit = no change +// '1' bit = turn off +void avrcoreSetLedsOff(u08 leds); + +//! Set on/off power setting of AVRCore serial port +// (0=off, 1=on) +void avrcoreSetSerialPortPower(u08 on); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/dallas.h b/3rd party/Procyuon avrlib/rsl/dallas.h new file mode 100644 index 0000000..d7ff55f --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallas.h @@ -0,0 +1,173 @@ +//***************************************************************************** +// File Name : dallas.c +// Title : Dallas 1-Wire Library +// Revision : 6 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Rev Description of change +// ----------- ----------- ------- ----------------------- +// 24-Sep-2003 rwatson 6 Created AddressCheck, WaitUntilDone +// 23-Sep-2003 rwatson 5 Created ReadRAM, WriteRAM, PrintError, PrintROM +// 22-Sep-2003 rwatson 4 Created MatchROM, PrintROM +// 21-Sep-2003 rwatson 3 Created ReadROM, FindDevices, FindNextDevice, CRC +// 20-Sep-2003 rwatson 2 Created ReadBit, WriteBit, ReadByte, WriteByte, Reset +// 20-Sep-2003 rwatson 1 Created the program structure +//***************************************************************************** + +#ifndef dallas_h +#define dallas_h + +//----- Include Files --------------------------------------------------------- +#include "global.h" + +//----- Defines --------------------------------------------------------------- +#define dallas_rev 6 + +// include configuration +#include "dallasconf.h" + +// define the max number devices on +// the bus if it isn't defined yet +#ifndef DALLAS_MAX_DEVICES +#define DALLAS_MAX_DEVICES 20 +#endif + +// indexes of named bytes in the +// dallas address array +#define DALLAS_FAMILY_IDX 0 // family code +#define DALLAS_A0_IDX 1 +#define DALLAS_A1_IDX 2 +#define DALLAS_A2_IDX 3 +#define DALLAS_A3_IDX 4 +#define DALLAS_A4_IDX 5 +#define DALLAS_A5_IDX 6 +#define DALLAS_CRC_IDX 7 // crc code + +// dallas return error codes +#define DALLAS_NO_ERROR 0 // all is well +#define DALLAS_PRESENCE 'h' // presence was detected +#define DALLAS_NO_PRESENCE 'g' // presence wasn't detected +#define DALLAS_VERIFY_ERROR 'v' // setup verification failed +#define DALLAS_ADDRESS_ERROR 'a' // bad address for command: either wrong family or bad CRC +#define DALLAS_CRC_ERROR 'c' // data/return value fails CRC check +#define DALLAS_DEVICE_ERROR 'd' // device not responding +#define DALLAS_NULL_POINTER 'p' // dallas function passed a NULL pointer +#define DALLAS_ZERO_LEN 'z' // ReadRAM or WriteRAM asked to read/write zero bytes +#define DALLAS_BUS_ERROR 'b' // Bus hardware error. (wrong voltage) Possible causes: + // - lack of pullup Resistor + // - Other master transmitting (Dallas is not multi-master) + // - Device failure +// ds2450 and ds18b20 errors +// defined here to work with PrintError +#define DALLAS_RESOLUTION_ERROR 'r' // invalid resolution specified in Dallas function +#define DALLAS_INVALID_CHANNEL 'i' // channel outside the range 'A' to 'D' +#define DALLAS_FORMAT_ERROR 'f' // results are not in a valid format (temp sensor) + +// ROM commands +#define DALLAS_READ_ROM 0x33 +#define DALLAS_MATCH_ROM 0x55 +#define DALLAS_SKIP_ROM 0xCC +#define DALLAS_SEARCH_ROM 0xF0 +#define DALLAS_CONDITIONAL_SEARCH 0xEC +#define DALLAS_READ_MEMORY 0xAA +#define DALLAS_WRITE_MEMORY 0x55 + +//----- Typedefs -------------------------------------------------------------- + +// typedef for the rom IDs +// done so we can access the entire id or each individual byte +typedef union dallas_rom_id_U +{ + long long id; + u08 byte[8]; +} dallas_rom_id_T; + +//----- Functions --------------------------------------------------------------- + +// dallasInit() +// Initializes the Dallas 1-wire Bus +// Currently this function does nothing +void dallasInit(void); + +// dallasReset() +// performs a reset on the 1-wire bus +// returns the presence detect (DALLAS_PRESENCE or DALLAS_NO_PRESENCE) +u08 dallasReset(void); + +// dallasReadBit() +// reads a bit from the 1-wire bus and returns this bit +// note: global interupts are not disabled in this function +// if using this function, use cli() and sei() before and after +u08 dallasReadBit(void); + +// dallasWriteBit() +// writes the passed in bit to the 1-wire bus +// note: global interupts are not disabled in this function +// if using this function, use cli() and sei() before and after +void dallasWriteBit(u08 bit); + +// dallasReadByte() +// reads a byte from the 1-wire bus and returns this byte +// note: global interupts are disabled in this function +u08 dallasReadByte(void); + +// dallasWriteByte() +// writes the passed in byte to the 1-wire bus +// note: global interupts are disabled in this function. +void dallasWriteByte(u08 byte); + +// dallasReadRAM() +// reads the RAM from the specified device, at the specified RAM address +// for the specified length. Data is stored into data variable +u08 dallasReadRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08 *data); + +// dallasWriteRAM() +// writes the specified data for the specified length to the RAM +// located at the specified address of the specified device +u08 dallasWriteRAM(dallas_rom_id_T* rom_id, u16 address, u08 len, u08* data); + +// dallasWaitUntilDone() +// waits until the conversion of a dallas device is done +void dallasWaitUntilDone(void); + +// dallasReadROM() +// finds the ROM code of a device if only 1 device is +// connected to the bus the ROM value is passed by referenced +// returns any error that occured or DALLAS_NO_ERROR +u08 dallasReadROM(dallas_rom_id_T* rom_id); + +// dallasMatchROM() +// performs a reset on the 1-wire bus and then +// selects the specified dallas device on the network +// returns any error that occured or DALLAS_NO_ERROR +u08 dallasMatchROM(dallas_rom_id_T* rom_id); + +// dallasPrintROM +// prints the ROM from MSB to LSB in the format: xx xx xx xx xx xx xx xx +void dallasPrintROM(dallas_rom_id_T* rom_id); + +// dallasAddressCheck() +// checks to make sure that the rom id is in the proper family, +// and if the crc of the id is correct +// returns the corresponding error or DALLAS_NO_ERROR +u08 dallasAddressCheck(dallas_rom_id_T* rom_id, u08 family); + +// dallasCRC() +// calculates the CRC from the lookup table +// returns the new crc value, which is also a global variable +u08 dallasCRC(u08 i); + +// dallasFindDevices() +// finds all the devices on the network, or up to the maximum defined value +// stores the ids in the given array, and returns the number of devices found +u08 dallasFindDevices(dallas_rom_id_T rom_id[]); + +// dallasPrintError() +// prints the error value as well as an error message if there was an error +// if DALLAS_NO_ERROR is passed in, nothing is done +void dallasPrintError(u08 error); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/dallas_bitbang.c b/3rd party/Procyuon avrlib/rsl/dallas_bitbang.c new file mode 100644 index 0000000..b024ab0 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallas_bitbang.c @@ -0,0 +1,569 @@ +//***************************************************************************** +// File Name : dallas.c +// Title : Dallas 1-Wire Library +// Revision : 6 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include string support +#include "rprintf.h" // include rprintf function library +#include "timer128.h" // include timer function library +#include "dallas.h" // include dallas support + +//----- Global Variables ------------------------------------------------------- +static u08 last_discrep = 0; // last discrepancy for FindDevices +static u08 done_flag = 0; // done flag for FindDevices + +u08 dallas_crc; // current crc global variable +u08 dallas_crc_table[] = // dallas crc lookup table +{ + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 +}; + +//----- Functions -------------------------------------------------------------- + +/*-------------------------------------------------------------------------- + * dallasFindNextDevice: find the next device on the bus + * input................ rom_id - pointer to store the rom id found + * returns.............. true or false if a device was found + *-------------------------------------------------------------------------*/ +u08 dallasFindNextDevice(dallas_rom_id_T* rom_id); + +void dallasDelayUs(u16 us) +{ + while(us--) // 6 cycles + { + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + } // loop jump 2 cycles +} + +void dallasInit(void) +{ +} + +u08 dallasReset(void) +{ + u08 presence = DALLAS_PRESENCE; + + cli(); + + // pull line low + sbi(DALLAS_DDR, DALLAS_PIN); + cbi(DALLAS_PORT, DALLAS_PIN); + + // wait for presence + dallasDelayUs(480); + + // allow line to return high + cbi(DALLAS_DDR, DALLAS_PIN); + sbi(DALLAS_PORT, DALLAS_PIN); + + // wait for presence + dallasDelayUs(70); + + // if device is not present, pin will be 1 + if (inb(DALLAS_PORTIN) & 0x01<>i) & 0x01); + + // allow a us delay between each write + dallasDelayUs(1); + } + + sei(); +} + +u08 dallasReadRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08 *data) +{ + u08 i; + u08 error; + + union int16_var_U + { + u16 i16; + u08 i08[2]; + } int16_var; + + // first make sure we actually have something to do + if (data == NULL) + return DALLAS_NULL_POINTER; + if (len == 0) + return DALLAS_ZERO_LEN; + + // reset the bus and request the device + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // enter read mode + dallasWriteByte(DALLAS_READ_MEMORY); + + // write address one byte at a time + int16_var.i16 = addr; + dallasWriteByte(int16_var.i08[0]); + dallasWriteByte(int16_var.i08[1]); + + // read data from device 1 byte at a time + for(i=0;ibyte[i] = dallasReadByte(); + + return DALLAS_NO_ERROR; +} + +u08 dallasMatchROM(dallas_rom_id_T* rom_id) +{ + u08 i; + + // reset the 1-wire and look for presence + i = dallasReset(); + if (i != DALLAS_PRESENCE) + return i; + + // send MATCH ROM command + dallasWriteByte(DALLAS_MATCH_ROM); + + // write id one byte at a time + for(i=0;i<8;i++) + dallasWriteByte(rom_id->byte[i]); + + return DALLAS_NO_ERROR; +} + +void dallasPrintROM(dallas_rom_id_T* rom_id) +{ + s08 i; + + // print out the rom in the format: xx xx xx xx xx xx xx xx + for(i=7;i>=0;i--) + { + rprintfu08(rom_id->byte[i]); + rprintfChar(' '); + } + + // print out the rom in the format: 0xXXXXXXXXXXXXXXXX + rprintfProgStrM(" (0x"); + for(i=7;i>=0;i--) + { + rprintfu08(rom_id->byte[i]); + } + rprintfProgStrM("ULL)"); + +} + +u08 dallasAddressCheck(dallas_rom_id_T* rom_id, u08 family) +{ +// u08 i; + +// dallas_crc = 0; + +// for(i=1;i<7;i++) +// { +// dallasCRC(rom_id->byte[i]); +// rprintfu08(rom_id->byte[i]); +// rprintfChar(' '); +// } +// rprintfCRLF(); + +// rprintfu08(dallas_crc); +// rprintfCRLF(); + + //run CRC on address + + //make sure we have the correct family + if (rom_id->byte[DALLAS_FAMILY_IDX] == family) + return DALLAS_NO_ERROR; + + return DALLAS_ADDRESS_ERROR; +} + +u08 dallasCRC(u08 i) +{ + // update the crc global variable and return it + dallas_crc = dallas_crc_table[dallas_crc^i]; + return dallas_crc; +} + +u08 dallasFindDevices(dallas_rom_id_T rom_id[]) +{ + u08 num_found = 0; + dallas_rom_id_T id; + + // reset the rom search last discrepancy global + last_discrep = 0; + done_flag = FALSE; + + // check to make sure presence is detected before we start + if (dallasReset() == DALLAS_PRESENCE) + { + // --> stang + //while (dallasFindNextDevice(&rom_id[num_found]) && (num_found0) + { + // all devices coupled have 0 or 1 + // shift 1 to determine if the msb is 0 or 1 + bit = i>>1; + } + else + { + // if this discrepancy is before the last discrepancy on a + // previous FindNextDevice then pick the same as last time + if (bit_indexbyte[byte_index] & bit_mask) > 0); + else + bit = (bit_index==last_discrep); + + // if 0 was picked then record position with bit mask + if (!bit) + discrep_marker = bit_index; + } + + // isolate bit in rom_id->byte[byte_index] with bit mask + if (bit) + rom_id->byte[byte_index] |= bit_mask; + else + rom_id->byte[byte_index] &= ~bit_mask; + + // ROM search write + cli(); + dallasWriteBit(bit); + sei(); + + // ncrement bit index counter and shift the bit mask + bit_index++; + bit_mask <<= 1; + + if (!bit_mask) + { + // if the mask is 0 then go to new ROM + // accumulate the CRC and incriment the byte index and bit mask + dallasCRC(rom_id->byte[byte_index]); + byte_index++; + bit_mask++; + } + } + } + + if ((bit_index < 65) || dallas_crc) + { + // search was unsuccessful - reset the last discrepancy to 0 and return false + last_discrep = 0; + return FALSE; + } + + // search was successful, so set last_discrep and done_flag + last_discrep = discrep_marker; + done_flag = (last_discrep==0); + + return TRUE; +} + +void dallasPrintError(u08 error) +{ + // if there was not an error, return + if (error == DALLAS_NO_ERROR) + return; + + // print header message + rprintfProgStrM("ERROR "); + rprintfChar(error); + rprintfProgStrM(": "); + + // print custom error message + switch (error) + { + case DALLAS_NO_PRESENCE: + rprintfProgStrM("no presence detected"); + break; + case DALLAS_INVALID_CHANNEL: + rprintfProgStrM("Invalid Chan"); + break; + case DALLAS_VERIFY_ERROR: + rprintfProgStrM("Verify"); + break; + case DALLAS_ADDRESS_ERROR: + rprintfProgStrM("Bad Addr"); + break; + case DALLAS_CRC_ERROR: + rprintfProgStrM("Data CRC"); + break; + case DALLAS_DEVICE_ERROR: + rprintfProgStrM("No response"); + break; + case DALLAS_FORMAT_ERROR: + rprintfProgStrM("Bad return format"); + break; + case DALLAS_NULL_POINTER: + rprintfProgStrM("Null Pointer"); + break; + case DALLAS_ZERO_LEN: + rprintfProgStrM("RAM rd/wr 0 bytes"); + break; + case DALLAS_BUS_ERROR: + rprintfProgStrM("Bus error, check pullup"); + break; + case DALLAS_RESOLUTION_ERROR: + rprintfProgStrM("resolution out of range"); + break; + default: + rprintfProgStrM("Unknown"); + } + rprintfCRLF(); +} diff --git a/3rd party/Procyuon avrlib/rsl/dallas_ds2482.c b/3rd party/Procyuon avrlib/rsl/dallas_ds2482.c new file mode 100644 index 0000000..bff62e6 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallas_ds2482.c @@ -0,0 +1,447 @@ +//***************************************************************************** +// File Name : dallas.c +// Title : Dallas 1-Wire Library +// Revision : 6 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include string support +#include "rprintf.h" // include rprintf function library +#include "timer128.h" // include timer function library +#include "ds2482.h" // include dallas support +#include "dallas.h" // include dallas support + +//----- Global Variables ------------------------------------------------------- +static u08 last_discrep = 0; // last discrepancy for FindDevices +static u08 done_flag = 0; // done flag for FindDevices + +u08 dallas_crc; // current crc global variable +u08 dallas_crc_table[] = // dallas crc lookup table +{ + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 +}; + +//----- Functions -------------------------------------------------------------- + +/*-------------------------------------------------------------------------- + * dallasFindNextDevice: find the next device on the bus + * input................ rom_id - pointer to store the rom id found + * returns.............. true or false if a device was found + *-------------------------------------------------------------------------*/ +u08 dallasFindNextDevice(dallas_rom_id_T* rom_id); + +void dallasInit(void) +{ + //ds2482Init(); +} + +u08 dallasReset(void) +{ + // reset the bus + if(ds2482BusReset()) + return DALLAS_PRESENCE; + else + return DALLAS_NO_PRESENCE; +} + +u08 dallasReadBit(void) +{ + return ds2482BusTransferBit(1); +} + +void dallasWriteBit(u08 bit) +{ + ds2482BusTransferBit(bit); +} + +u08 dallasReadByte(void) +{ + return ds2482BusReadByte(); +} + +void dallasWriteByte(u08 byte) +{ + ds2482BusWriteByte(byte); +} + +u08 dallasReadRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08 *data) +{ + u08 i; + u08 error; + + union int16_var_U + { + u16 i16; + u08 i08[2]; + } int16_var; + + // first make sure we actually have something to do + if (data == NULL) + return DALLAS_NULL_POINTER; + if (len == 0) + return DALLAS_ZERO_LEN; + + // reset the bus and request the device + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // enter read mode + dallasWriteByte(DALLAS_READ_MEMORY); + + // write address one byte at a time + int16_var.i16 = addr; + dallasWriteByte(int16_var.i08[0]); + dallasWriteByte(int16_var.i08[1]); + + // read data from device 1 byte at a time + for(i=0;ibyte[i] = dallasReadByte(); + + return DALLAS_NO_ERROR; +} + +u08 dallasMatchROM(dallas_rom_id_T* rom_id) +{ + u08 i; + + // reset the 1-wire and look for presence + i = dallasReset(); + if (i != DALLAS_PRESENCE) + return i; + + // send MATCH ROM command + dallasWriteByte(DALLAS_MATCH_ROM); + + // write id one byte at a time + for(i=0;i<8;i++) + dallasWriteByte(rom_id->byte[i]); + + return DALLAS_NO_ERROR; +} + +void dallasPrintROM(dallas_rom_id_T* rom_id) +{ + s08 i; + + // print out the rom in the format: xx xx xx xx xx xx xx xx + for(i=7;i>=0;i--) + { + rprintfu08(rom_id->byte[i]); + rprintfChar(' '); + } +} + +u08 dallasAddressCheck(dallas_rom_id_T* rom_id, u08 family) +{ +// u08 i; + +// dallas_crc = 0; + +// for(i=1;i<7;i++) +// { +// dallasCRC(rom_id->byte[i]); +// rprintfu08(rom_id->byte[i]); +// rprintfChar(' '); +// } +// rprintfCRLF(); + +// rprintfu08(dallas_crc); +// rprintfCRLF(); + + //run CRC on address + + //make sure we have the correct family + if (rom_id->byte[DALLAS_FAMILY_IDX] == family) + return DALLAS_NO_ERROR; + + return DALLAS_ADDRESS_ERROR; +} + +u08 dallasCRC(u08 i) +{ + // update the crc global variable and return it + dallas_crc = dallas_crc_table[dallas_crc^i]; + return dallas_crc; +} + +u08 dallasFindDevices(dallas_rom_id_T rom_id[]) +{ + u08 num_found = 0; + dallas_rom_id_T id; + + // reset the rom search last discrepancy global + last_discrep = 0; + done_flag = FALSE; + + // check to make sure presence is detected before we start + if (dallasReset() == DALLAS_PRESENCE) + { + // --> stang + //while (dallasFindNextDevice(&rom_id[num_found]) && (num_found0) + { + // all devices coupled have 0 or 1 + // shift 1 to determine if the msb is 0 or 1 + bit = i>>1; + } + else + { + // if this discrepancy is before the last discrepancy on a + // previous FindNextDevice then pick the same as last time + if (bit_indexbyte[byte_index] & bit_mask) > 0); + else + bit = (bit_index==last_discrep); + + // if 0 was picked then record position with bit mask + if (!bit) + discrep_marker = bit_index; + } + + // isolate bit in rom_id->byte[byte_index] with bit mask + if (bit) + rom_id->byte[byte_index] |= bit_mask; + else + rom_id->byte[byte_index] &= ~bit_mask; + + // ROM search write + //cli(); + dallasWriteBit(bit); + //sei(); + + // ncrement bit index counter and shift the bit mask + bit_index++; + bit_mask <<= 1; + + if (!bit_mask) + { + // if the mask is 0 then go to new ROM + // accumulate the CRC and incriment the byte index and bit mask + dallasCRC(rom_id->byte[byte_index]); + byte_index++; + bit_mask++; + } + } + } + + if ((bit_index < 65) || dallas_crc) + { + // search was unsuccessful - reset the last discrepancy to 0 and return false + last_discrep = 0; + return FALSE; + } + + // search was successful, so set last_discrep and done_flag + last_discrep = discrep_marker; + done_flag = (last_discrep==0); + + return TRUE; +} + +void dallasPrintError(u08 error) +{ + // if there was not an error, return + if (error == DALLAS_NO_ERROR) + return; + + // print header message + rprintfProgStrM("ERROR "); + rprintfChar(error); + rprintfProgStrM(": "); + + // print custom error message + switch (error) + { + case DALLAS_NO_PRESENCE: + rprintfProgStrM("no presence detected"); + break; + case DALLAS_INVALID_CHANNEL: + rprintfProgStrM("Invalid Chan"); + break; + case DALLAS_VERIFY_ERROR: + rprintfProgStrM("Verify"); + break; + case DALLAS_ADDRESS_ERROR: + rprintfProgStrM("Bad Addr"); + break; + case DALLAS_CRC_ERROR: + rprintfProgStrM("Data CRC"); + break; + case DALLAS_DEVICE_ERROR: + rprintfProgStrM("No response"); + break; + case DALLAS_FORMAT_ERROR: + rprintfProgStrM("Bad return format"); + break; + case DALLAS_NULL_POINTER: + rprintfProgStrM("Null Pointer"); + break; + case DALLAS_ZERO_LEN: + rprintfProgStrM("RAM rd/wr 0 bytes"); + break; + case DALLAS_BUS_ERROR: + rprintfProgStrM("Bus error, check pullup"); + break; + case DALLAS_RESOLUTION_ERROR: + rprintfProgStrM("resolution out of range"); + break; + default: + rprintfProgStrM("Unknown"); + } + rprintfCRLF(); +} diff --git a/3rd party/Procyuon avrlib/rsl/dallasconf.h b/3rd party/Procyuon avrlib/rsl/dallasconf.h new file mode 100644 index 0000000..ec2190e --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallasconf.h @@ -0,0 +1,32 @@ +/*! \file dallasconf.h \brief Dallas 1-Wire Bus Library Configuration. */ +//***************************************************************************** +// +// File Name : 'dallasconf.h' +// Title : Dallas 1-Wire Bus Library Configuration +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.10 +// Revised : 2004.10.10 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DALLASCONF_H +#define DALLASCONF_H + +// Select which general-purpose I/O pin +// will be used for driving the dallas bus +#define DALLAS_PORT PORTE // the output port +#define DALLAS_DDR DDRE // the DDR port +#define DALLAS_PORTIN PINE // the input port +#define DALLAS_PIN 7 // the pin number [0-7] + +// Define the max number of Dallas devices which +// can be automatically discovered on the bus +#define DALLAS_MAX_DEVICES 20 + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/dallasids.c b/3rd party/Procyuon avrlib/rsl/dallasids.c new file mode 100644 index 0000000..eaec65f --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallasids.c @@ -0,0 +1,106 @@ + +// subsystem dallas IDs +DallasSubsysId __attribute__ ((progmem)) SubsysArray[] = +{ + // # V1 controller Sense A/D V2 controller Temp sensor + { 1, {0x0100000000AC2D20ULL},{0x8A0000000087BB20ULL},{0xEF00000000B1B720ULL},{0x340000000920D728ULL} }, + { 2, {0x1E000000009FE020ULL},{0xE600000001094020ULL},{0x6400000000B90120ULL},{0xFC000000049BF328ULL} }, + { 3, {0x7A000000008E2D20ULL},{0xBB00000000AA3120ULL},{0x9100000000B12D20ULL},{0x640000000968C328ULL} }, + { 4, {0x1400000000C6F120ULL},{0x5200000000DED720ULL},{0x8700000000FA7520ULL},{0x6100000009697928ULL} }, + { 5, {0x1500000000A03F20ULL},{0x9200000000A8E320ULL},{0x0000000000C8D120ULL},{0x5800000009690128ULL} }, + { 6, {0xE1000000009F5B20ULL},{0x2900000001094A20ULL},{0x1000000001282020ULL},{0x220000000968A428ULL} }, + { 7, {0x6500000000905E20ULL},{0xA700000000AD8C20ULL},{0x50000000010B5220ULL},{0x7F00000009699828ULL} }, + { 8, {0xE600000000FA8B20ULL},{0x330000000112E720ULL},{0x3D0000000129FF20ULL},{0x170000000969AF28ULL} }, + { 9, {0x20ULL},{0x20ULL},{0x20ULL},{0x28ULL} }, + { 10, {0x1800000000F04F20ULL},{0x8000000000E5CB20ULL},{0xA900000000A04020ULL},{0x7600000004948F28ULL} }, + { 11, {0x7D00000000C75A20ULL},{0x4400000000E17F20ULL},{0x3700000000A32E20ULL},{0x48000000052F5228ULL} }, + { 12, {0x37000000010CD620ULL},{0x0500000000921720ULL},{0x3A00000000906820ULL},{0xC10000000525C528ULL} }, + { 13, {0x4D00000000D44920ULL},{0xA100000000C33A20ULL},{0x4E00000000C12B20ULL},{0xC800000004811728ULL} }, + { 14, {0x2D00000000EA2E20ULL},{0x4F00000000DD8B20ULL},{0x8D00000000B91720ULL},{0xE000000004EB9528ULL} }, + { 15, {0x3100000000BD0C20ULL},{0xDB000000008E2520ULL},{0xD500000000D52020ULL},{0x6900000004995E28ULL} }, + { 16, {0x7200000000C6BF20ULL},{0x2F00000000AD6420ULL},{0x3500000000864B20ULL},{0xFA000000049EBB28ULL} }, + { 17, {0x6F00000001B89A20ULL},{0xFF00000001F8B020ULL},{0xD000000000F3DE20ULL},{0x9600000004EC0C28ULL} }, + { 18, {0xD800000000B0AF20ULL},{0x3A000000009CC420ULL},{0xA800000000F05A20ULL},{0x6700000004E72D28ULL} }, + { 19, {0xB500000000C6F920ULL},{0xA0000000009CA720ULL},{0x3B00000000B0E620ULL},{0x4700000004814F28ULL} }, + { 20, {0x5500000000B0E420ULL},{0x4A00000000E75020ULL},{0x9000000000B0B120ULL},{0x4C00000005173E28ULL} }, + { 21, {0x5400000000BCCD20ULL},{0xEF000000009D1020ULL},{0x6A00000000B0A920ULL},{0x6000000005312028ULL} }, + { 22, {0xB900000000E4AA20ULL},{0xA600000000B12C20ULL},{0xEC000000009C9F20ULL},{0xAE00000004D68928ULL} }, + { 23, {0x0400000000A55F20ULL},{0xE000000000AB3820ULL},{0x6D000000009DA720ULL},{0xC1000000052E2628ULL} }, + { 24, {0x7F00000000ABF820ULL},{0x8C00000000A5B720ULL},{0xA100000000A00C20ULL},{0x44000000048D7528ULL} }, + { 25, {0x6300000000AB0A20ULL},{0x8B000000009D4D20ULL},{0xA500000000A55720ULL},{0x9B00000004FF4128ULL} }, + { 26, {0x20ULL},{0x20ULL},{0x20ULL},{0x28ULL} }, +// boards serialized 9/20/2005 + { 27, {0x2A000000055C4720ULL},{0xCB00000005403820ULL},{0xFD00000005766820ULL},{0x8B00000009212728ULL} }, + { 28, {0x5400000003C56020ULL},{0x4600000003A19220ULL},{0x10000000055BE620ULL},{0x32000000088C3128ULL} }, + { 29, {0x32000000055AC520ULL},{0x17000000053B4B20ULL},{0xDA000000053A4B20ULL},{0x77000000087B3728ULL} }, + { 30, {0xAA000000055BAC20ULL},{0xDA00000005430E20ULL},{0xEC000000054E3F20ULL},{0x8F000000087C7328ULL} }, + { 31, {0x1F000000056B9820ULL},{0x19000000056CE220ULL},{0x53000000054DFD20ULL},{0x750000000891EF28ULL} }, + { 32, {0x010000000586FD20ULL},{0x3E00000005399920ULL},{0xFB0000000543A220ULL},{0xAD0000000895A928ULL} }, + { 33, {0x3C00000003BE2020ULL},{0x2400000003A7AC20ULL},{0x7C00000003C73720ULL},{0x5F000000085A4028ULL} }, + { 34, {0x6300000005449D20ULL},{0x5A0000000563A120ULL},{0xBF0000000559A520ULL},{0x4E00000009758928ULL} }, + { 35, {0x66000000054DEF20ULL},{0xC2000000054C5D20ULL},{0xF0000000054CFF20ULL},{0x0A00000009256228ULL} }, + { 36, {0x4000000005627F20ULL},{0xA3000000054BEC20ULL},{0x93000000055EA920ULL},{0x1B000000085A3428ULL} }, + { 37, {0x47000000056C5120ULL},{0xF800000005594720ULL},{0xEA00000005775920ULL},{0x460000000894B528ULL} }, + { 38, {0xE6000000054A0420ULL},{0xC1000000054DD220ULL},{0x86000000056C2220ULL},{0xAE00000008927028ULL} }, + { 39, {0x350000000548CE20ULL},{0x410000000544A720ULL},{0x780000000539FE20ULL},{0x970000000923E728ULL} }, + // # V1 controller Sense A/D V2 controller Temp sensor + { 40, {0xE6000000053A9020ULL},{0xF8000000054AE520ULL},{0x3300000005386F20ULL},{0xC8000000088C2928ULL} }, + { 41, {0x6F000000056A6220ULL},{0x000000000549C520ULL},{0x7E000000054D3B20ULL},{0xB9000000088C4F28ULL} }, + { 42, {0x0F000000055B8220ULL},{0x5300000005862420ULL},{0xA700000005864520ULL},{0x09000000085FC228ULL} }, + { 43, {0x8800000003C56420ULL},{0x9D00000003BE2820ULL},{0x1D00000003C5FB20ULL},{0x8900000009221F28ULL} }, + { 44, {0x6B000000055EA220ULL},{0x26000000055E1F20ULL},{0x4D0000000541B020ULL},{0x5400000009297D28ULL} }, + { 45, {0xC700000005414B20ULL},{0xF0000000056EC620ULL},{0x1F00000005435B20ULL},{0xF1000000088C5128ULL} }, + { 46, {0x2600000005446C20ULL},{0x8A000000055B8520ULL},{0x59000000055B7D20ULL},{0x6200000009255528ULL} }, + { 47, {0x440000000576B420ULL},{0xC600000005481F20ULL},{0x6700000005771220ULL},{0x01000000087BE128ULL} }, + { 48, {0x480000000548C220ULL},{0x7B000000055B4720ULL},{0x240000000537C020ULL},{0xE100000009222828ULL} }, + { 49, {0x0D000000054D4E20ULL},{0xDD00000005775820ULL},{0x63000000056D4720ULL},{0x080000000891E328ULL} }, + { 50, {0xE1000000056DF020ULL},{0x650000000543E720ULL},{0x70000000055A8420ULL},{0x830000000976BB28ULL} }, + { 51, {0x5D000000056EA420ULL},{0xA1000000056DA220ULL},{0x8E000000055BA320ULL},{0xA20000000922EC28ULL} }, + { 52, {0xB9000000054E5620ULL},{0xA8000000054E4B20ULL},{0xD2000000053B1E20ULL},{0x1900000009247528ULL} }, + { 53, {0x31000000056C8720ULL},{0x060000000548E920ULL},{0xE60000000540FE20ULL},{0xD000000009267828ULL} }, + { 54, {0xF1000000056A2720ULL},{0x22000000055B4420ULL},{0x0A000000053E4120ULL},{0x8A00000008961B28ULL} }, + { 55, {0x4200000005380920ULL},{0xB7000000055AC220ULL},{0x06000000055B4B20ULL},{0x3B000000085A1D28ULL} }, + { 56, {0x31000000054D9520ULL},{0x3600000005409020ULL},{0x3A000000057DCD20ULL},{0x99000000085FFE28ULL} }, + { 57, {0x4D000000054D1C20ULL},{0x150000000574C920ULL},{0x63000000054D4C20ULL},{0x8800000008960828ULL} }, + { 58, {0x0400000003A2F820ULL},{0x7100000003A19320ULL},{0xDE00000003A7B420ULL},{0x07000000087C9B28ULL} }, +// boards serialized 2/23/2006 + { 59, {0x7000000003D2A920ULL},{0x9300000003AABC20ULL},{0x3000000003B79B20ULL},{0x990000009A395F28ULL} }, + { 60, {0x2400000003A82B20ULL},{0xE500000003A7DF20ULL},{0xFD00000003A88C20ULL},{0xB30000009A149728ULL} }, + { 61, {0x3600000003A17120ULL},{0xAE00000003D19520ULL},{0xCF00000003AC4A20ULL},{0x8E0000009A3E3828ULL} }, + { 62, {0x6F00000003AB8820ULL},{0xFC00000003C5A120ULL},{0x7D00000003AC4C20ULL},{0xAF0000009A3DBF28ULL} }, +// boards serialized 3/8/2006 + { 63, {0x4A00000003BEF620ULL},{0x5500000003C7D720ULL},{0x6E00000003A93F20ULL},{0xA40000009A55B028ULL} }, + { 64, {0x6000000003C19320ULL},{0x7100000003B8CB20ULL},{0xDB00000003A71720ULL},{0xCF0000009A20F828ULL} }, + { 65, {0xF800000003A93620ULL},{0xBE00000003A3AB20ULL},{0xB400000003A81720ULL},{0xA00000009A035F28ULL} }, + { 66, {0x7900000003A1DF20ULL},{0x9600000003CB1B20ULL},{0x1000000003B6AB20ULL},{0xF30000009A51AE28ULL} }, + { 67, {0x5500000003AA7F20ULL},{0x6E00000003BEF920ULL},{0x7A00000003AAAA20ULL},{0xD300000099E0D828ULL} }, + { 68, {0xA200000003A8BA20ULL},{0x5900000003C0F220ULL},{0xC300000003C09120ULL},{0x010000009A273828ULL} }, + { 69, {0xCE00000003C07E20ULL},{0x4C00000003A81C20ULL},{0x6800000003A5A620ULL},{0x6300000099F61228ULL} }, + { 70, {0x4C00000003A68220ULL},{0xE100000003B03F20ULL},{0xB700000003B78F20ULL},{0xB90000009A445728ULL} }, + { 71, {0x7600000003AAC020ULL},{0xF700000003A22920ULL},{0x3F00000003A97020ULL},{0xF20000009A176B28ULL} }, +// boards serialized 7/15/2006 + { 72, {0xD600000003BAC420ULL},{0xAA00000003AC9220ULL},{0x6000000003A7D820ULL},{0xBB0000009A10BF28ULL} }, + { 73, {0x9D00000003C8EA20ULL},{0xD200000003B8D020ULL},{0x8400000003AB8D20ULL},{0x5C0000009A50C628ULL} }, + { 74, {0x2000000003A1DC20ULL},{0x9D00000003AAC520ULL},{0xED00000003A81420ULL},{0x9A0000009A110A28ULL} }, + { 75, {0xD400000003C0B920ULL},{0x3C00000003B28C20ULL},{0x9D00000003CAD820ULL},{0x800000009A442F28ULL} }, + { 76, {0x8700000003AC5420ULL},{0xD100000003CAE020ULL},{0xC500000003BACA20ULL},{0xB50000009A1E5828ULL} }, + { 77, {0x0A00000003C6F820ULL},{0x0600000003B89820ULL},{0xFB00000003B92920ULL},{0x2500000099F30828ULL} }, + { 78, {0xBC00000003A3B820ULL},{0x2000000003C0D820ULL},{0xAD00000003C7DC20ULL},{0x6A00000099E00428ULL} }, + { 79, {0x0C00000003C7D420ULL},{0x7800000003ABA020ULL},{0xBD00000003ABF520ULL},{0xC00000009A55ED28ULL} }, + // # V1 controller Sense A/D V2 controller Temp sensor + { 80, {0x5900000003A82720ULL},{0xCC000000039E6C20ULL},{0x5500000003A3AE20ULL},{0xB50000009A0FC828ULL} }, + { 81, {0xFB00000003B6AE20ULL},{0xBE00000003A5FD20ULL},{0x2A00000003C08720ULL},{0x420000009A39EB28ULL} }, + { 82, {0x1400000003C70020ULL},{0x0800000003AD1520ULL},{0x0900000003AC8920ULL},{0x5F0000009A0D7A28ULL} }, + { 83, {0x5A00000003B6A620ULL},{0x4000000003A96F20ULL},{0x3700000003AC4120ULL},{0x840000009A183A28ULL} }, + { 84, {0x8700000003AA0220ULL},{0x2100000003CBBE20ULL},{0x5C00000003C05120ULL},{0xDB0000009A3E5128ULL} }, + { 85, {0xF900000003C07F20ULL},{0x8100000003AD7820ULL},{0xF300000003AFBA20ULL},{0xB500000099DDA128ULL} }, + { 86, {0x2100000003ABA320ULL},{0x0A00000003B03A20ULL},{0xE500000003D11D20ULL},{0x260000009A1CC028ULL} }, + { 87, {0x8D00000003A7E820ULL},{0xBF00000003D2A320ULL},{0x3D00000003BAC120ULL},{0xD300000099E81028ULL} } + +// { 88, }, +}; + + + + + diff --git a/3rd party/Procyuon avrlib/rsl/dallasids.h b/3rd party/Procyuon avrlib/rsl/dallasids.h new file mode 100644 index 0000000..ead74f7 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/dallasids.h @@ -0,0 +1,16 @@ + +#ifndef DALLASIDS_H +#define DALLASIDS_H + +// subsystem dallas ID structure + +typedef struct +{ + int serialnum; + dallas_rom_id_T V1; + dallas_rom_id_T S; + dallas_rom_id_T V2; + dallas_rom_id_T T; +} DallasSubsysId; + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/ds18b20.c b/3rd party/Procyuon avrlib/rsl/ds18b20.c new file mode 100644 index 0000000..ff529ba --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds18b20.c @@ -0,0 +1,201 @@ +//***************************************************************************** +// File Name : ds18b20.c +// Title : Dallas 1-Wire DS18B20 Temperature Sensor Library +// Revision : 3 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include "rprintf.h" // include rprintf function library +#include "dallas.h" // include dallas support +#include "ds18b20.h" // include ds18b20 support + +void ds18b20Init(void) +{ + // initialize the 1-wire + dallasInit(); +} + +u08 ds18b20Setup(dallas_rom_id_T* rom_id, u08 resolution, s08 alarm_low, s08 alarm_high) +{ + u08 error; + + // check resolution + if ((resolution < DS18B20_RES_MIN) || (resolution > DS18B20_RES_MAX)) + return DALLAS_RESOLUTION_ERROR; + + // check address + error = dallasAddressCheck(rom_id, DS18B20_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // starts writting at address 0x02, T_H + dallasWriteByte(DS18B20_WRITE_SCRATCHPAD); + dallasWriteByte(alarm_high); + dallasWriteByte(alarm_low); + + // convert resolution to bitmask + // valid value are 9-12 encoded as 0-4, resolution stored in bits 5&6 and bits 0-4 are always one + resolution = ((resolution - 9) << 5) | 0x60; + dallasWriteByte(resolution); + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // start reading at address 0x00 + dallasWriteByte(DS18B20_READ_SCRATCHPAD); + + dallasReadByte(); // 0x00, temp lsb + dallasReadByte(); // 0x01, temp msb + + // verify the data + if ((s08)dallasReadByte() != alarm_high) // 0x02, alarm high + return DALLAS_VERIFY_ERROR; + if ((s08)dallasReadByte() != alarm_low) // 0x03, alarm low + return DALLAS_VERIFY_ERROR; + if (dallasReadByte() != resolution) // 0x04, resolution + return DALLAS_VERIFY_ERROR; + + return DALLAS_NO_ERROR; +} + +u08 ds18b20Start(dallas_rom_id_T* rom_id) +{ + u08 error; + + // check address + error = dallasAddressCheck(rom_id, DS18B20_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // send convert command + dallasWriteByte(DS18B20_CONVERT_TEMP); + + return DALLAS_NO_ERROR; +} + +/*------ DallasTempGetResult ------*/ +u08 ds18b20Result(dallas_rom_id_T* rom_id, u16 *result) +{ + u08 error; + + union int16_var_U + { + u16 i16; + u08 i08[2]; + } int16_var; + + // check address + error = dallasAddressCheck(rom_id, DS18B20_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // send command + dallasWriteByte(DS18B20_READ_SCRATCHPAD); + + // read results 1 byte at a time + int16_var.i08[0] = dallasReadByte(); + int16_var.i08[1] = dallasReadByte(); + *result = int16_var.i16; + + return DALLAS_NO_ERROR; +} + +u08 ds18b20StartAndResult(dallas_rom_id_T* rom_id, u16 *result) +{ + u08 error; + + // start + error = ds18b20Start(rom_id); + if(error != DALLAS_NO_ERROR) + return error; + + // wait + dallasWaitUntilDone(); + + // return any errors - results passed by reference + return ds18b20Result(rom_id,result); +} + +void ds18b20Print(u16 result, u08 resolution) +{ + // print raw value + rprintfProgStrM(" 0x"); + rprintfu16(result); + rprintfChar(' '); + + // print real temp + rprintfNum(10, 4, TRUE , ' ', result>>4); + rprintf("."); + rprintfNum(10, 4, FALSE, '0', (10000*((u32)(result&0x000F)))/16 ); + rprintfProgStrM(" C"); +} + +/* OLD VERSION + +void ds18b20Print(u16 result, u08 resolution) +{ + u08 numerator; + + // print header + rprintfProgStrM(" 0x"); + rprintfu16(result); + rprintfChar(' '); + + // extract fractional part + numerator = result & 0x000F; + + // extract integer part + result >>= 4; + + // deal with negative numbers + if ((s08)result < 0) + { + // for negative fractions + if (numerator) + { + numerator = 16-numerator; // fractions are reversed + ++result; // the integer is one more than 2's complement + if (!(s08)result) // between -1 and 0 + rprintfChar('-'); // we have to take care of the negative sign + } + } + + // print integer part (signed) + rprintfNum(10,4,1,'0',(s08)result); + rprintfChar(' '); + + //Print fractional part. use numerator for numerator, resolution for denomiator + // bit resolution setup mask degree resolution + // -------------- ---------- ----------------- + // 9 0x00 1/2 + // 10 0x20 1/4 + // 11 0x40 1/8 + // 12 0x60 1/16 + numerator >>= (12-resolution); // scale fractional part of result to resolution + resolution = 2 << (resolution - 9); // create denominator as 2^(res-9) + rprintfNum(10,3,0,0,numerator); + rprintfChar('/'); + rprintfNum(10,3,0,0,resolution); +} +*/ diff --git a/3rd party/Procyuon avrlib/rsl/ds18b20.h b/3rd party/Procyuon avrlib/rsl/ds18b20.h new file mode 100644 index 0000000..09dcb7b --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds18b20.h @@ -0,0 +1,80 @@ +//***************************************************************************** +// File Name : ds18b20.c +// Title : Dallas 1-Wire DS18B20 Temperature Sensor Library +// Revision : 3 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Rev Description of change +// ----------- ----------- ------- ----------------------- +// 28-Sep-2003 rwatson 3 Added Print +// 27-Sep-2003 rwatson 2 Added Setup, Start, Result, StartAndResult +// 27-Sep-2003 rwatson 1 Created the program structure +//***************************************************************************** + +#ifndef ds18b20_h +#define ds18b20_h + +//----- Include Files --------------------------------------------------------- +#include "global.h" + +//----- Defines --------------------------------------------------------------- +#define ds18b20_rev 3 + +// family code +#define DS18B20_FAMILY 0x28 + +// function commands +#define DS18B20_CONVERT_TEMP 0x44 +#define DS18B20_WRITE_SCRATCHPAD 0x4E +#define DS18B20_READ_SCRATCHPAD 0xBE +#define DS18B20_COPY_SCRATCHPAD 0x48 +#define DS18B20_RECALL_E2 0xB8 +#define DS18B20_READ_POWER 0xB4 + +// resolution min and max +#define DS18B20_RES_MIN 9 +#define DS18B20_RES_MAX 12 + +// no alarm values for high and low +#define DS18B20_NO_ALARM_LOW -56 // min temp read is -55C +#define DS18B20_NO_ALARM_HIGH 126 // max temp read is 125C + +//----- Functions --------------------------------------------------------------- + +// ds18b20Init() +// initializes the dallas 1-wire bus +void ds18b20Init(void); + +// ds18b20Setup +// Sets up the device +// The parameters are the rom id of the device, +// the resolution [9-12], and the low and high alarm values. +// If no low and/or high alarm is desired, use the values -55 and/or 126 +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds18b20Setup(dallas_rom_id_T* rom_id, u08 resolution, s08 alarm_low, s08 alarm_high); + +// ds18b20Start() +// Start the conversion for the given device +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds18b20Start(dallas_rom_id_T* rom_id); + +// ds18b20Result() +// Gets the result of the conversion and stores it in *result +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds18b20Result(dallas_rom_id_T* rom_id, u16 *result); + +// ds18b20StartAndResult(); +// 1-step command to start the conversion and store the result in *result +// The conversion takes some time to do, so it can be more efficient +// to do the 1-step commands Start() and Result() +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds18b20StartAndResult(dallas_rom_id_T* rom_id, u16 *result); + +// ds18b20Print() +// Does a formatted print on the given resultat the given resolution: +xx x/xx +void ds18b20Print(u16 result, u08 resolution); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/ds2450.c b/3rd party/Procyuon avrlib/rsl/ds2450.c new file mode 100644 index 0000000..0f30741 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2450.c @@ -0,0 +1,457 @@ +//***************************************************************************** +// File Name : ds2450.c +// Title : Dallas 1-Wire DS2450 A2D Sensor Library +// Revision : 5 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include string support +#include +#include "timer128.h" +#include "dallas.h" // include dallas support +#include "ds2450.h" // include ds2450 support +#include "rprintf.h" + +//----- Functions --------------------------------------------------------------- + +/*-------------------------------------------------------------------------- + * ds2450Chan2Addr: converts the channel to the address in RAM + * input........... channel - the channel to get the address for [A-D] + * page - the page in RAM that we are dealing with + * address - where the address is stored + * returns......... the corresponding error or DALLAS_NO_ERROR + *-------------------------------------------------------------------------*/ +static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address); + +void ds2450Init(void) +{ + // initialize the dallas 1-wire + dallasInit(); +} + +u08 *capitalize (u08 *input) +{ + if(islower(*input)) + *input = toupper(*input); + return input; +} + +u08 ds2450Setup(dallas_rom_id_T* rom_id, u08 channel, u08 resolution, u08 range) +{ + u08 error; + u08 data[2]; + u16 address; + + // check resolution + if (resolution > DS2450_RES_MAX) + return DALLAS_RESOLUTION_ERROR; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // get address + capitalize(&channel); + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address + if (error != DALLAS_NO_ERROR) + return error; + + // convert to valid resolution - 16 bits = 0x00 + if (resolution == 16) + resolution = 0x00; + + // read in current digital output settings + error = dallasReadRAM(rom_id, address, 1, data); + if (error != DALLAS_NO_ERROR) + return error; + + // maintain digital output portion and add new resolution + data[0] = (data[0] & 0xF0) | resolution; + + // maintain alarm states and add new range + data[1] = (data[1] & 0xFE) | range; + + // actually write config, handles CRC too + error = dallasWriteRAM(rom_id, address, 2, data); + if (error != DALLAS_NO_ERROR) + return error; + + // Normally, the DS2450 is designed to run off of parasite power from the data line + // Typically the master (us) strongly pulls high long enough to power the conversion, so + // there is inherintly a long () delay introduced. Since the A2D code is designed to + // work for devices that use external power, we can elliminate this delay by writting + // the following byte per the DS2450 datasheet. + data[0] = DS2450_VCC_FLAG; + error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]); + if (error != DALLAS_NO_ERROR) + return error; + + // verify the data + error = dallasReadRAM(rom_id, address, 2, data); + if (error != DALLAS_NO_ERROR) + return error; + + if ((data[0] & 0x0F) != resolution) + return DALLAS_VERIFY_ERROR; + if ((data[1] & 0x01) != range) + return DALLAS_VERIFY_ERROR; + + return DALLAS_NO_ERROR; +} + +u08 ds2450Start(dallas_rom_id_T* rom_id, u08 channel) +{ + u08 mask; + u08 error; + u08 crc[2]; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // make sure the channel is a capital letter + capitalize(&channel); + // convert to integer 0 to 3 + channel -= 'A'; + + // make sure channel is a valid value + if (channel > 3) + return DALLAS_INVALID_CHANNEL; + + // shift over to construct input select mask + mask = 0x01 << channel; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // send convert command + dallasWriteByte(DS2450_CONVERT); + // input select mask + dallasWriteByte(mask); + // shift over some more for "read-out" control + mask = mask << channel; + + // set coresponding output buffer to zero + dallasWriteByte(mask); + + // we must read 2byte CRC16 to start the conversion: + crc[0] = dallasReadByte(); + crc[1] = dallasReadByte(); + + //replace with explicit CRC posibilities lookup table +// if (crc[0] == 0xFF && crc[1] == 0xFF) +// return DALLAS_DEVICE_ERROR; //if CRC = all one's, no one is paying attention + + return DALLAS_NO_ERROR; +} + +u08 ds2450Result(dallas_rom_id_T* rom_id, u08 channel, u16* result) +{ + u08 data[2]; + u08 error; + u16 address; + //u08 resolution; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if( error != DALLAS_NO_ERROR) + return error; + + // get the RAM address for the data for the channel + capitalize(&channel); + error = ds2450Chan2Addr(channel, DS2450_DATA_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the RAM from the device to get the data + error = dallasReadRAM(rom_id, address, 2, data); + /* + // get the address for the setup for the channel + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address + if (error != DALLAS_NO_ERROR) + return error; + + // read the RAM from the device to get the resolution + error = dallasReadRAM(rom_id, address, 1, &resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // get the resultion part of the data + resolution &=0x0F; + */ + // store the result by combining the 2 bytes + // the result's MSB is always the same, so we may need to + // shift the data over so that the LSB is at the first bit + *result = 0; + //*result = (((u16)data[1] << 8) | data[0]) >> (16 - resolution); + *result = (((u16)data[1] << 8) | data[0]); + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAndResult(dallas_rom_id_T* rom_id, u08 channel, u16 *result) +{ + u08 error; + + // start conversion + error = ds2450Start(rom_id, channel); + if (error != DALLAS_NO_ERROR) + return error; + + // wait till conversion done + dallasWaitUntilDone(); + + // return results + return ds2450Result(rom_id, channel, result); +} + +u08 ds2450SetupAll(dallas_rom_id_T* rom_id, u08 resolution, u08 range) +{ + u08 i; + u08 error; + u08 data[8]; + u16 address; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // check resolution + if (resolution > DS2450_RES_MAX) + return DALLAS_RESOLUTION_ERROR; + + // convert to valid resolution - 16 bits = 0x00 + if (resolution == 16) + resolution = 0; + + // get address - start with channel A + error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read in current settings so we can extract digital part + error = dallasReadRAM(rom_id, address, 8, data); + if (error != DALLAS_NO_ERROR) + return error; + + // build up config data to write - increment by 2 b/c two bytes per channel + for(i=0;i<8;i+= 2) + { + // maintain digital output settings + data[i] &= 0xF0; // extract digital output portion + data[i+1] &= 0xFE; + + // write resolution byte and range + data[i] |= resolution; + data[i+1] |= range; + } + + // actually write config - handles CRC too + error = dallasWriteRAM(rom_id, address, 8, data); + if (error != DALLAS_NO_ERROR) + return error; + + // Normally, the DS2450 is designed to run off of parasite power from the data line + // Typically the master (us) strongly pulls high long enough to power the conversion, so + // there is inherintly a long () delay introduced. Since the A2D code is designed to + // work for devices that use external power, we can elliminate this delay by writting + // the following byte per the DS2450 datasheet. + data[0] = DS2450_VCC_FLAG; + error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]); + if (error != DALLAS_NO_ERROR) + return error; + + error = dallasReadRAM(rom_id,address,8,data); + if (error != DALLAS_NO_ERROR) + return error; + + for(i=0;i<8;i+=2) + { + if ((data[i] & 0x0F) != resolution) + return DALLAS_VERIFY_ERROR; + if ((data[i+1] & 0x01) != range) + return DALLAS_VERIFY_ERROR; + } + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAll(dallas_rom_id_T* rom_id) +{ + u08 error; + u16 crc; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + dallasWriteByte(DS2450_CONVERT); // send convert command + dallasWriteByte(DS2450_CONVERT_ALL4_MASK); // select all 4 inputs + dallasWriteByte(DS2450_CLEAR_ALL4_MASK); // set all output buffers to zero + + // we must read 2byte CRC16 to start the conversion: + crc = dallasReadByte() | ((u16)dallasReadByte() << 8); + + // replace with explicit CRC posibilities lookup table +// if (crc == 0xFFFF) +// return DALLAS_DEVICE_ERROR; // if CRC = all one's, no one is paying attention + + return DALLAS_NO_ERROR; +} + +u08 ds2450ResultAll(dallas_rom_id_T* rom_id, u16 result[4]) +{ + //const u08 bytes_to_read = 10; // read 10bytes = 2/ch*4ch + CRC + u08 bytes_to_read = 10; + u08 i; + u08 error; + u08 data[10]; + u08 resolution[10]; + u16 address; + + // check address + + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // start address with channel A + error = ds2450Chan2Addr('A', DS2450_DATA_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the conversion data + error = dallasReadRAM(rom_id, address, bytes_to_read, data); + if (error != DALLAS_NO_ERROR) + return error; + + //FUTURE: do a real CRC16 check + + // start address with channel A + error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the resolution data + error = dallasReadRAM(rom_id, address, bytes_to_read, resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // check crc? + + // store the result by combining the 2 bytes + // the result's MSB is always the same, so we may need to + // shift the data over so that the LSB is at the first bit + error=0; + for(i=0;i<8;i+=2) + { + resolution[i] &= 0x0F; + if (!resolution[i]) + resolution[i] = 16; + + result[error] = 0; + //result[error] = (((u16)data[i+1] << 8) | data[i]) >> (16 - resolution[i]); + result[error] = (((u16)data[i+1] << 8) | data[i]); + error++; + } + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAndResultAll(dallas_rom_id_T* rom_id, u16 result[4]) +{ + u08 error; + + // start Conversion + error = ds2450StartAll(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // wait until conversion done + dallasWaitUntilDone(); + + // return any error - results passed by reference + return ds2450ResultAll(rom_id, result); +} + +void ds2450Print(u16 result, u08 range) +{ + u16 vscale; + + rprintfProgStrM(" 0x"); + rprintfu16(result); + rprintf(" "); + if(range) + vscale = 12800; + else + vscale = 25600; + + rprintfNum(10, 4, TRUE , ' ', result/vscale); + rprintf("."); + rprintfNum(10, 4, FALSE, '0', (((u32)(result%vscale))*10000)/vscale ); + rprintfProgStrM(" Volts"); +} + +u08 ds2450DigitalOut(dallas_rom_id_T* rom_id, u08 channel, dallas_a2d_out_T state) +{ + u08 error; + u08 old_resolution; + u16 address; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // get the address for the channel in the setup page + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read in current resolution + error = dallasReadRAM(rom_id, address, 1, &old_resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // extract resolution portion + old_resolution &= 0x0F; + + // write new setup byte + state |= old_resolution; + error = dallasWriteRAM(rom_id, address, 1, ((u08*)&state)); + if (error != DALLAS_NO_ERROR) + return error; + + return DALLAS_NO_ERROR; +} + +static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address) +{ + // make sure the channel is a capital letter + capitalize(&channel); + + //convert to integer 0 to 3 and check to see if it is valid + channel -= 'A'; + if (channel > 3) + return DALLAS_INVALID_CHANNEL; + + // use corresponding memory address + *address = (channel<<1) + page; // channel<<1 == channel*2, but faster + + return DALLAS_NO_ERROR; +} diff --git a/3rd party/Procyuon avrlib/rsl/ds2450.h b/3rd party/Procyuon avrlib/rsl/ds2450.h new file mode 100644 index 0000000..2853223 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2450.h @@ -0,0 +1,139 @@ +//***************************************************************************** +// File Name : ds2450.c +// Title : Dallas 1-Wire DS2450 A2D Sensor Library +// Revision : 5 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Rev Description of change +// ----------- ----------- ------- ----------------------- +// 07-Aug-2006 pwilliams 6 Fixed Error in strupr usage causing stack corruption +// 01-Oct-2003 rwatson 5 Fixed result error with MSB +// 30-Sep-2003 rwatson 4 CreatedDigitalOut +// 30-Sep-2003 rwatson 3 Created SetupAlll, StartAll, ResultAll, StartAndResultAll +// 29-Sep-2003 rwatson 2 Created Setup, Start, Result, StartAndResult +// 29-Sep-2003 rwatson 1 Created the program structure +//***************************************************************************** + +#ifndef ds2450_h +#define ds2450_h + +//----- Include Files --------------------------------------------------------- +#include "global.h" + +//----- Defines --------------------------------------------------------------- +#define ds2450_rev 6 + +// the two voltage ranges +#define DS2450_RANGE_2V 0x00 // 0-2.55V +#define DS2450_RANGE_5V 0x01 // 0-5.10V + +// the family code +#define DS2450_FAMILY 0x20 + +// the starting addresses +// of the pages in RAM +#define DS2450_DATA_PAGE 0x00 +#define DS2450_SETUP_PAGE 0x08 +#define DS2450_ALARM_PAGE 0x10 + +#define DS2450_VCC_FLAG 0x40 +#define DS2450_VCC_ADDR 0x1C + +// maximum allowable resolution +#define DS2450_RES_MAX 16 + +// function commands +#define DS2450_READ_MEMORY 0xAA +#define DS2450_WRITE_MEMORY 0x55 +#define DS2450_CONVERT 0x3C +#define DS2450_CONVERT_ALL4_MASK 0x0F +#define DS2450_CLEAR_ALL4_MASK 0x55 + +//----- Typedefs -------------------------------------------------------------- + +// enumerated constant for configuring +// and controlling an A2D channel as a digital output +typedef enum {DIGOUT_LOW=0x80, DIGOUT_OC=0xC0, DIGOUT_DISABLE=0x00} dallas_a2d_out_T; + +//----- Functions --------------------------------------------------------------- + +// ds2450Init() +// initializes the dallas 1-wire bus +void ds2450Init(void); + +//----- Single Channel Functions ---------------------------------------------- +// The following 4 functions are used for controlling a single channel on the +// a2d converter. If you are only using 1 channel, then these functions are +// faster. If you are using 2 or more channel, it is faster to use the All +// Channel Functions. This is because to convert all the channel only requires +// one command to the device, and then a read of the all the channel. To read +// two channel individually requires two commands to the device, and two reads. +// Therefore using the All Channel Functions for even just 2 channels is faster +// and more effificient. + +// ds2450Setup() +// Sets up the given device, for the given channel [A-D], +// the given resolution [1-16] and the given range 0-2.55 or 0-5.10 +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Setup(dallas_rom_id_T* rom_id, u08 channel, u08 resolution, u08 range); + +// ds2450Start() +// Starts the a2d conversion for the given device and the given channel [A-D] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Start(dallas_rom_id_T* rom_id, u08 channel); + +// ds2450Result() +// Gets the result from the a2d conversion +// for the given device and the given channel [A-D] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Result(dallas_rom_id_T* rom_id, u08 channel, u16* result); + +// ds2450StartAndResult() +// Starts the conversion of the given device and the given channel [A-D] +// Stores the result in the variable result +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAndResult(dallas_rom_id_T* rom_id, u08 channel, u16 *result); + +//----- All Channel Functions ------------------------------------------------- +// The following 4 commands are used to access data from all 4 channels on the +// a2d converter. These commands should be used if you are using more than one +// channel on the device. See the Single Channel Functions description for +// more information + +// ds2450SetupAll() +// Sets up the given device for all channels for the given resultion +// and the given range [0-2.55 or 0-5.10] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450SetupAll(dallas_rom_id_T* rom_id, u08 resolution, u08 range); + +// ds2450StartAll() +// Starts the conversion for all 4 channels on the given a2d converter +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAll(dallas_rom_id_T* rom_id); + +// ds2450ResultAll +// Gets the results from the given device +// and stores the result in the given array +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450ResultAll(dallas_rom_id_T* rom_id, u16 result[4]); + +// ds2450StartAndResultAll() +// 1-Step command to start the conversion for the given device, +// and store the results in the given array +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAndResultAll(dallas_rom_id_T* rom_id, u16 result[4]); + +// ds2450Print() +// Does a formatted print on the given result for the given range +void ds2450Print(u16 result, u08 range); + +//----- Digital Out Functions ------------------------------------------------- +// ds2450DigitalOut +// Use the given channel of the given device as a digital out +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450DigitalOut(dallas_rom_id_T* rom_id, u08 channel, dallas_a2d_out_T state); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/ds2450_old.c b/3rd party/Procyuon avrlib/rsl/ds2450_old.c new file mode 100644 index 0000000..3cbe947 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2450_old.c @@ -0,0 +1,449 @@ +//***************************************************************************** +// File Name : ds2450.c +// Title : Dallas 1-Wire DS2450 A2D Sensor Library +// Revision : 5 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include string support +#include "timer128.h" +#include "dallas.h" // include dallas support +#include "ds2450.h" // include ds2450 support +#include "rprintf.h" + +//----- Functions --------------------------------------------------------------- + +/*-------------------------------------------------------------------------- + * ds2450Chan2Addr: converts the channel to the address in RAM + * input........... channel - the channel to get the address for [A-D] + * page - the page in RAM that we are dealing with + * address - where the address is stored + * returns......... the corresponding error or DALLAS_NO_ERROR + *-------------------------------------------------------------------------*/ +static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address); + +void ds2450Init(void) +{ + // initialize the dallas 1-wire + dallasInit(); +} + +u08 ds2450Setup(dallas_rom_id_T* rom_id, u08 channel, u08 resolution, u08 range) +{ + u08 error; + u08 data[2]; + u16 address; + + // check resolution + if (resolution > DS2450_RES_MAX) + return DALLAS_RESOLUTION_ERROR; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // get address + strupr(&channel); + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address + if (error != DALLAS_NO_ERROR) + return error; + + // convert to valid resolution - 16 bits = 0x00 + if (resolution == 16) + resolution = 0x00; + + // read in current digital output settings + error = dallasReadRAM(rom_id, address, 1, data); + if (error != DALLAS_NO_ERROR) + return error; + + // maintain digital output portion and add new resolution + data[0] = (data[0] & 0xF0) | resolution; + + // maintain alarm states and add new range + data[1] = (data[1] & 0xFE) | range; + + // actually write config, handles CRC too + error = dallasWriteRAM(rom_id, address, 2, data); + if (error != DALLAS_NO_ERROR) + return error; + + // Normally, the DS2450 is designed to run off of parasite power from the data line + // Typically the master (us) strongly pulls high long enough to power the conversion, so + // there is inherintly a long () delay introduced. Since the A2D code is designed to + // work for devices that use external power, we can elliminate this delay by writting + // the following byte per the DS2450 datasheet. + data[0] = DS2450_VCC_FLAG; + error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]); + if (error != DALLAS_NO_ERROR) + return error; + + // verify the data + error = dallasReadRAM(rom_id, address, 2, data); + if (error != DALLAS_NO_ERROR) + return error; + + if ((data[0] & 0x0F) != resolution) + return DALLAS_VERIFY_ERROR; + if ((data[1] & 0x01) != range) + return DALLAS_VERIFY_ERROR; + + return DALLAS_NO_ERROR; +} + +u08 ds2450Start(dallas_rom_id_T* rom_id, u08 channel) +{ + u08 mask; + u08 error; + u08 crc[2]; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // make sure the channel is a capital letter + strupr(&channel); + // convert to integer 0 to 3 + channel -= 'A'; + + // make sure channel is a valid value + if (channel > 3) + return DALLAS_INVALID_CHANNEL; + + // shift over to construct input select mask + mask = 0x01 << channel; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // send convert command + dallasWriteByte(DS2450_CONVERT); + // input select mask + dallasWriteByte(mask); + // shift over some more for "read-out" control + mask = mask << channel; + + // set coresponding output buffer to zero + dallasWriteByte(mask); + + // we must read 2byte CRC16 to start the conversion: + crc[0] = dallasReadByte(); + crc[1] = dallasReadByte(); + + //replace with explicit CRC posibilities lookup table +// if (crc[0] == 0xFF && crc[1] == 0xFF) +// return DALLAS_DEVICE_ERROR; //if CRC = all one's, no one is paying attention + + return DALLAS_NO_ERROR; +} + +u08 ds2450Result(dallas_rom_id_T* rom_id, u08 channel, u16* result) +{ + u08 data[2]; + u08 error; + u16 address; + u08 resolution; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if( error != DALLAS_NO_ERROR) + return error; + + // get the RAM address for the data for the channel + strupr(&channel); + error = ds2450Chan2Addr(channel, DS2450_DATA_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the RAM from the device to get the data + error = dallasReadRAM(rom_id, address, 2, data); + + // get the address for the setup for the channel + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address + if (error != DALLAS_NO_ERROR) + return error; + + // read the RAM from the device to get the resolution + error = dallasReadRAM(rom_id, address, 1, &resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // get the resultion part of the data + resolution &=0x0F; + + // store the result by combining the 2 bytes + // the result's MSB is always the same, so we may need to + // shift the data over so that the LSB is at the first bit + *result = 0; + //*result = (((u16)data[1] << 8) | data[0]) >> (16 - resolution); + *result = (((u16)data[1] << 8) | data[0]); + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAndResult(dallas_rom_id_T* rom_id, u08 channel, u16 *result) +{ + u08 error; + + // start conversion + error = ds2450Start(rom_id, channel); + if (error != DALLAS_NO_ERROR) + return error; + + // wait till conversion done + dallasWaitUntilDone(); + + // return results + return ds2450Result(rom_id, channel, result); +} + +u08 ds2450SetupAll(dallas_rom_id_T* rom_id, u08 resolution, u08 range) +{ + u08 i; + u08 error; + u08 data[8]; + u16 address; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // check resolution + if (resolution > DS2450_RES_MAX) + return DALLAS_RESOLUTION_ERROR; + + // convert to valid resolution - 16 bits = 0x00 + if (resolution == 16) + resolution = 0; + + // get address - start with channel A + error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read in current settings so we can extract digital part + error = dallasReadRAM(rom_id, address, 8, data); + if (error != DALLAS_NO_ERROR) + return error; + + // build up config data to write - increment by 2 b/c two bytes per channel + for(i=0;i<8;i+= 2) + { + // maintain digital output settings + data[i] &= 0xF0; // extract digital output portion + data[i+1] &= 0xFE; + + // write resolution byte and range + data[i] |= resolution; + data[i+1] |= range; + } + + // actually write config - handles CRC too + error = dallasWriteRAM(rom_id, address, 8, data); + if (error != DALLAS_NO_ERROR) + return error; + + // Normally, the DS2450 is designed to run off of parasite power from the data line + // Typically the master (us) strongly pulls high long enough to power the conversion, so + // there is inherintly a long () delay introduced. Since the A2D code is designed to + // work for devices that use external power, we can elliminate this delay by writting + // the following byte per the DS2450 datasheet. + data[0] = DS2450_VCC_FLAG; + error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]); + if (error != DALLAS_NO_ERROR) + return error; + + error = dallasReadRAM(rom_id,address,8,data); + if (error != DALLAS_NO_ERROR) + return error; + + for(i=0;i<8;i+=2) + { + if ((data[i] & 0x0F) != resolution) + return DALLAS_VERIFY_ERROR; + if ((data[i+1] & 0x01) != range) + return DALLAS_VERIFY_ERROR; + } + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAll(dallas_rom_id_T* rom_id) +{ + u08 error; + u16 crc; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // reset and select node + error = dallasMatchROM(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + dallasWriteByte(DS2450_CONVERT); // send convert command + dallasWriteByte(DS2450_CONVERT_ALL4_MASK); // select all 4 inputs + dallasWriteByte(DS2450_CLEAR_ALL4_MASK); // set all output buffers to zero + + // we must read 2byte CRC16 to start the conversion: + crc = dallasReadByte() | ((u16)dallasReadByte() << 8); + + // replace with explicit CRC posibilities lookup table +// if (crc == 0xFFFF) +// return DALLAS_DEVICE_ERROR; // if CRC = all one's, no one is paying attention + + return DALLAS_NO_ERROR; +} + +u08 ds2450ResultAll(dallas_rom_id_T* rom_id, u16 result[4]) +{ + //const u08 bytes_to_read = 10; // read 10bytes = 2/ch*4ch + CRC + u08 bytes_to_read = 10; + u08 i; + u08 error; + u08 data[10]; + u08 resolution[10]; + u16 address; + + // check address + + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // start address with channel A + error = ds2450Chan2Addr('A', DS2450_DATA_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the conversion data + error = dallasReadRAM(rom_id, address, bytes_to_read, data); + if (error != DALLAS_NO_ERROR) + return error; + + //FUTURE: do a real CRC16 check + + // start address with channel A + error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read the resolution data + error = dallasReadRAM(rom_id, address, bytes_to_read, resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // check crc? + + // store the result by combining the 2 bytes + // the result's MSB is always the same, so we may need to + // shift the data over so that the LSB is at the first bit + error=0; + for(i=0;i<8;i+=2) + { + resolution[i] &= 0x0F; + if (!resolution[i]) + resolution[i] = 16; + + result[error] = 0; + //result[error] = (((u16)data[i+1] << 8) | data[i]) >> (16 - resolution[i]); + result[error] = (((u16)data[i+1] << 8) | data[i]); + error++; + } + + return DALLAS_NO_ERROR; +} + +u08 ds2450StartAndResultAll(dallas_rom_id_T* rom_id, u16 result[4]) +{ + u08 error; + + // start Conversion + error = ds2450StartAll(rom_id); + if (error != DALLAS_NO_ERROR) + return error; + + // wait until conversion done + dallasWaitUntilDone(); + + // return any error - results passed by reference + return ds2450ResultAll(rom_id, result); +} + +void ds2450Print(u16 result, u08 range) +{ + u16 vscale; + + rprintfProgStrM(" 0x"); + rprintfu16(result); + rprintf(" "); + if(range) + vscale = 12800; + else + vscale = 25600; + + rprintfNum(10, 4, TRUE , ' ', result/vscale); + rprintf("."); + rprintfNum(10, 4, FALSE, '0', (((u32)(result%vscale))*10000)/vscale ); + rprintfProgStrM(" Volts"); +} + +u08 ds2450DigitalOut(dallas_rom_id_T* rom_id, u08 channel, dallas_a2d_out_T state) +{ + u08 error; + u08 old_resolution; + u16 address; + + // check address + error = dallasAddressCheck(rom_id, DS2450_FAMILY); + if (error != DALLAS_NO_ERROR) + return error; + + // get the address for the channel in the setup page + error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); + if (error != DALLAS_NO_ERROR) + return error; + + // read in current resolution + error = dallasReadRAM(rom_id, address, 1, &old_resolution); + if (error != DALLAS_NO_ERROR) + return error; + + // extract resolution portion + old_resolution &= 0x0F; + + // write new setup byte + state |= old_resolution; + error = dallasWriteRAM(rom_id, address, 1, ((u08*)&state)); + if (error != DALLAS_NO_ERROR) + return error; + + return DALLAS_NO_ERROR; +} + +static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address) +{ + // make sure the channel is a capital letter + strupr(&channel); + + //convert to integer 0 to 3 and check to see if it is valid + channel -= 'A'; + if (channel > 3) + return DALLAS_INVALID_CHANNEL; + + // use corresponding memory address + *address = (channel<<1) + page; // channel<<1 == channel*2, but faster + + return DALLAS_NO_ERROR; +} diff --git a/3rd party/Procyuon avrlib/rsl/ds2450_old.h b/3rd party/Procyuon avrlib/rsl/ds2450_old.h new file mode 100644 index 0000000..dafa6f8 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2450_old.h @@ -0,0 +1,138 @@ +//***************************************************************************** +// File Name : ds2450.c +// Title : Dallas 1-Wire DS2450 A2D Sensor Library +// Revision : 5 +// Notes : +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Revision History: +// When Who Rev Description of change +// ----------- ----------- ------- ----------------------- +// 01-Oct-2003 rwatson 5 Fixed result error with MSB +// 30-Sep-2003 rwatson 4 CreatedDigitalOut +// 30-Sep-2003 rwatson 3 Created SetupAlll, StartAll, ResultAll, StartAndResultAll +// 29-Sep-2003 rwatson 2 Created Setup, Start, Result, StartAndResult +// 29-Sep-2003 rwatson 1 Created the program structure +//***************************************************************************** + +#ifndef ds2450_h +#define ds2450_h + +//----- Include Files --------------------------------------------------------- +#include "global.h" + +//----- Defines --------------------------------------------------------------- +#define ds2450_rev 5 + +// the two voltage ranges +#define DS2450_RANGE_2V 0x00 // 0-2.55V +#define DS2450_RANGE_5V 0x01 // 0-5.10V + +// the family code +#define DS2450_FAMILY 0x20 + +// the starting addresses +// of the pages in RAM +#define DS2450_DATA_PAGE 0x00 +#define DS2450_SETUP_PAGE 0x08 +#define DS2450_ALARM_PAGE 0x10 + +#define DS2450_VCC_FLAG 0x40 +#define DS2450_VCC_ADDR 0x1C + +// maximum allowable resolution +#define DS2450_RES_MAX 16 + +// function commands +#define DS2450_READ_MEMORY 0xAA +#define DS2450_WRITE_MEMORY 0x55 +#define DS2450_CONVERT 0x3C +#define DS2450_CONVERT_ALL4_MASK 0x0F +#define DS2450_CLEAR_ALL4_MASK 0x55 + +//----- Typedefs -------------------------------------------------------------- + +// enumerated constant for configuring +// and controlling an A2D channel as a digital output +typedef enum {DIGOUT_LOW=0x80, DIGOUT_OC=0xC0, DIGOUT_DISABLE=0x00} dallas_a2d_out_T; + +//----- Functions --------------------------------------------------------------- + +// ds2450Init() +// initializes the dallas 1-wire bus +void ds2450Init(void); + +//----- Single Channel Functions ---------------------------------------------- +// The following 4 functions are used for controlling a single channel on the +// a2d converter. If you are only using 1 channel, then these functions are +// faster. If you are using 2 or more channel, it is faster to use the All +// Channel Functions. This is because to convert all the channel only requires +// one command to the device, and then a read of the all the channel. To read +// two channel individually requires two commands to the device, and two reads. +// Therefore using the All Channel Functions for even just 2 channels is faster +// and more effificient. + +// ds2450Setup() +// Sets up the given device, for the given channel [A-D], +// the given resolution [1-16] and the given range 0-2.55 or 0-5.10 +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Setup(dallas_rom_id_T* rom_id, u08 channel, u08 resolution, u08 range); + +// ds2450Start() +// Starts the a2d conversion for the given device and the given channel [A-D] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Start(dallas_rom_id_T* rom_id, u08 channel); + +// ds2450Result() +// Gets the result from the a2d conversion +// for the given device and the given channel [A-D] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450Result(dallas_rom_id_T* rom_id, u08 channel, u16* result); + +// ds2450StartAndResult() +// Starts the conversion of the given device and the given channel [A-D] +// Stores the result in the variable result +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAndResult(dallas_rom_id_T* rom_id, u08 channel, u16 *result); + +//----- All Channel Functions ------------------------------------------------- +// The following 4 commands are used to access data from all 4 channels on the +// a2d converter. These commands should be used if you are using more than one +// channel on the device. See the Single Channel Functions description for +// more information + +// ds2450SetupAll() +// Sets up the given device for all channels for the given resultion +// and the given range [0-2.55 or 0-5.10] +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450SetupAll(dallas_rom_id_T* rom_id, u08 resolution, u08 range); + +// ds2450StartAll() +// Starts the conversion for all 4 channels on the given a2d converter +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAll(dallas_rom_id_T* rom_id); + +// ds2450ResultAll +// Gets the results from the given device +// and stores the result in the given array +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450ResultAll(dallas_rom_id_T* rom_id, u16 result[4]); + +// ds2450StartAndResultAll() +// 1-Step command to start the conversion for the given device, +// and store the results in the given array +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450StartAndResultAll(dallas_rom_id_T* rom_id, u16 result[4]); + +// ds2450Print() +// Does a formatted print on the given result for the given range +void ds2450Print(u16 result, u08 range); + +//----- Digital Out Functions ------------------------------------------------- +// ds2450DigitalOut +// Use the given channel of the given device as a digital out +// Returns either the corresponding error or DALLAS_NO_ERROR +u08 ds2450DigitalOut(dallas_rom_id_T* rom_id, u08 channel, dallas_a2d_out_T state); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/ds2482.c b/3rd party/Procyuon avrlib/rsl/ds2482.c new file mode 100644 index 0000000..52c9c0b --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2482.c @@ -0,0 +1,189 @@ +/*! \file ds2482.c \brief Dallas DS2482 I2C-to-Dallas1Wire Master Library. */ +//***************************************************************************** +// +// File Name : 'ds2482.c' +// Title : Dallas DS2482 I2C-to-Dallas1Wire Master Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.27 +// Revised : 2004.09.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "i2c.h" +#include "ds2482.h" + +#include "rprintf.h" +#include "timer.h" + +// global variables +u08 DS2482I2cAddr; + +// Functions +u08 ds2482Init(u08 i2cAddr) +{ + // select device + DS2482I2cAddr = i2cAddr; + // reset DS2482 chip + return ds2482Reset(DS2482I2cAddr); + +} + +u08 ds2482Reset(u08 i2cAddr) +{ + // select device + DS2482I2cAddr = i2cAddr; + return ds2482SendCmd(DS2482_CMD_DRST); +} + +u08 ds2482SendCmd(u08 cmd) +{ + u08 data; + u08 i2cStat; + + // send command + i2cStat = i2cMasterSendNI(DS2482I2cAddr, 1, &cmd); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + // check status + i2cStat = i2cMasterReceiveNI(DS2482I2cAddr, 1, &data); + +// rprintf("Cmd=0x%x Status=0x%x\r\n", cmd, data); + + return (i2cStat == I2C_OK); +} + +u08 ds2482SendCmdArg(u08 cmd, u08 arg) +{ + u08 data[2]; + u08 i2cStat; + + // prepare command + data[0] = cmd; + data[1] = arg; + // send command + i2cStat = i2cMasterSendNI(DS2482I2cAddr, 2, data); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + // check status + i2cStat = i2cMasterReceiveNI(DS2482I2cAddr, 1, data); + +// rprintf("Cmd=0x%x Arg=0x%x Status=0x%x\r\n", cmd, arg, data[0]); + + return (i2cStat == I2C_OK); +} + +u08 ds2482BusyWait(void) +{ + u08 status; + // set read pointer to status register + ds2482SendCmdArg(DS2482_CMD_SRP, DS2482_READPTR_SR); + // check status until busy bit is cleared + do + { + i2cMasterReceiveNI(DS2482I2cAddr, 1, &status); + } while(status & DS2482_STATUS_1WB); + // return the status register value + return status; +} + +u08 ds2482BusReset(void) +{ + u08 status; + // send 1-Wire bus reset command + ds2482SendCmd(DS2482_CMD_1WRS); + // wait for bus reset to finish, and get status + status = ds2482BusyWait(); + // return state of the presence bit + return (status & DS2482_STATUS_PPD); +} + +u08 ds2482BusTransferBit(u08 bit) +{ + u08 status; + // writes and reads a bit on the bus + // wait for DS2482 to be ready + ds2482BusyWait(); + // send 1WSB command + ds2482SendCmdArg(DS2482_CMD_1WSB, bit?0x00:0x80); + // wait for command to finish + status = ds2482BusyWait(); + // return read-slot bit value + if(status & DS2482_STATUS_SBR) + return 1; + else + return 0; +} + +u08 ds2482BusTriplet(u08 dir) +{ + u08 status; + // this command is used to simplify search-rom operations + // generates two read timeslots and one write timeslot + // dir input determines value of write if reads are both 0 + + // wait for DS2482 to be ready + ds2482BusyWait(); + // send 1WSB command + ds2482SendCmdArg(DS2482_CMD_1WT, dir?0x00:0x80); + // wait for command to finish + status = ds2482BusyWait(); + // return the value of the read slots + return (status & (DS2482_STATUS_SBR|DS2482_STATUS_TSB))>>5; +} + +u08 ds2482BusLevel(void) +{ + u08 status; + // get status + status = ds2482BusyWait(); + // return bus level value + if(status & DS2482_STATUS_LL) + return 1; + else + return 0; +} + +void ds2482BusWriteByte(u08 data) +{ + // wait for DS2482 to be ready + ds2482BusyWait(); + // send 1WWB command + ds2482SendCmdArg(DS2482_CMD_1WWB, data); +} + +u08 ds2482BusReadByte(void) +{ + u08 data; + // wait for DS2482 to be ready + ds2482BusyWait(); + // send 1WRB command + ds2482SendCmd(DS2482_CMD_1WRB); + // wait for read to finish + ds2482BusyWait(); + // set read pointer to data register + ds2482SendCmdArg(DS2482_CMD_SRP, DS2482_READPTR_RDR); + // read data + i2cMasterReceiveNI(DS2482I2cAddr, 1, &data); + // return data + return data; +} diff --git a/3rd party/Procyuon avrlib/rsl/ds2482.h b/3rd party/Procyuon avrlib/rsl/ds2482.h new file mode 100644 index 0000000..917955a --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/ds2482.h @@ -0,0 +1,91 @@ +/*! \file ds2482.h \brief Dallas DS2482 I2C-to-Dallas1Wire Master Library. */ +//***************************************************************************** +// +// File Name : 'ds2482.h' +// Title : Dallas DS2482 I2C-to-Dallas1Wire Master Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.27 +// Revised : 2004.09.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DS2482_H +#define DS2482_H + +#include "global.h" + +// constants/macros/typdefs +#define DS2482_I2C_ADDR 0x30 //< Base I2C address of DS2482 devices + +// DS2482 command defines +#define DS2482_CMD_DRST 0xF0 //< DS2482 Device Reset +#define DS2482_CMD_WCFG 0xD2 //< DS2482 Write Configuration +#define DS2482_CMD_CHSL 0xC3 //< DS2482 Channel Select +#define DS2482_CMD_SRP 0xE1 //< DS2482 Set Read Pointer +#define DS2482_CMD_1WRS 0xB4 //< DS2482 1-Wire Reset +#define DS2482_CMD_1WWB 0xA5 //< DS2482 1-Wire Write Byte +#define DS2482_CMD_1WRB 0x96 //< DS2482 1-Wire Read Byte +#define DS2482_CMD_1WSB 0x87 //< DS2482 1-Wire Single Bit +#define DS2482_CMD_1WT 0x78 //< DS2482 1-Wire Triplet + +// DS2482 status register bit defines +#define DS2482_STATUS_1WB 0x01 //< DS2482 Status 1-Wire Busy +#define DS2482_STATUS_PPD 0x02 //< DS2482 Status Presence Pulse Detect +#define DS2482_STATUS_SD 0x04 //< DS2482 Status Short Detected +#define DS2482_STATUS_LL 0x08 //< DS2482 Status 1-Wire Logic Level +#define DS2482_STATUS_RST 0x10 //< DS2482 Status Device Reset +#define DS2482_STATUS_SBR 0x20 //< DS2482 Status Single Bit Result +#define DS2482_STATUS_TSB 0x40 //< DS2482 Status Triplet Second Bit +#define DS2482_STATUS_DIR 0x80 //< DS2482 Status Branch Direction Taken + +// DS2482 configuration register bit defines +#define DS2482_CFG_APU 0x01 //< DS2482 Config Active Pull-Up +#define DS2482_CFG_PPM 0x02 //< DS2482 Config Presence Pulse Masking +#define DS2482_CFG_SPU 0x04 //< DS2482 Config Strong Pull-Up +#define DS2482_CFG_1WS 0x08 //< DS2482 Config 1-Wire Speed + +// DS2482 channel selection code defines +#define DS2482_CH_IO0 0xF0 //< DS2482 Select Channel IO0 +#define DS2482_CH_IO1 0xE1 //< DS2482 Select Channel IO1 +#define DS2482_CH_IO2 0xD2 //< DS2482 Select Channel IO2 +#define DS2482_CH_IO3 0xC3 //< DS2482 Select Channel IO3 +#define DS2482_CH_IO4 0xB4 //< DS2482 Select Channel IO4 +#define DS2482_CH_IO5 0xA5 //< DS2482 Select Channel IO5 +#define DS2482_CH_IO6 0x96 //< DS2482 Select Channel IO6 +#define DS2482_CH_IO7 0x87 //< DS2482 Select Channel IO7 + +// DS2482 read pointer code defines +#define DS2482_READPTR_SR 0xF0 //< DS2482 Status Register +#define DS2482_READPTR_RDR 0xE1 //< DS2482 Read Data Register +#define DS2482_READPTR_CSR 0xD2 //< DS2482 Channel Selection Register +#define DS2482_READPTR_CR 0xC3 //< DS2482 Configuration Register + +// functions + +//! Initialize the DS2482 chip +// returns: +// 0 if successful +// non-zero if unsuccessful (chip not present) +u08 ds2482Init(u08 i2cAddr); +u08 ds2482Reset(u08 i2cAddr); +u08 ds2482SendCmd(u08 cmd); +u08 ds2482SendCmdArg(u08 cmd, u08 arg); +u08 ds2482BusyWait(void); +u08 ds2482BusReset(void); +u08 ds2482BusTransferBit(u08 bit); +u08 ds2482BusTriplet(u08 dir); +u08 ds2482BusLevel(void); +void ds2482BusWriteByte(u08 data); +u08 ds2482BusReadByte(void); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/edp.c b/3rd party/Procyuon avrlib/rsl/edp.c new file mode 100644 index 0000000..967c5ae --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edp.c @@ -0,0 +1,494 @@ +/*! \file edp.c \brief Emerald Data Protocol System. */ +//***************************************************************************** +// +// File Name : 'edp.c' +// Title : Emerald Data Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.01 +// Revised : 2003.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include program-space support + +#include "global.h" // include our global settings +#include "i2c.h" // include I2C support +#include "rprintf.h" // include printf function library + +#include "edp.h" + +// globals +// EDP master/command: response code and reply buffer +u08 EdpCommandResponseCode; +//u08 EdpCommandReplyLength; +u08 EdpCommandReplyBuffer[EDP_REPLY_BUFFER_SIZE]; +u08 EdpCommandReplyChecksum; +// EDP slave: response code and reply buffer +u08 EdpSlaveResponseCode; +u08 EdpSlaveReplyLength; +u08 EdpSlaveReplyBuffer[EDP_REPLY_BUFFER_SIZE]; +// EDP slave request handler function pointer +EdpSlaveHandlerFuncType edpSlaveHandlerFunc; + +// functions +void edpInit(void) +{ + // initialize i2c interface and function library + i2cInit(); + // set i2c bit rate to 30KHz + i2cSetBitrate(30); + // set the Slave Receive Handler function + // (this function will run whenever a master somewhere else on the bus + // writes data to us as a slave) + i2cSetSlaveReceiveHandler( edpSlaveReceiveService ); + // set the Slave Transmit Handler function + // (this function will run whenever a master somewhere else on the bus + // attempts to read data from us as a slave) + i2cSetSlaveTransmitHandler( edpSlaveTransmitService ); +} + +void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction) +{ + edpSlaveHandlerFunc = edpSlaveHandlerFunction; +} + +// ************ EDP Master operations ************ +u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand) +{ + EdpReply* edpCommandReply = (EdpReply*)EdpCommandReplyBuffer; + u08* sendData; + u08* replyData; + u08 replyLength; + u08 checksum; + + // initialize response variables + edpCommandReply->Length = 0; + EdpCommandReplyChecksum = 0; + + #ifdef EDP_DEBUG + rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // disable TWI interrupt + cbi(TWCR, TWIE); + + // clear TWI interface + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with write + i2cSendByte( (deviceAddr&0xFE) ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // check if device is present and live + if( i2cGetStatus() != TW_MT_SLA_ACK) + { + // device did not ACK it's address, command will not continue + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + // enable TWI interrupt + sbi(TWCR, TWIE); + // return error + return EDP_COMMAND_NODEV; + } + + // send data + sendData = (u08*)edpCommand; + checksum = 0; + while(cmdLength) + { + i2cSendByte( *sendData ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + checksum += *sendData++; + cmdLength--; + } + + // send the checksum + i2cSendByte( ~checksum ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // read response code, return NACK + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + EdpCommandResponseCode = i2cGetReceivedByte(); + + if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY) + { + // a data reply is being sent + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + + // get length, return ACK + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + edpCommandReply->Length = i2cGetReceivedByte(); + // set temp variables + replyLength = edpCommandReply->Length; + replyData = edpCommandReply->Data; + + // get data, return ACKs + // preset checksum with the datalength byte + checksum = replyLength; + while(replyLength > 1) + { + i2cReceiveByte(TRUE); // receive data byte and return ACK + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + checksum += *replyData++; + replyLength--; + } + + // get last data (actually the checksum), return NACK (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + // add received checksum+1 to our checksum, the result should be zero + checksum += (*replyData) + 1; + // save the reply checksum + EdpCommandReplyChecksum = checksum; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return EDP_COMMAND_OK; +} + +// get the response code and reply from last command +u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply) +{ + u08 retval=EDP_REPLY_OK; + + // get the response code from last command + *responseCode = EdpCommandResponseCode; + // get the reply from last command + *edpReply = (EdpReply*)EdpCommandReplyBuffer; + + // check response code + if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY) + { + // there was a reply, check the checksum + // if it's non-zero, data corruption is present + if(EdpCommandReplyChecksum) + retval = EDP_REPLY_BADCHKSUM; + } + return retval; +} + +/* +u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData) +{ + u08* replyData = EdpCommandReplyBuffer; + u08 replyLength; + u08 checksum; + + // initialize response variables + EdpCommandReplyLength = 0; + EdpCommandReplyChecksum = 0; + + #ifdef EDP_DEBUG + rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // disable TWI interrupt + cbi(TWCR, TWIE); + + // clear TWI interface + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with write + i2cSendByte( (deviceAddr&0xFE) ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // check if device is present and live + if( i2cGetStatus() != TW_MT_SLA_ACK) + { + // device did not ACK it's address, command will not continue + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + // enable TWI interrupt + sbi(TWCR, TWIE); + // return error + return EDP_COMMAND_NODEV; + } + + // send data + checksum = 0; + while(sendLength) + { + i2cSendByte( *sendData ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + checksum += *sendData++; + sendLength--; + } + + // send the checksum + i2cSendByte( ~checksum ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // read response code, return NACK + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + EdpCommandResponseCode = i2cGetReceivedByte(); + + if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY) + { + // a data reply is being sent + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + + // get length, return ACK + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + replyLength = i2cGetReceivedByte(); + EdpCommandReplyLength = replyLength; + + // get data, return ACKs + // preset checksum with the datalength byte + checksum = replyLength; + while(replyLength > 1) + { + i2cReceiveByte(TRUE); // receive data byte and return ACK + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + checksum += *replyData++; + replyLength--; + } + + // get last data (actually the checksum), return NACK (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + // add received checksum+1 to our checksum, the result should be zero + checksum += (*replyData) + 1; + // save the reply checksum + EdpCommandReplyChecksum = checksum; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return EDP_COMMAND_OK; +} + +u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData) +{ + u08 retval=EDP_REPLY_OK; + + // get the response code and reply data from last command + *responseCode = EdpCommandResponseCode; + // get the reply length from last command + *replyLength = EdpCommandReplyLength; + // get the reply data from last command + *replyData = EdpCommandReplyBuffer; + + // check response code + if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY) + { + // there was a reply, check the checksum + // if it's non-zero, data corruption is present + if(EdpCommandReplyChecksum) + retval = EDP_REPLY_BADCHKSUM; + } + return retval; +} +*/ + +// ************ EDP Slave operations ************ + +// this function will run when a master somewhere else on the bus +// addresses us and wishes to write data to us +void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData) +{ + u08 i,checksum; + + // initialize the reply length from this command + EdpSlaveReplyLength = 0; + // verify the checksum + // initialize the checksum with 1 + checksum = 0x01; + // sum all the data in the packet and the data's checksum + for(i=0; iLength+1; + // initialize checksum + checksum = edpReply->Length+1; + // copy reply buffer to the transmit buffer + for(i=0; iLength; i++) + { + *transmitData++ = edpReply->Data[i]; + checksum += edpReply->Data[i]; + } + // copy checksum to transmit buffer + *transmitData++ = ~checksum; + // set number of bytes to transmit + transmitDataLength = edpReply->Length+2; + } + + // return number of bytes written to transmit buffer + return transmitDataLength; +} diff --git a/3rd party/Procyuon avrlib/rsl/edp.h b/3rd party/Procyuon avrlib/rsl/edp.h new file mode 100644 index 0000000..cd209fe --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edp.h @@ -0,0 +1,68 @@ +/*! \file edp.h \brief Emerald Data Protocol System. */ +//***************************************************************************** +// +// File Name : 'edp.h' +// Title : Emerald Data Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.01 +// Revised : 2003.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDP_H +#define EDP_H + +#include "edpdefs.h" + +// defines +//#define EDP_DEBUG +// edp reply buffer size +#ifndef EDP_REPLY_BUFFER_SIZE +#define EDP_REPLY_BUFFER_SIZE 128 +#endif +// edpSendCommand return values +#define EDP_COMMAND_OK 0 +#define EDP_COMMAND_NODEV 1 +// edpGetCommandReply return values +#define EDP_REPLY_OK 0 +#define EDP_REPLY_BADCHKSUM 1 + +// structs and typedefs +typedef struct +{ + u08 SrcAddr; + u08 Command; + u08 Data[]; +} EdpCommand; + +typedef struct +{ + u08 Length; + u08 Data[]; +} EdpReply; + +// typedefs +typedef u08 (*EdpSlaveHandlerFuncType)(u08 edpCmdLength, EdpCommand* edpCmd, + u08 edpReplyLengthMax, EdpReply* edpReply); + +// functions +void edpInit(void); +void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction); + +// ************ EDP Master operations ************ +u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand); +u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply); +//u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData); +//u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData); + +// ************ EDP Slave operations ************ +void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData); +u08 edpSlaveTransmitService(u08 transmitDataLengthMax, u08* transmitData); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/edpaddr.h b/3rd party/Procyuon avrlib/rsl/edpaddr.h new file mode 100644 index 0000000..2951456 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edpaddr.h @@ -0,0 +1,75 @@ +/*! \file edpaddr.h \brief Emerald Satellite EDP/I2C Bus Addresses. */ +//***************************************************************************** +// +// File Name : 'edpaddr.h' +// Title : Emerald Satellite EDP/I2C Bus Addresses +// Author : Bryan Palmintier & Pascal Stang - Copyright (C) 2003 +// Created : 09/08/2003 by PS +// Revised : 11/10/2003 by BP +// Version : 0.9 +// Target MCU : Any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPADDR_H +#define EDPADDR_H + +// The 8 bits of an EDP address byte breakdown as follows: +// b0: R/W bit (1=read, 0=write) +// b1-4: subsystem address (16 availible) +// b5-7: satellite network mask (up to 7 unique networks with 1 reserved by I2C) +// The ground station is a special case which uses 1110xxxx +#define EDPNET_MASK 0xE0 // mask for satellite/ground networks +#define EDPADDR_MASK 0x1E // mask for subsystem addresses + +// Satellite network addresses +#define EDPNET_SAT_A 0x00 // EM-1 +#define EDPNET_SAT_B 0x20 // EM-2 +#define EDPNET_SAT_C 0x40 // EM-3 +#define EDPNET_SAT_D 0x60 // EM-4 +#define EDPNET_SAT_E 0x80 // OK-1 +#define EDPNET_SAT_F 0xA0 // OK-2 +#define EDPNET_SAT_G 0xC0 + +// Ground Station network address +// NOTE: all devices on this network must maintain b4=0 +// or risk problems with 10bit I2C addressing +#define EDPNET_GROUND 0xE0 + +// Test subsystem address +// Note: it is OK to use these susbsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_TEST 0x02 // generic test address (LEDs etc) +#define EDPADDR_GROUND 0x04 // address for ground testing + +// Subsystem addresses +// "Core" subsystems, those found on all satellites, DO NOT EDIT +// Note: it is OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_COMM 0x06 +#define EDPADDR_DALMAST 0x08 +#define EDPADDR_SCHED 0x0A +#define EDPADDR_EXPSYS 0x0C +#define EDPADDR_ISCOMM 0x0E + +// "Common" subsystems, those found on many satellites, DO NOT EDIT +// Note: it is NOT OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_GPS 0x10 +#define EDPADDR_TORQUER 0x12 +#define EDPADDR_MECH 0x14 + +// Mission Specific subsystems, EDIT AS NEEDED +// Note: it is NOT OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_ODDSS 0x16 +#define EDPADDR_ULTRAWB 0x18 +#define EDPADDR_TETHER 0x1A + + +// As part of the I2C protocol 000000000 is reserved for general calls and +// all 1111xxxx are reserved for 10 bit addressing +#define EDPADDR_RESERVED_GENCALL 0x00 // reserved by I2C for general call address +#define EDPADDR_RESERVED_10BIT 0xF0 // reserved by I2C for 10bit addressing + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/edpdebug.c b/3rd party/Procyuon avrlib/rsl/edpdebug.c new file mode 100644 index 0000000..c021915 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edpdebug.c @@ -0,0 +1,190 @@ +/*! \file edpdebug.c \brief Emerald Data Protocol Debug Functions. */ +//***************************************************************************** +// +// File Name : 'edpdebug.c' +// Title : Emerald Data Protocol Debug Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.20 +// Revised : 2003.09.20 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include program-space support + +#include "global.h" // include our global settings +#include "rprintf.h" // include printf function library +#include "debug.h" // include debug helper library +#include "input.h" // include user-input functions + +#include "edp.h" +#include "edpdebug.h" + +// globals + +// functions + +void edpDisplayCommand(u08 length, EdpCommand* edpCommand) +{ + // print source and command char + rprintf("EDP SrcAddr: 0x%x Cmd: 0x%x '%c'\r\n", + edpCommand->SrcAddr, + edpCommand->Command, edpCommand->Command); + if(length-2) + { + // print data + rprintf("Data:\r\n"); + debugPrintHexTable(length-2, edpCommand->Data); + } +} + +void edpDisplayReply(u08 response, EdpReply* edpReply) +{ + u08 i; + u08 checksum; + + // display response + rprintf("EDP Response: 0x%x '%c'\r\n",response,response); + + // if data was received + if(response==EDP_RESP_DATA_REPLY) + { + // do checksum on reply + checksum = edpReply->Length; + for(i=0; i<(edpReply->Length-1); i++) + { + checksum += edpReply->Data[i]; + } + checksum = ~checksum; + // print message + rprintf("EDP Reply: "); + // show data received + rprintf("Length: 0x%x ",edpReply->Length); + rprintf("RxChksum=0x%x MyChksum=0x%x",edpReply->Data[edpReply->Length-1], checksum); + rprintfCRLF(); + rprintf("Data:\r\n"); + debugPrintHexTable((edpReply->Length-1), edpReply->Data); + rprintfCRLF(); + } +} +/* +void edpDisplayReplyOld(u08 response, u08 replyLength, u08* replyData) +{ + u08 i; + u08 checksum; + + // display response + rprintf("EDP Response: 0x%x '%c'\r\n",response,response); + + // if data was received + if(response==EDP_RESP_DATA_REPLY) + { + // do checksum on reply + checksum = replyLength; + for(i=0; i<(replyLength-1); i++) + { + checksum += replyData[i]; + } + checksum = ~checksum; + // print message + rprintf("EDP Reply: "); + // show data received + rprintf("Length: 0x%x ",replyLength); + rprintf("RxChksum=0x%x MyChksum=0x%x",replyData[replyLength-1], checksum); + rprintfCRLF(); + rprintf("Data:\r\n"); + debugPrintHexTable((replyLength-1), replyData); + rprintfCRLF(); + } +} +*/ + +u08 edpComposeCommand(u08 srcEdpAddr, u08* cmdBuffer) +{ + u08 string[80]; + u08 len; + u08 i; + + // instructions + rprintfProgStrM("Enter EDP Command, format [c][p1][p2][p3]...[pN]\r\n"); + rprintfProgStrM("[c] is command char, [px] parameters in 2-digit hex\r\n"); + + // get user input + rprintfProgStrM("EDP Command>"); + len = inputString(0x0D, 80, string); + rprintfCRLF(); + + // check for null user input + if(!len) + { + rprintfProgStrM("ERROR: No command\r\n"); + // return immediately with zero command length + return 0; + } + + // prepare command + cmdBuffer[0] = srcEdpAddr; + cmdBuffer[1] = string[0]; + for(i=0; i",edpCommand->Command,edpCommand->Command); + retval = edpSendCommand(destEdpAddr, cmdLength, edpCommand); + // handle result values + if(retval == EDP_COMMAND_OK) + { + // command sent successfully + rprintfProgStrM("Send Success!\r\n"); + } + else if(retval == EDP_COMMAND_NODEV) + { + // device did not exist + rprintfProgStrM("Send Failed->NO DEVICE!\r\n"); + rprintf("No EDP device could be contacted at address 0x%x.\r\n", destEdpAddr); + rprintfProgStrM("The device may be busy or not responding.\r\n"); + rprintfProgStrM("Check target device and I2C bus cabling.\r\n"); + // return immediately + return; + } + else + { + // other error + rprintfProgStrM("Send Failed->Unspecified Error!\r\n"); + // return immediately + return; + } + + // get the reply, if any, from the command + retval = edpGetCommandReply(&response, &edpReply); + // handle result values + if(retval == EDP_REPLY_BADCHKSUM) + { + rprintf("**** Reply has bad checksum ****\r\n"); + } + // display the reply + edpDisplayReply(response, edpReply); +} diff --git a/3rd party/Procyuon avrlib/rsl/edpdebug.h b/3rd party/Procyuon avrlib/rsl/edpdebug.h new file mode 100644 index 0000000..a9a43a7 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edpdebug.h @@ -0,0 +1,32 @@ +/*! \file edpdebug.h \brief Emerald Data Protocol Debug Functions. */ +//***************************************************************************** +// +// File Name : 'edpdebug.h' +// Title : Emerald Data Protocol Debug Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.20 +// Revised : 2003.09.20 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPDEBUG_H +#define EDPDEBUG_H + +#include "edp.h" + +// functions +u08 edpComposeCommand(u08 srcEdpAddr, u08* cmdBuffer); +void edpRunCommand(u08 destEdpAddr, u08 cmdLength, u08* cmdBuffer); + +// display functions +void edpDisplayCommand(u08 length, EdpCommand* edpCommand); +void edpDisplayReply(u08 response, EdpReply* edpReply); +//void edpDisplayReplyOld(u08 response, u08 replyLength, u08* replyData); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/edpdefs.h b/3rd party/Procyuon avrlib/rsl/edpdefs.h new file mode 100644 index 0000000..69e9364 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/edpdefs.h @@ -0,0 +1,82 @@ +/*! \file edpdefs.h \brief Emerald Data Protocol Defines and Constants. */ +//***************************************************************************** +// +// File Name : 'edpdefs.h' +// Title : Emerald Data Protocol Defines and Constants +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/08/2003 +// Revised : 09/08/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPDEFS_H +#define EDPDEFS_H + +// **** Constant Definitions ***** +// ---- Message Size, etc ---- +// Standard defines for various message format parameters +#define I2C_MAX_COMMAND_LENGTH 127 // [param1]...[param127] (does not include Command, From + // or Chk) Note that this an absolute maximum, + // subsystems/nodes are free to set lower maximum lengths + // For versions pre rev5, this was fixed at 5. +#define I2C_MAX_DATA_PACKET_LENGTH 127 // Raw Data: [data1]...[data126][Chk] (includes Chk for + + +// ---- Communication OK (value all uppercase ('A'-'Z') +#define EDP_RESP_ACK 'A' // indicates the command (to_send) was sent but has no return value. +#define EDP_RESP_DATA_REPLY 'R' // command valid and has return, examine reply and length for details + +// ---- Communication Error (values all lowercase ('a'-'z')) +#define EDP_RESP_UNKWN_CMD 'u' // given command is unrecognized by the subsystem at that address +#define EDP_RESP_CMD_CHK_ERROR 'c' // checksum error sending command +#define EDP_RESP_DATA_CHK_ERROR 'd' // checksum error receiving data +#define EDP_RESP_SEQUENCE_ERROR 's' // read/write out of order +#define EDP_RESP_READ_BEFORE_WRITE 'b' // requested read before writting associated Command +#define EDP_RESP_TOO_LONG 'l' // The command sent exceeds the maximum command length for node +#define EDP_RESP_TOO_FEW_PARAMS 'p' // The command sent has too few parameters +#define EDP_RESP_INCORRECT_PARAM 'i' // Parameters are incorrect (but there are the right number) +#define EDP_RESP_BUSY 'b' // The subsystem is still alive, but too busy to reply (AVOID USING) +#define EDP_RESP_NOT_ALLOWED 'n' // The command is recognized, but not allowed in the current + // operating mode. Try another command, or try again later +#define EDP_RESP_OTHER_ERROR 'e' // unspecified EDP/I2C error + +// ---- Check Sum ---- +/* The Checksum that is used is a rolling 8-bit sum from the [From] to the last parameter byte of a command + packet and from the [Length] to the last data byte of a Data packet. This sum is then 1-complemented + (~, not) and passed as [Chk]. This prevents a series of 0x00 replys from passing the correct check sum. + Because of the inversion, a packet with all zeros should have a checksum of 0xFF. + + The other nice feature of this checksum, is that no matter what the data is, if you add the checksum + ([Chk]) to the final sum, you should get 0xFF. + + To make it even cleaner, you can start the rolling checksum at 0x01 such that when you add in all of the + data bytes and the [Chk] byte, you get 0x00. This effectively makes the whole operation a twos complement +*/ +#define EDP_CHECKSUM_INIT 0x01 + +// -------- Reserved I2C commands --------- +// Define a short list of reserved commands. Subsystems can choose whether or +// not to implement these commands, but if they are implemented, they must +// function as described below. + +//Reserved Commands +#define EDP_CMD_SET_TIME ':' //0x3A Set the subsystem time, realtime.h format +#define EDP_CMD_RESERVED_1 ';' //0x3B Reserved for future command +#define EDP_CMD_ROM_WRITE '<' //0x3C Write to program ROM (uploadable code) +#define EDP_CMD_RESERVED_2 '=' //0x3D Reserved for future command +#define EDP_CMD_MEM_READ '>' //0x3E Read from program ROM (check program) +#define EDP_CMD_HELP '?' //0x3F Return human readable help string(s) +#define EDP_CMD_STATUS '@' //0x40 Get subsystem status + + +#define I2C_DATA_CONTINUE_MASK 0x80 // If MSB of length is set, then the data continues beyond + // this data packet + + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/erp.c b/3rd party/Procyuon avrlib/rsl/erp.c new file mode 100644 index 0000000..0bbb8ab --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/erp.c @@ -0,0 +1,129 @@ +/*! \file erp.c \brief Emerald Radio Protocol System. */ +//***************************************************************************** +// +// File Name : 'erp.c' +// Title : Emerald Radio Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.10 +// Revised : 2003.09.10 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include "global.h" // include our global settings +#include "debug.h" // include debug function library +#include "rprintf.h" // include printf function library + +#include "erp.h" +#include "edpdebug.h" + +// globals + +// functions +void erpDisplayHeader(ErpPacket* erpPacket) +{ + // show ERP packet header + rprintf("ERP Header: Callsign="); + rprintfStrLen(erpPacket->CallSign,0,CALLSIGN_FIELD_LEN); + rprintf(", Trg=0x%x, Src=0x%x, Seq#=%d, Type=", + erpPacket->ToAddress, + erpPacket->FromAddress, + erpPacket->SequenceNum); + // try to decode packet type + switch(erpPacket->Type) + { + case ERP_ECHO: rprintf("ECHO"); break; + case ERP_ECHOREPLY: rprintf("ECHOREPLY"); break; + case ERP_TEST: rprintf("TEST"); break; + case ERP_EDPCOMMAND: rprintf("EDPCOMMAND"); break; + case ERP_EDPREPLY: rprintf("EDPREPLY"); break; + case ERP_EDPREPLYNODEV: rprintf("EDPREPLYNODEV"); break; + default: rprintf("0x%x", erpPacket->Type); break; + } + rprintfCRLF(); +} + +void erpDisplayPacket(ErpPacket* erpPacket, u08 pktLength) +{ + u08 i; + u08 flag; + + // show ERP packet header + erpDisplayHeader(erpPacket); + + // dump complete raw packet data + if(pktLength) + { + // check if all characters are printable + flag = TRUE; + for(i=0; iEdpDestAddr); + // print embedded EDP command + edpDisplayCommand(length-1, &erpEdpCommand->EdpCommand); +} + +void erpDisplayEdpReply(u08 length, ErpEdpReply* erpEdpReply) +{ + // print embedded EDP reply + edpDisplayReply(erpEdpReply->EdpResponse, &erpEdpReply->EdpReply); +} + + +/* +void ErpPacketCreate(u08 targetI2cAddr, u08 pktType, u08 datalength, u08* data) +{ + // make packet structure in TxPacket memory + struct ErpPacket* erpPacket + = (struct ErpPacket*)TxPacket; + + // prepare Emerald packet header + memcpy(erpPacket->CallSign, MYCALLSIGN, CALLSIGN_FIELD_LEN); + erpPacket->ToAddress = targetI2cAddr; + erpPacket->FromAddress = LocalI2cAddr; + erpPacket->SequenceNum = SequenceNum++; + erpPacket->Type = pktType; + // copy data + for(i=0; iData[i] = *data++; + } +} + +void ErpPacketTx(void) +{ + // STX/ETX header + u08 stxetxStatus = 0x5A; + u08 stxetxType = 0xA5; + rprintf("Sending Packet: Status: 0x%x Type: 0x%x\r\n", stxetxStatus, stxetxType); + radioSend(stxetxStatus, stxetxType, EMRADIOHEADER_LEN+(len/2), packet); +} +*/ diff --git a/3rd party/Procyuon avrlib/rsl/erp.h b/3rd party/Procyuon avrlib/rsl/erp.h new file mode 100644 index 0000000..5e80d6a --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/erp.h @@ -0,0 +1,66 @@ +/*! \file erp.h \brief Emerald Radio Protocol System. */ +//***************************************************************************** +// +// File Name : 'erp.h' +// Title : Emerald Radio Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.10 +// Revised : 2003.09.10 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ERP_H +#define ERP_H + +#include "edp.h" + +// defines and typedefs +// Packet Types (tentative) +#define ERP_ECHO 0x01 +#define ERP_ECHOREPLY 0x02 +#define ERP_TEST 0x03 +#define ERP_EDPCOMMAND 0x10 +#define ERP_EDPREPLY 0x11 +#define ERP_EDPREPLYNODEV 0x12 + +#define CALLSIGN_FIELD_LEN 6 + +// structures and typedefs +typedef struct +{ + u08 CallSign[6]; + u08 ToAddress; + u08 FromAddress; + u08 SequenceNum; + u08 Type; + u08 Data[]; +} ErpPacket; +#define ERP_HEADER_LEN 10 + +typedef struct +{ + u08 EdpDestAddr; + EdpCommand EdpCommand; +} ErpEdpCommand; + +typedef struct +{ + u08 EdpResponse; + EdpReply EdpReply; +} ErpEdpReply; + + +// functions +// ERP display +void erpDisplayHeader(ErpPacket* erpPacket); +void erpDisplayPacket(ErpPacket* erpPacket, u08 pktLength); +void erpDisplayEdpCommand(u08 length, ErpEdpCommand* erpEdpCommand); +void erpDisplayEdpReply(u08 length, ErpEdpReply* erpEdpReply); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/input.c b/3rd party/Procyuon avrlib/rsl/input.c new file mode 100644 index 0000000..fb7718b --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/input.c @@ -0,0 +1,96 @@ +/*! \file input.c \brief User-Input Functions. */ +//***************************************************************************** +// +// File Name : 'input.c' +// Title : User-Input Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.11 +// Revised : 2003.09.11 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include "global.h" // include our global settings +#ifdef __AVR_ATmega128__ +#include "uart2.h" +#else +#include "uart.h" +#endif +#include "rprintf.h" // include printf function library + +#include "input.h" + +// defines and typedefs +#ifndef INPUT_UART +#define INPUT_UART 1 +#endif + +// globals + +// functions +u08 inputString(u08 termChar, u08 termLen, u08* data) +{ + u08 s=0; + u08 length=0; + + while(length < termLen) + { + // get input + #ifdef __AVR_ATmega128__ + while(!uartReceiveByte(INPUT_UART,&s)); + #else + while(!uartReceiveByte(&s)); + #endif + + // handle special characters + if(s == 0x08) // backspace + { + if(length > 0) + { + // echo backspace-space-backspace + rprintfChar(0x08); + rprintfChar(' '); + rprintfChar(0x08); + length--; + } + } + else if(s == termChar) // termination character + { + // save null-termination + data[length] = 0; + break; + } + else + { + // echo character + rprintfChar(s); + // save character + data[length++] = s; + } + } + return length; +} + +u08 asciiHexToByte(u08* string) +{ + // convert 2-byte hex string to byte + return (asciiHexToNibble(string[0])<<4) + asciiHexToNibble(string[1]); +} + +u08 asciiHexToNibble(u08 character) +{ + // convert 1-byte hex ascii character to nibble + if((character >= 0x30) && (character <= 0x39)) + return character-0x30; + else if((character >= 'A') && (character <= 'F')) + return character-'A'+10; + else if((character >= 'a') && (character <= 'f')) + return character-'a'+10; + else return 0; +} diff --git a/3rd party/Procyuon avrlib/rsl/input.h b/3rd party/Procyuon avrlib/rsl/input.h new file mode 100644 index 0000000..a1a2c68 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/input.h @@ -0,0 +1,26 @@ +/*! \file input.h \brief User-Input Functions. */ +//***************************************************************************** +// +// File Name : 'input.h' +// Title : User-Input Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.11 +// Revised : 2003.09.11 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef INPUT_H +#define INPUT_H + +// functions +u08 inputString(u08 termChar, u08 termLen, u08* data); +u08 asciiHexToByte(u08* string); +u08 asciiHexToNibble(u08 character); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/mitelgps.c b/3rd party/Procyuon avrlib/rsl/mitelgps.c new file mode 100644 index 0000000..1e8f95c --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/mitelgps.c @@ -0,0 +1,288 @@ +/*! \file .c \brief Mitel GPS STX/ETX driver function library. */ +//***************************************************************************** +// +// File Name : 'mitelgps.c' +// Title : Mitel GPS STX/ETX driver function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2003.04.11 +// Revised : 2003.08.26 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "uart2.h" +#include "gps.h" + +#include "mitelgps.h" + +// Program ROM constants + +// Global variables +// external GPS information structure/repository (in gps.h/gps.c) +extern GpsInfoType GpsInfo; +// packet processing buffer +u08 MitelGpsPacket[MITELGPS_BUFFERSIZE]; +// debug flag +u08 debug; +#define MITELGPS_DEBUG_PKTPARSE 0x01 +#define MITELGPS_DEBUG_EXTRACT 0x02 +// function pointer to single byte output routine +static void (*TxByteFunc)(unsigned char c); + +void mitelgpsInit(void (*txbytefunc)(unsigned char c)) +{ + // set transmit function + // (this function will be used for all SendPacket commands) + TxByteFunc = txbytefunc; + // set debug status + debug = 0; +} + +void mitelgpsSendPacket(u08* data, u08 dataLength) +{ + u08 i; + u08 dataIdx = 0; + u08 checksum = 0; + + // start of packet + MitelGpsPacket[dataIdx++] = STX; + // add packet type and packet data + for(i=0; idatalength > 1) + { + // look for a start of Mitel GPS STX/ETX packet + if(bufferGetAtIndex(rxBuffer,0) == STX) + { + // found start + startFlag = TRUE; + // done looking for start + break; + } + else + // not STX, dump character from buffer + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength); i++) + { + // check for end of Mitel GPS STX/ETX packet + if(bufferGetAtIndex(rxBuffer,i) == ETX) + { + // have a packet end + // dump initial STX + bufferGetFromFront(rxBuffer); + // copy data to MitelGpsPacket + for(j=0; j<(i-1); j++) + { + MitelGpsPacket[j] = bufferGetFromFront(rxBuffer); + checksum ^= MitelGpsPacket[j]; + } + // null-terminate copied string + MitelGpsPacket[j] = 0; + // dump ending ETX + bufferGetFromFront(rxBuffer); + + // verify checksum + // undo checksum summing of the checksum itself + checksum ^= MitelGpsPacket[j-2]; + checksum ^= MitelGpsPacket[j-1]; + if( checksum == convertAsciiHexToInt(&MitelGpsPacket[j-2], 2) ) + { + // found a good packet + if(debug & MITELGPS_DEBUG_PKTPARSE) + { + rprintf("Rx Mitel GPS packet type: %c%c%c len: %d\r\n", + MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j); + rprintfStr(MitelGpsPacket); + rprintfCRLF(); + } + // done with this processing session + foundpacket = TRUE; + break; + } + else + { + if(debug & MITELGPS_DEBUG_PKTPARSE) + { + rprintf("Rx Mitel GPS packet type: %c%c%c len: %d Bad Checksum Rcvd: 0x%c%c Calc: 0x%x\r\n", + MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j, MitelGpsPacket[j-2], MitelGpsPacket[j-1], checksum); + } + } + } + } + } + + // handle and direct the received packet + if(foundpacket) + { + // switch on the packet type + packetType = convertAsciiHexToInt(&MitelGpsPacket[1], 2); + switch( packetType ) + { + case MITELTYPE_NAVDATAGND: mitelgpsProcessNAVDATAGND(MitelGpsPacket); break; + case MITELTYPE_CHNLSTATGND: mitelgpsProcessCHNLSTATGND(MitelGpsPacket); break; + case MITELTYPE_NAVDATA: mitelgpsProcessNAVDATA(MitelGpsPacket); break; + case MITELTYPE_RAWDATA: mitelgpsProcessRAWDATA(MitelGpsPacket); break; + case MITELTYPE_CHNLSTAT: mitelgpsProcessCHNLSTAT(MitelGpsPacket); break; + case MITELTYPE_RELNAVECEF: break; + case MITELTYPE_RELNAVRTN: break; + default: + if(debug & MITELGPS_DEBUG_PKTPARSE) + rprintf("Unhandled Mitel GPS packet type: 0x%x\r\n", packetType); + break; + } + } + + return foundpacket; +} + +void mitelgpsProcessNAVDATAGND(u08* packet) +{ + // process "F00" report packets - Navigation Data (Ground) + char* endptr; + + if(debug & MITELGPS_DEBUG_EXTRACT) + { + rprintf("MITELGPS: "); + rprintfStr(packet); + rprintfCRLF(); + } + + // start parsing just after "F00" + // get latitude [sdd.dddddd] + GpsInfo.PosLLA.lat.f = strtod(&packet[3], &endptr); + // get longitude [sddd.dddddd] + GpsInfo.PosLLA.lon.f = strtod(&packet[3+10], &endptr); + // get altitude [sxxxxxx.x] + GpsInfo.PosLLA.alt.f = strtod(&packet[3+10+11], &endptr); + // get speed [sxxx.xx] + GpsInfo.VelHS.speed.f = strtod(&packet[3+10+11+9], &endptr); + // get heading [ddd] + GpsInfo.VelHS.heading.f = strtod(&packet[3+10+11+9+7], &endptr); + + // get # of SVs tracked [xx] + GpsInfo.numSVs = atoi(&packet[3+10+11+9+7+5+7+5+5+5]); +} + +void mitelgpsProcessCHNLSTATGND(u08* packet) +{ + // process "F03" report packets - Channel Status (Ground) +} + +void mitelgpsProcessNAVDATA(u08* packet) +{ + // process "F40" report packets - Navigation Data + char* endptr; + + // start parsing just after "F40" + // get gps week number [xxxx]=4 + GpsInfo.WeekNum = atoi(&packet[3]); + // get gps time of week [xxxxxx.xxxxx]=12 + GpsInfo.TimeOfWeek.f = strtod(&packet[3+4], &endptr); + // gps-utc time difference? [xx]=2 + // get ECEF X [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.x.f = strtod(&packet[3+4+12+2], &endptr); + // get ECEF Y [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.y.f = strtod(&packet[3+4+12+2+12], &endptr); + // get ECEF Z [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.z.f = strtod(&packet[3+4+12+2+12+12], &endptr); + // get ECEF vX [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.x.f = strtod(&packet[3+4+12+2+12+12+12], &endptr); + // get ECEF vY [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.y.f = strtod(&packet[3+4+12+2+12+12+12+12], &endptr); + // get ECEF vZ [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.z.f = strtod(&packet[3+4+12+2+12+12+12+12+12], &endptr); +} + +void mitelgpsProcessRAWDATA(u08* packet) +{ + // process "F42" report packets - Pseudorange, carrier phase, doppler +} + +void mitelgpsProcessCHNLSTAT(u08* packet) +{ + // process "F43" report packets - Channel Status +} + +// data conversions +u32 convertAsciiHexToInt(u08* string, u08 numdigits) +{ + u08 i; + u32 num = 0; + + for(i=0; i= 'a') + num |= string[i]-'a'+10; + else if(string[i] >= 'A') + num |= string[i]-'A'+10; + else + num |= string[i]-'0'; + } + return num; +} + +void convertIntToAsciiHex(u32 num, u08* string, u08 numdigits) +{ + u08 i; + + for(i=0; i>4; + } +} diff --git a/3rd party/Procyuon avrlib/rsl/mitelgps.h b/3rd party/Procyuon avrlib/rsl/mitelgps.h new file mode 100644 index 0000000..b46a77e --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/mitelgps.h @@ -0,0 +1,62 @@ +/*! \file mitelgps.c \brief Mitel GPS STX/ETX driver function library. */ +//***************************************************************************** +// +// File Name : 'mitelgps.h' +// Title : Mitel GPS STX/ETX driver function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2003.04.11 +// Revised : 2003.06.08 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MITELGPS_H +#define MITELGPS_H + +#include "global.h" + +// constants/macros/typdefs +// packet buffer size (must be able to contain biggest packet) +#define MITELGPS_BUFFERSIZE 0x0400 + +// packet delimiters +#define STX 0x02 +#define ETX 0x03 + +// report packet types +#define MITELTYPE_NAVDATAGND 0x00 +#define MITELTYPE_CHNLSTATGND 0x03 +#define MITELTYPE_NAVDATA 0x40 +#define MITELTYPE_RAWDATA 0x42 +#define MITELTYPE_CHNLSTAT 0x43 +#define MITELTYPE_RELNAVECEF 0x45 +#define MITELTYPE_RELNAVRTN 0x46 + +// functions +void mitelgpsInit(void (*txbytefunc)(unsigned char c)); +void mitelgpsSendPacket(u08* data, u08 dataLength); +u08 mitelgpsProcess(cBuffer* rxBuffer); + +// packet processing functions +void mitelgpsProcessNAVDATAGND(u08* packet); +void mitelgpsProcessCHNLSTATGND(u08* packet); +void mitelgpsProcessNAVDATA(u08* packet); +void mitelgpsProcessRAWDATA(u08* packet); +void mitelgpsProcessCHNLSTAT(u08* packet); + +// data conversions (these functions should move somewhere else) +u32 convertAsciiHexToInt(u08* string, u08 numdigits); +void convertIntToAsciiHex(u32 num, u08* string, u08 numdigits); + + + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/radiolinx.c b/3rd party/Procyuon avrlib/rsl/radiolinx.c new file mode 100644 index 0000000..99eadde --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/radiolinx.c @@ -0,0 +1,52 @@ +/*! \file radiolinx.c \brief Linx Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiolinx.c' +// Title : Linx Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "buffer.h" // include buffer support +#include "uartsw.h" // include software UART driver +#include "stxetx.h" // include STX/ETX protocol library + +#include "radiolinx.h" + +// global variables + +// functions +void radioInit(void) +{ + // Initialize radio interface + // Since this radio creates a special serial interface, + // we initialize it here. + uartswInit(); + // set baud rate of comm + uartswSetBaudRate(4800); + // initialize stxetx to use the software UART for sending data + stxetxInit(uartswSendByte); +} + +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr) +{ + stxetxSend(status, type, datalength, dataptr); +} + +cBuffer* radioGetRxBuffer(void) +{ + return uartswGetRxBuffer(); +} diff --git a/3rd party/Procyuon avrlib/rsl/radiolinx.h b/3rd party/Procyuon avrlib/rsl/radiolinx.h new file mode 100644 index 0000000..db28137 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/radiolinx.h @@ -0,0 +1,26 @@ +/*! \file radiolinx.h \brief Linx Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiolinx.h' +// Title : Linx Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RADIOLINX_H +#define RADIOLINX_H + +// functions +void radioInit(void); +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr); +cBuffer* radioGetRxBuffer(void); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/radiot96.c b/3rd party/Procyuon avrlib/rsl/radiot96.c new file mode 100644 index 0000000..7cb4fa6 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/radiot96.c @@ -0,0 +1,67 @@ +/*! \file radiot96.c \brief DataRadio T96-SR Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiot96.c' +// Title : DataRadio T96-SR Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "buffer.h" // include buffer support +#include "timer128.h" // include timer function library +#include "uart2.h" // include software UART driver +#include "stxetx.h" // include STX/ETX protocol library +#include "radiot96.h" + +// global variables + +// functions +void radioInit(void) +{ + // Initialize radio interface + // set baud rate of comm + uartSetBaudRate(COMM_UART, 19200); + // initialize stxetx to use the UART for sending data + #if COMM_UART == 0 + stxetxInit(uart0SendByte); + #else + stxetxInit(uart1SendByte); + #endif + // prepare PTT + cbi(RADIO_PTT_PORT, RADIO_PTT_PIN); + sbi(RADIO_PTT_DDR, RADIO_PTT_PIN); +} + +void radioPTT(u08 pttFlag) +{ + if(pttFlag) + sbi(RADIO_PTT_PORT, RADIO_PTT_PIN); + else + cbi(RADIO_PTT_PORT, RADIO_PTT_PIN); +} + +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr) +{ + radioPTT(TRUE); + timerPause(RADIO_PPT_DELAYMS); + stxetxSend(status, type, datalength, dataptr); + radioPTT(FALSE); +} + +cBuffer* radioGetRxBuffer(void) +{ + return uartGetRxBuffer(COMM_UART); +} diff --git a/3rd party/Procyuon avrlib/rsl/radiot96.h b/3rd party/Procyuon avrlib/rsl/radiot96.h new file mode 100644 index 0000000..642d6b2 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/radiot96.h @@ -0,0 +1,35 @@ +/*! \file radiot96.h \brief DataRadio T96-SR Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiot96.h' +// Title : DataRadio T96-SR Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RADIOT96_H +#define RADIOT96_H + +// Radio PTT +#define RADIO_PTT_DDR DDRD +#define RADIO_PTT_PORT PORTD +#define RADIO_PTT_PIN PD7 + +#define RADIO_PPT_DELAYMS 100 + +#define COMM_UART 1 + +// functions +void radioInit(void); +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr); +cBuffer* radioGetRxBuffer(void); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/satmb.c b/3rd party/Procyuon avrlib/rsl/satmb.c new file mode 100644 index 0000000..56168e1 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/satmb.c @@ -0,0 +1,151 @@ +/*! \file satmb.c \brief Satellite Motherboard Driver Functions. */ +//***************************************************************************** +// +// File Name : 'satmb.c' +// Title : Satellite Motherboard Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.13 +// Revised : 2004.10.13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "dallas.h" +#include "ds2450.h" +#include "satmb.h" +#include "dallasids.h" + +// globals + +// functions +void satmbInit(void) +{ + // preset serial port power to on + satmbSetSerialPortPower(1); +} + +void satmbSetSerialPortPower(u08 on) +{ + // set I/O control line to output + sbi(SATMB_SER_PWR_DDR, SATMB_SER_PWR_PIN); + // set serial port power state + if(on) + sbi(SATMB_SER_PWR_PORT, SATMB_SER_PWR_PIN); + else + cbi(SATMB_SER_PWR_PORT, SATMB_SER_PWR_PIN); +} + +void satmbSerialRtsCtsInit(void) +{ + // initialize RTS/CTS lines for operation + // RTS is input, set pullup + cbi(SATMB_SER_RTS_DDR, SATMB_SER_RTS_PIN); + sbi(SATMB_SER_RTS_PORT, SATMB_SER_RTS_PIN); + // CTS is output, init low + sbi(SATMB_SER_CTS_DDR, SATMB_SER_CTS_PIN); + cbi(SATMB_SER_CTS_PORT, SATMB_SER_CTS_PIN); +} + +u08 satmbSerialRtsCheck(void) +{ + if(inb(SATMB_SER_RTS_PORTIN) & (1<S, 16, DS2450_RANGE_5V); + // read current-level A/D + ds2450StartAndResult(&targetSubsysId->S, 'A', &value); + // calculate milliamp value + // ma = 1000*(((value/65536)*5.12V)/(50*R)) + // for R=0.47/2 ohms + // return result + return value/150; +} + +u16 satmbV2GetCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read current-level A/D + ds2450StartAndResult(&targetSubsysId->S, 'C', &value); + // calculate milliamp value + // ma = 1000*(((value/65536)*5.12V)/(50*R)) + // for R=0.1/2 ohms + // return result + return value/32; +} + +u08 satmbV1GetOverCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read overcurrent state A/D + ds2450StartAndResult(&targetSubsysId->S, 'B', &value); + // return result + return (value>0x8000); +} + +u08 satmbV2GetOverCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read overcurrent state A/D + ds2450StartAndResult(&targetSubsysId->S, 'D', &value); + // return result + return (value>0x8000); +} + +void satmbV1SetPowerState(DallasSubsysId* targetSubsysId, u08 state) +{ + satmbSetPowerState(&targetSubsysId->V1, state); +} + +void satmbV2SetPowerState(DallasSubsysId* targetSubsysId, u08 state) +{ + satmbSetPowerState(&targetSubsysId->V2, state); +} + +void satmbSetPowerState(dallas_rom_id_T* targetRomId, u08 state) +{ + if(state) + { + // reset overcurrent flag + ds2450DigitalOut(targetRomId, 'B', DIGOUT_LOW); + ds2450DigitalOut(targetRomId, 'B', DIGOUT_OC); + // assert enable + ds2450DigitalOut(targetRomId, 'A', DIGOUT_LOW); + } + // pulse clock line + ds2450DigitalOut(targetRomId, 'C', DIGOUT_OC); + ds2450DigitalOut(targetRomId, 'C', DIGOUT_LOW); + ds2450DigitalOut(targetRomId, 'C', DIGOUT_OC); + // release enable + ds2450DigitalOut(targetRomId, 'A', DIGOUT_OC); +} diff --git a/3rd party/Procyuon avrlib/rsl/satmb.h b/3rd party/Procyuon avrlib/rsl/satmb.h new file mode 100644 index 0000000..eeabd61 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/satmb.h @@ -0,0 +1,130 @@ +/*! \file satmb.h \brief Satellite Motherboard Driver Functions. */ +//***************************************************************************** +// +// File Name : 'satmb.h' +// Title : Satellite Motherboard Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.13 +// Revised : 2005.10.24 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SATMB_H +#define SATMB_H + +#include "dallas.h" +#include "dallasids.h" + + +// defines and typedefs + +// SAT-MB serial port control +// CTS is an output signal +#define SATMB_SER_CTS_PORT PORTB +#define SATMB_SER_CTS_DDR DDRB +#define SATMB_SER_CTS_PORTIN PINB +#define SATMB_SER_CTS_PIN PB5 +// RTS is an input signal +#define SATMB_SER_RTS_PORT PORTB +#define SATMB_SER_RTS_DDR DDRB +#define SATMB_SER_RTS_PORTIN PINB +#define SATMB_SER_RTS_PIN PB6 +// Serial Port Power Control (set low to turn off) +#define SATMB_SER_PWR_PORT PORTD +#define SATMB_SER_PWR_DDR DDRD +#define SATMB_SER_PWR_PORTIN PIND +#define SATMB_SER_PWR_PIN PD5 + +// SAT-MB Linx Radio Transceiver +// Non-UART RX line (receive) +#define SATMB_LINX_IO_RX_PORT PORTD +#define SATMB_LINX_IO_RX_DDR DDRD +#define SATMB_LINX_IO_RX_PORTIN PIND +#define SATMB_LINX_IO_RX_PIN PD4 +// Non-UART TX line (transmit) +#define SATMB_LINX_IO_TX_PORT PORTB +#define SATMB_LINX_IO_TX_DDR DDRB +#define SATMB_LINX_IO_TX_PORTIN PINB +#define SATMB_LINX_IO_TX_PIN PB7 +// Linx Radio Power Control (set low to turn off) +#define SATMB_LINX_PWR_PORT PORTD +#define SATMB_LINX_PWR_DDR DDRD +#define SATMB_LINX_PWR_PORTIN PIND +#define SATMB_LINX_PWR_PIN PD5 +// Radio Receive Signal Strength Indicator (RSSI) +// this is an analog output +#define SATMB_LINX_RSSI_PORT PORTF +#define SATMB_LINX_RSSI_DDR DDRF +#define SATMB_LINX_RSSI_PORTIN PINF +#define SATMB_LINX_RSSI_PIN PF7 + +// SAT-MB Direct Dallas Bus Driver +// Dallas Line Pin +#define SATMB_DALLAS_LINE_PORT PORTE +#define SATMB_DALLAS_LINE_DDR DDRE +#define SATMB_DALLAS_LINE_PORTIN PINE +#define SATMB_DALLAS_LINE_PIN PE7 +// Dallas OC-Tx Pin +#define SATMB_DALLAS_TX_PORT PORTE +#define SATMB_DALLAS_TX_DDR DDRE +#define SATMB_DALLAS_TX_PORTIN PINE +#define SATMB_DALLAS_TX_PIN PE3 +// Dallas Strong-Pullup Pin +#define SATMB_DALLAS_SPU_PORT PORTE +#define SATMB_DALLAS_SPU_DDR DDRE +#define SATMB_DALLAS_SPU_PORTIN PINE +#define SATMB_DALLAS_SPU_PIN PE4 + +// functions + +//! Initializes SAT-MB hardware +void satmbInit(void); + +//! Controls power to the SAT-MB serial port +// TRUE = on +// FALSE = off +void satmbSetSerialPortPower(u08 on); + +//! Initializes the SAT-MB serial port RTS/CTS lines +void satmbSerialRtsCtsInit(void); + +//! Returns the current state of the SAT-MB serial port RTS line +u08 satmbSerialRtsCheck(void); + +//! Sets the current state of the SAT-MB serial port CTS line +void satmbSerialCtsSet(u08 state); + +// Power control commands (dallas bus) +void satmbSetPowerState(dallas_rom_id_T* targetRomId, u08 state); + +//! Get the current draw from the indicated subsystem's V1 power control (V1 is usually 5V supply) +u16 satmbV1GetCurrent(DallasSubsysId* targetSubsysId); + +//! Get the current draw from the indicated subsystem's V2 power control (V2 is usually 12V supply) +u16 satmbV2GetCurrent(DallasSubsysId* targetSubsysId); + +//! Get the over-current state from the indicated subsystem's V1 power control +/// Returns TRUE if over-current, FALSE otherwise +u08 satmbV1GetOverCurrent(DallasSubsysId* targetSubsysId); + +//! Get the over-current state from the indicated subsystem's V2 power control +/// Returns TRUE if over-current, FALSE otherwise +u08 satmbV2GetOverCurrent(DallasSubsysId* targetSubsysId); + +//! Set the power control state for the indicated subsystem's V1 +/// state = 1, turns the subsystem's V1 on +/// state = 0, turns the subsystem's V1 off +void satmbV1SetPowerState(DallasSubsysId* targetSubsysId, u08 state); + +//! Set the power control state for the indicated subsystem's V2 +/// state = 1, turns the subsystem's V2 on +/// state = 0, turns the subsystem's V2 off +void satmbV2SetPowerState(DallasSubsysId* targetSubsysId, u08 state); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/uartsw-satmb.c b/3rd party/Procyuon avrlib/rsl/uartsw-satmb.c new file mode 100644 index 0000000..4ea9362 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/uartsw-satmb.c @@ -0,0 +1,353 @@ +/*! \file uartsw.c \brief Software Interrupt-driven UART function library. */ +//***************************************************************************** +// +// File Name : 'uartsw.c' +// Title : Software Interrupt-driven UART function library +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer.h" +#include "uartsw.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u16 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC1A interrupt + cbi(TIMSK, OCIE1A); + // attach TxBit service routine to OC1A + timerAttach(TIMER1OUTCOMPAREA_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // attach RxBit service routine to OC1B + timerAttach(TIMER1OUTCOMPAREB_INT, uartswRxBitService); + // attach RxBit service routine to ICP + timerAttach(TIMER1INPUTCAPTURE_INT, uartswRxBitService); + // trigger on rising edge + sbi(TCCR1B, ICES1); + // enable ICP interrupt + sbi(TIMSK, TICIE1); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE1A); + cbi(TIMSK, OCIE1B); + cbi(TIMSK, TICIE1); + // detach the service routines + timerDetach(TIMER1OUTCOMPAREA_INT); + timerDetach(TIMER1OUTCOMPAREB_INT); + timerDetach(TIMER1INPUTCAPTURE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + // set timer prescaler + timer1SetPrescaler(TIMER_CLK_DIV1); + // calculate division factor for requested baud rate, and set it + UartswBaudRateDiv = (u16)((F_CPU+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // schedule the next bit + outw(OCR1A, inw(TCNT1) + UartswBaudRateDiv); + // enable OC1A interrupt + sbi(TIMSK, OCIE1A); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + if( !(UartswTxData & 0x01) ) + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + } + // schedule the next bit + outw(OCR1A, inw(OCR1A) + UartswBaudRateDiv); + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - OC1B + if(!UartswRxBusy) + { + // this is a start bit + // disable ICP interrupt + cbi(TIMSK, TICIE1); + // schedule data bit sampling 1.5 bit periods from now + outw(OCR1B, inw(TCNT1) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC1B interrupt flag + sbi(TIFR, OCF1B); + // enable OC1B interrupt + sbi(TIMSK, OCIE1B); + // set start bit flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + if( !(inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // clear ICP interrupt flag + sbi(TIFR, ICF1); + // enable ICP interrupt + sbi(TIMSK, TICIE1); + // clear start bit flag + UartswRxBusy = FALSE; + } + } +} + +/* +void uartswRxBitService(void) +{ + u16 thisBitTime; + u08 bitperiods; + u08 i; + + // bit transition was detected + // record bit's edge time + thisBitTime = inw(ICR1); + + cbi(PORTB, 0); + + if(!UartswRxStartBit) + { + // this is a start bit + // switch to falling-edge trigger + cbi(TCCR1B, ICES1); + // record bit time + UartswRxBitTime = thisBitTime; + // set start bit flag + UartswRxStartBit = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // how many bit periods since last edge? + bitperiods = (thisBitTime - UartswRxBitTime + UartswBaudRateDiv/2)/UartswBaudRateDiv; + // set last edge time + UartswRxBitTime = thisBitTime; + + if(bitperiods > 10) + { + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + else + { + + + if( inb(TCCR1B) & (1< 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + } + } + + // turn off debug LEDs + delay(10); + sbi(PORTB, 0); + sbi(PORTB, 1); +} +*/ diff --git a/3rd party/Procyuon avrlib/rsl/uartsw-satmb.h b/3rd party/Procyuon avrlib/rsl/uartsw-satmb.h new file mode 100644 index 0000000..7bb8e39 --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/uartsw-satmb.h @@ -0,0 +1,75 @@ +/*! \file uartsw.h \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw.h' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 1 Output Compare A for transmit timing +// -Timer 1 Output Compare B for receive timing +// -Timer 1 Input Capture for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupt from Timer1 can still be used for +// other timing, but the prescaler for Timer1 must not be changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the Timer1 Input Capture (IC1) I/O pin. +// These options should be configured by editing your local copy of +// "uartswconf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW_H +#define UARTSW_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartswconf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/uartsw128.c b/3rd party/Procyuon avrlib/rsl/uartsw128.c new file mode 100644 index 0000000..66d8b1f --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/uartsw128.c @@ -0,0 +1,285 @@ +/*! \file uartsw2.c \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.c' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer128.h" +#include "uartsw128.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u08 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + // attach TxBit service routine to OC2 + timerAttach(TIMER2OUTCOMPARE_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // attach RxBit service routine to OC0 + timerAttach(TIMER0OUTCOMPARE_INT, uartswRxBitService); + // INT2 trigger on rising edge + sbi(EICRA, ISC20); + // enable INT2 interrupt + sbi(EIMSK, INT2); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE2); + cbi(TIMSK, OCIE0); + cbi(EIMSK, INT2); + // detach the service routines + timerDetach(TIMER2OUTCOMPARE_INT); + timerDetach(TIMER0OUTCOMPARE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + u16 div; + + // set timer prescaler + if( baudrate > (F_CPU/64L*256L) ) + //CHANGE THE ABOVE LINE IF CLOCK FREQ OF AVRLINX BOARD DIFFERS + //FROM AVRSAT + { + // if the requested baud rate is high, + // set timer prescalers to div-by-64 + timer2SetPrescaler(TIMERRTC_CLK_DIV64); + timer0SetPrescaler(TIMER_CLK_DIV64); + div = 64; + } + else + { + // if the requested baud rate is low, + // set timer prescalers to div-by-256 + timer2SetPrescaler(TIMERRTC_CLK_DIV256); + timer0SetPrescaler(TIMER_CLK_DIV256); + div = 256; + } + + // calculate division factor for requested baud rate, and set it + //UartswBaudRateDiv = (u08)(((F_CPU/64L)+(baudrate/2L))/(baudrate*1L)); + //UartswBaudRateDiv = (u08)(((F_CPU/256L)+(baudrate/2L))/(baudrate*1L)); + UartswBaudRateDiv = (u08)(((F_CPU/div)+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);//changed to cbi -JGM + // schedule the next bit + outb(OCR2, inb(TCNT2) + UartswBaudRateDiv); + // enable OC2 interrupt + sbi(TIMSK, OCIE2); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + if( !(UartswTxData & 0x01) ) + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);//changed to cbi -JGM + else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);//changed to sbi -JGM + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);//changed to sbi -JGM + } + // schedule the next bit + outb(OCR2, inb(OCR2) + UartswBaudRateDiv); //WHAT IS INB? + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - Timer 0 output compare + if(!UartswRxBusy) + { + // UART was not previously busy, + // this must be is a start bit + + // disable INT2 interrupt + cbi(EIMSK, INT2); + // schedule data bit sampling 1.5 bit periods from now + outb(OCR0, inb(TCNT0) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC0 interrupt flag + sbi(TIFR, OCF0); + // enable OC0 interrupt + sbi(TIMSK, OCIE0); + // set busy flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + if((inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // clear INT2 interrupt flag + sbi(EIFR, INTF2); + // enable INT interrupt + sbi(EIMSK, INT2); + // clear busy flag + UartswRxBusy = FALSE; + } + } +} + +SIGNAL(SIG_INTERRUPT2) +{ + // run RxBit service routine + uartswRxBitService(); +} diff --git a/3rd party/Procyuon avrlib/rsl/uartsw128.h b/3rd party/Procyuon avrlib/rsl/uartsw128.h new file mode 100644 index 0000000..51afa8f --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/uartsw128.h @@ -0,0 +1,76 @@ +/*! \file uartsw2.h \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.h' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 2 Output Capture for transmit timing +// -Timer 0 Output Capture for receive timing +// -External Interrupt 2 for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +// be used for other timing, but the prescalers for these timers must not be +// changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +// These options should be configured by editing your local copy of +// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2_H +#define UARTSW2_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartsw128conf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/3rd party/Procyuon avrlib/rsl/uartsw128conf.h b/3rd party/Procyuon avrlib/rsl/uartsw128conf.h new file mode 100644 index 0000000..a75f3aa --- /dev/null +++ b/3rd party/Procyuon avrlib/rsl/uartsw128conf.h @@ -0,0 +1,57 @@ +/*! \file uartsw2conf.h \brief Interrupt-driven Software UART Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'uartsw2conf.h' +// Title : Interrupt-driven Software UART Driver Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 2 Output Capture for transmit timing +// -Timer 0 Output Capture for receive timing +// -External Interrupt 2 for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +// be used for other timing, but the prescalers for these timers must not be +// changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +// These options should be configured by editing your local copy of +// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2CONF_H +#define UARTSW2CONF_H + +// constants/macros/typdefs + +#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes + +// UART transmit pin defines +#define UARTSW_TX_PORT PORTB ///< UART Transmit Port +#define UARTSW_TX_DDR DDRB ///< UART Transmit DDR +#define UARTSW_TX_PIN PB7 ///< UART Transmit Pin + +// UART receive pin defines +// This pin must correspond to the +// External Interrupt 2 (INT2) pin for your processor +#define UARTSW_RX_PORT PORTD ///< UART Receive Port +#define UARTSW_RX_DDR DDRD ///< UART Receive DDR +#define UARTSW_RX_PORTIN PIND ///< UART Receive Port Input +#define UARTSW_RX_PIN PD4 ///< UART Receive Pin + +#endif diff --git a/3rd party/Procyuon avrlib/rtc.c b/3rd party/Procyuon avrlib/rtc.c new file mode 100644 index 0000000..1595a27 --- /dev/null +++ b/3rd party/Procyuon avrlib/rtc.c @@ -0,0 +1,130 @@ +/*! \file rtc.c \brief Real-time clock function library. */ +//***************************************************************************** +// +// File Name : 'rtc.c' +// Title : Real-time clock function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 5/10/2002 +// Revised : 9/30/2002 +// Version : 0.6 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include +#endif + +#include "global.h" +// include timer support +#ifdef __AVR_ATmega128__ + #include "timer128.h" +#else + #include "timer.h" +#endif +// include rtc header +#include "rtc.h" + +// Program ROM constants +static char __attribute__ ((progmem)) MonthDayTable[] = {31,28,31,30,31,30,31,31,30,31,30,31}; + +// Global variables +// time registers +RtcTimeType RtcTime; + +void rtcInit(void) +{ + // set up timer for RTC operation + // initialize real-time registers + RtcTime.totaltics = 0; + RtcTime.tics = 0; + RtcTime.seconds = 0; + RtcTime.minutes = 0; + RtcTime.hours = 0; + RtcTime.day = 1; + RtcTime.month = 1; + RtcTime.year = 2000; + + // select the correct RTC timer based on bit defines + #ifdef AS2 + // use timer2 for most AVRs + // initialize timer 2 + timer2Init(); + // count with 32.768KHz/8 + timer2SetPrescaler(TIMER_CLK_DIV8); + // switch to asynchronous input (32KHz crystal) + sbi(ASSR, AS2); + // attach service to real-time clock interrupt + // rtcService() will be called at ((32768/8)/256) = 16Hz + timerAttach(TIMER2OVERFLOW_INT, rtcService); + #else + #ifdef AS0 + // use timer0 for ATmega103, ATmega128 + // initialize timer 0 + timer0Init(); + // count with 32.768KHz/8 + timer0SetPrescaler(TIMER_CLK_DIV8); + // switch to asynchronous input (32KHz crystal) + sbi(ASSR, AS0); + // attach service to real-time clock interrupt + // rtcService() will be called at ((32768/8)/256) = 16Hz + timerAttach(TIMER0OVERFLOW_INT, rtcService); + #endif + #endif +} + +void rtcService(void) +{ + // update real-time clock registers + RtcTime.totaltics++; + RtcTime.tics++; + // check for overflows + if(RtcTime.tics == 16) // tics + { + RtcTime.tics = 0; + RtcTime.seconds++; // increment seconds + if(RtcTime.seconds > 59) // check seconds overflow + { + RtcTime.seconds -= 60; + RtcTime.minutes++; // increment minutes + if(RtcTime.minutes > 59) // check minutes overflow + { + RtcTime.minutes -= 60; + RtcTime.hours++; // increment hours + if(RtcTime.hours > 23) // check hours overflow + { + RtcTime.hours -= 24; + RtcTime.day++; // increment days + // check days overflow + if(RtcTime.day == pgm_read_byte(&MonthDayTable[RtcTime.month-1])) + { + RtcTime.day = 1; + RtcTime.month++; // increment months + if(RtcTime.month == 13) // check months overflow + { + RtcTime.month = 1; + RtcTime.year++; // increment years + } + } + } + } + } + } +} + +RtcTimeType* rtcGetTime(void) +{ + // return the real-time clock data + return &RtcTime; +} + diff --git a/3rd party/Procyuon avrlib/rtc.h b/3rd party/Procyuon avrlib/rtc.h new file mode 100644 index 0000000..2441c2d --- /dev/null +++ b/3rd party/Procyuon avrlib/rtc.h @@ -0,0 +1,49 @@ +/*! \file rtc.h \brief real-time clock function library. */ +//***************************************************************************** +// +// File Name : 'rtc.h' +// Title : real-time clock function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 5/10/2002 +// Revised : 7/12/2002 +// Version : 0.5 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RTC_H +#define RTC_H + +#include "global.h" + +// constants/macros/typdefs +typedef struct struct_RtcTime +{ + // hardware + u08 tics; + u16 totaltics; + // time of day + u08 hours; + u08 minutes; + u08 seconds; + // date + u08 day; + u08 month; + u16 year; +} RtcTimeType; + + +// functions +void rtcInit(void); +void rtcService(void); +RtcTimeType* rtcGetTime(void); + +#endif diff --git a/3rd party/Procyuon avrlib/servo.c b/3rd party/Procyuon avrlib/servo.c new file mode 100644 index 0000000..ff0e2a3 --- /dev/null +++ b/3rd party/Procyuon avrlib/servo.c @@ -0,0 +1,169 @@ +/*! \file servo.c \brief Interrupt-driven RC Servo function library. */ +//***************************************************************************** +// +// File Name : 'servo.c' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/31/2002 +// Revised : 8/02/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include +#endif + +#include "global.h" +#include "servo.h" + +// Program ROM constants + +// Global variables +// servo channel registers +u16 ServoPosTics; +u16 ServoPeriodTics; +u08 ServoChannel; +ServoChannelType ServoChannels[SERVO_NUM_CHANNELS]; + +// functions + +//! initializes software PWM system +void servoInit(void) +{ + u08 channel; + // disble the timer1 output compare A interrupt + cbi(TIMSK, OCIE1A); + // set the prescaler for timer1 + timer1SetPrescaler(TIMER_CLK_DIV256); + // attach the software PWM service routine to timer1 output compare A + timerAttach(TIMER1OUTCOMPAREA_INT, servoService); + // enable and clear channels + for(channel=0; channel>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + // enable the timer1 output compare A interrupt + sbi(TIMSK, OCIE1A); +} + +//! turns off software PWM system +void servoOff(void) +{ + // disable the timer1 output compare A interrupt + cbi(TIMSK, OCIE1A); + // detach the service routine + timerDetach(TIMER1OUTCOMPAREA_INT); +} + +//! set port and I/O pin for channel +void servoSetChannelIO(u08 channel, u08 port, u08 pin) +{ + ServoChannels[channel].port = port; + ServoChannels[channel].pin = (1<<(pin&0x07)); +} + +//! set servo position on channel +void servoSetPosition(u08 channel, u08 position) +{ + // input should be between 0 and SERVO_POSITION_MAX + u16 pos_scaled; + // calculate scaled position + pos_scaled = ((u16)position*(SERVO_MAX-SERVO_MIN)/SERVO_POSITION_MAX)+SERVO_MIN; + // set position + servoSetPositionRaw(channel, pos_scaled); +} + +//! get servo position on channel +u08 servoGetPosition(u08 channel) +{ + return (u08)( ((servoGetPositionRaw(channel)-SERVO_MIN)*SERVO_POSITION_MAX)/(SERVO_MAX-SERVO_MIN) ); +} + +//! set servo position on channel (raw unscaled format) +void servoSetPositionRaw(u08 channel, u16 position) +{ + // bind to limits + position = MAX(position, SERVO_MIN); + position = MIN(position, SERVO_MAX); + // set position + ServoChannels[channel].duty = position; +} + +//! get servo position on channel (raw unscaled format) +u16 servoGetPositionRaw(u08 channel) +{ + return ServoChannels[channel].duty; +} + +void servoService(void) +{ + u16 nextTics; + + if(ServoChannel < SERVO_NUM_CHANNELS) + { + // turn off current channel + outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) & ~(ServoChannels[ServoChannel].pin)); + } + + // next channel + ServoChannel++; + + if(ServoChannel != SERVO_NUM_CHANNELS) + { + // loop to channel 0 if needed + if(ServoChannel > SERVO_NUM_CHANNELS) ServoChannel = 0; + // turn on new channel + outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) | (ServoChannels[ServoChannel].pin)); + // schedule turn off time + nextTics = ServoChannels[ServoChannel].duty; + } + else //(Channel == SERVO_NUM_CHANNELS) + { + // ***we could save time by precalculating this + // schedule end-of-period + nextTics = ServoPeriodTics-ServoPosTics; + } + + // schedule next interrupt + u16 OCValue; + // read in current value of output compare register OCR1A + OCValue = inb(OCR1AL); // read low byte of OCR1A + OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A + // increment OCR1A value by nextTics + OCValue += nextTics; +// OCR1A+=nextTics; + // set future output compare time to this new value + outb(OCR1AH, (OCValue>>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + // set our new tic position + ServoPosTics += nextTics; + if(ServoPosTics >= ServoPeriodTics) ServoPosTics = 0; +} diff --git a/3rd party/Procyuon avrlib/servo.h b/3rd party/Procyuon avrlib/servo.h new file mode 100644 index 0000000..42fd977 --- /dev/null +++ b/3rd party/Procyuon avrlib/servo.h @@ -0,0 +1,116 @@ +/*! \file servo.h \brief Interrupt-driven RC Servo function library. */ +//***************************************************************************** +// +// File Name : 'servo.h' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/31/2002 +// Revised : 8/02/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +/// \ingroup driver_sw +/// \defgroup servo Interrupt-driven RC Servo Function Library (servo.c) +/// \code #include "servo.h" \endcode +/// \par Overview +/// This code allows you to drive up to 8 RC servos from any +/// combination of ports and pins on the AVR processor. Using interrupts, +/// this code continuously sends control signals to the servo to maintain +/// position even while your code is doing other work. +/// +/// The servoInit and servoOff effectively turn on and turn off servo +/// control. When you run ServoInit, it automatically assigns each +/// "channel" of servo control to be output on the SERVO_DEFAULT_PORT. +/// One "channel" of servo control can control one servo and must be +/// assigned single I/O pin for output. +/// +/// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then +/// then by default the code will use SERVO_DEFAULT_PORT pins 0-7. +/// If you're only using four channels, then pins 0-3 will be used by +/// default. +/// +/// The command servoSetChannelIO(channel, port, pin) allows you to +/// reassign the output of any channel to any port and I/O pin you +/// choose. For exampe, if you have an RC servo connected to PORTC, pin 6, +/// and you wish to use channel 2 to control it, use: +/// +/// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6) +/// +/// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port) +/// +/// The servoSetPostion and servoGetPosition commands allow you to command +/// a given servo to your desired position. The position you request must +/// lie between the SERVO_MIN and SERVO_MAX limit you defined. +/// +/// \WARNING: This servo library has been tested to work without issue on +/// several different AVR processors and with several different brands/kinds +/// of servos. However: +/// - Proper output duty cylces are dependent upon a user calibation and +/// configuration. +/// - IF YOUR SERVOS ARE EXCEPTIONALLY POWERFUL, AN ERRONEOUS OUTPUT DUTY +/// CYCLE GENERATED FROM THIS CODE OR ANY OTHER SOURCE CAN DAMAGE YOUR +/// SERVO'S INTERNAL DRIVER CHIP OR ITS GEARS! +/// - I have never experienced any servo damage from erroneous control signal +/// input, but it is possible. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SERVO_H +#define SERVO_H + +#include "global.h" +#include "timer.h" + +// include configuration +#include "servoconf.h" + +typedef struct struct_ServoChannel +{ + // hardware I/O port and pin for this channel + u08 port; + u08 pin; + // PWM duty setting which corresponds to servo position + u16 duty; +} ServoChannelType; + +// functions + +// initializes servo system +// You must run this to begin servo control +void servoInit(void); + +// turns off servo system +// This stops controlling the servos and +// returns control of the SERVOPORT to your code +void servoOff(void); + +// set the port and I/O pin you wish to use for a given channel +// If you do not assign a port and I/O pin for a channel (ie. you don't +// use this command) then all output will be done through the +// SERVO_DEFAULT_PORT. See above definition of SERVO_DEFAULT_PORT. +void servoSetChannelIO(u08 channel, u08 port, u08 pin); + +// set and get servo position on a given channel +// servoSetPosition() commands the servo on to the position you +// desire. The position input must lie between 0 and POSITION_MAX and +// will be automatically scaled to raw positions between SERVO_MIN and +// SERVO_MAX +// servoGetPosition() returns the most recently set postition of the +// servo on . The return value will be scaled 0->POSITION_MAX +void servoSetPosition(u08 channel, u08 position); +u08 servoGetPosition(u08 channel); + +// set and get raw servo position on a given channel +// Works like non-raw commands but position is not scaled. Position must +// be between SERVO_MIN and SERVO_MAX +void servoSetPositionRaw(u08 channel, u16 position); +u16 servoGetPositionRaw(u08 channel); + +// servo interrupt service routine +void servoService(void); + +#endif diff --git a/3rd party/Procyuon avrlib/spi.c b/3rd party/Procyuon avrlib/spi.c new file mode 100644 index 0000000..8a58ab6 --- /dev/null +++ b/3rd party/Procyuon avrlib/spi.c @@ -0,0 +1,153 @@ +/*! \file spi.c \brief SPI interface driver. */ +//***************************************************************************** +// +// File Name : 'spi.c' +// Title : SPI interface driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 06/06/2002 +// Version : 0.6 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "spi.h" + +// Define the SPI_USEINT key if you want SPI bus operation to be +// interrupt-driven. The primary reason for not using SPI in +// interrupt-driven mode is if the SPI send/transfer commands +// will be used from within some other interrupt service routine +// or if interrupts might be globally turned off due to of other +// aspects of your program +// +// Comment-out or uncomment this line as necessary +//#define SPI_USEINT + +// global variables +volatile u08 spiTransferComplete; + +// SPI interrupt service handler +#ifdef SPI_USEINT +SIGNAL(SIG_SPI) +{ + spiTransferComplete = TRUE; +} +#endif + +// access routines +void spiInit() +{ +#ifdef __AVR_ATmega128__ + // setup SPI I/O pins + sbi(PORTB, 1); // set SCK hi + sbi(DDRB, 1); // set SCK as output + cbi(DDRB, 3); // set MISO as input + sbi(DDRB, 2); // set MOSI as output + sbi(DDRB, 0); // SS must be output for Master mode to work +#elif __AVR_ATmega8__ + // setup SPI I/O pins + sbi(PORTB, 5); // set SCK hi + sbi(DDRB, 5); // set SCK as output + cbi(DDRB, 4); // set MISO as input + sbi(DDRB, 3); // set MOSI as output + sbi(DDRB, 2); // SS must be output for Master mode to work +#else + // setup SPI I/O pins + sbi(PORTB, 7); // set SCK hi + sbi(DDRB, 7); // set SCK as output + cbi(DDRB, 6); // set MISO as input + sbi(DDRB, 5); // set MOSI as output + sbi(DDRB, 4); // SS must be output for Master mode to work +#endif + + // setup SPI interface : + // master mode + sbi(SPCR, MSTR); + // clock = f/4 +// cbi(SPCR, SPR0); +// cbi(SPCR, SPR1); + // clock = f/16 + cbi(SPCR, SPR0); + sbi(SPCR, SPR1); + // select clock phase positive-going in middle of data + cbi(SPCR, CPOL); + // Data order MSB first + cbi(SPCR,DORD); + // enable SPI + sbi(SPCR, SPE); + + + // some other possible configs + //outp((1<>8) & 0x00FF))<<8; + // send LS byte of given data + rxData |= (spiTransferByte(data & 0x00FF)); + + // return the received data + return rxData; +} diff --git a/3rd party/Procyuon avrlib/spi.h b/3rd party/Procyuon avrlib/spi.h new file mode 100644 index 0000000..9b95d21 --- /dev/null +++ b/3rd party/Procyuon avrlib/spi.h @@ -0,0 +1,56 @@ +/*! \file spi.h \brief SPI interface driver. */ +//***************************************************************************** +// +// File Name : 'spi.h' +// Title : SPI interface driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 06/06/2002 +// Version : 0.6 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_avr +/// \defgroup spi SPI (Serial Peripheral Interface) Function Library (spi.c) +/// \code #include "spi.h" \endcode +/// \par Overview +/// Provides basic byte and word transmitting and receiving via the AVR +/// SPI interface.  Due to the nature of SPI, every SPI communication operation +/// is both a transmit and simultaneous receive. +/// +/// \note Currently, only MASTER mode is supported. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SPI_H +#define SPI_H + +#include "global.h" + +// function prototypes + +// SPI interface initializer +void spiInit(void); + +// spiSendByte(u08 data) waits until the SPI interface is ready +// and then sends a single byte over the SPI port. This command +// does not receive anything. +void spiSendByte(u08 data); + +// spiTransferByte(u08 data) waits until the SPI interface is ready +// and then sends a single byte over the SPI port. The function also +// returns the byte that was received during transmission. +u08 spiTransferByte(u08 data); + +// spiTransferWord(u08 data) works just like spiTransferByte but +// operates on a whole word (16-bits of data). +u16 spiTransferWord(u16 data); + +#endif diff --git a/3rd party/Procyuon avrlib/spieeprom.c b/3rd party/Procyuon avrlib/spieeprom.c new file mode 100644 index 0000000..e16b078 --- /dev/null +++ b/3rd party/Procyuon avrlib/spieeprom.c @@ -0,0 +1,90 @@ +/*! \file spieeprom.c \brief Interface for standard SPI EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'spieeprom.c' +// Title : Interface for standard SPI EEPROM memories +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.07 +// Revised : 2004.10.07 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "spi.h" +#include "spieeprom.h" + +// functions +void spieepromInit(void) +{ + // although there is no code here + // don't forget to initialize the SPI interface itself +// sbi(DDRB, 0); +} + +u08 spieepromReadByte(u32 memAddr) +{ + u08 data; +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_READ); + // send address + spiTransferByte(memAddr>>8); + spiTransferByte(memAddr&0x00FF); + // read contents of memory address + data = spiTransferByte(0xFF); + // return data + return data; +// sbi(PORTB,0); +} + +void spieepromWriteByte(u32 memAddr, u08 data) +{ + // wait for any previous write to complete + while(spieepromReadStatus() & SPIEEPROM_STATUS_WIP); + +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WRITE); + // send address + spiTransferByte(memAddr>>8); + spiTransferByte(memAddr&0x00FF); + // send data to be written + spiTransferByte(data); +// sbi(PORTB,0); +} + +void spieepromWriteEnable(void) +{ +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WREN); +// sbi(PORTB,0); +} + +void spieepromWriteDisable(void) +{ +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WRDI); +// sbi(PORTB,0); +} + +u08 spieepromReadStatus(void) +{ + u08 status; +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_RDSR); + // get status register value + status = spiTransferByte(0xFF); +// sbi(PORTB,0); + return status; +} diff --git a/3rd party/Procyuon avrlib/spieeprom.h b/3rd party/Procyuon avrlib/spieeprom.h new file mode 100644 index 0000000..20b4c98 --- /dev/null +++ b/3rd party/Procyuon avrlib/spieeprom.h @@ -0,0 +1,64 @@ +/*! \file spieeprom.h \brief Interface for standard SPI EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'spieeprom.h' +// Title : Interface for standard SPI EEPROM memories +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.07 +// Revised : 2004.10.07 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +/// \ingroup driver_hw +/// \defgroup spieeprom Interface for standard SPI EEPROM memories (spieeprom.c) +/// \code #include "spieeprom.h" \endcode +/// \par Overview +/// This library provides functions for reading and writing standard +/// 25Cxxx/25LCxxx SPI EEPROM memories. Memory sizes up to 64Kbytes are +/// supported. Future revisions may include page-write support. +/// +/// \Note Library not fully tested! +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SPIEEPROM_H +#define SPIEEPROM_H + +#include "global.h" + +// defines and constants +// commands +#define SPIEEPROM_CMD_READ 0x03 ///< Read byte(s) +#define SPIEEPROM_CMD_WRITE 0x02 ///< Write byte(s) +#define SPIEEPROM_CMD_WREN 0x06 ///< Write Enable +#define SPIEEPROM_CMD_WRDI 0x04 ///< Write Disable +#define SPIEEPROM_CMD_RDSR 0x05 ///< Read Status Register +#define SPIEEPROM_CMD_WRSR 0x01 ///< Write Status Register + +// status register bit defines +#define SPIEEPROM_STATUS_WIP 0x01 ///< Write in progress +#define SPIEEPROM_STATUS_WEL 0x01 ///< Write enable +#define SPIEEPROM_STATUS_BP0 0x01 ///< Block Proection 0 +#define SPIEEPROM_STATUS_BP1 0x01 ///< Block Proection 1 +#define SPIEEPROM_STATUS_WPEN 0x01 ///< Write Protect Enable + +// functions + +//! Initialize SPI EEPROM interface +void spieepromInit(void); + +//! In the SPI EEPROM read a byte from memory location [memAddr] +u08 spieepromReadByte(u32 memAddr); + +//! In the SPI EEPROM write a byte [data] to the memory location [memAddr] +void spieepromWriteByte(u32 memAddr, u08 data); + +void spieepromWriteEnable(void); +void spieepromWriteDisable(void); +u08 spieepromReadStatus(void); + +#endif diff --git a/3rd party/Procyuon avrlib/spiflash.c b/3rd party/Procyuon avrlib/spiflash.c new file mode 100644 index 0000000..6b853e9 --- /dev/null +++ b/3rd party/Procyuon avrlib/spiflash.c @@ -0,0 +1,146 @@ +/*! \file spiflash.c \brief SPI Flash Memory Driver (M25Pxx/AT25Fxxx/etc). */ +//***************************************************************************** +// +// File Name : 'spiflash.c' +// Title : SPI Flash Memory Driver (M25Pxx/AT25Fxxx/etc) +// Author : Pascal Stang - Copyright (C) 2006 +// Created : 2006-04-15 +// Revised : 2006-07-02 +// Version : 0.1 +// Target MCU : AVR processors +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +//***************************************************************************** + +// system includes +#include "avr/io.h" +#include "global.h" + +// library includes +#include "spi.h" +#include "spiflash.h" + +#define SPIFLASH_CONFIG_CS DDRB |= (1<<0) +#define SPIFLASH_ASSERT_CS PORTB &= (1<<0) +#define SPIFLASH_RELEASE_CS PORTB |= (1<<0) + +// functions +void spiflashInit(void) +{ + // initialize spi + spiInit(); + // initialize chip select + SPIFLASH_RELEASE_CS; + SPIFLASH_CONFIG_CS; +} + +unsigned short spiflashGetID(void) +{ + unsigned short id; + + SPIFLASH_ASSERT_CS; + spiByte(0, SPIFLASH_CMD_RDID, 0); + id = spiByte(0, 0x00, 0)<<8; + id |= spiByte(0, 0x00, 1); + SPIFLASH_RELEASE_CS; + + return id; +} + +void spiflashChipErase(void) +{ + // enable write + SPIFLASH_ASSERT_CS; + spiByte(0, SPIFLASH_CMD_WREN, 1); + SPIFLASH_RELEASE_CS; + + // clock out dummy byte to waste time + spiByte(0, 0x00, 1); + + // do chip erase + SPIFLASH_ASSERT_CS; + spiByte(0, SPIFLASH_CMD_CHIPERASE, 1); + SPIFLASH_RELEASE_CS; + + // clock out dummy byte to waste time + spiByte(0, 0x00, 1); + + // wait until write is done + SPIFLASH_ASSERT_CS; + spiByte(0, SPIFLASH_CMD_RDSR, 0); + while(spiByte(0, 0x00, 0) & SPIFLASH_STATUS_BUSY); + SPIFLASH_RELEASE_CS; +} + +void spiflashRead(unsigned long addr, unsigned long nbytes, unsigned char *data) +{ + // begin read + SPIFLASH_ASSERT_CS; + // issue read command + spiByte(0, SPIFLASH_CMD_READ, 0); + // send address + spiByte(0, addr>>16, 0); + spiByte(0, addr>>8, 0); + spiByte(0, addr>>0, 0); + // read data + while(nbytes--) + *data++ = spiByte(0, 0x00, 0); + // end read + SPIFLASH_RELEASE_CS; +} + +void spiflashWrite(unsigned long addr, unsigned long nbytes, unsigned char *data) +{ + unsigned int page; + unsigned int i; + unsigned int pagelen; + + // loop through pages to be programmed + for(page=0; page<((nbytes+SPIFLASH_PAGESIZE-1)>>8); page++) + { + // program this page + + // enable write + SPIFLASH_ASSERT_CS; + spiByte(0, SPIFLASH_CMD_WREN, 1); + SPIFLASH_RELEASE_CS; + + // clock out dummy byte to waste time + spiByte(0, 0x00, 1); + + // begin write + SPIFLASH_ASSERT_CS; + // issue write command + spiByte(0, SPIFLASH_CMD_PAGEPROG, 0); + // send address + spiByte(0, addr>>16, 0); + spiByte(0, addr>>8, 0); + spiByte(0, addr>>0, 0); + // program exactly the number of bytes requested + if( ((page<<8)+SPIFLASH_PAGESIZE) <= nbytes) + pagelen = SPIFLASH_PAGESIZE; + else + pagelen = nbytes-(page<<8); + // transfer data + for(i=0; i beeper off +/// - '1' state => beeper on +void spyglassSetBeeper(u08 state); + +//! Sets the contrast voltage of the spyglass LCD. +/// Lower numbers are darker contrast, higher numbers are lighter contrast. +u08 spyglassSetLcdContrast(u08 contrast); + +// *********** LCD commands *********** + +//! Initialize LCD for operation. +void spyglassLcdInit(void); +//! Set write/cursor position to upper left. +void spyglassLcdHome(void); +//! Clear LCD display. +void spyglassLcdClear(void); +//! Set write/cursor posision on LCD display (x=col, y=line). +void spyglassLcdGotoXY(u08 x, u08 y); +//! Write control or display data to LCD. +void spyglassLcdWrite(u08 rs, u08 data); +//! Write character to LCD. +void spyglassLcdWriteChar(u08 c); + +// *********** LOW-LEVEL ACCESS *********** + +//! Write I/O Data to PCF8574 I2C<->Digital I/O chip. +u08 pcf8574Write(u08 nodeAddr, u08 data); +//! Read I/O Data from PCF8574 I2C<->Digital I/O chip. +u08 pcf8574Read(u08 nodeAddr); + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/sramsw.c b/3rd party/Procyuon avrlib/sramsw.c new file mode 100644 index 0000000..19e59c1 --- /dev/null +++ b/3rd party/Procyuon avrlib/sramsw.c @@ -0,0 +1,113 @@ +/*! \file sramsw.c \brief Software-driven SRAM memory bus access functions. */ +//***************************************************************************** +// +// File Name : 'sramsw.c' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "sramsw.h" + +// global variables + +// functions +void sramswInit(void) +{ + // initialize port state + outb(SRAM_ADL, 0xFF); // addr/data port set to 0xFF (pull-ups enabled) + outb(SRAM_AH, 0x00); // high addr port set to 0x00 + // initialize port directions + outb(SRAM_ADL_DDR, 0x00); // addr/data port set to input + outb(SRAM_AH_DDR, 0xFF); // high addr port set to output + // initialize control line states + sbi(SRAM_CTRL, SRAM_WR); // de-assert write (active low) + sbi(SRAM_CTRL, SRAM_RD); // de-assert read (active low) + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + // set control line direction + sbi(SRAM_CTRL_DDR, SRAM_WR); + sbi(SRAM_CTRL_DDR, SRAM_RD); + sbi(SRAM_CTRL_DDR, SRAM_ALE); + // set page lines direction + outb(SRAM_PAGE_DDR, inb(SRAM_PAGE_DDR) | SRAM_PAGE_MASK ); + // initialize page + sramswSetPage(0); +} + +void sramswOff(void) +{ +} + +void sramswWrite(u32 addr, u08 data) +{ + // set page + sramswSetPage( (addr & 0x00FF0000)>>16 ); + // set high-order address + outb(SRAM_AH, (addr & 0x0000FF00)>>8 ); + // set low-order address + outb(SRAM_ADL, addr & 0x000000FF); + // apply low-order address to latch + outb(SRAM_ADL_DDR, 0xFF); + // clock latch to save low-order address + sbi(SRAM_CTRL, SRAM_ALE); // assert ALE (active high) + asm volatile ("nop"); + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + + // apply data to memory + outb(SRAM_ADL, data); + // clock write line to store data + cbi(SRAM_CTRL, SRAM_WR); // assert write (active low) + asm volatile ("nop"); + sbi(SRAM_CTRL, SRAM_WR); // de-assert write (active low) +} + +u08 sramswRead(u32 addr) +{ + u08 data; + + // set page + sramswSetPage( (addr & 0x00FF0000)>>16 ); + // set high-order address + outb(SRAM_AH, (addr & 0x0000FF00)>>8 ); + // set low-order address + outb(SRAM_ADL, addr & 0x000000FF); + // apply low-order address to latch + outb(SRAM_ADL_DDR, 0xFF); + // clock latch to save low-order address + sbi(SRAM_CTRL, SRAM_ALE); // assert ALE (active high) + asm volatile ("nop"); + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + + // switch data bus to input + outb(SRAM_ADL_DDR, 0x00); + // clear pullups + outb(SRAM_ADL, 0x00); + // request data from memory + cbi(SRAM_CTRL, SRAM_RD); // assert read (active low) + // retrieve data + asm volatile ("nop"); + data = inb(SRAM_ADL_IN); + // release read line + sbi(SRAM_CTRL, SRAM_RD); // de-assert read (active low) + // switch data bus to output + outb(SRAM_ADL_DDR, 0xFF); + + return data; +} + +void sramswSetPage(u08 page) +{ + outb(SRAM_PAGE, (page & SRAM_PAGE_MASK)); +} diff --git a/3rd party/Procyuon avrlib/sramsw.h b/3rd party/Procyuon avrlib/sramsw.h new file mode 100644 index 0000000..a1be369 --- /dev/null +++ b/3rd party/Procyuon avrlib/sramsw.h @@ -0,0 +1,38 @@ +/*! \file sramsw.h \brief Software-driven SRAM memory bus access functions. */ +//***************************************************************************** +// +// File Name : 'sramsw.h' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SRAMSW_H +#define SRAMSW_H + +#include "global.h" +// include project-dependent configurations +// sramswconf.h allows the user to choose which ports +// and pins are used in the memory bus +#include "sramswconf.h" + +// function prototypes + +//! Initialize the memory bus +void sramswInit(void); +//! Write data using the memory bus +void sramswWrite(u32 addr, u08 data); +//! Read data using the memory bus +u08 sramswRead(u32 addr); +//! Set memory page +void sramswSetPage(u08 page); + +#endif diff --git a/3rd party/Procyuon avrlib/sta013.c b/3rd party/Procyuon avrlib/sta013.c new file mode 100644 index 0000000..d56191b --- /dev/null +++ b/3rd party/Procyuon avrlib/sta013.c @@ -0,0 +1,701 @@ +/*! \file sta013.c \brief STMicroelectronics STA013 MP3 player driver. */ +//***************************************************************************** +// +// File Name : 'sta013.c' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang +// Created : 10/22/2000 +// Revised : 7/11/2003 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "i2csw.h" +#include "timer.h" +//#include "procyon.h" + +#include "sta013.h" + +// bitrate and sampling frequency mappings +//static int __attribute__ ((progmem)) MP3_Bitrates[] = +// { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0, +// 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}; +static unsigned char __attribute__ ((progmem)) MP3_Bitrates[] = + { 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80, 0, + 0, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 0}; + +static unsigned char __attribute__ ((progmem)) MP3_SamplingFrequencies[] = + { 11, 12, 8, 0, // MPEG 2.5 rates + 0, 0, 0, 0, // reserved rates + 22, 24, 16, 0, // MPEG 2 rates + 44, 48, 32, 0 // MPEG 1 rates + }; + +// STA013 firmware update and configuration data +static unsigned char __attribute__ ((progmem)) STA013_UpdateData[] = + { +0x3a, 0x01, 0x2a, 0x04, 0x28, 0x00, 0x29, 0x00, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, +0x26, 0x00, 0x27, 0x00, 0x28, 0x01, 0x28, 0x02, 0x21, 0x8f, +0x28, 0x03, 0x21, 0x00, 0x28, 0x04, 0x28, 0x05, 0x28, 0x06, +0x28, 0x07, 0x28, 0x08, 0x28, 0x09, 0x28, 0x0a, 0x28, 0x0b, +0x28, 0x0c, 0x20, 0x80, 0x21, 0x90, 0x28, 0x0d, 0x20, 0x00, +0x21, 0x00, 0x28, 0x0e, 0x20, 0x81, 0x21, 0x91, 0x28, 0x0f, +0x20, 0x00, 0x21, 0x92, 0x28, 0x10, 0x21, 0x00, 0x28, 0x11, +0x21, 0x93, 0x28, 0x12, 0x21, 0x00, 0x28, 0x13, 0x28, 0x14, +0x28, 0x15, 0x20, 0x82, 0x28, 0x16, 0x20, 0x00, 0x28, 0x17, +0x28, 0x18, 0x28, 0x19, 0x21, 0x94, 0x28, 0x1a, 0x21, 0x95, +0x28, 0x1b, 0x21, 0x96, 0x28, 0x1c, 0x21, 0x00, 0x28, 0x1d, +0x20, 0x83, 0x28, 0x1e, 0x20, 0x00, 0x28, 0x1f, 0x21, 0x97, +0x28, 0x20, 0x21, 0x00, 0x28, 0x21, 0x28, 0x22, 0x28, 0x23, +0x28, 0x24, 0x28, 0x25, 0x28, 0x26, 0x28, 0x27, 0x28, 0x28, +0x28, 0x29, 0x28, 0x2a, 0x20, 0x84, 0x28, 0x2b, 0x20, 0x00, +0x28, 0x2c, 0x28, 0x2d, 0x28, 0x2e, 0x28, 0x2f, 0x28, 0x30, +0x28, 0x31, 0x28, 0x32, 0x20, 0x85, 0x28, 0x33, 0x20, 0x00, +0x28, 0x34, 0x28, 0x35, 0x28, 0x36, 0x28, 0x37, 0x21, 0x98, +0x28, 0x38, 0x21, 0x00, 0x28, 0x39, 0x28, 0x3a, 0x28, 0x3b, +0x28, 0x3c, 0x28, 0x3d, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x40, +0x28, 0x41, 0x28, 0x42, 0x28, 0x43, 0x28, 0x44, 0x28, 0x45, +0x28, 0x46, 0x28, 0x47, 0x28, 0x48, 0x28, 0x49, 0x28, 0x4a, +0x28, 0x4b, 0x28, 0x4c, 0x28, 0x4d, 0x28, 0x4e, 0x28, 0x4f, +0x28, 0x50, 0x28, 0x51, 0x28, 0x52, 0x28, 0x53, 0x28, 0x54, +0x28, 0x55, 0x28, 0x56, 0x28, 0x57, 0x28, 0x58, 0x28, 0x59, +0x28, 0x5a, 0x28, 0x5b, 0x28, 0x5c, 0x28, 0x5d, 0x28, 0x5e, +0x28, 0x5f, 0x28, 0x60, 0x28, 0x61, 0x28, 0x62, 0x21, 0x99, +0x28, 0x63, 0x21, 0x00, 0x28, 0x64, 0x28, 0x65, 0x28, 0x66, +0x28, 0x67, 0x28, 0x68, 0x28, 0x69, 0x28, 0x6a, 0x28, 0x6b, +0x28, 0x6c, 0x28, 0x6d, 0x28, 0x6e, 0x28, 0x6f, 0x28, 0x70, +0x28, 0x71, 0x28, 0x72, 0x28, 0x73, 0x28, 0x74, 0x28, 0x75, +0x28, 0x76, 0x28, 0x77, 0x28, 0x78, 0x28, 0x79, 0x28, 0x7a, +0x28, 0x7b, 0x28, 0x7c, 0x28, 0x7d, 0x28, 0x7e, 0x28, 0x7f, +0x28, 0x80, 0x28, 0x81, 0x28, 0x82, 0x28, 0x83, 0x28, 0x84, +0x28, 0x85, 0x28, 0x86, 0x28, 0x87, 0x28, 0x88, 0x28, 0x89, +0x28, 0x8a, 0x28, 0x8b, 0x28, 0x8c, 0x28, 0x8d, 0x28, 0x8e, +0x28, 0x8f, 0x28, 0x90, 0x28, 0x91, 0x20, 0x86, 0x28, 0x92, +0x20, 0x87, 0x28, 0x93, 0x20, 0x00, 0x28, 0x94, 0x28, 0x95, +0x28, 0x96, 0x28, 0x97, 0x28, 0x98, 0x28, 0x99, 0x28, 0x9a, +0x28, 0x9b, 0x28, 0x9c, 0x28, 0x9d, 0x28, 0x9e, 0x28, 0x9f, +0x21, 0x9a, 0x28, 0xa0, 0x21, 0x00, 0x28, 0xa1, 0x28, 0xa2, +0x28, 0xa3, 0x28, 0xa4, 0x28, 0xa5, 0x28, 0xa6, 0x28, 0xa7, +0x28, 0xa8, 0x28, 0xa9, 0x28, 0xaa, 0x28, 0xab, 0x28, 0xac, +0x28, 0xad, 0x28, 0xae, 0x28, 0xaf, 0x28, 0xb0, 0x28, 0xb1, +0x28, 0xb2, 0x28, 0xb3, 0x28, 0xb4, 0x28, 0xb5, 0x28, 0xb6, +0x28, 0xb7, 0x28, 0xb8, 0x28, 0xb9, 0x20, 0x88, 0x28, 0xba, +0x20, 0x00, 0x28, 0xbb, 0x20, 0x89, 0x28, 0xbc, 0x20, 0x00, +0x28, 0xbd, 0x28, 0xbe, 0x28, 0xbf, 0x28, 0xc0, 0x28, 0xc1, +0x28, 0xc2, 0x28, 0xc3, 0x21, 0x9b, 0x28, 0xc4, 0x21, 0x00, +0x28, 0xc5, 0x28, 0xc6, 0x28, 0xc7, 0x28, 0xc8, 0x28, 0xc9, +0x28, 0xca, 0x28, 0xcb, 0x28, 0xcc, 0x28, 0xcd, 0x28, 0xce, +0x28, 0xcf, 0x28, 0xd0, 0x28, 0xd1, 0x28, 0xd2, 0x28, 0xd3, +0x28, 0xd4, 0x28, 0xd5, 0x28, 0xd6, 0x28, 0xd7, 0x28, 0xd8, +0x28, 0xd9, 0x28, 0xda, 0x28, 0xdb, 0x28, 0xdc, 0x28, 0xdd, +0x28, 0xde, 0x28, 0xdf, 0x28, 0xe0, 0x28, 0xe1, 0x20, 0x8a, +0x28, 0xe2, 0x20, 0x8b, 0x28, 0xe3, 0x20, 0x00, 0x28, 0xe4, +0x28, 0xe5, 0x28, 0xe6, 0x28, 0xe7, 0x28, 0xe8, 0x28, 0xe9, +0x28, 0xea, 0x28, 0xeb, 0x28, 0xec, 0x28, 0xed, 0x28, 0xee, +0x28, 0xef, 0x28, 0xf0, 0x28, 0xf1, 0x28, 0xf2, 0x28, 0xf3, +0x28, 0xf4, 0x28, 0xf5, 0x28, 0xf6, 0x28, 0xf7, 0x28, 0xf8, +0x20, 0x8c, 0x28, 0xf9, 0x20, 0x00, 0x21, 0x9c, 0x28, 0xfa, +0x21, 0x9d, 0x28, 0xfb, 0x20, 0x8d, 0x21, 0x9e, 0x28, 0xfc, +0x20, 0x8e, 0x21, 0x9f, 0x28, 0xfd, 0x20, 0x00, 0x21, 0x00, +0x28, 0xfe, 0x28, 0xff, 0x2a, 0x01, 0x28, 0x00, 0x22, 0x01, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0xa4, 0x27, 0x07, +0x28, 0x01, 0x21, 0xc7, 0x22, 0x00, 0x23, 0x80, 0x26, 0xc4, +0x27, 0x0c, 0x28, 0x02, 0x20, 0x09, 0x21, 0x1c, 0x22, 0x04, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x03, 0x20, 0x00, 0x21, 0x00, +0x22, 0x00, 0x23, 0xa6, 0x26, 0xa0, 0x27, 0x07, 0x28, 0x04, +0x28, 0x05, 0x20, 0x05, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0x06, 0x20, 0x00, 0x22, 0x03, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x07, 0x21, 0xae, +0x22, 0x00, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0xa4, +0x27, 0x00, 0x28, 0x08, 0x21, 0x48, 0x22, 0x01, 0x23, 0x80, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0x09, 0x20, 0x09, 0x21, 0x04, +0x22, 0x04, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x0a, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0xa8, 0x26, 0xa4, 0x27, 0x07, +0x28, 0x0b, 0x28, 0x0c, 0x21, 0x40, 0x22, 0x20, 0x23, 0x80, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0x0d, 0x22, 0x24, 0x26, 0xc6, +0x28, 0x0e, 0x21, 0x9e, 0x22, 0x00, 0x26, 0xc8, 0x28, 0x0f, +0x20, 0x09, 0x21, 0x02, 0x22, 0x14, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x10, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0x11, 0x20, 0x00, 0x21, 0x01, +0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, +0x28, 0x12, 0x21, 0xc3, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x20, 0x27, 0x00, 0x28, 0x13, 0x20, 0x03, 0x21, 0xc2, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x14, 0x21, 0xb3, +0x22, 0x08, 0x28, 0x15, 0x20, 0x00, 0x21, 0xc6, 0x22, 0x00, +0x23, 0x95, 0x26, 0x00, 0x27, 0x08, 0x28, 0x16, 0x21, 0x00, +0x23, 0x00, 0x24, 0x96, 0x25, 0x03, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x17, 0x20, 0x42, 0x21, 0xb6, 0x23, 0x80, 0x24, 0x89, +0x25, 0x07, 0x28, 0x18, 0x20, 0x00, 0x21, 0x00, 0x23, 0x94, +0x26, 0x0e, 0x28, 0x19, 0x20, 0x0f, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x1a, 0x20, 0x00, 0x23, 0x93, 0x26, 0xa8, +0x27, 0x03, 0x28, 0x1b, 0x26, 0x28, 0x27, 0x00, 0x28, 0x1c, +0x21, 0x01, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, +0x27, 0x0a, 0x28, 0x1d, 0x21, 0xc5, 0x23, 0x95, 0x24, 0x89, +0x25, 0x07, 0x26, 0x20, 0x27, 0x00, 0x28, 0x1e, 0x21, 0x00, +0x23, 0x94, 0x26, 0x00, 0x27, 0x0a, 0x28, 0x1f, 0x26, 0x0e, +0x28, 0x20, 0x20, 0x03, 0x21, 0x79, 0x22, 0x01, 0x23, 0x83, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x21, 0x21, 0x32, 0x28, 0x22, +0x20, 0x00, 0x21, 0x04, 0x22, 0x00, 0x23, 0x80, 0x24, 0x00, +0x25, 0xfc, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x23, 0x21, 0x00, +0x23, 0x00, 0x25, 0x00, 0x28, 0x24, 0x21, 0xa3, 0x22, 0x0d, +0x23, 0x80, 0x24, 0x9e, 0x25, 0x3b, 0x28, 0x25, 0x20, 0x42, +0x21, 0x57, 0x22, 0x01, 0x24, 0x89, 0x25, 0x07, 0x28, 0x26, +0x20, 0x00, 0x21, 0x43, 0x22, 0x0d, 0x24, 0x00, 0x25, 0x38, +0x28, 0x27, 0x21, 0x08, 0x22, 0x98, 0x23, 0x95, 0x24, 0x89, +0x25, 0x07, 0x26, 0x24, 0x27, 0x00, 0x28, 0x28, 0x20, 0x42, +0x21, 0x93, 0x22, 0x01, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x29, 0x20, 0x03, 0x21, 0x7e, 0x22, 0x04, 0x23, 0x83, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x2a, 0x20, 0x00, 0x21, 0xb0, +0x22, 0x00, 0x23, 0x95, 0x26, 0xa0, 0x27, 0x07, 0x28, 0x2b, +0x21, 0x00, 0x23, 0x00, 0x24, 0x0c, 0x25, 0x04, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x2c, 0x21, 0x02, 0x23, 0x80, 0x24, 0x86, +0x25, 0xc3, 0x26, 0xab, 0x28, 0x2d, 0x20, 0x42, 0x21, 0x97, +0x22, 0x01, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0x2e, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x24, 0x1f, 0x25, 0x04, +0x28, 0x2f, 0x21, 0xb2, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x20, 0x27, 0x04, 0x28, 0x30, 0x20, 0x42, 0x21, 0x8b, +0x22, 0x04, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x31, +0x20, 0x00, 0x21, 0xb1, 0x22, 0x00, 0x23, 0x95, 0x26, 0xa0, +0x27, 0x07, 0x28, 0x32, 0x20, 0x03, 0x21, 0x75, 0x22, 0x04, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x33, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0x34, 0x20, 0x00, 0x21, 0x60, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x35, 0x21, 0x08, +0x22, 0x98, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x24, +0x27, 0x00, 0x28, 0x36, 0x21, 0xbc, 0x22, 0x00, 0x28, 0x37, +0x21, 0xa3, 0x22, 0x0d, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x38, 0x21, 0x60, 0x22, 0x00, +0x23, 0x80, 0x24, 0x00, 0x25, 0x38, 0x26, 0xaa, 0x28, 0x39, +0x21, 0x06, 0x22, 0x98, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x3a, 0x21, 0xbe, 0x22, 0x00, +0x28, 0x3b, 0x20, 0x05, 0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x3c, 0x20, 0x00, 0x21, 0x60, 0x23, 0x00, +0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x3d, +0x21, 0x42, 0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x3e, 0x21, 0x0c, 0x22, 0x98, +0x26, 0xa4, 0x27, 0x07, 0x28, 0x3f, 0x21, 0x08, 0x28, 0x40, +0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x41, 0x21, 0x0c, 0x22, 0x98, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x24, 0x27, 0x00, +0x28, 0x42, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0x43, 0x20, 0x00, 0x23, 0x80, +0x24, 0x00, 0x25, 0x10, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x44, +0x21, 0x22, 0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x45, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x04, 0x25, 0x12, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x46, 0x20, 0x03, 0x21, 0xd4, 0x22, 0x05, 0x23, 0x83, +0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x47, +0x20, 0x00, 0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x48, 0x21, 0xb3, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x00, 0x27, 0x08, +0x28, 0x49, 0x21, 0x00, 0x23, 0x00, 0x24, 0x09, 0x25, 0x00, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x4a, 0x21, 0x02, 0x23, 0x80, +0x24, 0x86, 0x25, 0x3b, 0x28, 0x4b, 0x20, 0x42, 0x21, 0xdd, +0x22, 0x05, 0x24, 0x89, 0x25, 0x07, 0x28, 0x4c, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x24, 0x1f, 0x25, 0x00, 0x28, 0x4d, +0x21, 0xb3, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, +0x27, 0x00, 0x28, 0x4e, 0x21, 0x00, 0x23, 0x00, 0x24, 0x97, +0x25, 0x03, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x4f, 0x20, 0x42, +0x21, 0xe2, 0x22, 0x05, 0x23, 0x80, 0x24, 0x89, 0x25, 0x07, +0x28, 0x50, 0x20, 0x00, 0x21, 0x10, 0x22, 0x00, 0x23, 0x00, +0x24, 0x80, 0x25, 0xcc, 0x26, 0xab, 0x28, 0x51, 0x21, 0x00, +0x22, 0x40, 0x23, 0xb4, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, +0x27, 0x04, 0x28, 0x52, 0x22, 0x00, 0x23, 0xb0, 0x26, 0x92, +0x27, 0x09, 0x28, 0x53, 0x21, 0x14, 0x22, 0x01, 0x23, 0x95, +0x26, 0x00, 0x27, 0x08, 0x28, 0x54, 0x21, 0x48, 0x23, 0xa4, +0x26, 0x2a, 0x27, 0x00, 0x28, 0x55, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x09, 0x25, 0x00, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x56, 0x21, 0x08, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, +0x28, 0x57, 0x20, 0x42, 0x21, 0x11, 0x22, 0x07, 0x24, 0x89, +0x25, 0x07, 0x28, 0x58, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x24, 0x1f, 0x25, 0x00, 0x28, 0x59, 0x21, 0x14, 0x22, 0x01, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, 0x27, 0x00, +0x28, 0x5a, 0x21, 0x16, 0x26, 0x02, 0x27, 0x09, 0x28, 0x5b, +0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x80, 0x25, 0x48, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x5c, 0x23, 0xa0, 0x24, 0x89, +0x25, 0x07, 0x26, 0x14, 0x27, 0x09, 0x28, 0x5d, 0x24, 0x80, +0x25, 0x50, 0x26, 0xa4, 0x27, 0x04, 0x28, 0x5e, 0x21, 0x16, +0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x27, 0x00, +0x28, 0x5f, 0x21, 0x04, 0x22, 0x00, 0x23, 0x00, 0x24, 0x9c, +0x25, 0x78, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x60, 0x21, 0x43, +0x22, 0x0d, 0x24, 0x01, 0x25, 0xc4, 0x26, 0xab, 0x28, 0x61, +0x21, 0x03, 0x22, 0x00, 0x24, 0x15, 0x28, 0x62, 0x21, 0x00, +0x24, 0x00, 0x25, 0x00, 0x26, 0xaa, 0x28, 0x63, 0x21, 0x5e, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x10, 0x27, 0x09, +0x28, 0x64, 0x21, 0x03, 0x23, 0x00, 0x24, 0x15, 0x25, 0xc4, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x65, 0x21, 0x00, 0x23, 0x80, +0x24, 0x00, 0x25, 0x06, 0x26, 0xaa, 0x28, 0x66, 0x24, 0x8f, +0x25, 0xe3, 0x26, 0xab, 0x28, 0x67, 0x20, 0x42, 0x21, 0xcd, +0x22, 0x07, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0x68, +0x20, 0x00, 0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0x69, 0x21, 0x00, 0x23, 0x80, +0x24, 0x8f, 0x25, 0x03, 0x26, 0xaa, 0x28, 0x6a, 0x20, 0x42, +0x21, 0xdd, 0x22, 0x07, 0x24, 0x89, 0x25, 0x07, 0x28, 0x6b, +0x20, 0x00, 0x21, 0x43, 0x22, 0x0d, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0x6c, 0x21, 0x00, 0x22, 0x00, +0x24, 0x00, 0x25, 0x04, 0x26, 0xaa, 0x28, 0x6d, 0x20, 0x03, +0x21, 0x7f, 0x22, 0x01, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x6e, 0x21, 0x62, 0x28, 0x6f, +0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x70, 0x20, 0x00, 0x21, 0x06, 0x23, 0x95, +0x26, 0x00, 0x27, 0x08, 0x28, 0x71, 0x21, 0x01, 0x23, 0x00, +0x24, 0x97, 0x25, 0x3b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x72, +0x20, 0x42, 0x21, 0x0e, 0x22, 0x08, 0x23, 0x80, 0x24, 0x89, +0x25, 0x07, 0x28, 0x73, 0x20, 0x03, 0x21, 0x3c, 0x22, 0x0b, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x74, 0x20, 0x00, +0x21, 0x03, 0x22, 0x00, 0x23, 0x95, 0x26, 0x02, 0x27, 0x08, +0x28, 0x75, 0x21, 0x27, 0x23, 0x00, 0x24, 0x81, 0x25, 0xc4, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x76, 0x21, 0x00, 0x23, 0x80, +0x24, 0x09, 0x25, 0x48, 0x26, 0xaa, 0x28, 0x77, 0x21, 0x58, +0x22, 0x34, 0x23, 0xa3, 0x24, 0x89, 0x25, 0x07, 0x26, 0x2a, +0x27, 0x00, 0x28, 0x78, 0x21, 0x00, 0x22, 0x00, 0x23, 0xa0, +0x26, 0x00, 0x27, 0x09, 0x28, 0x79, 0x21, 0x07, 0x23, 0x80, +0x24, 0x03, 0x25, 0x39, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x7a, +0x21, 0x04, 0x23, 0x00, 0x24, 0x1c, 0x25, 0x38, 0x28, 0x7b, +0x21, 0x07, 0x23, 0x80, 0x24, 0x83, 0x25, 0x39, 0x28, 0x7c, +0x21, 0x03, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x02, +0x27, 0x08, 0x28, 0x7d, 0x21, 0x27, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc4, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x7e, 0x21, 0x00, +0x23, 0x80, 0x24, 0x09, 0x25, 0x48, 0x26, 0xaa, 0x28, 0x7f, +0x21, 0x58, 0x22, 0x34, 0x23, 0xa3, 0x24, 0x89, 0x25, 0x07, +0x26, 0x2a, 0x27, 0x00, 0x28, 0x80, 0x21, 0x06, 0x22, 0x00, +0x23, 0x00, 0x24, 0x81, 0x25, 0xc0, 0x26, 0x93, 0x27, 0x01, +0x28, 0x81, 0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x82, 0x20, 0x02, 0x21, 0x66, +0x22, 0x08, 0x23, 0x00, 0x24, 0x00, 0x25, 0x66, 0x28, 0x83, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x1f, +0x25, 0x02, 0x28, 0x84, 0x21, 0x06, 0x24, 0x89, 0x25, 0x07, +0x26, 0xdc, 0x27, 0x0c, 0x28, 0x85, 0x21, 0x00, 0x23, 0xaa, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x86, 0x23, 0xb6, 0x26, 0x00, +0x27, 0x08, 0x28, 0x87, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x88, 0x21, 0x05, 0x24, 0x89, +0x25, 0x07, 0x26, 0xdc, 0x27, 0x0c, 0x28, 0x89, 0x21, 0x00, +0x23, 0xaa, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x8a, 0x23, 0xb6, +0x26, 0x00, 0x27, 0x08, 0x28, 0x8b, 0x23, 0x80, 0x24, 0x86, +0x25, 0x3b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x8c, 0x20, 0x42, +0x21, 0x7b, 0x22, 0x08, 0x24, 0x89, 0x25, 0x07, 0x28, 0x8d, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0x82, 0x28, 0x8e, 0x21, 0x05, 0x24, 0x81, 0x25, 0xc2, +0x26, 0xab, 0x28, 0x8f, 0x20, 0x03, 0x21, 0x93, 0x22, 0x08, +0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, +0x28, 0x90, 0x20, 0x00, 0x21, 0x05, 0x22, 0x00, 0x23, 0x00, +0x24, 0x81, 0x25, 0xc0, 0x26, 0x13, 0x27, 0x01, 0x28, 0x91, +0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x92, 0x20, 0x02, 0x21, 0x7e, 0x22, 0x08, +0x23, 0x00, 0x24, 0x00, 0x25, 0x66, 0x28, 0x93, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x1f, 0x25, 0x02, +0x28, 0x94, 0x21, 0x05, 0x24, 0x89, 0x25, 0x07, 0x26, 0xdc, +0x27, 0x0c, 0x28, 0x95, 0x21, 0x00, 0x23, 0xaa, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x96, 0x23, 0xb6, 0x26, 0x00, 0x27, 0x08, +0x28, 0x97, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x98, 0x21, 0x05, 0x24, 0x89, 0x25, 0x07, +0x26, 0xdc, 0x27, 0x0c, 0x28, 0x99, 0x21, 0x00, 0x23, 0xaa, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x9a, 0x23, 0x80, 0x24, 0x1f, +0x25, 0x02, 0x28, 0x9b, 0x21, 0x01, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc2, 0x26, 0xab, 0x28, 0x9c, 0x20, 0x03, 0x21, 0x93, +0x22, 0x08, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, +0x27, 0x0d, 0x28, 0x9d, 0x20, 0x00, 0x21, 0x04, 0x22, 0x00, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0x9e, 0x21, 0x60, +0x23, 0xc4, 0x26, 0xaa, 0x27, 0x04, 0x28, 0x9f, 0x21, 0x00, +0x23, 0xc0, 0x26, 0x00, 0x27, 0x09, 0x28, 0xa0, 0x20, 0x42, +0x21, 0xcb, 0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xa1, 0x20, 0x70, 0x21, 0x54, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x12, 0x27, 0x08, 0x28, 0xa2, 0x20, 0x02, 0x21, 0xcc, +0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xa3, +0x20, 0x03, 0x21, 0xca, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xa4, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x8c, 0x25, 0x0c, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xa5, 0x21, 0x04, 0x24, 0x82, 0x25, 0x78, 0x28, 0xa6, +0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, 0x26, 0x12, +0x27, 0x04, 0x28, 0xa7, 0x20, 0x03, 0x21, 0xde, 0x22, 0x0f, +0x23, 0x83, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xa8, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x00, 0x24, 0x9c, +0x25, 0x78, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xa9, 0x21, 0x00, +0x23, 0x80, 0x24, 0x81, 0x25, 0x40, 0x28, 0xaa, 0x20, 0x03, +0x21, 0xcf, 0x22, 0x0f, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, +0x26, 0x26, 0x27, 0x0d, 0x28, 0xab, 0x20, 0x70, 0x21, 0x08, +0x22, 0xb8, 0x23, 0x95, 0x26, 0xa0, 0x27, 0x04, 0x28, 0xac, +0x20, 0x03, 0x21, 0xd4, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xad, 0x21, 0x27, 0x22, 0x0b, 0x28, 0xae, +0x20, 0x70, 0x21, 0x63, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, +0x27, 0x08, 0x28, 0xaf, 0x20, 0x00, 0x21, 0x01, 0x22, 0x00, +0x23, 0x80, 0x24, 0x86, 0x25, 0xcb, 0x26, 0xab, 0x27, 0x0a, +0x28, 0xb0, 0x20, 0x42, 0x21, 0xdd, 0x22, 0x08, 0x24, 0x89, +0x25, 0x07, 0x26, 0xaa, 0x28, 0xb1, 0x20, 0x00, 0x21, 0x18, +0x22, 0x80, 0x23, 0x95, 0x26, 0xa4, 0x27, 0x00, 0x28, 0xb2, +0x20, 0x03, 0x21, 0xd9, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xb3, 0x20, 0x70, 0x21, 0x0a, 0x22, 0xb8, +0x23, 0x95, 0x26, 0xa0, 0x27, 0x00, 0x28, 0xb4, 0x20, 0x02, +0x21, 0xe0, 0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xb5, 0x20, 0x70, 0x21, 0x0a, 0x22, 0xb8, 0x23, 0x95, +0x26, 0xa0, 0x27, 0x00, 0x28, 0xb6, 0x21, 0x54, 0x26, 0x02, +0x27, 0x08, 0x28, 0xb7, 0x20, 0x00, 0x21, 0x18, 0x22, 0x80, +0x26, 0xa4, 0x27, 0x00, 0x28, 0xb8, 0x21, 0x00, 0x22, 0x00, +0x23, 0x80, 0x24, 0x80, 0x25, 0x48, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xb9, 0x20, 0x70, 0x21, 0x5e, 0x22, 0xb8, 0x23, 0x95, +0x24, 0x89, 0x25, 0x07, 0x26, 0x12, 0x27, 0x08, 0x28, 0xba, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x09, +0x25, 0x4b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xbb, 0x20, 0x70, +0x21, 0x5f, 0x22, 0xb8, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x10, 0x27, 0x08, 0x28, 0xbc, 0x20, 0x00, 0x21, 0x00, +0x22, 0x00, 0x23, 0x00, 0x24, 0x1c, 0x25, 0x83, 0x26, 0xab, +0x27, 0x0a, 0x28, 0xbd, 0x20, 0x03, 0x21, 0x32, 0x22, 0x09, +0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, +0x28, 0xbe, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, +0x24, 0x82, 0x25, 0x8c, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xbf, +0x20, 0x03, 0x21, 0x25, 0x22, 0x09, 0x23, 0x83, 0x24, 0x89, +0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xc0, 0x20, 0x42, +0x21, 0xbc, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xc1, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0xc2, 0x20, 0x70, 0x21, 0x0f, +0x22, 0xb8, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, +0x27, 0x00, 0x28, 0xc3, 0x20, 0x03, 0x21, 0xe3, 0x22, 0x0f, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xc4, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0xc5, 0x20, 0x00, 0x21, 0x03, 0x23, 0x95, 0x26, 0x14, +0x27, 0x08, 0x28, 0xc6, 0x21, 0xa6, 0x23, 0xa4, 0x26, 0x2a, +0x27, 0x05, 0x28, 0xc7, 0x21, 0x00, 0x23, 0xa0, 0x26, 0x44, +0x27, 0x09, 0x28, 0xc8, 0x21, 0x18, 0x22, 0x6d, 0x23, 0x80, +0x24, 0x9e, 0x25, 0x7b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xc9, +0x20, 0x42, 0x21, 0x13, 0x22, 0x0b, 0x24, 0x89, 0x25, 0x07, +0x28, 0xca, 0x20, 0x00, 0x21, 0xae, 0x22, 0x00, 0x23, 0x95, +0x26, 0x24, 0x27, 0x00, 0x28, 0xcb, 0x21, 0x00, 0x22, 0x03, +0x23, 0x80, 0x24, 0x87, 0x25, 0x7b, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xcc, 0x20, 0x42, 0x21, 0x16, 0x22, 0x0b, 0x24, 0x89, +0x25, 0x07, 0x28, 0xcd, 0x20, 0x00, 0x21, 0xae, 0x22, 0x00, +0x23, 0x95, 0x26, 0x24, 0x27, 0x00, 0x28, 0xce, 0x20, 0x05, +0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xcf, +0x20, 0x03, 0x21, 0x0d, 0x22, 0x0b, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xd0, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x80, 0x26, 0x02, 0x27, 0x00, 0x28, 0xd1, +0x23, 0x80, 0x24, 0x09, 0x25, 0x48, 0x26, 0x1e, 0x28, 0xd2, +0x21, 0x58, 0x22, 0x34, 0x23, 0x33, 0x24, 0x80, 0x25, 0x07, +0x26, 0x2a, 0x28, 0xd3, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, +0x26, 0x80, 0x27, 0x10, 0x28, 0xd4, 0x21, 0x10, 0x23, 0x63, +0x26, 0x2a, 0x27, 0x00, 0x28, 0xd5, 0x21, 0x00, 0x23, 0x60, +0x26, 0xa8, 0x27, 0x12, 0x28, 0xd6, 0x21, 0xaf, 0x22, 0x4c, +0x23, 0x00, 0x26, 0xc8, 0x27, 0x0c, 0x28, 0xd7, 0x21, 0x00, +0x22, 0x00, 0x26, 0x80, 0x27, 0x05, 0x28, 0xd8, 0x23, 0x80, +0x24, 0x86, 0x25, 0x3b, 0x26, 0x1e, 0x27, 0x00, 0x28, 0xd9, +0x20, 0x42, 0x21, 0x1c, 0x22, 0x0e, 0x23, 0x00, 0x24, 0x80, +0x25, 0x07, 0x28, 0xda, 0x20, 0x00, 0x21, 0x35, 0x22, 0x29, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0xdb, 0x20, 0x02, 0x21, 0x1d, +0x22, 0x0e, 0x26, 0x1e, 0x27, 0x00, 0x28, 0xdc, 0x20, 0x00, +0x21, 0x7f, 0x22, 0x34, 0x26, 0xc4, 0x27, 0x0c, 0x28, 0xdd, +0x21, 0x00, 0x22, 0x00, 0x23, 0x90, 0x24, 0x9f, 0x25, 0x04, +0x26, 0x10, 0x27, 0x0a, 0x28, 0xde, 0x23, 0x00, 0x24, 0x84, +0x25, 0x00, 0x26, 0x80, 0x27, 0x10, 0x28, 0xdf, 0x21, 0x06, +0x23, 0x63, 0x24, 0x80, 0x25, 0x07, 0x26, 0x2a, 0x27, 0x00, +0x28, 0xe0, 0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0xe1, 0x20, 0x05, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0xe2, 0x20, 0x70, 0x21, 0x61, 0x22, 0xb8, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0xe3, 0x20, 0x00, +0x21, 0x01, 0x22, 0x00, 0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, +0x26, 0xab, 0x27, 0x0a, 0x28, 0xe4, 0x20, 0x42, 0x21, 0xce, +0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xe5, +0x20, 0x70, 0x21, 0x50, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, +0x27, 0x08, 0x28, 0xe6, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, +0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xe7, 0x20, 0x70, +0x21, 0x64, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, 0x27, 0x08, +0x28, 0xe8, 0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x80, +0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xe9, +0x20, 0x42, 0x21, 0xd3, 0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, +0x26, 0xaa, 0x28, 0xea, 0x20, 0x70, 0x21, 0x51, 0x22, 0xb8, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0xeb, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0xec, 0x20, 0x70, 0x21, 0x65, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x12, 0x27, 0x08, 0x28, 0xed, 0x20, 0x00, 0x21, 0x01, +0x22, 0x00, 0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, +0x27, 0x0a, 0x28, 0xee, 0x20, 0x42, 0x21, 0xd8, 0x22, 0x0f, +0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xef, 0x20, 0x70, +0x21, 0x52, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, 0x27, 0x08, +0x28, 0xf0, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0xf1, 0x20, 0x70, 0x21, 0x61, +0x22, 0xb8, 0x23, 0x95, 0x26, 0x02, 0x27, 0x08, 0x28, 0xf2, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x80, 0x24, 0x86, +0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xf3, 0x20, 0x42, +0x21, 0xdd, 0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, +0x28, 0xf4, 0x20, 0x70, 0x21, 0x50, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x02, 0x27, 0x08, 0x28, 0xf5, 0x20, 0x05, 0x21, 0x00, +0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xf6, +0x20, 0x00, 0x21, 0x01, 0x23, 0x80, 0x24, 0x86, 0x25, 0xcb, +0x26, 0xab, 0x27, 0x0a, 0x28, 0xf7, 0x20, 0x42, 0x21, 0xe1, +0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xf8, +0x20, 0x00, 0x21, 0x02, 0x22, 0x00, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc4, 0x26, 0xab, 0x28, 0xf9, 0x21, 0x00, 0x23, 0x80, +0x24, 0x89, 0x25, 0x48, 0x26, 0xaa, 0x28, 0xfa, 0x20, 0x05, +0x23, 0x84, 0x25, 0x07, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xfb, +0x20, 0x70, 0x21, 0x4e, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x10, +0x27, 0x08, 0x28, 0xfc, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, +0x28, 0xfd, 0x20, 0x42, 0x21, 0xe7, 0x22, 0x0f, 0x24, 0x89, +0x25, 0x07, 0x26, 0xaa, 0x28, 0xfe, 0x20, 0x00, 0x21, 0xbb, +0x22, 0x00, 0x23, 0x95, 0x26, 0x20, 0x27, 0x00, 0x28, 0xff, +0x20, 0x05, 0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x2a, 0x08, 0x10, 0x01, 0x3a, 0x00, 0x64, 0x3a, 0x65, 0xbb, +0x08, 0x3a, 0x09, 0xbb, 0x50, 0x10, 0x52, 0x67, 0x51, 0x77, +0x05, 0xa1, 0x18, 0x04, 0xff, 0xff + }; + +void sta013HWReset(void) +{ + sbi(DDRD, 2); // set reset pin to output + sbi(PORTD, 2); // clock RESET low + cbi(PORTD, 2); + timerPause(10); + sbi(PORTD, 2); + + // give the sta013 a little time to come out of reset + timerPause(50); +} + +u08 sta013ReadReg(u08 reg) +{ + u08 data; + i2cReceive(STA_I2C_DEV, reg, 1, &data); + return data; +} + +void sta013WriteReg(u08 reg, u08 data) +{ + i2cSend(STA_I2C_DEV, reg, 1, &data); +} + +void sta013DownloadUpdate(void) +{ + u16 i; + u08 reg, data; + + i=0; + // get first reg/data pair + reg = pgm_read_byte(STA013_UpdateData + i++); + data = pgm_read_byte(STA013_UpdateData + i++); + // loop until end of update + while( (reg != 0xff) ) + { + sta013WriteReg(reg, data); + reg = pgm_read_byte(STA013_UpdateData + i++); + data = pgm_read_byte(STA013_UpdateData + i++); + } +} + + +u08 sta013Init(void) +{ + // reset STA013 device + sta013HWReset(); + + // identify STA013 device + if(sta013ReadReg(STA_REG_IDENT) != STA_IDENT) + { + return FALSE; + } + + // do firmware configuration and update + sta013DownloadUpdate(); + // start decoder + sta013StartDecoder(); + + return TRUE; +} + + +void sta013StartDecoder(void) +{ + // Soft reset + sta013WriteReg(STA_REG_SOFT_RESET, 0x01); + sta013WriteReg(STA_REG_SOFT_RESET, 0x00); + + // Mute and configure DAC output + sta013WriteReg(STA_REG_MUTE, 0x01); + sta013WriteReg(STA_REG_PCMDIVIDER, 0x01); // 32-bit mode, O_FAC = 256 + sta013WriteReg(STA_REG_PCMCONF, 0x31); // 18-bit mode & more + + // Configure PLL for MP3 rates + sta013WriteReg(STA_REG_PLLFRAC_441_H, 0x67); + sta013WriteReg(STA_REG_PLLFRAC_441_L, 0x77); + sta013WriteReg(STA_REG_PLLFRAC_H, 0xbb); + sta013WriteReg(STA_REG_PLLFRAC_L, 0x3a); + sta013WriteReg(STA_REG_MFSDF_441, 0x10); + sta013WriteReg(STA_REG_MFSDF, 0x0F); + + // Configure interface polarities, etc + sta013WriteReg(STA_REG_PLLCTL_2, 0x0C); + sta013WriteReg(STA_REG_PLLCTL_3, 0x00); + sta013WriteReg(STA_REG_PLLCTL_1, 0xA1); + sta013WriteReg(STA_REG_SCLK_POL, 0x00); // data sampled on rising edge + sta013WriteReg(STA_REG_REQ_POL, 0x01); // REQ line active high + sta013WriteReg(STA_REG_DATA_REQ_ENABLE, 0x04); + sta013WriteReg(STA_REG_PLLCTL_1, 0xA1); + + // Set audio tone controls + sta013SetTone(0, 0, 0, 0); + + // Unmute and start running + sta013WriteReg(STA_REG_RUN, 0x01); + sta013WriteReg(STA_REG_PLAY, 0x01); + sta013WriteReg(STA_REG_MUTE, 0x00); +} + + +void sta013StopDecoder(void) +{ + // mute output + sta013WriteReg(STA_REG_MUTE, 0x01); + // soft reset + sta013WriteReg(STA_REG_SOFT_RESET, 0x01); + sta013WriteReg(STA_REG_SOFT_RESET, 0x00); +} + + +void sta013PauseDecoder(void) +{ + // enable mute + sta013WriteReg(STA_REG_MUTE, 0x01); + // stop the decoder + sta013WriteReg(STA_REG_PLAY, 0x00); +} + + +void sta013ResumeDecoder(void) +{ + // run the decoder + sta013WriteReg(STA_REG_PLAY, 0x01); + // disable mute + sta013WriteReg(STA_REG_MUTE, 0x00); +} + +void sta013GetMP3Info(u16 *bitrate, u08 *sampFreq, u08 *mode) +{ + u08 headL, headM, headH; + u08 mpegID, bitrateIndex, sampFreqIndex; + + // get the MP3 header info + headH = sta013ReadReg(STA_REG_HEAD_H); + headM = sta013ReadReg(STA_REG_HEAD_M); + headL = sta013ReadReg(STA_REG_HEAD_L); + + // IDex:ID is in head[20:19] + // 00 - MPEG2.5 + // 01 - reserved + // 10 - MPEG2 + // 11 - MPEG1 + mpegID = (headH & 0x18)>>3; + + // sampling frequency is in head[11:10] + sampFreqIndex = ((headM & 0x0C)>>2) | (mpegID<<2); + + // bitrate index is in head[15:12] + bitrateIndex = ((headM & 0xF0)>>4) | ((mpegID & 0x01)<<4); + //bitrateIndex = ((headM & 0xF0)>>4) | (1<<4); + + // mode is in head[7:6] + // 00 - stereo + // 01 - joint stereo + // 10 - dual channel + // 11 - single channel (mono) + *mode = (headL & 0xC0)>>6; + + *bitrate = 2 * pgm_read_byte( MP3_Bitrates + bitrateIndex ); + *sampFreq = pgm_read_byte( MP3_SamplingFrequencies + sampFreqIndex ); + +/* + header = (unsigned long)sta013ReadReg(STA_REG_HEAD_H) << 16 | + (unsigned long)sta013ReadReg(STA_REG_HEAD_M) << 8 | + (unsigned long)sta013ReadReg(STA_REG_HEAD_L); + +// hdr->word = l; +// hdr->emphasis = l & 0x03; +// hdr->isOriginal = (l >> 2) & 0x01; +// hdr->isCopyrighted = (l >> 3) & 0x01; +// hdr->modeExtension = (l >> 4) & 0x03; +// hdr->mode = (l >> 6) & 0x03; +// hdr->private = (l >> 8) & 0x01; +// hdr->padding = (l >> 9) & 0x01; +// hdr->frequencyIndex = (l >> 10) & 0x03; +// hdr->bitrateIndex = (l >> 12) & 0x0f; +// hdr->protection = (l >> 16) & 0x01; +// hdr->layer = (l >> 17) & 0x03; +// hdr->ID = (l >> 19) & 0x01; +// hdr->ID_ex = (l >> 20) & 0x01; +*/ +} + +u16 sta013GetAverageBitrate(void) +{ + return (2 * sta013ReadReg(STA_REG_AVERAGE_BITRATE)); +} + +void sta013SetVolume(u08 volume, s08 balance) +{ + char attenL, attenR; + + // volume is expected as 0-100 value + // Note: + // #define MIN_VOLUME_ATTENUATION 0 + // #define MAX_VOLUME_ATTENUATION 96 + + if( balance > 0) + { // balance to the left, attenuate right + attenL = (100 - volume); + attenR = (100 - volume) - (balance); + } + else + { // balance to the right, attenuate left + attenL = (100 - volume) + (balance); + attenR = (100 - volume); + } + // respect limits + attenL = MIN(attenL,MAX_VOLUME_ATTENUATION); + attenL = MAX(attenL,MIN_VOLUME_ATTENUATION); + attenR = MIN(attenR,MAX_VOLUME_ATTENUATION); + attenR = MAX(attenR,MIN_VOLUME_ATTENUATION); + + // set volume + sta013WriteReg(STA_REG_DLA, attenL); + sta013WriteReg(STA_REG_DLB, MAX_VOLUME_ATTENUATION); + sta013WriteReg(STA_REG_DRA, attenR); + sta013WriteReg(STA_REG_DRB, MAX_VOLUME_ATTENUATION); +} + + +void sta013SetTone(s08 bassEnh, u16 bassFreq, s08 trebleEnh, u16 trebleFreq) +{ + // set bass enhancement + sta013WriteReg(STA_REG_BASS_FREQUENCY_LOW, (bassFreq ) & 0xFF ); + sta013WriteReg(STA_REG_BASS_FREQUENCY_HIGH, (bassFreq>>8) & 0xFF ); + // respect limits + bassEnh = MIN(bassEnh,MAX_BASS_ENHANCE); + bassEnh = MAX(bassEnh,MIN_BASS_ENHANCE); + sta013WriteReg(STA_REG_BASS_ENHANCE, bassEnh); + + // set treble enhancement + sta013WriteReg(STA_REG_TREBLE_FREQUENCY_LOW, (trebleFreq ) & 0xFF ); + sta013WriteReg(STA_REG_TREBLE_FREQUENCY_HIGH, (trebleFreq>>8) & 0xFF ); + // respect limits + trebleEnh = MIN(trebleEnh,MAX_TREBLE_ENHANCE); + trebleEnh = MAX(trebleEnh,MIN_TREBLE_ENHANCE); + sta013WriteReg(STA_REG_TREBLE_ENHANCE, trebleEnh); + + // set attentuation to avoid clipping + sta013WriteReg( STA_REG_TONE_ATTEN, MAX(bassEnh,trebleEnh) ); +} + +u08 sta013Demand(void) +{ + return bit_is_set(STA013_DEMAND_PORTIN,STA013_DEMAND_PIN); +} diff --git a/3rd party/Procyuon avrlib/sta013.h b/3rd party/Procyuon avrlib/sta013.h new file mode 100644 index 0000000..a4e95a7 --- /dev/null +++ b/3rd party/Procyuon avrlib/sta013.h @@ -0,0 +1,139 @@ +/*! \file sta013.h \brief STMicroelectronics STA013 MP3 player driver. */ +//***************************************************************************** +// +// File Name : 'sta013.h' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang +// Created : 10/22/2000 +// Revised : 12/04/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup driver_hw +/// \defgroup sta013 ST STA013 MP3 Player Driver (sta013.c) +/// \code #include "sta013.h" \endcode +/// \par Overview +/// This library interfaces to the I2C control port of the STA013 MP3 +/// decoder chip.  All functions necessary for setup and and control of the +/// decoder chip are included.  Supported functions include decoder initialize, +/// decoder start, stop, pause, and resume, get bitrate and sample rate, set +/// volume and tone controls. +/// +/// \NOTE The actual MP3 music data must be transmitted through a separate +/// interface using SPI.  The SPI function library is suitable for this. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef STA013_H +#define STA013_H + +#include "global.h" + +// include project-dependent configuration +#include "sta013conf.h" + +// STA013 I2C address +#define STA_I2C_DEV 0x86 +#define STA_IDENT 0xAC + +// STA013 register (sub)address +#define STA_REG_VERSION 0x00 +#define STA_REG_IDENT 0x01 +#define STA_REG_PLLCTL_1 0x05 +#define STA_REG_PLLCTL_2 0x06 +#define STA_REG_PLLCTL_3 0x07 +#define STA_REG_REQ_POL 0x0c +#define STA_REG_SCLK_POL 0x0d +#define STA_REG_ERROR_CODE 0x0f +#define STA_REG_SOFT_RESET 0x10 +#define STA_REG_PLAY 0x13 +#define STA_REG_MUTE 0x14 +#define STA_REG_CMD_INTERRUPT 0x16 +#define STA_REG_DATA_REQ_ENABLE 0x18 +#define STA_REG_SYNCSTATUS 0x40 +#define STA_REG_ANCCOUNT_L 0x41 +#define STA_REG_ANCCOUNT_H 0x42 +#define STA_REG_HEAD_H 0x43 +#define STA_REG_HEAD_M 0x44 +#define STA_REG_HEAD_L 0x45 +#define STA_REG_DLA 0x46 +#define STA_REG_DLB 0x47 +#define STA_REG_DRA 0x48 +#define STA_REG_DRB 0x49 +#define STA_REG_MFSDF_441 0x50 +#define STA_REG_PLLFRAC_441_L 0x51 +#define STA_REG_PLLFRAC_441_H 0x52 +#define STA_REG_PCMDIVIDER 0x54 +#define STA_REG_PCMCONF 0x55 +#define STA_REG_PCMCROSS 0x56 +#define STA_REG_ANC_DATA_1 0x59 +#define STA_REG_ANC_DATA_2 0x5a +#define STA_REG_ANC_DATA_3 0x5b +#define STA_REG_ANC_DATA_4 0x5c +#define STA_REG_ANC_DATA_5 0x5d +#define STA_REG_MFSDF 0x61 +#define STA_REG_DAC_CLK_MODE 0x63 +#define STA_REG_PLLFRAC_L 0x64 +#define STA_REG_PLLFRAC_H 0x65 +#define STA_REG_FRAME_CNT_L 0x67 +#define STA_REG_FRAME_CNT_M 0x68 +#define STA_REG_FRAME_CNT_H 0x69 +#define STA_REG_AVERAGE_BITRATE 0x6a +#define STA_REG_SOFTVERSION 0x71 +#define STA_REG_RUN 0x72 +#define STA_REG_TREBLE_FREQUENCY_LOW 0x77 +#define STA_REG_TREBLE_FREQUENCY_HIGH 0x78 +#define STA_REG_BASS_FREQUENCY_LOW 0x79 +#define STA_REG_BASS_FREQUENCY_HIGH 0x7a +#define STA_REG_TREBLE_ENHANCE 0x7b +#define STA_REG_BASS_ENHANCE 0x7c +#define STA_REG_TONE_ATTEN 0x7d + +#define MIN_VOLUME_ATTENUATION 0 +#define MAX_VOLUME_ATTENUATION 96 +#define MIN_TONE_ATTENUATION 0 +#define MAX_TONE_ATTENUATION 96 +#define MIN_BASS_FREQUENCY 100 +#define MAX_BASS_FREQUENCY 500 +#define MIN_BASS_ENHANCE -12 // -18dB in 1.5 dB steps +#define MAX_BASS_ENHANCE +12 // +18dB in 1.5 dB steps +#define MIN_TREBLE_FREQUENCY 1000 +#define MAX_TREBLE_FREQUENCY 5000 +#define MIN_TREBLE_ENHANCE -12 // -18dB in 1.5 dB steps +#define MAX_TREBLE_ENHANCE +12 // +18dB in 1.5 dB steps +#define SOFTMUTE_VOLUME_CHANGE 20 + +// global variables +//u16 Sta013UpdateIndex; + +// prototypes +void sta013HWReset(void); +u08 sta013ReadReg(u08 reg); +void sta013WriteReg(u08 reg, u08 data); +void sta013DownloadUpdate(void); +u08 sta013Init(void); + +void sta013StartDecoder(void); +void sta013StopDecoder(void); +void sta013PauseDecoder(void); +void sta013ResumeDecoder(void); + +void sta013GetMP3Info(u16 *bitrate, u08 *sampFreq, u08 *mode); +u16 sta013GetAverageBitrate(void); + +void sta013SetVolume(u08 volume, s08 balance); +void sta013SetTone(s08 bassEnh, u16 bassFreq, s08 trebleEnh, u16 trebleFreq); + + +u08 sta013Demand(void); + +#endif diff --git a/3rd party/Procyuon avrlib/stxetx.c b/3rd party/Procyuon avrlib/stxetx.c new file mode 100644 index 0000000..5978950 --- /dev/null +++ b/3rd party/Procyuon avrlib/stxetx.c @@ -0,0 +1,218 @@ +/*! \file stxetx.c \brief STX/ETX Packet Protocol Implementation Library. */ +//***************************************************************************** +// +// File Name : 'stxetx.c' +// Title : STX/ETX Packet Protocol Implementation Library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 10/9/2002 +// Revised : 6/30/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// Description : This library provides a set of functions needed to send and +// receive STX/ETX packets. STX/ETX is a simple packet protocol that can +// be wrapped around user data for one or more of the following reasons: +// +// 1. packetization is needed +// - Using packets can be helpful if your data naturally forms +// little "bunches" or if different types of data must be sent +// over the same channel (a serial cable, for example). If your +// data forms "bunches", you can send user data inside STX/ETX +// packets with a predetermined structure, like an array of A/D +// conversion results. If you need a way to tell the receiver +// what kind of data you're sending, you can use the TYPE field +// in the STX/ETX packet. +// 2. error checking is needed +// - STX/ETX packets will add a checksum to your data. This +// allows the receiver to verify that data was received correctly +// and is error-free. Packets which are corrupted in transmission +// and fail the the checksum test are automatically discarded. +// Error checking is especially useful when the data transmission +// channel is unreliable or noisy (examples: radio, infrared, long +// cables, etc) +// +// STX/ETX packets have the following structure: +// +// [STX][status][type][length][user data...][checksum][ETX] +// +// All fields are 1 byte except for user data which may be 0-255 bytes. +// Uppercase fields are constant (STX=0x02, ETX=0x03), lowercase fields +// vary. The length field is the number of bytes in the user data area. +// The checksum is the 8-bit sum of all bytes between but not including +// STX/ETX. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "global.h" +#include "stxetx.h" +//#include "rprintf.h" + +// function pointer to data output routine +static void (*stxetxDataOut)(unsigned char data); + +// received packet data buffer +unsigned char stxetxRxPacket[STXETX_MAXRXPACKETSIZE]; + +// functions + + +// Initialize STX/ETX packet protocol library +void stxetxInit(void (*dataout_func)(unsigned char data)) +{ + stxetxDataOut = dataout_func; +} + +// Send/Create STX/ETX packet +void stxetxSend(unsigned char status, unsigned char type, unsigned char datalength, unsigned char* dataptr) +{ + unsigned char checksum = 0; + unsigned short i; + + // write packet header + stxetxDataOut(STX); + stxetxDataOut(status); + stxetxDataOut(type); + stxetxDataOut(datalength); + // update checksum + checksum += status + type + datalength; + // copy data into packet + for(i = 0; i < datalength; i++) + { + stxetxDataOut(*dataptr); + checksum += *dataptr; + dataptr++; + } + // write packet trailer + stxetxDataOut(checksum); + stxetxDataOut(ETX); +} + +// process buffer containing STX/ETX packets +unsigned char stxetxProcess(cBuffer* rxBuffer) +{ + unsigned char foundpacket = FALSE; + unsigned short i; + unsigned char length, checksum; + //unsigned char type; + + // process the buffer + // go through buffer looking for packets + // the STX must be located at least STXETX_HEADERLENGTH+STXETX_TRAILERLENGTH from end + // otherwise we must not have a complete packet + while( rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+(u16)STXETX_TRAILERLENGTH) ) + { + // look for a potential start of packet + if(bufferGetAtIndex(rxBuffer, 0) == STX) + { + // if this is a start, then get the length + length = bufferGetAtIndex(rxBuffer, STXETX_LENGTHOFFSET); + + // now we must have at least STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH in buffer to continue + if(rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH)) + { + // check to see if ETX is in the right position + if(bufferGetAtIndex(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH-1) == ETX) + { + // found potential packet + // test checksum + checksum = 0; + // sum data between STX and ETX, not including checksum itself + // (u16) casting needed to avoid unsigned/signed mismatch + for(i = 0; i<((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH-(u16)STXETX_NOETXSTXCHECKSUM); i++) + { + checksum += bufferGetAtIndex(rxBuffer, i+STXETX_STATUSOFFSET); + } + // compare checksums + if(checksum == bufferGetAtIndex(rxBuffer, STXETX_CHECKSUMOFFSET+length)) + { + //we have a packet! + foundpacket = TRUE; + + // copy data to buffer + // (don't copy STX, ETX, or CHECKSUM) + for(i = 0; i < ((u16)STXETX_HEADERLENGTH+length-1); i++) + { + stxetxRxPacket[i] = bufferGetAtIndex(rxBuffer, i+1); + } + + // debug + //rprintf("STXETX Received packet type: 0x%x\n", bufferGetAtIndex(rxBuffer, STXETX_TYPEOFFSET)); + + // dump this packet from the + bufferDumpFromFront(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH); + + // done with this processing session + break; + } + else + { + // checksum bad + //rprintf("STXETX Received packet with bad checksum\r\n"); + // for now, we dump these + // dump this STX + bufferGetFromFront(rxBuffer); + } + } + else + { + // no ETX or ETX in wrong position + // dump this STX + bufferGetFromFront(rxBuffer); + } + } + else + { + // not enough data in buffer to decode pending packet + // wait until next time + break; + } + } + else + { + // this is not a start, dump it + bufferGetFromFront(rxBuffer); + } + } + + // check if receive buffer is full with no packets decoding + // (ie. deadlocked on garbage data or packet that exceeds buffer size) + if(!bufferIsNotFull(rxBuffer)) + { + // dump receive buffer contents to relieve deadlock + bufferFlush(rxBuffer); + } + + return foundpacket; +} + +unsigned char stxetxGetRxPacketStatus(void) +{ + // return the packet's status + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_STATUSOFFSET-1]; +} + +unsigned char stxetxGetRxPacketType(void) +{ + // return the packet's type + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_TYPEOFFSET-1]; +} + +unsigned char stxetxGetRxPacketDatalength(void) +{ + // return the packet's datalength + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_LENGTHOFFSET-1]; +} + +unsigned char* stxetxGetRxPacketData(void) +{ + // return a pointer to the packet's data payload + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket+STXETX_DATAOFFSET-1; +} diff --git a/3rd party/Procyuon avrlib/stxetx.h b/3rd party/Procyuon avrlib/stxetx.h new file mode 100644 index 0000000..db6463a --- /dev/null +++ b/3rd party/Procyuon avrlib/stxetx.h @@ -0,0 +1,112 @@ +/*! \file stxetx.h \brief STX/ETX Packet Protocol Implementation Library. */ +//***************************************************************************** +// +// File Name : 'stxetx.h' +// Title : STX/ETX Packet Protocol Implementation Library +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 10/9/2002 +// Revised : 02/10/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +/// \ingroup general +/// \defgroup stxetx STX/ETX Packet Protocol Library (stxetx.c) +/// \code #include "stxetx.h" \endcode +/// \par Overview +/// This library provides functions needed to transmit and receive STX/ETX +/// packets over any interface which can send and receive bytes.  STX/ETX is a +/// simple packet protocol for serial data streams and offers packetization, +/// type tagging, and checksum protection for user data.  Common uses of STX/ETX +/// might include radio communications were it can improve data reliability over +/// lossy channels.  STX/ETX may also be used effectively anywhere multiple +/// access to the communication medium is required.  The packets can be made +/// to contain destination addresses or routing information as well as data. +/// +/// \par STX/ETX Details +/// STX/ETX is a simple packet protocol that can be wrapped around user +/// data for one or more of the following reasons: +/// 1. packetization is needed +/// - Using packets can be helpful if your data naturally forms +/// little "bunches" or if different types of data must be sent +/// over the same channel (a serial cable, for example). If your +/// data forms "bunches", you can send user data inside STX/ETX +/// packets with a predetermined structure, like an array of A/D +/// conversion results. If you need a way to tell the receiver +/// what kind of data you're sending, you can use the TYPE field +/// in the STX/ETX packet. +/// 2. error checking is needed +/// - STX/ETX packets will add a checksum to your data. This +/// allows the receiver to verify that data was received correctly +/// and is error-free. Packets which are corrupted in transmission +/// and fail the the checksum test are automatically discarded. +/// Error checking is especially useful when the data transmission +/// channel is unreliable or noisy (examples: radio, infrared, long +/// cables, etc) +/// +/// STX/ETX packets have the following structure: +/// +/// [STX][status][type][length][user data...][checksum][ETX] +/// +/// All fields are 1 byte except for user data which may be 0-255 bytes. +/// Uppercase fields are constant (STX=0x02, ETX=0x03), lowercase fields +/// vary. The length field is the number of bytes in the user data area. +/// The checksum is the 8-bit sum of all bytes between but not including +/// STX/ETX. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef STXETX_H +#define STXETX_H + +#include "buffer.h" + +// include project-dependent configuration options +#include "stxetxconf.h" + +// constants +// packet markers +#define STX 0x02 // start transmission marker +#define ETX 0x03 // end transmission marker +// packet length parameters +#define STXETX_HEADERLENGTH 4 // number of bytes required for packet header +#define STXETX_TRAILERLENGTH 2 // number of bytes required for packet trailer +// packet field offsets +#define STXETX_STATUSOFFSET 1 // number of bytes from STX to STATUS +#define STXETX_TYPEOFFSET 2 // number of bytes from STX to TYPE +#define STXETX_LENGTHOFFSET 3 // number of bytes from STX to LENGTH +#define STXETX_DATAOFFSET 4 // number of bytes from STX to the data +#define STXETX_CHECKSUMOFFSET 4 // number of bytes from STX+[length] to CHECKSUM +#define STXETX_NOETXSTXCHECKSUM 3 // number of bytes used by STX,ETX,CHECKSUM + + +// function prototypes + +//! Initialize STX/ETX packet protocol library +void stxetxInit(void (*dataout_func)(unsigned char data)); + +//! Send/Create STX/ETX packet +void stxetxSend(unsigned char status, unsigned char type, unsigned char datalength, unsigned char* dataptr); + +//! Process a buffer containing STX/ETX packets +unsigned char stxetxProcess(cBuffer* rxBuffer); + +//! Returns the received packet's status +unsigned char stxetxGetRxPacketStatus(void); + +//! Returns the received packet's type +unsigned char stxetxGetRxPacketType(void); + +//! Returns the received packet's datalength +unsigned char stxetxGetRxPacketDatalength(void); + +//! Returns pointer to the received packet's data +unsigned char* stxetxGetRxPacketData(void); + + +#endif +//@} diff --git a/3rd party/Procyuon avrlib/timer.c b/3rd party/Procyuon avrlib/timer.c new file mode 100644 index 0000000..90a93c7 --- /dev/null +++ b/3rd party/Procyuon avrlib/timer.c @@ -0,0 +1,469 @@ +/*! \file timer.c \brief System Timer function library. */ +//***************************************************************************** +// +// File Name : 'timer.c' +// Title : System Timer function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 07/09/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include +#include + +#include "global.h" +#include "timer.h" + +#include "rprintf.h" + +// Program ROM constants +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + +// Global variables +// time registers +volatile unsigned long TimerPauseReg; +volatile unsigned long Timer0Reg0; +volatile unsigned long Timer2Reg0; + +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + +// delay for a minimum of microseconds +// the time resolution is dependent on the time the loop takes +// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us +void delay_us(unsigned short time_us) +{ + unsigned short delay_loops; + register unsigned short i; + + delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + + // one loop takes 5 cpu cycles + for (i=0; i < delay_loops; i++) {}; +} +/* +void delay_ms(unsigned char time_ms) +{ + unsigned short delay_count = F_CPU / 4000; + + unsigned short cnt; + asm volatile ("\n" + "L_dl1%=:\n\t" + "mov %A0, %A2\n\t" + "mov %B0, %B2\n" + "L_dl2%=:\n\t" + "sbiw %A0, 1\n\t" + "brne L_dl2%=\n\t" + "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + :"r"(time_ms), "r"((unsigned short) (delay_count)) + ); +} +*/ +void timerInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum number of milliseconds + u08 timerThres; + u32 ticRateHz; + u32 pause; + + // capture current pause timer value + timerThres = inb(TCNT0); + // reset pause timer overflow count + TimerPauseReg = 0; + // calculate delay for [pause_ms] milliseconds + // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))) + ticRateHz = F_CPU/timer0GetPrescaler(); + // precision management + // prevent overflow and precision underflow + // -could add more conditions to improve accuracy + if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + pause = (pause_ms*ticRateHz)/1000; + else + pause = pause_ms*(ticRateHz/1000); + + // loop until time expires + while( ((TimerPauseReg<<8) | inb(TCNT0)) < (pause+timerThres) ) + { + if( TimerPauseReg < (pause>>8)); + { + // save power by idling the processor + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } + } + + /* old inaccurate code, for reference + + // calculate delay for [pause_ms] milliseconds + u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); + u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000; + + TimerPauseReg = 0; + while(TimerPauseReg < pause); + + */ +} + +void timer0ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer0Reg0 = 0; // initialize time registers +} + +long timer0GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer0ClearOverflowCount() command was called) + return Timer0Reg0; +} + +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer2Reg0 = 0; // initialize time registers +} + +long timer2GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer2ClearOverflowCount() command was called) + return Timer2Reg0; +} +#endif + +void timer1PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on OC1A and OC1B pins + + // enable timer1 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + else + { // default 8bit mode + cbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); +} + +#ifdef WGM10 +// include support for arbitrary top-count PWM +// on new AVR processors that support it +void timer1PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR1A,WGM10); + sbi(TCCR1A,WGM11); + sbi(TCCR1B,WGM12); + sbi(TCCR1B,WGM13); + + // set top count value + ICR1 = topcount; + + // clear output compare value A + OCR1A = 0; + // clear output compare value B + OCR1B = 0; + +} +#endif + +void timer1PWMOff(void) +{ + // turn off timer1 PWM mode + cbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + // set PWM1A/B (OutputCompare action) to none + timer1PWMAOff(); + timer1PWMBOff(); +} + +void timer1PWMAOn(void) +{ + // turn on channel A (OC1A) PWM output + // set OC1A as non-inverted PWM + sbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOn(void) +{ + // turn on channel B (OC1B) PWM output + // set OC1B as non-inverted PWM + sbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMAOff(void) +{ + // turn off channel A (OC1A) PWM output + // set OC1A (OutputCompare action) to none + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOff(void) +{ + // turn off channel B (OC1B) PWM output + // set OC1B (OutputCompare action) to none + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC1A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A + //outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A + OCR1A = pwmDuty; +} + +void timer1PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC1B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B + //outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B + OCR1B = pwmDuty; +} + +//! Interrupt handler for tcnt0 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) +{ + Timer0Reg0++; // increment low-order counter + + // increment pause counter + TimerPauseReg++; + + // if a user function is defined, execute it too + if(TimerIntFunc[TIMER0OVERFLOW_INT]) + TimerIntFunc[TIMER0OVERFLOW_INT](); +} + +//! Interrupt handler for tcnt1 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OVERFLOW_INT]) + TimerIntFunc[TIMER1OVERFLOW_INT](); +} + +#ifdef TCNT2 // support timer2 only if it exists +//! Interrupt handler for tcnt2 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) +{ + Timer2Reg0++; // increment low-order counter + + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OVERFLOW_INT]) + TimerIntFunc[TIMER2OVERFLOW_INT](); +} +#endif + +#ifdef OCR0 +// include support for Output Compare 0 for new AVR processors that support it +//! Interrupt handler for OutputCompare0 match (OC0) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + TimerIntFunc[TIMER0OUTCOMPARE_INT](); +} +#endif + +//! Interrupt handler for CutputCompare1A match (OC1A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + TimerIntFunc[TIMER1OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare1B match (OC1B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + TimerIntFunc[TIMER1OUTCOMPAREB_INT](); +} + +//! Interrupt handler for InputCapture1 (IC1) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + TimerIntFunc[TIMER1INPUTCAPTURE_INT](); +} + +//! Interrupt handler for OutputCompare2 match (OC2) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} diff --git a/3rd party/Procyuon avrlib/timer.h b/3rd party/Procyuon avrlib/timer.h new file mode 100644 index 0000000..881d1b5 --- /dev/null +++ b/3rd party/Procyuon avrlib/timer.h @@ -0,0 +1,314 @@ +/*! \file timer.h \brief System Timer function library. */ +//***************************************************************************** +// +// File Name : 'timer.h' +// Title : System Timer function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 02/10/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_avr +/// \defgroup timer Timer Function Library (timer.c) +/// \code #include "timer.h" \endcode +/// \par Overview +/// This library provides functions for use with the timers internal +/// to the AVR processors. Functions include initialization, set prescaler, +/// calibrated pause function (in milliseconds), attaching and detaching of +/// user functions to interrupts, overflow counters, PWM. Arbitrary +/// frequency generation has been moved to the Pulse Library. +/// +/// \par About Timers +/// The Atmel AVR-series processors each contain at least one +/// hardware timer/counter. Many of the processors contain 2 or 3 +/// timers. Generally speaking, a timer is a hardware counter inside +/// the processor which counts at a rate related to the main CPU clock +/// frequency. Because the counter value increasing (counting up) at +/// a precise rate, we can use it as a timer to create or measure +/// precise delays, schedule events, or generate signals of a certain +/// frequency or pulse-width. +/// \par +/// As an example, the ATmega163 processor has 3 timer/counters. +/// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. +/// This means that they overflow, or roll over back to zero, at a +/// count value of 256 for 8bits or 65536 for 16bits. A prescaler is +/// avaiable for each timer, and the prescaler allows you to pre-divide +/// the main CPU clock rate down to a slower speed before feeding it to +/// the counting input of a timer. For example, if the CPU clock +/// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, +/// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is +/// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. +/// In fact, when it hits 255, it will overflow and start again at +/// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 +/// times per second. +/// \par +/// Timer0 can be used a number of ways simultaneously. First, the +/// value of the timer can be read by accessing the CPU register \c TCNT0. +/// We could, for example, figure out how long it takes to execute a +/// C command by recording the value of \c TCNT0 before and after +/// execution, then subtract (after-before) = time elapsed. Or we can +/// enable the overflow interrupt which goes off every time T0 +/// overflows and count out longer delays (multiple overflows), or +/// execute a special periodic function at every overflow. +/// \par +/// The other timers (Timer1 and Timer2) offer all the abilities of +/// Timer0 and many more features. Both T1 and T2 can operate as +/// general-purpose timers, but T1 has special hardware allowing it to +/// generate PWM signals, while T2 is specially designed to help count +/// out real time (like hours, minutes, seconds). See the +/// Timer/Counter section of the processor datasheet for more info. +/// +//***************************************************************************** +//@{ + +#ifndef TIMER_H +#define TIMER_H + +#include "global.h" + +// constants/macros/typdefs + +// processor compatibility fixes +#ifdef __AVR_ATmega323__ + // redefinition for the Mega323 + #define CTC1 CTC10 +#endif +#ifndef PWM10 + // mega128 PWM bits + #define PWM10 WGM10 + #define PWM11 WGM11 +#endif + + +// Timer/clock prescaler values and timer overflow rates +// tics = rate at which the timer counts up +// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) +// 16bit [overflow] = rate at which the timer overflows 16bits (65536) +// +// overflows can be used to generate periodic interrupts +// +// for 8MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz +// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz +// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz +// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz +// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 4MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz +// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz +// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz +// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz +// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 3.69MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz +// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz +// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz +// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz +// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 32.768KHz crystal on timer 2 (use for real-time clock) +// 0 = STOP +// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz +// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz +// 3 = CLOCK/32 tics= 1024kHz 8bitoverflow= 4Hz +// 4 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz +// 5 = CLOCK/128 tics= 256Hz 8bitoverflow= 1Hz +// 6 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz +// 7 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz + +#define TIMER_CLK_STOP 0x00 ///< Timer Stopped +#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU +#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 +#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 +#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 +#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 +#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge +#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge +#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask + +#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped +#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU +#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 +#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 +#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 +#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 +#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 +#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 +#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask + +// default prescale settings for the timers +// these settings are applied when you call +// timerInit or any of the timerInit +#define TIMER0PRESCALE TIMER_CLK_DIV8 ///< timer 0 prescaler default +#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default +#define TIMER2PRESCALE TIMERRTC_CLK_DIV64 ///< timer 2 prescaler default + +// interrupt macros for attaching user functions to timer interrupts +// use these with timerAttach( intNum, function ) +#define TIMER0OVERFLOW_INT 0 +#define TIMER1OVERFLOW_INT 1 +#define TIMER1OUTCOMPAREA_INT 2 +#define TIMER1OUTCOMPAREB_INT 3 +#define TIMER1INPUTCAPTURE_INT 4 +#define TIMER2OVERFLOW_INT 5 +#define TIMER2OUTCOMPARE_INT 6 +#ifdef OCR0 // for processors that support output compare on Timer0 +#define TIMER0OUTCOMPARE_INT 7 +#define TIMER_NUM_INTERRUPTS 8 +#else +#define TIMER_NUM_INTERRUPTS 7 +#endif + +// default type of interrupt handler to use for timers +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef TIMER_INTERRUPT_HANDLER +#define TIMER_INTERRUPT_HANDLER SIGNAL +#endif + +// functions +#define delay delay_us +#define delay_ms timerPause +void delay_us(unsigned short time_us); + +//! initializes timing system (all timers) +// runs all timer init functions +// sets all timers to default prescale values #defined in systimer.c +void timerInit(void); + +// default initialization routines for each timer +void timer0Init(void); ///< initialize timer0 +void timer1Init(void); ///< initialize timer1 +#ifdef TCNT2 // support timer2 only if it exists +void timer2Init(void); ///< initialize timer2 +#endif + +// Clock prescaler set/get commands for each timer/counter +// For setting the prescaler, you should use one of the #defines +// above like TIMER_CLK_DIVx, where [x] is the division rate +// you want. +// When getting the current prescaler setting, the return value +// will be the [x] division value currently set. +void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler +u16 timer0GetPrescaler(void); ///< get timer0 prescaler +void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler +u16 timer1GetPrescaler(void); ///< get timer0 prescaler +#ifdef TCNT2 // support timer2 only if it exists +void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler +u16 timer2GetPrescaler(void); ///< get timer2 prescaler +#endif + + +// TimerAttach and Detach commands +// These functions allow the attachment (or detachment) of any user function +// to a timer interrupt. "Attaching" one of your own functions to a timer +// interrupt means that it will be called whenever that interrupt happens. +// Using attach is better than rewriting the actual INTERRUPT() function +// because your code will still work and be compatible if the timer library +// is updated. Also, using Attach allows your code and any predefined timer +// code to work together and at the same time. (ie. "attaching" your own +// function to the timer0 overflow doesn't prevent timerPause from working, +// but rather allows you to share the interrupt.) +// +// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); +// timerDetach(TIMER1OVERFLOW_INT) +// +// timerAttach causes the myOverflowFunction() to be attached, and therefore +// execute, whenever an overflow on timer1 occurs. timerDetach removes the +// association and executes no user function when the interrupt occurs. +// myOverflowFunction must be defined with no return value and no arguments: +// +// void myOverflowFunction(void) { ... } + +//! Attach a user function to a timer interrupt +void timerAttach(u08 interruptNum, void (*userFunc)(void) ); +//! Detach a user function from a timer interrupt +void timerDetach(u08 interruptNum); + + +// timing commands +/// A timer-based delay/pause function +/// @param pause_ms Number of integer milliseconds to wait. +void timerPause(unsigned short pause_ms); + +// overflow counters +void timer0ClearOverflowCount(void); ///< Clear timer0's overflow counter. +long timer0GetOverflowCount(void); ///< read timer0's overflow counter +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void); ///< clear timer2's overflow counter +long timer2GetOverflowCount(void); ///< read timer0's overflow counter +#endif + +/// @defgroup timerpwm Timer PWM Commands +/// @ingroup timer +/// These commands control PWM functionality on timer1 +// PWM initialization and set commands for timer1 +// timer1PWMInit() +// configures the timer1 hardware for PWM mode on pins OC1A and OC1B. +// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution +// +// timer1PWMOff() +// turns off all timer1 PWM output and set timer mode to normal state +// +// timer1PWMAOn() and timer1PWMBOn() +// turn on output of PWM signals to OC1A or OC1B pins +// NOTE: Until you define the OC1A and OC1B pins as outputs, and run +// this "on" command, no PWM output will be output +// +// timer1PWMAOff() and timer1PWMBOff() +// turn off output of PWM signals to OC1A or OC1B pins +// +// timer1PWMASet() and timer1PWMBSet() +// sets the PWM duty cycle for each channel +// NOTE: should be in the range 0-255 for 8bit PWM +// should be in the range 0-511 for 9bit PWM +// should be in the range 0-1023 for 10bit PWM +// NOTE: the PWM frequency can be controlled in increments by setting the +// prescaler for timer1 +//@{ + + +/// Enter standard PWM Mode on timer1. +/// \param bitRes indicates the period/resolution to use for PWM output in timer bits. +/// Must be either 8, 9, or 10 bits corresponding to PWM periods of 256, 512, or 1024 timer tics. +void timer1PWMInit(u08 bitRes); + +/// Enter PWM Mode on timer1 with a specific top-count value. +/// \param topcount indicates the desired PWM period in timer tics. +/// Can be a number between 1 and 65535 (16-bit). +void timer1PWMInitICR(u16 topcount); + +/// Turn off all timer1 PWM output and set timer mode to normal. +void timer1PWMOff(void); + +/// Turn on/off Timer1 PWM outputs. +void timer1PWMAOn(void); ///< Turn on timer1 Channel A (OC1A) PWM output. +void timer1PWMBOn(void); ///< Turn on timer1 Channel B (OC1B) PWM output. +void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output +void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output + +void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output +void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output + +//@} +//@} + +// Pulse generation commands have been moved to the pulse.c library + +#endif diff --git a/3rd party/Procyuon avrlib/timer128.c b/3rd party/Procyuon avrlib/timer128.c new file mode 100644 index 0000000..00c2892 --- /dev/null +++ b/3rd party/Procyuon avrlib/timer128.c @@ -0,0 +1,689 @@ +/*! \file timer128.c \brief System Timer function library for Mega128. */ +//***************************************************************************** +// +// File Name : 'timer128.c' +// Title : System Timer function library for Mega128 +// Author : Pascal Stang - Copyright (C) 2000-2003 +// Created : 11/22/2000 +// Revised : 02/24/2003 +// Version : 1.2 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include +#include + +#include "global.h" +#include "timer128.h" + +// Program ROM constants +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + +// Global variables +// time registers +volatile unsigned long TimerPauseReg; +volatile unsigned long Timer0Reg0; +volatile unsigned long Timer0Reg1; +volatile unsigned long Timer2Reg0; +volatile unsigned long Timer2Reg1; + +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + +// delay for a minimum of microseconds +// the time resolution is dependent on the time the loop takes +// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us +void delay_us(unsigned short time_us) +{ + unsigned short delay_loops; + register unsigned short i; + + delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + + // one loop takes 5 cpu cycles + for (i=0; i < delay_loops; i++) {}; +} +/* +void delay_ms(unsigned char time_ms) +{ + unsigned short delay_count = F_CPU / 4000; + + unsigned short cnt; + asm volatile ("\n" + "L_dl1%=:\n\t" + "mov %A0, %A2\n\t" + "mov %B0, %B2\n" + "L_dl2%=:\n\t" + "sbiw %A0, 1\n\t" + "brne L_dl2%=\n\t" + "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + :"r"(time_ms), "r"((unsigned short) (delay_count)) + ); +} +*/ +void timerInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum number of milliseconds + u08 timerThres; + u32 ticRateHz; + u32 pause; + + // capture current pause timer value + timerThres = inb(TCNT2); + // reset pause timer overflow count + TimerPauseReg = 0; + // calculate delay for [pause_ms] milliseconds + // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR2))) + ticRateHz = F_CPU/timer2GetPrescaler(); + // precision management + // prevent overflow and precision underflow + // -could add more conditions to improve accuracy + if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + pause = (pause_ms*ticRateHz)/1000; + else + pause = pause_ms*(ticRateHz/1000); + + // loop until time expires + while( ((TimerPauseReg<<8) | inb(TCNT2)) < (pause+timerThres) ) + { + if( TimerPauseReg < (pause>>8)); + { + // save power by idling the processor + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } + } +} + +void timer0ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer0Reg0 = 0; // initialize time registers + Timer0Reg1 = 0; // initialize time registers +} + +long timer0GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer0ClearOverflowCount() command was called) + return Timer0Reg0; +} + +void timer2ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer2Reg0 = 0; // initialize time registers + Timer2Reg1 = 0; // initialize time registers +} + +long timer2GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer2ClearOverflowCount() command was called) + return Timer2Reg0; +} + + +void timer1PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on pins OC1A, OC1B, and OC1C + + // enable Timer1 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR1A,WGMA1); + cbi(TCCR1A,WGMA0); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR1A,WGMA1); + sbi(TCCR1A,WGMA0); + } + else + { // default 8bit mode + cbi(TCCR1A,WGMA1); + sbi(TCCR1A,WGMA0); + } + + // set clear-timer-on-compare-match + //cbi(TCCR1B,CTC1); + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); + // clear output compare value C + outb(OCR1CH, 0); + outb(OCR1CL, 0); +} + +void timer1PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR1A,WGM10); + sbi(TCCR1A,WGM11); + sbi(TCCR1B,WGM12); + sbi(TCCR1B,WGM13); + + // set top count value + ICR1H = (u08)(topcount>>8); + ICR1L = (u08)topcount; + + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); + // clear output compare value C + outb(OCR1CH, 0); + outb(OCR1CL, 0); +} + +void timer1PWMOff(void) +{ + // turn off PWM on Timer1 + cbi(TCCR1A,WGMA1); + cbi(TCCR1A,WGMA0); + // clear (disable) clear-timer-on-compare-match + //cbi(TCCR1B,CTC1); + // set PWM1A/B/C (OutputCompare action) to none + timer1PWMAOff(); + timer1PWMBOff(); + timer1PWMCOff(); +} + +void timer1PWMAOn(void) +{ + // turn on channel A (OC1A) PWM output + // set OC1A as non-inverted PWM + sbi(TCCR1A,COMA1); + cbi(TCCR1A,COMA0); +} + +void timer1PWMBOn(void) +{ + // turn on channel B (OC1B) PWM output + // set OC1B as non-inverted PWM + sbi(TCCR1A,COMB1); + cbi(TCCR1A,COMB0); +} + +void timer1PWMCOn(void) +{ + // turn on channel C (OC1C) PWM output + // set OC1C as non-inverted PWM + sbi(TCCR1A,COMC1); + cbi(TCCR1A,COMC0); +} + +void timer1PWMAOff(void) +{ + // turn off channel A (OC1A) PWM output + // set OC1A (OutputCompare action) to none + cbi(TCCR1A,COMA1); + cbi(TCCR1A,COMA0); +} + +void timer1PWMBOff(void) +{ + // turn off channel B (OC1B) PWM output + // set OC1B (OutputCompare action) to none + cbi(TCCR1A,COMB1); + cbi(TCCR1A,COMB0); +} + +void timer1PWMCOff(void) +{ + // turn off channel C (OC1C) PWM output + // set OC1C (OutputCompare action) to none + cbi(TCCR1A,COMC1); + cbi(TCCR1A,COMC0); +} + +void timer1PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC1A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1AH, (pwmDuty>>8)); // set the high 8bits of OCR1A + outb(OCR1AL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1A +} + +void timer1PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC1B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1BH, (pwmDuty>>8)); // set the high 8bits of OCR1B + outb(OCR1BL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1B +} + +void timer1PWMCSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel C + // this PWM output is generated on OC1C pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1CH, (pwmDuty>>8)); // set the high 8bits of OCR1C + outb(OCR1CL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1C +} + + +void timer3PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on pins OC3A, OC3B, and OC3C + + // enable Timer3 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR3A,WGMA1); + cbi(TCCR3A,WGMA0); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR3A,WGMA1); + sbi(TCCR3A,WGMA0); + } + else + { // default 8bit mode + cbi(TCCR3A,WGMA1); + sbi(TCCR3A,WGMA0); + } + + // set clear-timer-on-compare-match + //cbi(TCCR3B,CTC1); + // clear output compare value A + outb(OCR3AH, 0); + outb(OCR3AL, 0); + // clear output compare value B + outb(OCR3BH, 0); + outb(OCR3BL, 0); + // clear output compare value B + outb(OCR3CH, 0); + outb(OCR3CL, 0); +} + +void timer3PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR3A,WGM30); + sbi(TCCR3A,WGM31); + sbi(TCCR3B,WGM32); + sbi(TCCR3B,WGM33); + + // set top count value + ICR3H = (u08)(topcount>>8); + ICR3L = (u08)topcount; + + // clear output compare value A + outb(OCR3AH, 0); + outb(OCR3AL, 0); + // clear output compare value B + outb(OCR3BH, 0); + outb(OCR3BL, 0); + // clear output compare value C + outb(OCR3CH, 0); + outb(OCR3CL, 0); +} + +void timer3PWMOff(void) +{ + // turn off PWM mode on Timer3 + cbi(TCCR3A,WGMA1); + cbi(TCCR3A,WGMA0); + // clear (disable) clear-timer-on-compare-match + //cbi(TCCR3B,CTC1); + // set OC3A/B/C (OutputCompare action) to none + timer3PWMAOff(); + timer3PWMBOff(); + timer3PWMCOff(); +} + +void timer3PWMAOn(void) +{ + // turn on channel A (OC3A) PWM output + // set OC3A as non-inverted PWM + sbi(TCCR3A,COMA1); + cbi(TCCR3A,COMA0); +} + +void timer3PWMBOn(void) +{ + // turn on channel B (OC3B) PWM output + // set OC3B as non-inverted PWM + sbi(TCCR3A,COMB1); + cbi(TCCR3A,COMB0); +} + +void timer3PWMCOn(void) +{ + // turn on channel C (OC3C) PWM output + // set OC3C as non-inverted PWM + sbi(TCCR3A,COMC1); + cbi(TCCR3A,COMC0); +} + +void timer3PWMAOff(void) +{ + // turn off channel A (OC3A) PWM output + // set OC3A (OutputCompare action) to none + cbi(TCCR3A,COMA1); + cbi(TCCR3A,COMA0); +} + +void timer3PWMBOff(void) +{ + // turn off channel B (OC3B) PWM output + // set OC3B (OutputCompare action) to none + cbi(TCCR3A,COMB1); + cbi(TCCR3A,COMB0); +} + +void timer3PWMCOff(void) +{ + // turn off channel C (OC3C) PWM output + // set OC3C (OutputCompare action) to none + cbi(TCCR3A,COMC1); + cbi(TCCR3A,COMC0); +} + +void timer3PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC3A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3AH, (pwmDuty>>8)); // set the high 8bits of OCR3A + outb(OCR3AL, (pwmDuty&0x00FF)); // set the low 8bits of OCR3A +} + +void timer3PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC3B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3BH, (pwmDuty>>8)); // set the high 8bits of OCR3B + outb(OCR3BL, (pwmDuty&0x00FF)); // set the low 8bits of OCR3B +} + +void timer3PWMCSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC3C pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3CH, (pwmDuty>>8)); // set the high 8bits of OCR3C + outb(OCR3CL, (pwmDuty&0x00FF)); // set the low 8bits of OCR3C +} + + +//! Interrupt handler for tcnt0 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) +{ + Timer0Reg0++; // increment low-order counter + if(!Timer0Reg0) // if low-order counter rollover + Timer0Reg1++; // increment high-order counter + + // if a user function is defined, execute it too + if(TimerIntFunc[TIMER0OVERFLOW_INT]) + TimerIntFunc[TIMER0OVERFLOW_INT](); +} + +//! Interrupt handler for Timer1 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OVERFLOW_INT]) + TimerIntFunc[TIMER1OVERFLOW_INT](); +} + +//! Interrupt handler for Timer2 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) +{ + Timer2Reg0++; // increment low-order counter + if(!Timer2Reg0) // if low-order counter rollover + Timer2Reg1++; // increment high-order counter + + // increment pause counter + TimerPauseReg++; + + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OVERFLOW_INT]) + TimerIntFunc[TIMER2OVERFLOW_INT](); +} + +//! Interrupt handler for Timer3 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW3) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OVERFLOW_INT]) + TimerIntFunc[TIMER3OVERFLOW_INT](); +} + +//! Interrupt handler for OutputCompare0 match (OC0) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + TimerIntFunc[TIMER0OUTCOMPARE_INT](); +} + +//! Interrupt handler for OutputCompare1A match (OC1A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + TimerIntFunc[TIMER1OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare1B match (OC1B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + TimerIntFunc[TIMER1OUTCOMPAREB_INT](); +} + +//! Interrupt handler for OutputCompare1C match (OC1C) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1C) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREC_INT]) + TimerIntFunc[TIMER1OUTCOMPAREC_INT](); +} + +//! Interrupt handler for InputCapture1(IC1) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + TimerIntFunc[TIMER1INPUTCAPTURE_INT](); +} + +//! Interrupt handler for OutputCompare2 match (OC2) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} + +//! Interrupt handler for OutputCompare3A match (OC3A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREA_INT]) + TimerIntFunc[TIMER3OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare3B match (OC3B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREB_INT]) + TimerIntFunc[TIMER3OUTCOMPAREB_INT](); +} + +//! Interrupt handler for OutputCompare3C match (OC3C) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3C) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREC_INT]) + TimerIntFunc[TIMER3OUTCOMPAREC_INT](); +} + +//! Interrupt handler for InputCapture3 (IC3) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE3) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3INPUTCAPTURE_INT]) + TimerIntFunc[TIMER3INPUTCAPTURE_INT](); +} diff --git a/3rd party/Procyuon avrlib/timer128.h b/3rd party/Procyuon avrlib/timer128.h new file mode 100644 index 0000000..e5e63b0 --- /dev/null +++ b/3rd party/Procyuon avrlib/timer128.h @@ -0,0 +1,300 @@ +/*! \file timer128.h \brief System Timer function library for Mega128. */ +//***************************************************************************** +// +// File Name : 'timer128.h' +// Title : System Timer function library for Mega128 +// Author : Pascal Stang - Copyright (C) 2000-2003 +// Created : 11/22/2000 +// Revised : 02/10/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_avr +/// \defgroup timer128 Timer Function Library for ATmega128 (timer128.c) +/// \code #include "timer128.h" \endcode +/// \par Overview +/// This library provides functions for use with the timers internal to the +/// AVR ATmega128.  Functions include initialization, set prescaler, +/// calibrated pause function (in milliseconds), attaching and detaching +/// of user functions to interrupts, overflow counters, and PWM. +/// +/// \par About Timers +/// The Atmel AVR-series processors each contain at least one +/// hardware timer/counter. Many of the processors contain 2 or 3 +/// timers. Generally speaking, a timer is a hardware counter inside +/// the processor which counts at a rate related to the main CPU clock +/// frequency. Because the counter value increasing (counting up) at +/// a precise rate, we can use it as a timer to create or measure +/// precise delays, schedule events, or generate signals of a certain +/// frequency or pulse-width. +/// \par +/// As an example, the ATmega163 processor has 3 timer/counters. +/// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. +/// This means that they overflow, or roll over back to zero, at a +/// count value of 256 for 8bits or 65536 for 16bits. A prescaler is +/// avaiable for each timer, and the prescaler allows you to pre-divide +/// the main CPU clock rate down to a slower speed before feeding it to +/// the counting input of a timer. For example, if the CPU clock +/// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, +/// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is +/// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. +/// In fact, when it hits 255, it will overflow and start again at +/// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 +/// times per second. +/// \par +/// Timer0 can be used a number of ways simultaneously. First, the +/// value of the timer can be read by accessing the CPU register \c TCNT0. +/// We could, for example, figure out how long it takes to execute a +/// C command by recording the value of \c TCNT0 before and after +/// execution, then subtract (after-before) = time elapsed. Or we can +/// enable the overflow interrupt which goes off every time T0 +/// overflows and count out longer delays (multiple overflows), or +/// execute a special periodic function at every overflow. +/// \par +/// The other timers (Timer1 and Timer2) offer all the abilities of +/// Timer0 and many more features. Both T1 and T2 can operate as +/// general-purpose timers, but T1 has special hardware allowing it to +/// generate PWM signals, while T2 is specially designed to help count +/// out real time (like hours, minutes, seconds). See the +/// Timer/Counter section of the processor datasheet for more info. +/// +//***************************************************************************** +//@{ + +#ifndef TIMER128_H +#define TIMER128_H + +#include "global.h" + +// constants/macros/typdefs + +// Timer/clock prescaler values and timer overflow rates +// tics = rate at which the timer counts up +// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) +// 16bit [overflow] = rate at which the timer overflows 16bits (65536) +// +// overflows can be used to generate periodic interrupts +// +// for 8MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz +// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz +// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz +// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz +// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 4MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz +// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz +// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz +// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz +// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 3.69MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz +// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz +// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz +// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz +// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 32.768KHz crystal on timer 2 (use for real-time clock) +// 0 = STOP +// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz +// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz +// 3 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz +// 4 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz +// 5 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz + +#define TIMER_CLK_STOP 0x00 ///< Timer Stopped +#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU +#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 +#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 +#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 +#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 +#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge +#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge +#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask + +#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped +#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU +#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 +#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 +#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 +#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 +#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 +#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 +#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask + +// default prescale settings for the timers +// these settings are applied when you call +// timerInit or any of the timerInit +#define TIMER0PRESCALE TIMERRTC_CLK_DIV64 ///< timer 0 prescaler default +#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default +#define TIMER2PRESCALE TIMER_CLK_DIV8 ///< timer 2 prescaler default +#define TIMER3PRESCALE TIMER_CLK_DIV64 ///< timer 3 prescaler default + +// interrupt macros for attaching user functions to timer interrupts +// use these with timerAttach( intNum, function ) +// timer 0 +#define TIMER0OVERFLOW_INT 0 +#define TIMER0OUTCOMPARE_INT 1 +// timer 1 +#define TIMER1OVERFLOW_INT 2 +#define TIMER1OUTCOMPAREA_INT 3 +#define TIMER1OUTCOMPAREB_INT 4 +#define TIMER1OUTCOMPAREC_INT 5 +#define TIMER1INPUTCAPTURE_INT 6 +// timer 2 +#define TIMER2OVERFLOW_INT 7 +#define TIMER2OUTCOMPARE_INT 8 +// timer 3 +#define TIMER3OVERFLOW_INT 9 +#define TIMER3OUTCOMPAREA_INT 10 +#define TIMER3OUTCOMPAREB_INT 11 +#define TIMER3OUTCOMPAREC_INT 12 +#define TIMER3INPUTCAPTURE_INT 13 + +#define TIMER_NUM_INTERRUPTS 14 + +// type of interrupt handler to use for timers +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef TIMER_INTERRUPT_HANDLER +#define TIMER_INTERRUPT_HANDLER SIGNAL +#endif + +// functions +#define delay delay_us +#define delay_ms timerPause +void delay_us(unsigned short time_us); + +// initializes timing system +// runs all timer init functions +// sets all timers to default prescale values #defined in systimer.c +void timerInit(void); + +// default initialization routines for each timer +void timer0Init(void); +void timer1Init(void); +void timer2Init(void); +void timer3Init(void); + +// Clock prescaler set/get commands for each timer/counter +// For setting the prescaler, you should use one of the #defines +// above like TIMER_CLK_DIVx, where [x] is the division rate +// you want. +// When getting the current prescaler setting, the return value +// will be the [x] division value currently set. +void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler division index +void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler division index +void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler division index +void timer3SetPrescaler(u08 prescale); ///< set timer3 prescaler division index +u16 timer0GetPrescaler(void); ///< get timer0 prescaler division rate +u16 timer1GetPrescaler(void); ///< get timer1 prescaler division rate +u16 timer2GetPrescaler(void); ///< get timer2 prescaler division rate +u16 timer3GetPrescaler(void); ///< get timer3 prescaler division rate + + +// TimerAttach and Detach commands +// These functions allow the attachment (or detachment) of any user function +// to a timer interrupt. "Attaching" one of your own functions to a timer +// interrupt means that it will be called whenever that interrupt happens. +// Using attach is better than rewriting the actual INTERRUPT() function +// because your code will still work and be compatible if the timer library +// is updated. Also, using Attach allows your code and any predefined timer +// code to work together and at the same time. (ie. "attaching" your own +// function to the timer0 overflow doesn't prevent timerPause from working, +// but rather allows you to share the interrupt.) +// +// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); +// timerDetach(TIMER1OVERFLOW_INT) +// +// timerAttach causes the myOverflowFunction() to be attached, and therefore +// execute, whenever an overflow on timer1 occurs. timerDetach removes the +// association and executes no user function when the interrupt occurs. +// myOverflowFunction must be defined with no return value and no arguments: +// +// void myOverflowFunction(void) { ... } + +void timerAttach(u08 interruptNum, void (*userFunc)(void) ); +void timerDetach(u08 interruptNum); + + +// timing commands +// timerPause pauses for the number of milliseconds specified in +void timerPause(unsigned short pause_ms); + +// overflow counters +// to be documented +void timer0ClearOverflowCount(void); +long timer0GetOverflowCount(void); +void timer2ClearOverflowCount(void); +long timer2GetOverflowCount(void); + +// PWM initialization and set commands for timerX (where X is either 1 or 3) +// timerXPWMInit() +// configures the timerX hardware for PWM mode on pins OCXA, OCXB, and OCXC. +// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution +// +// timerXPWMOff() +// turns off all timerX PWM output and set timer mode to normal state +// +// timerXPWMAOn(), timerXPWMBOn(), timerXPWMCOn() +// turn on output of PWM signals to OCXA,B,C pins +// NOTE: Until you define the OCXA,B,C pins as outputs, and run +// this "on" command, no PWM output will be output +// +// timerXPWMAOff(), timerXPWMBOff(), timerXPWMCOff() +// turn off output of PWM signals to OCXA,B,C pins +// +// timerXPWMASet(), timer1PWMBSet(), timerXPWMCSet() +// sets the PWM duty cycle for each channel +// NOTE: should be in the range 0-255 for 8bit PWM +// should be in the range 0-511 for 9bit PWM +// should be in the range 0-1023 for 10bit PWM +// NOTE: the PWM frequency can be controlled in increments by setting the +// prescaler for timer1 + +void timer1PWMInit(u08 bitRes); ///< initialize and set timer1 mode to PWM +void timer1PWMInitICR(u16 topcount);///< initialize and set timer1 mode to PWM with specific top count +void timer1PWMOff(void); ///< turn off all timer1 PWM output and set timer mode to normal +void timer1PWMAOn(void); ///< turn on timer1 Channel A (OC1A) PWM output +void timer1PWMBOn(void); ///< turn on timer1 Channel B (OC1B) PWM output +void timer1PWMCOn(void); ///< turn on timer1 Channel C (OC1C) PWM output +void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output +void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output +void timer1PWMCOff(void); ///< turn off timer1 Channel C (OC1C) PWM output +void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output +void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output +void timer1PWMCSet(u16 pwmDuty); ///< set duty of timer1 Channel C (OC1C) PWM output + +void timer3PWMInit(u08 bitRes); ///< initialize and set timer3 mode to PWM +void timer3PWMInitICR(u16 topcount);///< initialize and set timer3 mode to PWM with specific top count +void timer3PWMOff(void); ///< turn off all timer3 PWM output and set timer mode to normal +void timer3PWMAOn(void); ///< turn on timer3 Channel A (OC3A) PWM output +void timer3PWMBOn(void); ///< turn on timer3 Channel B (OC3B) PWM output +void timer3PWMCOn(void); ///< turn on timer3 Channel C (OC3C) PWM output +void timer3PWMAOff(void); ///< turn off timer3 Channel A (OC3A) PWM output +void timer3PWMBOff(void); ///< turn off timer3 Channel B (OC3B) PWM output +void timer3PWMCOff(void); ///< turn off timer3 Channel C (OC3C) PWM output +void timer3PWMASet(u16 pwmDuty); ///< set duty of timer3 Channel A (OC3A) PWM output +void timer3PWMBSet(u16 pwmDuty); ///< set duty of timer3 Channel B (OC3B) PWM output +void timer3PWMCSet(u16 pwmDuty); ///< set duty of timer3 Channel C (OC3C) PWM output + +//@} + +// Pulse generation commands have been moved to the pulse.c library + +#endif diff --git a/3rd party/Procyuon avrlib/timerx8.c b/3rd party/Procyuon avrlib/timerx8.c new file mode 100644 index 0000000..9c7f60e --- /dev/null +++ b/3rd party/Procyuon avrlib/timerx8.c @@ -0,0 +1,472 @@ +/*! \file timerx8.c \brief Timer function library for ATmegaXX8 Processors. */ +//***************************************************************************** +// +// File Name : 'timerx8.c' +// Title : Timer function library for ATmegaXX8 Processors +// Author : Pascal Stang - Copyright (C) 2000-2005 +// Created : 11/22/2000 +// Revised : 06/15/2005 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include +#include + +#include "global.h" +#include "timerx8.h" + +// Program ROM constants +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + +// Global variables +// time registers +volatile unsigned long TimerPauseReg; +volatile unsigned long Timer0Reg0; +volatile unsigned long Timer2Reg0; + +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + +// delay for a minimum of microseconds +// the time resolution is dependent on the time the loop takes +// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us +void delay_us(unsigned short time_us) +{ + unsigned short delay_loops; + register unsigned short i; + + delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + + // one loop takes 5 cpu cycles + for (i=0; i < delay_loops; i++) {}; +} +/* +void delay_ms(unsigned char time_ms) +{ + unsigned short delay_count = F_CPU / 4000; + + unsigned short cnt; + asm volatile ("\n" + "L_dl1%=:\n\t" + "mov %A0, %A2\n\t" + "mov %B0, %B2\n" + "L_dl2%=:\n\t" + "sbiw %A0, 1\n\t" + "brne L_dl2%=\n\t" + "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + :"r"(time_ms), "r"((unsigned short) (delay_count)) + ); +} +*/ +void timerInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum number of milliseconds + u08 timerThres; + u32 ticRateHz; + u32 pause; + + // capture current pause timer value + timerThres = TCNT0; + // reset pause timer overflow count + TimerPauseReg = 0; + // calculate delay for [pause_ms] milliseconds + // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))) + ticRateHz = F_CPU/timer0GetPrescaler(); + // precision management + // prevent overflow and precision underflow + // -could add more conditions to improve accuracy + if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + pause = (pause_ms*ticRateHz)/1000; + else + pause = pause_ms*(ticRateHz/1000); + + // loop until time expires + while( ((TimerPauseReg<<8) | (TCNT0)) < (pause+timerThres) ) + { + if( TimerPauseReg < (pause>>8)); + { + // save power by idling the processor + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } + } + + /* old inaccurate code, for reference + + // calculate delay for [pause_ms] milliseconds + u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); + u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000; + + TimerPauseReg = 0; + while(TimerPauseReg < pause); + + */ +} + +void timer0ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer0Reg0 = 0; // initialize time registers +} + +long timer0GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer0ClearOverflowCount() command was called) + return Timer0Reg0; +} + +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer2Reg0 = 0; // initialize time registers +} + +long timer2GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer2ClearOverflowCount() command was called) + return Timer2Reg0; +} +#endif + +void timer1PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on OC1A and OC1B pins + + // enable timer1 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + else + { // default 8bit mode + cbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + + // clear output compare value A + OCR1A = 0; + // clear output compare value B + OCR1B = 0; +} + +#ifdef WGM10 +// include support for arbitrary top-count PWM +// on new AVR processors that support it +void timer1PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR1A,WGM10); + sbi(TCCR1A,WGM11); + sbi(TCCR1B,WGM12); + sbi(TCCR1B,WGM13); + + // set top count value + ICR1 = topcount; + + // clear output compare value A + OCR1A = 0; + // clear output compare value B + OCR1B = 0; + +} +#endif + +void timer1PWMOff(void) +{ + // turn off timer1 PWM mode + cbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + // set PWM1A/B (OutputCompare action) to none + timer1PWMAOff(); + timer1PWMBOff(); +} + +void timer1PWMAOn(void) +{ + // turn on channel A (OC1A) PWM output + // set OC1A as non-inverted PWM + sbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOn(void) +{ + // turn on channel B (OC1B) PWM output + // set OC1B as non-inverted PWM + sbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMAOff(void) +{ + // turn off channel A (OC1A) PWM output + // set OC1A (OutputCompare action) to none + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOff(void) +{ + // turn off channel B (OC1B) PWM output + // set OC1B (OutputCompare action) to none + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC1A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A + //outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A + OCR1A = pwmDuty; +} + +void timer1PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC1B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B + //outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B + OCR1B = pwmDuty; +} + +//! Interrupt handler for tcnt0 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) +{ + Timer0Reg0++; // increment low-order counter + + // increment pause counter + TimerPauseReg++; + + // if a user function is defined, execute it too + if(TimerIntFunc[TIMER0OVERFLOW_INT]) + TimerIntFunc[TIMER0OVERFLOW_INT](); +} + +//! Interrupt handler for tcnt1 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OVERFLOW_INT]) + TimerIntFunc[TIMER1OVERFLOW_INT](); +} + +#ifdef TCNT2 // support timer2 only if it exists +//! Interrupt handler for tcnt2 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) +{ + Timer2Reg0++; // increment low-order counter + + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OVERFLOW_INT]) + TimerIntFunc[TIMER2OVERFLOW_INT](); +} +#endif + +#ifdef OCR0 +// include support for Output Compare 0 for new AVR processors that support it +//! Interrupt handler for OutputCompare0 match (OC0) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + TimerIntFunc[TIMER0OUTCOMPARE_INT](); +} +#endif + +//! Interrupt handler for CutputCompare1A match (OC1A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + TimerIntFunc[TIMER1OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare1B match (OC1B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + TimerIntFunc[TIMER1OUTCOMPAREB_INT](); +} + +//! Interrupt handler for InputCapture1 (IC1) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + TimerIntFunc[TIMER1INPUTCAPTURE_INT](); +} + +//! Interrupt handler for OutputCompare2A match (OC2A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} + +//! Interrupt handler for OutputCompare2B match (OC2B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} diff --git a/3rd party/Procyuon avrlib/timerx8.h b/3rd party/Procyuon avrlib/timerx8.h new file mode 100644 index 0000000..d48a5c2 --- /dev/null +++ b/3rd party/Procyuon avrlib/timerx8.h @@ -0,0 +1,314 @@ +/*! \file timerx8.h \brief Timer function library for ATmegaXX8 Processors. */ +//***************************************************************************** +// +// File Name : 'timerx8.h' +// Title : Timer function library for ATmegaXX8 Processors +// Author : Pascal Stang - Copyright (C) 2000-2005 +// Created : 11/22/2000 +// Revised : 06/15/2005 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_avr +/// \defgroup timerx8 Timer Function Library for ATmegaXX8 (timerx8.c) +/// \code #include "timerx8.h" \endcode +/// \par Overview +/// This library provides functions for use with the timers internal +/// to the AVR processors. Functions include initialization, set prescaler, +/// calibrated pause function (in milliseconds), attaching and detaching of +/// user functions to interrupts, overflow counters, PWM. Arbitrary +/// frequency generation has been moved to the Pulse Library. +/// +/// \par About Timers +/// The Atmel AVR-series processors each contain at least one +/// hardware timer/counter. Many of the processors contain 2 or 3 +/// timers. Generally speaking, a timer is a hardware counter inside +/// the processor which counts at a rate related to the main CPU clock +/// frequency. Because the counter value increasing (counting up) at +/// a precise rate, we can use it as a timer to create or measure +/// precise delays, schedule events, or generate signals of a certain +/// frequency or pulse-width. +/// \par +/// As an example, the ATmega163 processor has 3 timer/counters. +/// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. +/// This means that they overflow, or roll over back to zero, at a +/// count value of 256 for 8bits or 65536 for 16bits. A prescaler is +/// avaiable for each timer, and the prescaler allows you to pre-divide +/// the main CPU clock rate down to a slower speed before feeding it to +/// the counting input of a timer. For example, if the CPU clock +/// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, +/// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is +/// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. +/// In fact, when it hits 255, it will overflow and start again at +/// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 +/// times per second. +/// \par +/// Timer0 can be used a number of ways simultaneously. First, the +/// value of the timer can be read by accessing the CPU register \c TCNT0. +/// We could, for example, figure out how long it takes to execute a +/// C command by recording the value of \c TCNT0 before and after +/// execution, then subtract (after-before) = time elapsed. Or we can +/// enable the overflow interrupt which goes off every time T0 +/// overflows and count out longer delays (multiple overflows), or +/// execute a special periodic function at every overflow. +/// \par +/// The other timers (Timer1 and Timer2) offer all the abilities of +/// Timer0 and many more features. Both T1 and T2 can operate as +/// general-purpose timers, but T1 has special hardware allowing it to +/// generate PWM signals, while T2 is specially designed to help count +/// out real time (like hours, minutes, seconds). See the +/// Timer/Counter section of the processor datasheet for more info. +/// +//***************************************************************************** +//@{ + +#ifndef TIMER_H +#define TIMER_H + +#include "global.h" + +// constants/macros/typdefs + +// processor compatibility fixes +#ifdef __AVR_ATmega323__ + // redefinition for the Mega323 + #define CTC1 CTC10 +#endif +#ifndef PWM10 + // mega128 PWM bits + #define PWM10 WGM10 + #define PWM11 WGM11 +#endif + + +// Timer/clock prescaler values and timer overflow rates +// tics = rate at which the timer counts up +// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) +// 16bit [overflow] = rate at which the timer overflows 16bits (65536) +// +// overflows can be used to generate periodic interrupts +// +// for 8MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz +// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz +// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz +// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz +// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 4MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz +// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz +// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz +// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz +// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 3.69MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz +// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz +// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz +// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz +// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 32.768KHz crystal on timer 2 (use for real-time clock) +// 0 = STOP +// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz +// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz +// 3 = CLOCK/32 tics= 1024kHz 8bitoverflow= 4Hz +// 4 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz +// 5 = CLOCK/128 tics= 256Hz 8bitoverflow= 1Hz +// 6 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz +// 7 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz + +#define TIMER_CLK_STOP 0x00 ///< Timer Stopped +#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU +#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 +#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 +#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 +#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 +#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge +#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge +#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask + +#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped +#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU +#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 +#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 +#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 +#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 +#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 +#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 +#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask + +// default prescale settings for the timers +// these settings are applied when you call +// timerInit or any of the timerInit +#define TIMER0PRESCALE TIMER_CLK_DIV8 ///< timer 0 prescaler default +#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default +#define TIMER2PRESCALE TIMERRTC_CLK_DIV64 ///< timer 2 prescaler default + +// interrupt macros for attaching user functions to timer interrupts +// use these with timerAttach( intNum, function ) +#define TIMER0OVERFLOW_INT 0 +#define TIMER1OVERFLOW_INT 1 +#define TIMER1OUTCOMPAREA_INT 2 +#define TIMER1OUTCOMPAREB_INT 3 +#define TIMER1INPUTCAPTURE_INT 4 +#define TIMER2OVERFLOW_INT 5 +#define TIMER2OUTCOMPARE_INT 6 +#ifdef OCR0 // for processors that support output compare on Timer0 +#define TIMER0OUTCOMPARE_INT 7 +#define TIMER_NUM_INTERRUPTS 8 +#else +#define TIMER_NUM_INTERRUPTS 7 +#endif + +// default type of interrupt handler to use for timers +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef TIMER_INTERRUPT_HANDLER +#define TIMER_INTERRUPT_HANDLER SIGNAL +#endif + +// functions +#define delay delay_us +#define delay_ms timerPause +void delay_us(unsigned short time_us); + +//! initializes timing system (all timers) +// runs all timer init functions +// sets all timers to default prescale values #defined in systimer.c +void timerInit(void); + +// default initialization routines for each timer +void timer0Init(void); ///< initialize timer0 +void timer1Init(void); ///< initialize timer1 +#ifdef TCNT2 // support timer2 only if it exists +void timer2Init(void); ///< initialize timer2 +#endif + +// Clock prescaler set/get commands for each timer/counter +// For setting the prescaler, you should use one of the #defines +// above like TIMER_CLK_DIVx, where [x] is the division rate +// you want. +// When getting the current prescaler setting, the return value +// will be the [x] division value currently set. +void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler +u16 timer0GetPrescaler(void); ///< get timer0 prescaler +void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler +u16 timer1GetPrescaler(void); ///< get timer0 prescaler +#ifdef TCNT2 // support timer2 only if it exists +void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler +u16 timer2GetPrescaler(void); ///< get timer2 prescaler +#endif + + +// TimerAttach and Detach commands +// These functions allow the attachment (or detachment) of any user function +// to a timer interrupt. "Attaching" one of your own functions to a timer +// interrupt means that it will be called whenever that interrupt happens. +// Using attach is better than rewriting the actual INTERRUPT() function +// because your code will still work and be compatible if the timer library +// is updated. Also, using Attach allows your code and any predefined timer +// code to work together and at the same time. (ie. "attaching" your own +// function to the timer0 overflow doesn't prevent timerPause from working, +// but rather allows you to share the interrupt.) +// +// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); +// timerDetach(TIMER1OVERFLOW_INT) +// +// timerAttach causes the myOverflowFunction() to be attached, and therefore +// execute, whenever an overflow on timer1 occurs. timerDetach removes the +// association and executes no user function when the interrupt occurs. +// myOverflowFunction must be defined with no return value and no arguments: +// +// void myOverflowFunction(void) { ... } + +//! Attach a user function to a timer interrupt +void timerAttach(u08 interruptNum, void (*userFunc)(void) ); +//! Detach a user function from a timer interrupt +void timerDetach(u08 interruptNum); + + +// timing commands +/// A timer-based delay/pause function +/// @param pause_ms Number of integer milliseconds to wait. +void timerPause(unsigned short pause_ms); + +// overflow counters +void timer0ClearOverflowCount(void); ///< Clear timer0's overflow counter. +long timer0GetOverflowCount(void); ///< read timer0's overflow counter +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void); ///< clear timer2's overflow counter +long timer2GetOverflowCount(void); ///< read timer0's overflow counter +#endif + +/// @defgroup timerpwm Timer PWM Commands +/// @ingroup timer +/// These commands control PWM functionality on timer1 +// PWM initialization and set commands for timer1 +// timer1PWMInit() +// configures the timer1 hardware for PWM mode on pins OC1A and OC1B. +// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution +// +// timer1PWMOff() +// turns off all timer1 PWM output and set timer mode to normal state +// +// timer1PWMAOn() and timer1PWMBOn() +// turn on output of PWM signals to OC1A or OC1B pins +// NOTE: Until you define the OC1A and OC1B pins as outputs, and run +// this "on" command, no PWM output will be output +// +// timer1PWMAOff() and timer1PWMBOff() +// turn off output of PWM signals to OC1A or OC1B pins +// +// timer1PWMASet() and timer1PWMBSet() +// sets the PWM duty cycle for each channel +// NOTE: should be in the range 0-255 for 8bit PWM +// should be in the range 0-511 for 9bit PWM +// should be in the range 0-1023 for 10bit PWM +// NOTE: the PWM frequency can be controlled in increments by setting the +// prescaler for timer1 +//@{ + + +/// Enter standard PWM Mode on timer1. +/// \param bitRes indicates the period/resolution to use for PWM output in timer bits. +/// Must be either 8, 9, or 10 bits corresponding to PWM periods of 256, 512, or 1024 timer tics. +void timer1PWMInit(u08 bitRes); + +/// Enter PWM Mode on timer1 with a specific top-count value. +/// \param topcount indicates the desired PWM period in timer tics. +/// Can be a number between 1 and 65535 (16-bit). +void timer1PWMInitICR(u16 topcount); + +/// Turn off all timer1 PWM output and set timer mode to normal. +void timer1PWMOff(void); + +/// Turn on/off Timer1 PWM outputs. +void timer1PWMAOn(void); ///< Turn on timer1 Channel A (OC1A) PWM output. +void timer1PWMBOn(void); ///< Turn on timer1 Channel B (OC1B) PWM output. +void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output +void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output + +void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output +void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output + +//@} +//@} + +// Pulse generation commands have been moved to the pulse.c library + +#endif diff --git a/3rd party/Procyuon avrlib/tsip.c b/3rd party/Procyuon avrlib/tsip.c new file mode 100644 index 0000000..a654cdd --- /dev/null +++ b/3rd party/Procyuon avrlib/tsip.c @@ -0,0 +1,331 @@ +/*! \file tsip.c \brief TSIP (Trimble Standard Interface Protocol) function library. */ +//***************************************************************************** +// +// File Name : 'tsip.c' +// Title : TSIP (Trimble Standard Interface Protocol) function library +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.08.27 +// Revised : 2003.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "uart2.h" +#include "gps.h" + +#include "tsip.h" + +// Program ROM constants + +// Global variables +extern GpsInfoType GpsInfo; +#define BUFFERSIZE 0x40 +u08 TsipPacket[BUFFERSIZE]; +u08 debug; + +// function pointer to single byte output routine +static void (*TsipTxByteFunc)(unsigned char c); + +void tsipInit(void (*txbytefunc)(unsigned char c)) +{ + // set transmit function + // (this function will be used for all SendPacket commands) + TsipTxByteFunc = txbytefunc; + + // set debug status + debug = 0; + + // compose GPS receiver configuration packet + u08 packet[4]; + packet[0] = BV(POS_LLA); + packet[1] = BV(VEL_ENU); + packet[2] = 0; + packet[3] = 0; + // send configuration + tsipSendPacket(TSIPTYPE_SET_IO_OPTIONS, 4, packet); +} + +void tsipSendPacket(u08 tsipType, u08 dataLength, u08* data) +{ + u08 i; + u08 dataIdx = 0; + + // start of packet + TsipPacket[dataIdx++] = DLE; + // packet type + TsipPacket[dataIdx++] = tsipType; + // add packet data + for(i=0; idatalength > 1) + { + // look for a potential start of TSIP packet + if(bufferGetAtIndex(rxBuffer,0) == DLE) + { + // make sure the next byte is not DLE or ETX + data = bufferGetAtIndex(rxBuffer,1); + if((data != DLE) && (data != ETX)) + { + // found potential start + startFlag = TRUE; + // done looking for start + break; + } + } + else + // not DLE, dump character from buffer + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength)-1; i++) + { + // check for potential end of TSIP packet + if((bufferGetAtIndex(rxBuffer,i) == DLE) && (bufferGetAtIndex(rxBuffer,i+1) == ETX)) + { + // have a packet end + // dump initial DLE + bufferGetFromFront(rxBuffer); + // copy data to TsipPacket + TsipPacketIdx = 0; + for(j=0; j<(i-1); j++) + { + data = bufferGetFromFront(rxBuffer); + if(data == DLE) + { + if(bufferGetAtIndex(rxBuffer,0) == DLE) + { + // found double-DLE escape sequence, skip one of them + bufferGetFromFront(rxBuffer); + j++; + } + } + TsipPacket[TsipPacketIdx++] = data; + } + // dump ending DLE+ETX + bufferGetFromFront(rxBuffer); + bufferGetFromFront(rxBuffer); + + // found a packet + if(debug) + { + rprintf("Rx TSIP packet type: 0x%x len: %d rawlen: %d\r\n", + TsipPacket[0], + TsipPacketIdx, + i); + for(k=0; k +#include + +#include "buffer.h" +#include "uart.h" + +// UART global variables +// flag variables +volatile u08 uartReadyTx; ///< uartReadyTx flag +volatile u08 uartBufferedTx; ///< uartBufferedTx flag +// receive and transmit buffers +cBuffer uartRxBuffer; ///< uart receive buffer +cBuffer uartTxBuffer; ///< uart transmit buffer +unsigned short uartRxOverflow; ///< receive overflow counter + +#ifndef UART_BUFFERS_EXTERNAL_RAM + // using internal ram, + // automatically allocate space in ram for each buffer + static char uartRxData[UART_RX_BUFFER_SIZE]; + static char uartTxData[UART_TX_BUFFER_SIZE]; +#endif + +typedef void (*voidFuncPtru08)(unsigned char); +volatile static voidFuncPtru08 UartRxFunc; + +// enable and initialize the uart +void uartInit(void) +{ + // initialize the buffers + uartInitBuffers(); + // initialize user receive handler + UartRxFunc = 0; + + // enable RxD/TxD and interrupts + outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + + // set default baud rate + uartSetBaudRate(UART_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx = TRUE; + uartBufferedTx = FALSE; + // clear overflow count + uartRxOverflow = 0; + // enable interrupts + sei(); +} + +// create and initialize the uart transmit and receive buffers +void uartInitBuffers(void) +{ + #ifndef UART_BUFFERS_EXTERNAL_RAM + // initialize the UART receive buffer + bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE); + // initialize the UART transmit buffer + bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE); + #else + // initialize the UART receive buffer + bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE); + // initialize the UART transmit buffer + bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE); + #endif +} + +// redirects received data to a user function +void uartSetRxHandler(void (*rx_func)(unsigned char c)) +{ + // set the receive interrupt to run the supplied user function + UartRxFunc = rx_func; +} + +// set the uart baud rate +void uartSetBaudRate(u32 baudrate) +{ + // calculate division factor for requested baud rate, and set it + u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); + outb(UBRRL, bauddiv); + #ifdef UBRRH + outb(UBRRH, bauddiv>>8); + #endif +} + +// returns the receive buffer structure +cBuffer* uartGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartRxBuffer; +} + +// returns the transmit buffer structure +cBuffer* uartGetTxBuffer(void) +{ + // return tx buffer pointer + return &uartTxBuffer; +} + +// transmits a byte over the uart +void uartSendByte(u08 txData) +{ + // wait for the transmitter to be ready + while(!uartReadyTx); + // send byte + outb(UDR, txData); + // set ready state to FALSE + uartReadyTx = FALSE; +} + +// gets a single byte from the uart receive buffer (getchar-style) +int uartGetByte(void) +{ + u08 c; + if(uartReceiveByte(&c)) + return c; + else + return -1; +} + +// gets a byte (if available) from the uart receive buffer +u08 uartReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartRxBuffer.size) + { + // make sure we have data + if(uartRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +// flush all data out of the receive buffer +void uartFlushReceiveBuffer(void) +{ + // flush all data from receive buffer + //bufferFlush(&uartRxBuffer); + // same effect as above + uartRxBuffer.datalength = 0; +} + +// return true if uart receive buffer is empty +u08 uartReceiveBufferIsEmpty(void) +{ + if(uartRxBuffer.datalength == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + +// add byte to end of uart Tx buffer +u08 uartAddToTxBuffer(u08 data) +{ + // add data byte to the end of the tx buffer + return bufferAddToEnd(&uartTxBuffer, data); +} + +// start transmission of the current uart Tx buffer contents +void uartSendTxBuffer(void) +{ + // turn on buffered transmit + uartBufferedTx = TRUE; + // send the first byte to get things going by interrupts + uartSendByte(bufferGetFromFront(&uartTxBuffer)); +} +/* +// transmit nBytes from buffer out the uart +u08 uartSendBuffer(char *buffer, u16 nBytes) +{ + register u08 first; + register u16 i; + + // check if there's space (and that we have any bytes to send at all) + if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes) + { + // grab first character + first = *buffer++; + // copy user buffer to uart transmit buffer + for(i = 0; i < nBytes-1; i++) + { + // put data bytes at end of buffer + bufferAddToEnd(&uartTxBuffer, *buffer++); + } + + // send the first byte to get things going by interrupts + uartBufferedTx = TRUE; + uartSendByte(first); + // return success + return TRUE; + } + else + { + // return failure + return FALSE; + } +} +*/ +// UART Transmit Complete Interrupt Handler +UART_INTERRUPT_HANDLER(SIG_UART_TRANS) +{ + // check if buffered tx is enabled + if(uartBufferedTx) + { + // check if there's data left in the buffer + if(uartTxBuffer.datalength) + { + // send byte from top of buffer + outb(UDR, bufferGetFromFront(&uartTxBuffer)); + } + else + { + // no data left + uartBufferedTx = FALSE; + // return to ready state + uartReadyTx = TRUE; + } + } + else + { + // we're using single-byte tx mode + // indicate transmit complete, back to ready + uartReadyTx = TRUE; + } +} + +// UART Receive Complete Interrupt Handler +UART_INTERRUPT_HANDLER(SIG_UART_RECV) +{ + u08 c; + + // get received char + c = inb(UDR); + + // if there's a user function to handle this receive event + if(UartRxFunc) + { + // call it and pass the received data + UartRxFunc(c); + } + else + { + // otherwise do default processing + // put received char in buffer + // check if there's space + if( !bufferAddToEnd(&uartRxBuffer, c) ) + { + // no space in buffer + // count overflow + uartRxOverflow++; + } + } +} diff --git a/3rd party/Procyuon avrlib/uart.h b/3rd party/Procyuon avrlib/uart.h new file mode 100644 index 0000000..6be57f5 --- /dev/null +++ b/3rd party/Procyuon avrlib/uart.h @@ -0,0 +1,232 @@ +/*! \file uart.h \brief UART driver with buffer support. */ +//***************************************************************************** +// +// File Name : 'uart.h' +// Title : UART driver with buffer support +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 02/01/2004 +// Version : 1.3 +// Target MCU : ATMEL AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +/// \ingroup driver_avr +/// \defgroup uart UART Driver/Function Library (uart.c) +/// \code #include "uart.h" \endcode +/// \par Overview +/// This library provides both buffered and unbuffered transmit and receive +/// functions for the AVR processor UART.  Buffered access means that the +/// UART can transmit and receive data in the "background", while your code +/// continues executing.  Also included are functions to initialize the +/// UART, set the baud rate, flush the buffers, and check buffer status. +/// +/// \note For full text output functionality, you may wish to use the rprintf +/// functions along with this driver. +/// +/// \par About UART operations +/// Most Atmel AVR-series processors contain one or more hardware UARTs +/// (aka, serial ports). UART serial ports can communicate with other +/// serial ports of the same type, like those used on PCs. In general, +/// UARTs are used to communicate with devices that are RS-232 compatible +/// (RS-232 is a certain kind of serial port). +/// \par +/// By far, the most common use for serial communications on AVR processors +/// is for sending information and data to a PC running a terminal program. +/// Here is an exmaple: +/// \code +/// uartInit(); // initialize UART (serial port) +/// uartSetBaudRate(9600); // set UART speed to 9600 baud +/// rprintfInit(uartSendByte); // configure rprintf to use UART for output +/// rprintf("Hello World\r\n"); // send "hello world" message via serial port +/// \endcode +/// +/// \warning The CPU frequency (F_CPU) must be set correctly in \c global.h +/// for the UART library to calculate correct baud rates. Furthermore, +/// certain CPU frequencies will not produce exact baud rates due to +/// integer frequency division round-off. See your AVR processor's +/// datasheet for full details. +// +//***************************************************************************** +//@{ + +#ifndef UART_H +#define UART_H + +#include "global.h" +#include "buffer.h" + +//! Default uart baud rate. +/// This is the default speed after a uartInit() command, +/// and can be changed by using uartSetBaudRate(). +#define UART_DEFAULT_BAUD_RATE 9600 + +// buffer memory allocation defines +// buffer sizes +#ifndef UART_TX_BUFFER_SIZE +//! Number of bytes for uart transmit buffer. +/// Do not change this value in uart.h, but rather override +/// it with the desired value defined in your project's global.h +#define UART_TX_BUFFER_SIZE 0x0040 +#endif +#ifndef UART_RX_BUFFER_SIZE +//! Number of bytes for uart receive buffer. +/// Do not change this value in uart.h, but rather override +/// it with the desired value defined in your project's global.h +#define UART_RX_BUFFER_SIZE 0x0040 +#endif + +// define this key if you wish to use +// external RAM for the UART buffers +//#define UART_BUFFER_EXTERNAL_RAM +#ifdef UART_BUFFER_EXTERNAL_RAM + // absolute address of uart buffers + #define UART_TX_BUFFER_ADDR 0x1000 + #define UART_RX_BUFFER_ADDR 0x1100 +#endif + +//! Type of interrupt handler to use for uart interrupts. +/// Value may be SIGNAL or INTERRUPT. +/// \warning Do not change unless you know what you're doing. +#ifndef UART_INTERRUPT_HANDLER +#define UART_INTERRUPT_HANDLER SIGNAL +#endif + +// compatibility with most newer processors +#ifdef UCSRB + #define UCR UCSRB +#endif +// compatibility with old Mega processors +#if defined(UBRR) && !defined(UBRRL) + #define UBRRL UBRR +#endif +// compatibility with megaXX8 processors +#if defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega644__) + #define UDR UDR0 + #define UCR UCSR0B + #define RXCIE RXCIE0 + #define TXCIE TXCIE0 + #define RXC RXC0 + #define TXC TXC0 + #define RXEN RXEN0 + #define TXEN TXEN0 + #define UBRRL UBRR0L + #define UBRRH UBRR0H + #define SIG_UART_TRANS SIG_USART_TRANS + #define SIG_UART_RECV SIG_USART_RECV + #define SIG_UART_DATA SIG_USART_DATA +#endif +// compatibility with mega169 processors +#if defined(__AVR_ATmega169__) + #define SIG_UART_TRANS SIG_USART_TRANS + #define SIG_UART_RECV SIG_USART_RECV + #define SIG_UART_DATA SIG_USART_DATA +#endif +// compatibility with dual-uart processors +// (if you need to use both uarts, please use the uart2 library) +#if defined(__AVR_ATmega161__) + #define UDR UDR0 + #define UCR UCSR0B + #define UBRRL UBRR0 + #define SIG_UART_TRANS SIG_UART0_TRANS + #define SIG_UART_RECV SIG_UART0_RECV + #define SIG_UART_DATA SIG_UART0_DATA +#endif +#if defined(__AVR_ATmega128__) +#ifdef UART_USE_UART1 + #define UDR UDR1 + #define UCR UCSR1B + #define UBRRL UBRR1L + #define UBRRH UBRR1H + #define SIG_UART_TRANS SIG_UART1_TRANS + #define SIG_UART_RECV SIG_UART1_RECV + #define SIG_UART_DATA SIG_UART1_DATA +#else + #define UDR UDR0 + #define UCR UCSR0B + #define UBRRL UBRR0L + #define UBRRH UBRR0H + #define SIG_UART_TRANS SIG_UART0_TRANS + #define SIG_UART_RECV SIG_UART0_RECV + #define SIG_UART_DATA SIG_UART0_DATA +#endif +#endif + +// functions + +//! Initializes uart. +/// \note After running this init function, the processor +/// I/O pins that used for uart communications (RXD, TXD) +/// are no long available for general purpose I/O. +void uartInit(void); + +//! Initializes transmit and receive buffers. +/// Automatically called from uartInit() +void uartInitBuffers(void); + +//! Redirects received data to a user function. +/// +void uartSetRxHandler(void (*rx_func)(unsigned char c)); + +//! Sets the uart baud rate. +/// Argument should be in bits-per-second, like \c uartSetBaudRate(9600); +void uartSetBaudRate(u32 baudrate); + +//! Returns pointer to the receive buffer structure. +/// +cBuffer* uartGetRxBuffer(void); + +//! Returns pointer to the transmit buffer structure. +/// +cBuffer* uartGetTxBuffer(void); + +//! Sends a single byte over the uart. +/// \note This function waits for the uart to be ready, +/// therefore, consecutive calls to uartSendByte() will +/// go only as fast as the data can be sent over the +/// serial port. +void uartSendByte(u08 data); + +//! Gets a single byte from the uart receive buffer. +/// Returns the byte, or -1 if no byte is available (getchar-style). +int uartGetByte(void); + +//! Gets a single byte from the uart receive buffer. +/// Function returns TRUE if data was available, FALSE if not. +/// Actual data is returned in variable pointed to by "data". +/// Example usage: +/// \code +/// char myReceivedByte; +/// uartReceiveByte( &myReceivedByte ); +/// \endcode +u08 uartReceiveByte(u08* data); + +//! Returns TRUE/FALSE if receive buffer is empty/not-empty. +/// +u08 uartReceiveBufferIsEmpty(void); + +//! Flushes (deletes) all data from receive buffer. +/// +void uartFlushReceiveBuffer(void); + +//! Add byte to end of uart Tx buffer. +/// Returns TRUE if successful, FALSE if failed (no room left in buffer). +u08 uartAddToTxBuffer(u08 data); + +//! Begins transmission of the transmit buffer under interrupt control. +/// +void uartSendTxBuffer(void); + +//! Sends a block of data via the uart using interrupt control. +/// \param buffer pointer to data to be sent +/// \param nBytes length of data (number of bytes to sent) +u08 uartSendBuffer(char *buffer, u16 nBytes); + +#endif +//@} + + diff --git a/3rd party/Procyuon avrlib/uart2.c b/3rd party/Procyuon avrlib/uart2.c new file mode 100644 index 0000000..96ec1cd --- /dev/null +++ b/3rd party/Procyuon avrlib/uart2.c @@ -0,0 +1,379 @@ +/*! \file uart2.c \brief Dual UART driver with buffer support. */ +//***************************************************************************** +// +// File Name : 'uart2.c' +// Title : Dual UART driver with buffer support +// Author : Pascal Stang - Copyright (C) 2000-2004 +// Created : 11/20/2000 +// Revised : 07/04/2004 +// Version : 1.0 +// Target MCU : ATMEL AVR Series +// Editor Tabs : 4 +// +// Description : This is a UART driver for AVR-series processors with two +// hardware UARTs such as the mega161 and mega128 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "buffer.h" +#include "uart2.h" + +// UART global variables +// flag variables +volatile u08 uartReadyTx[2]; +volatile u08 uartBufferedTx[2]; +// receive and transmit buffers +cBuffer uartRxBuffer[2]; +cBuffer uartTxBuffer[2]; +unsigned short uartRxOverflow[2]; +#ifndef UART_BUFFER_EXTERNAL_RAM + // using internal ram, + // automatically allocate space in ram for each buffer + static char uart0RxData[UART0_RX_BUFFER_SIZE]; + static char uart0TxData[UART0_TX_BUFFER_SIZE]; + static char uart1RxData[UART1_RX_BUFFER_SIZE]; + static char uart1TxData[UART1_TX_BUFFER_SIZE]; +#endif + +typedef void (*voidFuncPtru08)(unsigned char); +volatile static voidFuncPtru08 UartRxFunc[2]; + +void uartInit(void) +{ + // initialize both uarts + uart0Init(); + uart1Init(); +} + +void uart0Init(void) +{ + // initialize the buffers + uart0InitBuffers(); + // initialize user receive handlers + UartRxFunc[0] = 0; + // enable RxD/TxD and interrupts + outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + // set default baud rate + uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx[0] = TRUE; + uartBufferedTx[0] = FALSE; + // clear overflow count + uartRxOverflow[0] = 0; + // enable interrupts + sei(); +} + +void uart1Init(void) +{ + // initialize the buffers + uart1InitBuffers(); + // initialize user receive handlers + UartRxFunc[1] = 0; + // enable RxD/TxD and interrupts + outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + // set default baud rate + uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx[1] = TRUE; + uartBufferedTx[1] = FALSE; + // clear overflow count + uartRxOverflow[1] = 0; + // enable interrupts + sei(); +} + +void uart0InitBuffers(void) +{ + #ifndef UART_BUFFER_EXTERNAL_RAM + // initialize the UART0 buffers + bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE); + #else + // initialize the UART0 buffers + bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE); + #endif +} + +void uart1InitBuffers(void) +{ + #ifndef UART_BUFFER_EXTERNAL_RAM + // initialize the UART1 buffers + bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE); + #else + // initialize the UART1 buffers + bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE); + #endif +} + +void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c)) +{ + // make sure the uart number is within bounds + if(nUart < 2) + { + // set the receive interrupt to run the supplied user function + UartRxFunc[nUart] = rx_func; + } +} + +void uartSetBaudRate(u08 nUart, u32 baudrate) +{ + // calculate division factor for requested baud rate, and set it + u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); + if(nUart) + { + outb(UBRR1L, bauddiv); + #ifdef UBRR1H + outb(UBRR1H, bauddiv>>8); + #endif + } + else + { + outb(UBRR0L, bauddiv); + #ifdef UBRR0H + outb(UBRR0H, bauddiv>>8); + #endif + } +} + +cBuffer* uartGetRxBuffer(u08 nUart) +{ + // return rx buffer pointer + return &uartRxBuffer[nUart]; +} + +cBuffer* uartGetTxBuffer(u08 nUart) +{ + // return tx buffer pointer + return &uartTxBuffer[nUart]; +} + +void uartSendByte(u08 nUart, u08 txData) +{ + // wait for the transmitter to be ready +// while(!uartReadyTx[nUart]); + // send byte + if(nUart) + { + while(!(UCSR1A & (1< +#include + +#include "global.h" +#include "timer.h" +#include "uartsw.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u16 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC1A interrupt + cbi(TIMSK, OCIE1A); + // attach TxBit service routine to OC1A + timerAttach(TIMER1OUTCOMPAREA_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // attach RxBit service routine to OC1B + timerAttach(TIMER1OUTCOMPAREB_INT, uartswRxBitService); + // attach RxBit service routine to ICP + timerAttach(TIMER1INPUTCAPTURE_INT, uartswRxBitService); + #ifdef UARTSW_INVERT + // trigger on rising edge + sbi(TCCR1B, ICES1); + #else + // trigger on falling edge + cbi(TCCR1B, ICES1); + #endif + // enable ICP interrupt + sbi(TIMSK, TICIE1); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE1A); + cbi(TIMSK, OCIE1B); + cbi(TIMSK, TICIE1); + // detach the service routines + timerDetach(TIMER1OUTCOMPAREA_INT); + timerDetach(TIMER1OUTCOMPAREB_INT); + timerDetach(TIMER1INPUTCAPTURE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + // set timer prescaler + timer1SetPrescaler(TIMER_CLK_DIV1); + // calculate division factor for requested baud rate, and set it + UartswBaudRateDiv = (u16)((F_CPU+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + #ifdef UARTSW_INVERT + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + + // schedule the next bit + outw(OCR1A, inw(TCNT1) + UartswBaudRateDiv); + // enable OC1A interrupt + sbi(TIMSK, OCIE1A); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + #ifdef UARTSW_INVERT + if( !(UartswTxData & 0x01) ) + #else + if( (UartswTxData & 0x01) ) + #endif + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + } + // schedule the next bit + outw(OCR1A, inw(OCR1A) + UartswBaudRateDiv); + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - OC1B + if(!UartswRxBusy) + { + // this is a start bit + // disable ICP interrupt + cbi(TIMSK, TICIE1); + // schedule data bit sampling 1.5 bit periods from now + outw(OCR1B, inw(TCNT1) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC1B interrupt flag + sbi(TIFR, OCF1B); + // enable OC1B interrupt + sbi(TIMSK, OCIE1B); + // set start bit flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + #ifdef UARTSW_INVERT + if( !(inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // clear ICP interrupt flag + sbi(TIFR, ICF1); + // enable ICP interrupt + sbi(TIMSK, TICIE1); + // clear start bit flag + UartswRxBusy = FALSE; + } + } +} + +/* +void uartswRxBitService(void) +{ + u16 thisBitTime; + u08 bitperiods; + u08 i; + + // bit transition was detected + // record bit's edge time + thisBitTime = inw(ICR1); + + cbi(PORTB, 0); + + if(!UartswRxStartBit) + { + // this is a start bit + // switch to falling-edge trigger + cbi(TCCR1B, ICES1); + // record bit time + UartswRxBitTime = thisBitTime; + // set start bit flag + UartswRxStartBit = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // how many bit periods since last edge? + bitperiods = (thisBitTime - UartswRxBitTime + UartswBaudRateDiv/2)/UartswBaudRateDiv; + // set last edge time + UartswRxBitTime = thisBitTime; + + if(bitperiods > 10) + { + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + else + { + + + if( inb(TCCR1B) & (1< 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + } + } + + // turn off debug LEDs + delay(10); + sbi(PORTB, 0); + sbi(PORTB, 1); +} +*/ diff --git a/3rd party/Procyuon avrlib/uartsw.h b/3rd party/Procyuon avrlib/uartsw.h new file mode 100644 index 0000000..da02bb3 --- /dev/null +++ b/3rd party/Procyuon avrlib/uartsw.h @@ -0,0 +1,78 @@ +/*! \file uartsw.h \brief Software Interrupt-driven UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw.h' +// Title : Software Interrupt-driven UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +/// \ingroup driver_sw +/// \defgroup uartsw Software Interrupt-driven UART Driver (uartsw.c) +/// \code #include "uartsw.h" \endcode +/// \par Overview +/// This uart library emulates the operation of a UART (serial port) using +/// the AVR's hardware timers, I/O pins, and some software. +/// +/// Specifically, this code uses: +/// -Timer 1 Output Compare A for transmit timing +/// -Timer 1 Output Compare B for receive timing +/// -Timer 1 Input Capture for receive triggering +/// +/// The above resources cannot be used for other purposes while this software +/// UART is enabled. The overflow interrupt from Timer1 can still be used for +/// other timing, but the prescaler for Timer1 must not be changed. +/// +/// Serial output from this UART can be routed to any I/O pin. Serial input +/// for this UART must come from the Timer1 Input Capture (IC1) I/O pin. +/// These options should be configured by editing your local copy of +/// "uartswconf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW_H +#define UARTSW_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartswconf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/3rd party/Procyuon avrlib/uartsw2.c b/3rd party/Procyuon avrlib/uartsw2.c new file mode 100644 index 0000000..8bfe15e --- /dev/null +++ b/3rd party/Procyuon avrlib/uartsw2.c @@ -0,0 +1,308 @@ +/*! \file uartsw2.c \brief Software Interrupt-driven UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.c' +// Title : Software Interrupt-driven UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer.h" +#include "uartsw2.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u08 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + // attach TxBit service routine to OC2 + timerAttach(TIMER2OUTCOMPARE_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // attach RxBit service routine to OC0 + timerAttach(TIMER0OUTCOMPARE_INT, uartswRxBitService); + // INT2 trigger on rising/falling edge + #ifdef UARTSW_INVERT + sbi(MCUCSR, ISC2); // rising edge + #else + cbi(MCUCSR, ISC2); // falling edge + #endif + // enable INT2 interrupt + sbi(GICR, INT2); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE2); + cbi(TIMSK, OCIE0); + cbi(GICR, INT2); + // detach the service routines + timerDetach(TIMER2OUTCOMPARE_INT); + timerDetach(TIMER0OUTCOMPARE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + u16 div; + + // set timer prescaler + if( baudrate > (F_CPU/64L*256L) ) + { + // if the requested baud rate is high, + // set timer prescalers to div-by-64 + timer2SetPrescaler(TIMERRTC_CLK_DIV64); + timer0SetPrescaler(TIMER_CLK_DIV64); + div = 64; + } + else + { + // if the requested baud rate is low, + // set timer prescalers to div-by-256 + timer2SetPrescaler(TIMERRTC_CLK_DIV256); + timer0SetPrescaler(TIMER_CLK_DIV256); + div = 256; + } + + // calculate division factor for requested baud rate, and set it + //UartswBaudRateDiv = (u08)(((F_CPU/64L)+(baudrate/2L))/(baudrate*1L)); + //UartswBaudRateDiv = (u08)(((F_CPU/256L)+(baudrate/2L))/(baudrate*1L)); + UartswBaudRateDiv = (u08)(((F_CPU/div)+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + #ifdef UARTSW_INVERT + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + // schedule the next bit + outb(OCR2, inb(TCNT2) + UartswBaudRateDiv); + // enable OC2 interrupt + sbi(TIMSK, OCIE2); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + #ifdef UARTSW_INVERT + if( !(UartswTxData & 0x01) ) + #else + if( (UartswTxData & 0x01) ) + #endif + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + } + // schedule the next bit + outb(OCR2, inb(OCR2) + UartswBaudRateDiv); + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - Timer 0 output compare + if(!UartswRxBusy) + { + // UART was not previously busy, + // this must be is a start bit + + // disable INT2 interrupt + cbi(GICR, INT2); + // schedule data bit sampling 1.5 bit periods from now + outb(OCR0, inb(TCNT0) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC0 interrupt flag + sbi(TIFR, OCF0); + // enable OC0 interrupt + sbi(TIMSK, OCIE0); + // set busy flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + #ifdef UARTSW_INVERT + if( !(inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // clear INT2 interrupt flag + sbi(GIFR, INTF2); + // enable INT interrupt + sbi(GICR, INT2); + // clear busy flag + UartswRxBusy = FALSE; + } + } +} + +SIGNAL(SIG_INTERRUPT2) +{ + // run RxBit service routine + uartswRxBitService(); +} diff --git a/3rd party/Procyuon avrlib/uartsw2.h b/3rd party/Procyuon avrlib/uartsw2.h new file mode 100644 index 0000000..75b58e0 --- /dev/null +++ b/3rd party/Procyuon avrlib/uartsw2.h @@ -0,0 +1,79 @@ +/*! \file uartsw2.h \brief Software Interrupt-driven UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.h' +// Title : Software Interrupt-driven UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +/// \ingroup driver_sw +/// \defgroup uartsw2 Software Interrupt-driven UART Driver (uartsw2.c) +/// \code #include "uartsw2.h" \endcode +/// \par Overview +/// This uart library emulates the operation of a UART (serial port) using +/// the AVR's hardware timers, I/O pins, and some software. +/// +/// Specifically, this code uses: +/// -Timer 2 Output Capture for transmit timing +/// -Timer 0 Output Capture for receive timing +/// -External Interrupt 2 for receive triggering +/// +/// The above resources cannot be used for other purposes while this software +/// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +/// be used for other timing, but the prescalers for these timers must not be +/// changed. +/// +/// Serial output from this UART can be routed to any I/O pin. Serial input +/// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +/// These options should be configured by editing your local copy of +/// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2_H +#define UARTSW2_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartsw2conf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/3rd party/Procyuon avrlib/vt100.c b/3rd party/Procyuon avrlib/vt100.c new file mode 100644 index 0000000..f533d13 --- /dev/null +++ b/3rd party/Procyuon avrlib/vt100.c @@ -0,0 +1,69 @@ +/*! \file vt100.c \brief VT100 terminal function library. */ +//***************************************************************************** +// +// File Name : 'vt100.c' +// Title : VT100 terminal function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "rprintf.h" +#include "vt100.h" + +// Program ROM constants + +// Global variables + +// Functions +void vt100Init(void) +{ + // initializes terminal to "power-on" settings + // ESC c + rprintfProgStrM("\x1B\x63"); +} + +void vt100ClearScreen(void) +{ + // ESC [ 2 J + rprintfProgStrM("\x1B[2J"); +} + +void vt100SetAttr(u08 attr) +{ + // ESC [ Ps m + rprintf("\x1B[%dm",attr); +} + +void vt100SetCursorMode(u08 visible) +{ + if(visible) + // ESC [ ? 25 h + rprintf("\x1B[?25h"); + else + // ESC [ ? 25 l + rprintf("\x1B[?25l"); +} + +void vt100SetCursorPos(u08 line, u08 col) +{ + // ESC [ Pl ; Pc H + rprintf("\x1B[%d;%dH",line,col); +} + diff --git a/3rd party/Procyuon avrlib/vt100.h b/3rd party/Procyuon avrlib/vt100.h new file mode 100644 index 0000000..b05dba5 --- /dev/null +++ b/3rd party/Procyuon avrlib/vt100.h @@ -0,0 +1,72 @@ +/*! \file vt100.h \brief VT100 terminal function library. */ +//***************************************************************************** +// +// File Name : 'vt100.h' +// Title : VT100 terminal function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// \ingroup general +/// \defgroup vt100 VT100 Terminal Function Library (vt100.c) +/// \code #include "vt100.h" \endcode +/// \par Overview +/// This library provides functions for sending VT100 escape codes to +/// control a connected VT100 or ANSI terminal.  Commonly useful functions +/// include setting the cursor position, clearing the screen, setting the text +/// attributes (bold, inverse, blink, etc), and setting the text color.  This +/// library will slowly be expanded to include support for codes as needed and +/// may eventually receive VT100 escape codes too. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef VT100_H +#define VT100_H + +#include "global.h" + +// constants/macros/typdefs +// text attributes +#define VT100_ATTR_OFF 0 +#define VT100_BOLD 1 +#define VT100_USCORE 4 +#define VT100_BLINK 5 +#define VT100_REVERSE 7 +#define VT100_BOLD_OFF 21 +#define VT100_USCORE_OFF 24 +#define VT100_BLINK_OFF 25 +#define VT100_REVERSE_OFF 27 + +// functions + +//! vt100Init() initializes terminal and vt100 library +/// Run this init routine once before using any other vt100 function. +void vt100Init(void); + +//! vt100ClearScreen() clears the terminal screen +void vt100ClearScreen(void); + +//! vt100SetAttr() sets the text attributes like BOLD or REVERSE +/// Text written to the terminal after this function is called will have +/// the desired attribuutes. +void vt100SetAttr(u08 attr); + +//! vt100SetCursorMode() sets the cursor to visible or invisible +void vt100SetCursorMode(u08 visible); + +//! vt100SetCursorPos() sets the cursor position +/// All text which is written to the terminal after a SetCursorPos command +/// will begin at the new location of the cursor. +void vt100SetCursorPos(u08 line, u08 col); + +#endif diff --git a/3rd party/Procyuon avrlib/xmodem.c b/3rd party/Procyuon avrlib/xmodem.c new file mode 100644 index 0000000..a87244d --- /dev/null +++ b/3rd party/Procyuon avrlib/xmodem.c @@ -0,0 +1,247 @@ +/*! \file xmodem.c \brief XModem Transmit/Receive Implementation with CRC and 1K support. */ +//***************************************************************************** +// +// File Name : 'xmodem.c' +// Title : XModem Transmit/Receive Implementation with CRC and 1K support +// Author : Pascal Stang - Copyright (C) 2006 +// Created : 4/22/2006 +// Revised : 7/22/2006 +// Version : 0.1 +// Target MCU : AVR processors +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include "rprintf.h" +#include "timer.h" + +#include "xmodem.h" + +//#define XMODEM_BUFFER_SIZE 128 +#define XMODEM_BUFFER_SIZE 1024 + +// pointers to stream I/O functions +static void (*xmodemOut)(unsigned char c); +static int (*xmodemIn)(void); + +void xmodemInit(void (*sendbyte_func)(unsigned char c), int (*getbyte_func)(void)) +{ + // assign function pointers + xmodemOut = sendbyte_func; + xmodemIn = getbyte_func; +} + +long xmodemReceive( int (*write)(unsigned char* buffer, int size) ) +{ + // create xmodem buffer + // 1024b for Xmodem 1K + // 128 bytes for Xmodem std. + // + 5b header/crc + NULL + unsigned char xmbuf[XMODEM_BUFFER_SIZE+6]; + unsigned char seqnum=1; // xmodem sequence number starts at 1 + unsigned short pktsize=128; // default packet size is 128 bytes + unsigned char response='C'; // solicit a connection with CRC enabled + char retry=XMODEM_RETRY_LIMIT; + unsigned char crcflag=0; + unsigned long totalbytes=0; + int i,c; + + while(retry > 0) + { + // solicit a connection/packet + xmodemOut(response); + // wait for start of packet + if( (c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) >= 0) + { + switch(c) + { + case SOH: + pktsize = 128; + break; + #if(XMODEM_BUFFER_SIZE>=1024) + case STX: + pktsize = 1024; + break; + #endif + case EOT: + xmodemInFlush(); + xmodemOut(ACK); + // completed transmission normally + return totalbytes; + case CAN: + if((c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) == CAN) + { + xmodemInFlush(); + xmodemOut(ACK); + // transaction cancelled by remote node + return XMODEM_ERROR_REMOTECANCEL; + } + default: + break; + } + } + else + { + // timed out, try again + // no need to flush because receive buffer is already empty + retry--; + //response = NAK; + continue; + } + + // check if CRC mode was accepted + if(response == 'C') crcflag = 1; + // got SOH/STX, add it to processing buffer + xmbuf[0] = c; + // try to get rest of packet + for(i=0; i<(pktsize+crcflag+4-1); i++) + { + if((c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) >= 0) + { + xmbuf[1+i] = c; + } + else + { + // timed out, try again + retry--; + xmodemInFlush(); + response = NAK; + break; + } + } + // packet was too small, retry + if(i<(pktsize+crcflag+4-1)) + continue; + + // got whole packet + // check validity of packet + if( (xmbuf[1] == (unsigned char)(~xmbuf[2])) && // sequence number was transmitted w/o error + xmodemCrcCheck(crcflag, &xmbuf[3], pktsize) ) // packet is not corrupt + { + // is this the packet we were waiting for? + if(xmbuf[1] == seqnum) + { + // write/deliver data + write(&xmbuf[3], pktsize); + //spiflashWrite(flashaddr, pktsize, &xmbuf[3]); + totalbytes += pktsize; + // next sequence number + seqnum++; + // reset retries + retry = XMODEM_RETRY_LIMIT; + // reply with ACK + response = ACK; + continue; + } + else if(xmbuf[1] == (unsigned char)(seqnum-1)) + { + // this is a retransmission of the last packet + // ACK and move on + response = ACK; + continue; + } + else + { + // we are completely out of sync + // cancel transmission + xmodemInFlush(); + xmodemOut(CAN); + xmodemOut(CAN); + xmodemOut(CAN); + return XMODEM_ERROR_OUTOFSYNC; + } + } + else + { + // packet was corrupt + // NAK it and try again + retry--; + xmodemInFlush(); + response = NAK; + continue; + } + } + + // exceeded retry count + xmodemInFlush(); + xmodemOut(CAN); + xmodemOut(CAN); + xmodemOut(CAN); + return XMODEM_ERROR_RETRYEXCEED; +} + + +long xmodemTransmit( int (*read)(unsigned char* buffer, int size) ) +{ + // still to be written + return 0; +} + +uint16_t crc_xmodem_update(uint16_t crc, uint8_t data) +{ + int i; + + crc = crc ^ ((uint16_t)data << 8); + for (i=0; i<8; i++) + { + if(crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + + return crc; +} + +int xmodemCrcCheck(int crcflag, const unsigned char *buffer, int size) +{ + // crcflag=0 - do regular checksum + // crcflag=1 - do CRC checksum + + if(crcflag) + { + unsigned short crc=0; + unsigned short pktcrc = (buffer[size]<<8)+buffer[size+1]; + // do CRC checksum + while(size--) + crc = crc_xmodem_update(crc, *buffer++); + // check checksum against packet + if(crc == pktcrc) + return 1; + } + else + { + int i; + unsigned char cksum = 0; + // do regular checksum + for(i=0; i= 0); +} diff --git a/3rd party/Procyuon avrlib/xmodem.h b/3rd party/Procyuon avrlib/xmodem.h new file mode 100644 index 0000000..7d40ff4 --- /dev/null +++ b/3rd party/Procyuon avrlib/xmodem.h @@ -0,0 +1,76 @@ +/*! \file xmodem.h \brief XModem Transmit/Receive Implementation with CRC and 1K support. */ +//***************************************************************************** +// +// File Name : 'xmodem.h' +// Title : XModem Transmit/Receive Implementation with CRC and 1K support +// Author : Pascal Stang - Copyright (C) 2006 +// Created : 4/22/2006 +// Revised : 7/22/2006 +// Version : 0.1 +// Target MCU : AVR processors +// Editor Tabs : 4 +// +/// \ingroup general +/// \defgroup xmodem XModem Transmit/Receive Implementation with CRC and 1K support (xmodem.c) +/// \code #include "xmodem.h" \endcode +/// \par Overview +/// This XModem implementation supports both 128b and 1K packets with or +/// without CRC checking. The xmodem library must be initialized to use +/// a particular I/O stream by passing appropriate getbyte() and sendbyte() +/// functions to xmodemInit(). The xmodem transfer routines also expect +/// function pointers to read and write data blocks on the local system. +/// While this use of function pointers increases code size, it has great +/// adaptability. The generalized read/write data functions mean that it +/// is easy to pipe data to/from any storage device like EEPROMs or flash +/// cards, rather than being limited to just processor RAM. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** +//@{ + +#ifndef XMODEM_H +#define XMODEM_H + +// xmodem control characters +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +// xmodem timeout/retry parameters +#define XMODEM_TIMEOUT_DELAY 1000 +#define XMODEM_RETRY_LIMIT 16 + +// error return codes +#define XMODEM_ERROR_REMOTECANCEL -1 +#define XMODEM_ERROR_OUTOFSYNC -2 +#define XMODEM_ERROR_RETRYEXCEED -3 + + +//! initialize xmodem stream I/O routines +void xmodemInit(void (*sendbyte_func)(unsigned char c), int (*getbyte_func)(void)); + +//! xmodem receive +long xmodemReceive( int (*write)(unsigned char* buffer, int size) ); + +//! xmodem transmit +long xmodemTransmit( int (*read)(unsigned char* buffer, int size) ); + +//! xmodem CRC/checksum error checking +int xmodemCrcCheck(int crcflag, const unsigned char *buffer, int size); + +// extra stream I/O functions +//! get incoming character (wait for timeout) +int xmodemInTime(unsigned short timeout); + +//! flush incoming character stream +void xmodemInFlush(void); + +#endif + +//@} diff --git a/3rd party/tools/Hex2bin/COPYING b/3rd party/tools/Hex2bin/COPYING new file mode 100644 index 0000000..86cf81a --- /dev/null +++ b/3rd party/tools/Hex2bin/COPYING @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/3rd party/tools/Hex2bin/ChangeLog_hex2bin b/3rd party/tools/Hex2bin/ChangeLog_hex2bin new file mode 100644 index 0000000..8e10e71 --- /dev/null +++ b/3rd party/tools/Hex2bin/ChangeLog_hex2bin @@ -0,0 +1,37 @@ +(ISO8859-1 latin 1 encoding) +- hex2bin 1.0.8 - 20100402 - Jacques Pelletier + Fixed a bug with physical address calculation with extended linear address records + ADDRESS_MASK is now calculated from MEMORY_SIZE + +- hex2bin 1.0.7 - 20091212 - Jacques Pelletier + Fixed the crash on 0 byte length data records + +- hex2bin 1.0.6 - 20080103 - Jacques Pelletier + Fixed a bug when generating binary files near the end of the buffer + +- hex2bin 1.0.5 - 20071005 - PaweÅ‚ Grabski - + Improved parsing of options. + +- hex2bin 1.0.4 - 20050126 - Jacques Pelletier - + Corrected the conversion LF -> CR+LF bug + applied patch for correcting the incorrect handling of + extended segment address record + added the Rockwell checksum extensions, and modified them a bit to allow + other types later. + +- hex2bin 1.0.3 - 20040617 - Alf Lacis - + Added pad byte (may not always want FF). + Added 'break;' to remove GNU compiler warning about label at + end of compound statement + Added PROGRAM & VERSION strings. + +- hex2bin 1.0.2 - + Corrected Bug in checksum verification + +- hex2bin 1.0.1 - + Added checking for memory indexing out of bound. + Added segmented and linear extended addressing in hex2bin. + Corrected an error: & were interverted with && (and bitwise, logical and). + +- hex2bin 1.0.0 - + Initial release diff --git a/3rd party/tools/Hex2bin/ChangeLog_mot2bin b/3rd party/tools/Hex2bin/ChangeLog_mot2bin new file mode 100644 index 0000000..dbe591a --- /dev/null +++ b/3rd party/tools/Hex2bin/ChangeLog_mot2bin @@ -0,0 +1,31 @@ +(ISO8859-1 latin 1 encoding) +- mot2bin 1.0.8 - 20100402 - Jacques Pelletier + ADDRESS_MASK is now calculated from MEMORY_SIZE + +- mot2bin 1.0.7 - 20091212 - Jacques Pelletier + Fixed the crash on 0 byte length data records + +- mot2bin 1.0.6 - 20080103 - Jacques Pelletier + Corrected a bug when generating a binary file near the end of the buffer. + +- mot2bin 1.0.5 - 20071005 - PaweÅ‚ Grabski - + Improved parsing of options (same code as hex2bin). + +- mot2bin 1.0.4 - 20050128 - Jacques Pelletier - + Modified the checksum code to be able to generate other checksum types + later (ex. CRC). + +- mot2bin 1.0.3 - 20041026 - Scott A. Mintz - + Modified the MOT2BIN file to compute a checksum over a range using + 8bit, 16bit little endian, or 16bit big endian and optionally forcing + the checksum to a specific value by modifying a memory location. + +- mot2bin 1.0.2 - 20040617 - Alf Lacis - + Added pad byte (may not always want FF). + Added initialisation to Checksum to remove GNU + compiler warning about possible uninitialised usage + Added 2x'break;' to remove GNU compiler warning about label at + end of compound statement + Added PROGRAM & VERSION strings. + +- no previous ChangeLog - diff --git a/3rd party/tools/Hex2bin/Makefile b/3rd party/tools/Hex2bin/Makefile new file mode 100644 index 0000000..fa4026e --- /dev/null +++ b/3rd party/tools/Hex2bin/Makefile @@ -0,0 +1,36 @@ +# Makefile hex2bin +WIN_GCC = i586-mingw32msvc-gcc + +INSTALL_DIR = /usr/local +MAN_DIR = $(INSTALL_DIR)/man/man1 + +all: hex2bin mot2bin hex2bin.1 + +hex2bin.1: hex2bin.pod + pod2man hex2bin.pod > hex2bin.1 + +hex2bin: hex2bin.c + gcc -O2 -Wall -o hex2bin hex2bin.c + +mot2bin: mot2bin.c + gcc -O2 -Wall -o mot2bin mot2bin.c + +windows: + $(WIN_GCC) -O2 -Wall -o Windows/hex2bin.exe hex2bin.c + $(WIN_GCC) -O2 -Wall -o Windows/mot2bin.exe mot2bin.c + +install: + cp hex2bin mot2bin $(INSTALL_DIR)/bin + cp hex2bin.1 $(MAN_DIR) + +clean: + rm core *.o hex2bin mot2bin + +test: + hex2bin nochecksum.hex +# Generates a checksum error, but 'make' will ignore this error ('-' before hex2bin) + -hex2bin -c nochecksum.hex + hex2bin -c linear.hex + hex2bin -c segmented.hex + -hex2bin -c example.hex + mot2bin -c example2.s19 diff --git a/3rd party/tools/Hex2bin/README b/3rd party/tools/Hex2bin/README new file mode 100644 index 0000000..759208e --- /dev/null +++ b/3rd party/tools/Hex2bin/README @@ -0,0 +1,152 @@ +Yet Another Hex to bin converter + +It can handle the extended Intel hex format in segmented and linear address +modes. Records need not be sorted and there can be gaps between records. + +Some hex files are produced by compilers. They generate objects files for each +module in a project, and when the linker generates the final hex file, the +object files are stored within the hex files, but modules can appear not +necessary in order of address. + +How does it work? + +Hex2bin/mot2bin allocates a 4 MBytes buffer and just place the converted bytes in its +buffer. At the end, the buffer is written to disk. Using a buffer eliminates +the need to sort records. + + +1. Compiling on Linux or other unix platforms + + make + + then + + make install + + This will install the program to /usr/local/bin. + +1a. Compiling for Windows on Msys, Cygwin or DOS prompt + + The programs can be compiled as follows: + gcc -O2 -Wall -o hex2bin.exe hex2bin.c + gcc -O2 -Wall -o mot2bin.exe mot2bin.c + +2. Using hex2bin + + hex2bin example.hex + + hex2bin will generate a binary file example.bin starting at the + lowest address in the hex file. + +3. Notes + + If the lowest address isn't 0000, + ex: 0100: (the first record begins with :nn010000xxx ) + + there will be problems when using the binary file to program a EPROM + since the first byte supposed to be at 0100 is stored in the binary file + at 0000. + + you can specify a starting address on the command line: + + hex2bin -s 0000 start_at_0100.hex + + This start address is not the same thing as the start address record in + the hex file. The start address record is used to specify the starting + address for execution of the binary code. + + The bytes will be stored in the binary file with a padding from 0000 + to the lowest address minus 1 (00FF in this case). Padding bytes are all FF by + default so an EPROM programmer can skip these bytes when programming. The padding + value can be changed with the -p option. + + EPROM, EEPROM and Flash memories contain all FF when erased. + + This program does minimal error checking since many hex files are + generated by known good assemblers. + + When the source file name is + for-example.test.hex + the binary created will have the name + for-example.bin + the ".test" part will be dropped. + + Hex2bin/mot2bin assume the source file doesn't contain overlapping records, + if so, overlaps will be silently executed, causing some esoteric bugs in your + application. + + Since the code for testing for overlapping records migh be quite elaborate, + I prefer to leave this as it is for now, to minimize maintenance of the code. + +4. Checksum of source file + + By default, it ignores checksum errors, so that someone can change + by hand some bytes allowing quick and dirty changes. + If you want checksum error reporting, specify the option -c. + + hex2bin -c example.hex + + If there is a checksum error somewhere, the program will continue the + conversion anyway. + + The example file example.hex contains some records with checksum errors. + +5. Checksum inserted inside binary file + + A checksum value can be inserted in the resulting binary file. + + hex2bin -k [0|1|2] -r [start] [end] -f [address] [value] + + -k Select checksum type: + + 0 = 8-bit checksum + 1 = 16-bit checksum, little endian + 2 = 16-bit checskum, big endian + + -r Range to compute checksum over (default is min and max addresses) + + -f Address and value of checksum to force + +6. Motorola S files + + mot2bin example.s19 + + Options for mot2bin are the same as hex2bin. Executing the program + without argument will display available options. Some are specific to + Motorola files. + + This program will handle S19 files generated for Motorola micropro- + cessors. Since I use this program for an EPROM programmer, I will + rarely need to have more than 4M, I limited the source program for + 24 bits or 16 bits address records. + + 32 bits records are now supported, but obviously I can't allocate all + the memory for the binary target. What I did is simply assume that the + binary file will occupy less than 4M. + +8. Goodies + + Description of the file formats is included. + Added examples files for extended addressing. + +9. Error messages + + "0 byte length data record ignored" + + This means that an empty data record was read. Since it's empty, it's simply + ignored and should have no impact on the binary file. + + "Data record skipped at ..." + + This means that the records are falling outside the memory buffer. You may + try to increase the buffer size to 2M or 4M. There is a define at the + beginning of the file: MEMORY_SIZE. + +10. History + + See ChangeLog + +11. Other hex tool + + There is a program that supports more formats and has more features. + See SRecord at http://srecord.sourceforge.net/ diff --git a/3rd party/tools/Hex2bin/doc/S-record.txt b/3rd party/tools/Hex2bin/doc/S-record.txt new file mode 100644 index 0000000..ba4abc1 --- /dev/null +++ b/3rd party/tools/Hex2bin/doc/S-record.txt @@ -0,0 +1,361 @@ +S-Record Format + + A file in Motorola S-record format is an ASCII file. There are three different + formats: + + S19 for 16-bit address + S2 for 24-bit address + S3 for 32-bit address + + + The files consist of optional symbol table information, data specifications + for loading memory, and a terminator record. + + [ $$ {module_record} + symbol records + $$ [ module_record ] + symbol_records + $$] + header_record + data_records + record_count_record + terminator_record + + +Module Record (Optional) + + Each object file contains one record for each module that is a component of it. This + record contains the name of the module. There is one module record for each relocatable + object created by the assembler. The name of the relocatable object module + contained in the record comes from the IDNT directive. For absolute objects created + by the linker, there is one module record for each relocatable object file linked, + plus an additional record whose name comes from the NAME command for the + linker. + + Example: + + $$ MODNAME + + +Symbol Record (Optional) + + As many symbol records as needed can be contained in the object module. Up to 4 + symbols per line can be used, but it is not mandatory that each line contain 4 + symbols. A module can contain only symbol records. + + Example: + + APPLE $00000 LABEL1 $ODOC3 + MEM $OFFFF ZEEK $01947 + + The module name associated with the symbols can be specified in the + module_record preceding the symbol records. + + Example: + + $$MAIN + + Symbols are assumed to be in the module named in the preceding module_record + until another module is specified with another module_record. Symbols defined by + the linker's PUBLIC command appear following the first module record, which + indicates the name of the output object module specified by the linker's NAME + command. + + +***************************************************************************************** + +Header Record (SO) + + Each object module has exactly one header record with the following format: + + S00600004844521B + + Description: + + S0 Identifies the record as a header record + 06 The number of bytes following this one + 0000 The address field, which is ignored + 484452 The string HDR in ASCII + 1B The checksum + + + +***************************************************************************************** + +Data Record (S1) + + A data record specifies data bytes that are to be loaded into memory. Figure 1 + shows the format for such a record. The columns shown in the figure represent half + of a byte (4 bits). + + --------------------------------------------- + | 1 2 3 4 5 6 7 8 9 ... 40 41 42 | + | | + | S ID byte load data...data checksum | + | count address 1 n | + --------------------------------------------- + Figure 1: Data Record Formatter 16-Bit Load Address + + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character identifying the record type. + For data records, this character is 1. + + 3 to 4 Contain the count of the number of bytes following this one + within the record. The count includes the checksum and the + load address bytes but not the byte count itself. + + 5 to 8 Contain the load address. The first data byte is to be loaded + into this address and subsequent bytes into the next sequential + address. Columns 5 and 6 contain the high-order address + byte, and columns 7 and 8 contain the low-order address byte. + + 9 to 40 Contain the specifications for up to 16 bytes of data. + + 41 to 42 Contain a checksum for the record. To calculate this, take the + sum of the values of all bytes from the byte count up to the + last data byte, inclusive, modulo 256. Subtract this result + from 255. + + +***************************************************************************************** + +Data Record (S2) + + + A data record specifies data bytes that are to be loaded into memory. Figure 2 + shows the format for such a record. The columns shown in the figure represent half + of a byte (4 bits). + + + ---------------------------------------------------- + | 1 2 3 4 5 6 7 8 9 10 11 ... 42 43 44 | + | | + | S ID byte load data...data checksum | + | count address 1 n | + ---------------------------------------------------- + Figure 2: Data Record Format for 24-Bit Load Address + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character identifying the record type. + For data records, this character is 2. + + 3 to 4 Contain the count of the number of bytes following this one + within the record. The count includes the checksum and the + load address bytes but not the byte count itself. + + 5 to 10 Contain the load address. The first data byte is to be loaded + into this address and subsequent bytes into the next sequential + address. Columns 5 and 6 contain the high-order address + byte, and columns 9 and 10 contain the low-order address byte. + + 11 to 42 Contain the specifications for up to 16 bytes of data. + + 43 to 44 Contain a checksum for the record. To calculate this, take the + sum of the values of all bytes from the byte count up to the + last data byte, inclusive, modulo 256. Subtract this result + from 255. + + +***************************************************************************************** + +Data Record (S3) + + + A data record specifies data bytes that are to be loaded into memory. Figure 3 + shows the format for such a record. The columns shown in the figure represent half + of a byte (4 bits). + + ---------------------------------------------------------- + | 1 2 3 4 5 6 7 8 9 10 11 12 13 ... 44 45 46 | + | | + | S ID byte load data...data checksum | + | count address 1 n | + ---------------------------------------------------------- + Figure 3: Data Record Format for 32-Bit Load Address + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character identifying the record type. + For data records, this digit is 3 for 32-bit addresses. + + 3 to 4 Contain the count of the number of bytes following this one + within the record. The count includes the checksum and the + load address bytes but not the byte count itself. + + 5 to 12 Contain the load address. The first data byte is to be loaded + into this address and subsequent bytes into the next sequential + address. Columns 5 and 6 contain the high-order address + byte, and columns 11 and 12 contain the low-order address byte. + + 13 to 44 Contain the specifications for up to 15 bytes of data. + + 45 to 46 Contain a checksum for the record. To calculate this, take the + sum of the values of all bytes from the byte count up to the + last data byte, inclusive, modulo 256. Subtract this result + from 255. + + +***************************************************************************************** + +Record Count Record (S5) + + + The record count record verifies the number of data records preceding it. Figure 4 + shows the format for such a record. The columns shown in the figure represent half + of a byte (4 bits). + + -------------------------------------- + | 1 2 3 4 5 6 7 8 9 10 | + | | + | S ID byte # of data checksum | + | count records | + -------------------------------------- + Figure 4: Record Count Record Format + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character 5, which indicates a record + count record. + + 3 to 4 Contain the byte count, ASCII string 03. + + 5 to 8 Contain the number of data records in this file. The high- + order byte is in columns 5 and 6. + + 9 to 10 Contain the checksum for the record. + + Example: + + S503010DEE + + The example above shows a record count record indicating a total of 269 records + (0x010D) and a checksum of 0xEE. + + + +***************************************************************************************** + +Terminator Record for 32-bit address (S7) + + A terminator record specifies the end of the data records. Figure 5 shows the + format for such a record. The columns shown in the figure represent half of a byte + (4 bits). + + ------------------------------------- + | 1 2 3 4 5...12 13 14 | + | | + | S ID byte load checksum | + | count address | + ------------------------------------- + Figure5: Terminator Record Format for 32-Bit Load Address + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character 7, which indicates a 32-bit + load address. + + 3 to 4 Contain the byte count, ASCII string 04. + + 5 to 12 Contain the load address that is either set to zero or to the + starting address specified in the END directive or START + command (there are no data bytes). + + 13 to 14 Contain the checksum for the record. + +***************************************************************************************** + +Terminator Record for 24-bit address (S8) + + + A terminator record specifies the end of the data records. Figure 6 shows the + format for such a record. The columns shown in the figure represent half of a byte + (4 bits). + + ---------------------------------------- + | 1 2 3 4 5 6 7 8 9 10 11 12 | + | | + | S ID byte load checksum | + | count address | + ---------------------------------------- + Figure 6: Terminator Record Format for 24-Bit Load Address + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character 8, which indicates a 24-bit + load address. + + 3 to 4 Contain the byte count, ASCII string 04. + + 5 to 10 Contain the load address, which is either set to zero or to the + starting address specified in the END directive or START + command. There are no data bytes. + + 11 to 12 Contain the checksum for the record. + + Example: + + S804000AF0001 + + The previous example shows a terminator record with a 24-bit load address of + 0x000AF0 and a checksum of 0x01. + + +***************************************************************************************** + +Terminator Record for 16-bit address (S9) + + + A terminator record specifies the end of the data records. Figure 7 shows the + format for such a record. The columns shown in the figure represent half of a byte + (4 bits). + + ------------------------------------- + | 1 2 3 4 5 6 7 8 9 10 | + | | + | S ID byte load checksum | + | count address | + ------------------------------------- + Figure 7: Terminator Record Format for 16-Bit Load Address + + + Column Description + + 1 Contains the ASCII character S, which indicates the start of + a record in Motorola S-record format. + + 2 Contains the ASCII character 9, which indicates a 16-bit + load address. + + 3 to 4 Contain the byte count, ASCII string 04. + + 5 to 8 Contain the load address, which is either set to zero or to the + starting address specified in the END directive or START + command (there are no data bytes). + + 9 to 10 Contain the checksum for the record. + + + +***************************************************************************************** + hagen.v.tronje@on-line.de diff --git a/3rd party/tools/Hex2bin/doc/formats.txt b/3rd party/tools/Hex2bin/doc/formats.txt new file mode 100644 index 0000000..25e5e37 --- /dev/null +++ b/3rd party/tools/Hex2bin/doc/formats.txt @@ -0,0 +1,72 @@ +Hex formats + +Intel +===== + +Hexadecimal values are always in uppercase. Each line is a record. +The sum of all the bytes in each record should be 00 (modulo 256). + +Record types: + +00: data records +01: end-of-file record +02: extended address record + +Data record +----------- + + :0D011C0000000000C3E0FF0000000000C30F + +: 0D 011C 00 00000000C3E0FF0000000000C3 0F +| | | | -------------+------------ | +| | | | | +--- Checksum +| | | | +------------------ Data bytes +| | | +--------------------------------- Record type +| | +------------------------------------- Address +| +----------------------------------------- Number of data bytes ++-------------------------------------------- Start of record + + +End of file record +------------------ + + :00000001FE + +: 00 0000 01 FE +| | | | | +| | | | +--- Checksum +| | | +------ Record type +| | +---------- Address +| +-------------- Number of data bytes ++----------------- Start of record + + + +Extended address record +----------------------- + + :02010002E0001B + +: 02 0100 02 E000 1B +| | | | | | +| | | | | +--- Checksum +| | | | +-------- Segment address +| | | +----------- Record type +| | +--------------- Address +| +------------------- Number of data bytes ++---------------------- Start of record + +Following data records will start at E000:0100 or E0100 + + + + + + + + + + + + + diff --git a/3rd party/tools/Hex2bin/doc/intelhex.spc b/3rd party/tools/Hex2bin/doc/intelhex.spc new file mode 100644 index 0000000..946d586 --- /dev/null +++ b/3rd party/tools/Hex2bin/doc/intelhex.spc @@ -0,0 +1,409 @@ + +====================================================================== + +Intel +Hexadecimal Object File +Format Specification +Revision A, 1/6/88 + + + +DISCLAIMER + +Intel makes no representation or warranties with respect to the contents +hereof and specifically disclaims any implied warranties of +merchantability or fitness for any particular purpose. Further, Intel +reserves the right to revise this publication from time to time in the +content hereof without obligation of Intel to notify any person of such +revision or changes. The publication of this specification should not +be construed as a commitment on Intel's part to implement any product. + + +1. Introduction +This document describes the hexadecimal object file format for the Intel +8- bit, 16-bit, and 32-bit microprocessors. The hexadecimal format is +suitable as input to PROM programmers or hardware emulators. +Hexadecimal object file format is a way of representing an absolute +binary object file in ASCII. Because the file is in ASCII instead of +binary, it is possible to store the file is non-binary medium such as +paper-tape, punch cards, etc.; and the file can also be displayed on CRT +terminals, line printers, etc.. The 8-bit hexadecimal object file +format allows for the placement of code and data within the 16-bit +linear address space of the Intel 8-bit processors. The 16-bit +hexadecimal format allows for the 20-bit segmented address space of the +Intel 16-bit processors. And the 32-bit format allows for the 32-bit +linear address space of the Intel 32-bit processors. +The hexadecimal representation of binary is coded in ASCII alphanumeric +characters. For example, the 8-bit binary value 0011-1111 is 3F in +hexadecimal. To code this in ASCII, one 8-bit byte containing the ASCII +code for the character '3' (0011-0011 or 033H) and one 8-bit byte +containing the ASCII code for the character 'F' (0100-0110 or 046H) are +required. For each byte value, the high-order hexadecimal digit is +always the first digit of the pair of hexadecimal digits. This +representation (ASCII hexadecimal) requires twice as ma ny bytes as the +binary representation. +A hexadecimal object file is blocked into records, each of which +contains the record type, length, memory load address and checksum in +addition to the data. There are currently six (6) different types of +records that are defined, not all combinations of these records are +meaningful, however. The records are: + +Data Record (8-, 16-, or 32-bit formats) +End of File Record (8-, 16-, or 32-bit formats) +Extended Segment Address Record (16- or 32-bit formats) +Start Segment Address Record (16- or 32-bit formats) +Extended Linear Address Record (32-bit format only) +Start Linear Address Record (32-bit format only) + + +2. General Record Format +| RECORD | LOAD | | | INFO | | +| MARK | RECLEN | OFFSET | RECTYP | or | CHKSUM | +| ':' | | | | DATA | | + 1-byte 1-byte 2-bytes 1-byte n-bytes 1-byte + +Each record begins with a RECORD MARK field containing 03AH, the ASCII +code for the colon (':') character. +Each record has a RECLEN field which specifies the number of bytes of +information or data which follows the RECTYP field of the record. Note +that one data byte is represented by two ASCII characters. The maximum +value of the RECLEN field is hexadecimal 'FF' or 255. +Each record has a LOAD OFFSET field which specifies the 16-bit starting +load offset of the data bytes, therefore this field is only used for +Data Records. In other records where this field is not used, it should +be coded as four ASCII zero characters ('0000' or 030303030H). +Each record has a RECTYP field which specifies the record type of this +record. The RECTYP field is used to interpret the remaining information +within the record. The encoding for all the current record types are: + +'00' Data Record +'01' End of File Record +'02' Extended Segment Address Record +'03' Start Segment Address Record +'04' Extended Linear Address Record +'05' Start Linear Address Record + +Each record has a variable length INFO/DATA field, it consists of zero +or more bytes encoded as pairs of hexadecimal digits. The +interpretation of this field depends on the RECTYP field. +Each record ends with a CHKSUM field that contains the ASCII hexadecimal +representation of the two's complement of the 8-bit bytes that result +from converting each pair of ASCII hexadecimal digits to one byte of +binary, from and including the RECLEN field to and including the last +byte of the INFO/DATA field. Therefore, the sum of all the ASCII pairs +in a record after converting to binary, from the RECLEN field to and +including the CHKSUM field, is zero. + + +3. Extended Linear Address Record (32-bit format only) +| RECORD | LOAD | | | | | +| MARK | RECLEN | OFFSET | RECTYP | ULBA | CHKSUM | +| ':' | '02' | '0000' | '04' | | | + 1-byte 1-byte 2-bytes 1-byte 2-bytes 1-byte + +The 32-bit Extended Linear Address Record is used to specify bits 16-31 +of the Linear Base Address (LBA), where bits 0-15 of the LBA are zero. +Bits 16-31 of the LBA are referred to as the Upper Linear Base Address +(ULBA). The absolute memory address of a content byte in a subsequent +Data Record is obtained by adding the LBA to an offset calculated by +adding the LOAD OFFSET field of the containing Data Record to the index +of the byte in the Data Record (0, 1, 2, ... n). This offset addition +is done modulo 4G (i.e., 32-bits), ignoring any carry, so that offset +wrap-around loading (from OFFFFFFFFH to OOOOOOOOOH) results in wrapping +around from the end to the beginning of the 4G linear address defined by +the LBA. The linear address at which a particular byte is loaded is +calculated as: +(LBA + DRLO + DRI) MOD 4G +where: +DRLO is the LOAD OFFSET field of a Data Record. +DRI is the data byte index within the Data Record. + +When an Extended Linear Address Record defines the value of LBA, it may +appear anywhere within a 32-bit hexadecimal object file. This value +remains in effect until another Extended Linear Address Record is +encountered. The LBA defaults to zero until an Extended Linear Address +Record is encountered. +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII colon +(':') character. + +RECLEN +The field contains 03032H, the hexadecimal encoding of the ASCII +characters '02', which is the length, in bytes, of the ULBA data +information within this record. + +LOAD OFFSET +This field contains 030303030H, the hexadecimal encoding of the ASCII +characters '0000', since this field is not used for this record. + +RECTYP +This field contains 03034H, the hexadecimal encoding of the ASCII +character '04', which specifies the record type to be an Extended Linear +Address Record. + +ULBA +This field contains four ASCII hexadecimal digits that specify the +16-bit Upper Linear Base Address value. The high-order byte is the +10th/llth character pair of the record. The low-order byte is the +12th/13th character pair of the record. + +CHKSUM +This field contains the check sum on the RECLEN, LOAD OFFSET, RECTYP, +and ULBA fields. + + +4. Extended Segment Address Record (16- or 32-bit formats) +| RECORD | LOAD | | | | | +| MARK | RECLEN | OFFSET | RECTYP | USBA | CHKSUM | +| ':' | '02' | '0000' | '02' | | | + 1-byte 1-byte 2-bytes 1-byte 2-bytes 1-byte + +The 16-bit Extended Segment Address Record is used to specify bits 4-19 +of the Segment Base Address (SBA), where bits 0-3 of the SBA are zero. +Bits 4-19 of the SBA are referred to as the Upper Segment Base Address +(USBA). The absolute memory address of a content byte in a subsequent +Data Record is obtained by adding the SBA to an offset calculated by +adding the LOAD OFFSET field of the containing Data Record to the index +of the byte in the Data Record (0, 1, 2, ... n). This offset addition +is done modulo 64K (i.e., 16-bits), ignoring any carry, so that offset +wraparound loading (from OFFFFH to OOOOOH) results in wrapping around +from the end to the beginning of the 64K segment defined by the SBA. +The address at which a particular byte is loaded is calculated as: + + SBA + ([DRLO + DRI] MOD 64K) + +where: + DRLO is the LOAD OFFSET field of a Data Record. + DRI is the data byte index within the Data Record. + +When an Extended Segment Address Record defines the value of SBA, it +may appear anywhere within a 16-bit hexadecimal object file. This +value remains in effect until another Extended Segment Address +Record is encountered. The SBA defaults to zero until an Extended +Segment Address Record is encountered. + +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII +colon (':') character. + +RECLEN +The field contains 03032H, the hexadecimal encoding of the ASCII +characters '02', which is the length, in bytes, of the USBA data +information within this record. + +LOAD OFFSET +This field contains 030303030H, the hexadecimal encoding of the +ASCII characters '0000', since this field is not used for this +record. + +RECTYP +This field contains 03032H, the hexadecimal encoding of the ASCII +character '02', which specifies the record type to be an Extended +Segment Address Record. + +USBA +This field contains four ASCII hexadecimal digits that specify the +16-bit Upper Segment Base Address value. The high-order byte is the +10th/1lth character pair of the record. The low-order byte is the +12th/13th character pair of the record. + +CHKSUM +This field contains the check sum on the RECLEN, LOAD OFFSET, +RECTYP, and USBA fields. + +5. Data Record (8-, 16-, or 32-bit formats) + +| RECORD | LOAD | | | | | +| MARK | RECLEN | OFFSET | RECTYP | DATA | CHKSUM | +| ':' | | | '00' | | | + 1-byte 1-byte 2-bytes 1-byte n-bytes 1-byte + + +The Data Record provides a set of hexadecimal digits that represent +the ASCII code for data bytes that make up a portion of a memory +image. The method for calculating the absolute address (linear in +the 8-bit and 32-bit case and segmented in the 16-bit case) for each +byte of data is described in the discussions of the Extended Linear +Address Record and the Extended Segment Address Record. + +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII +colon (':') character. + +RECLEN +The field contains two ASCII hexadecimal digits that specify the +number of data bytes in the record. The maximum value is 'FF' or +04646H (255 decimal). + +LOAD OFFSET +This field contains four ASCII hexadecimal digits representing the +offset from the LBA (see Extended Linear Address Record) or SBA (see +Extended Segment Address Record) defining the address which the +first byte of the data is to be placed. + +RECTYP +This field contains 03030H, the hexadecimal encoding of the ASCII +character '00', which specifies the record type to be a Data Record. + +DATA +This field contains pairs of ASCII hexadecimal digits, one pair for +each data byte. + +CHKSUM +This field contains the check sum on the RECLEN, LOAD OFFSET, +RECTYP, and DATA fields. + + +6. Start Linear Address Record (32-bit format only) + +| RECORD | LOAD | | | | | +| MARK | RECLEN | OFFSET | RECTYP | EIP | CHKSUM | +| ':' | '04' | '0000' | '05' | | | + 1-byte 1-byte 2-bytes 1-byte 4-bytes 1-byte + + +The Start Linear Address Record is used to specify the execution +start address for the object file. The value given is the 32-bit +linear address for the EIP register. Note that this record only +specifies the code address within the 32-bit linear address space of +the 80386. If the code is to start execution in the real mode of +the 80386, then the Start Segment Address Record should be used +instead, since that record specifies both the CS and IP register +contents necessary for real mode. + +The Start Linear Address Record can appear anywhere in a 32-bit +hexadecimal object file. If such a record is not present in a +hexadecimal object file, a loader is free to assign a default start +address. + +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII +colon (':') character. + +RECLEN +The field contains 03034H, the hexadecimal encoding of the ASCII +characters '04', which is the length, in bytes, of the EIP register +content within this record. + +LOAD OFFSET +This field contains 030303030H, the hexadecimal encoding of the +ASCII characters '0000', since this field is not used for this +record. + +RECTYP +This field contains 03035H, the hexadecimal encoding of the ASCII +character '05', which specifies the record type to be a Start Linear +Address Record. + +EIP +This field contains eight ASCII hexadecimal digits that specify the +32-bit EIP register contents. The high-order byte is the 10th/1lth +character pair. + +CHKSUM +This field contains the check sum on the RECLEN, LOAD OFFSET, +RECTYP, and EIP fields. + + +7. Start Segment Address Record (16- or 32-bit formats) + +| RECORD | LOAD | | | | | +| MARK | RECLEN | OFFSET | RECTYP | CS/IP | CHKSUM | +| ':' | '04' | '0000' | '03' | | | + 1-byte 1-byte 2-bytes 1-byte 4-bytes 1-byte + + +The Start Segment Address Record is used to specify the execution +start address for the object file. The value given is the 20-bit +segment address for the CS and IP registers. Note that this record +only specifies the code address within the 20-bit segmented address +space of the 8086/80186. + +The Start Segment Address Record can appear anywhere in a 16-bit +hexadecimal object file. If such a record is not present in a +hexadecimal object file, a loader is free to assign a default start +address. + +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII +colon (':') character. + +RECLEN +The field contains 03034H, the hexadecimal encoding of the ASCII +characters '04', which is the length, in bytes, of the CS/IP +register contents within this record. + +LOAD OFFSET +This field contains 030303030H, the hexadecimal encoding of the +ASCII characters '0000', since this field is not used for this +record. + +RECTYP +This field contains 03033H, the hexadecimal encoding of the ASCII +character '03', which specifies the record type to be a Start +Segment Address Record. + +CS/IP +This field contains eight ASCII hexadecimal digits that specify the +16-bit CS register and 16-bit IP register contents. The high-order +byte of the CS register content is the 10th/llth character pair, the +low-order byte is the 12th/13th character pair of the record. The +high-order byte of the IP register content is the 14th/15th +character pair, the low-order byte is the 16th/17th character pair +of the record. + +CHKSUM +This field contains the check sum on the RECLEN, LOAD OFFSET, +RECTYP, and CS/IP fields. + + + +8. End of File Record (8-, 16-, or 32-bit formats) + +| RECORD | LOAD | | | | +| MARK | RECLEN | OFFSET | RECTYP | CHKSUM | +| ':' | '00' | '0000' | '01' | | + 1-byte 1-byte 2-bytes 1-byte 1-byte + +The End of File Record specifies the end of the hexadecimal object +file. + +The contents of the individual fields within the record are: + +RECORD MARK +This field contains 03AH, the hexadecimal encoding of the ASCII +colon (':') character. + +RECLEN +The field contains 03030H, the hexadecimal encoding of the ASCII +characters '00'. Since this record does not contain any INFO/DATA +bytes, the length is zero. + +LOAD OFFSET +This field contains 030303030H, the hexadecimal encoding of the +ASCII characters '0000', since this field is not used for this +record. + +RECTYP +This field contains 03031H, the hexadecimal encoding of the ASCII +character '01', which specifies the record type to be an End of File +Record. + +CHKSUM +This field contains the check sum an the RECLEN, LOAD OFFSET, and +RECTYP fields. Since all the fields are static, the check sum can +also be calculated statically, and the value is 04646H, the +hexadecimal encoding of the ASCII characters 'FF'. + +======================================================================== +END diff --git a/3rd party/tools/Hex2bin/doc/srec.txt b/3rd party/tools/Hex2bin/doc/srec.txt new file mode 100644 index 0000000..818e4af --- /dev/null +++ b/3rd party/tools/Hex2bin/doc/srec.txt @@ -0,0 +1,447 @@ +S-Records + + + -S-Record Format- + + Chaplin@keinstr.uucp (Roger Chaplin) reposted an article written + by mcdchg!motmpl!ron (Ron Widell) that explained how Motorola + S-Records are formatted. This comes from a unix man page. No + mention of which version of Unix is specified. This section + of the FAQ is a bit long. An anonymous ftp archive is currently + being sought. When one is found, the section will be placed in + the archive. + + + SREC(4) UNIX 5.0 (03/21/84) SREC(4) + + + An S-record file consists of a sequence of specially formatted + ASCII character strings. An S-record will be less than or equal to + 78 bytes in length. + + The order of S-records within a file is of no significance and no + particular order may be assumed. + + The general format of an S-record follow: + + +------------------//-------------------//-----------------------+ + | type | count | address | data | checksum | + +------------------//-------------------//-----------------------+ + + type A char-2- field. These characters describe the + type of record (S0, S1, S2, S3, S5, S7, S8, or + S9). + count A char-2- field. These characters when paired and + interpreted as a hexadecimal value, display the + count of remaining character pairs in the record. + + address A char-4,6, or 8- field. These characters grouped + and interpreted as a hexadecimal value, display + the address at which the data field is to be + loaded into memory. The length of the field + depends on the number of bytes necessary to hold + the address. A 2-byte address uses 4 characters, + a 3-byte address uses 6 characters, and a 4-byte + address uses 8 characters. + data A char -0-64- field. These characters when paired + and interpreted as hexadecimal values represent + the memory loadable data or descriptive + information. + + checksum A char-2- field. These characters when paired and + interpreted as a hexadecimal value display the + least significant byte of the ones complement of + the sum of the byte values represented by the + pairs of characters making up the count, the + address, and the data fields. + + Each record is terminated with a line feed. If any + additional or different record terminator(s) or delay + characters are needed during transmission to the target + system it is the responsibility of the transmitting program + to provide them. + + S0 Record The type of record is 'S0' (0x5330). The address + + + field is unused and will be filled with zeros + (0x0000). The header information within the data + field is divided into the following subfields. + + mname is char-20- and is the + module name. + ver is char-2- and is the + version number. + + rev is char-2- and is the + revision number. + description is char-0-36- and is a + text comment. + + Each of the subfields is composed of ASCII bytes + whose associated characters, when paired, + represent one byte hexadecimal values in the case + of the version and revision numbers, or represent + the hexadecimal values of the ASCII characters + comprising the module name and description. + + S1 Record The type of record field is 'S1' (0x5331). The + address field is interpreted as a 2-byte address. + The data field is composed of memory loadable + data. + S2 Record The type of record field is 'S2' (0x5332). The + address field is interpreted as a 3-byte address. + The data field is composed of memory loadable + data. + + S3 Record The type of record field is 'S3' (0x5333). The + address field is interpreted as a 4-byte address. + The data field is composed of memory loadable + data. + S5 Record The type of record field is 'S5' (0x5335). The + address field is interpreted as a 2-byte value + and contains the count of S1, S2, and S3 records + previously transmitted. There is no data field. + + S7 Record The type of record field is 'S7' (0x5337). The + address field contains the starting execution + address and is interpreted as 4-byte address. + There is no data field. + S8 Record The type of record field is 'S8' (0x5338). The + address field contains the starting execution + address and is interpreted as 3-byte address. + There is no data field. + + S9 Record The type of record field is 'S9' (0x5339). The + address field contains the starting execution + address and is interpreted as 2-byte address. + There is no data field. + + EXAMPLE + + Shown below is a typical S-record format file. + + S00600004844521B + S1130000285F245F2212226A000424290008237C2A + S11300100002000800082629001853812341001813 + S113002041E900084E42234300182342000824A952 + S107003000144ED492 + S5030004F8 + S9030000FC + + The file consists of one S0 record, four S1 records, one S5 + record and an S9 record. + + The S0 record is comprised as follows: + + S0 S-record type S0, indicating it is a header + record. + 06 Hexadecimal 06 (decimal 6), indicating that six + character pairs (or ASCII bytes) follow. + + 00 00 Four character 2-byte address field, zeroes in + this example. + 48 ASCII H, D, and R - "HDR". + + 1B The checksum. + + The first S1 record is comprised as follows: + S1 S-record type S1, indicating it is a data record + to be loaded at a 2-byte address. + + 13 Hexadecimal 13 (decimal 19), indicating that + nineteen character pairs, representing a 2 byte + address, 16 bytes of binary data, and a 1 byte + checksum, follow. + 00 00 Four character 2-byte address field; hexidecimal + address 0x0000, where the data which follows is to + be loaded. + + 28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen + character pairs representing the actual binary + data. + 2A The checksum. + + The second and third S1 records each contain 0x13 (19) + character pairs and are ended with checksums of 13 and 52, + respectively. The fourth S1 record contains 07 character + pairs and has a checksum of 92. + + The S5 record is comprised as follows: + + S5 S-record type S5, indicating it is a count record + indicating the number of S1 records. + + + + 03 Hexadecimal 03 (decimal 3), indicating that three + character pairs follow. + + 00 04 Hexadecimal 0004 (decimal 4), indicating that + there are four data records previous to this + record. + F8 The checksum. + + The S9 record is comprised as follows: + + S9 S-record type S9, indicating it is a termination + record. + 03 Hexadecimal 03 (decimal 3), indicating that three + character pairs follow. + + 00 00 The address field, hexadecimal 0 (decimal 0) + indicating the starting execution address. + FC The checksum. + + + -Intel Hex ASCII Format- + + Intel HEX-ASCII format takes the form: + + +----------------------------------- Start Character + | + | +-------------------------------- Byte Count + | | (# of data bytes) + | | + | | +-------------------------- Address of first data. + | | | + | | | +-------------------- Record Type (00 data, + | | | | 01 end of record) + | | | | + | | | | +------------ Data Bytes + | | | | | + | | | | | +---- Checksum + | | | | | | + | / \ / \ / \ / \ / \ + : B C A A A A T T H H ... H H C C + + An examples: + + :10000000DB00E60F5F1600211100197ED300C3004C + :1000100000000101030307070F0F1F1F3F3F7F7FF2 + :01002000FFE0 + :00000001FF + + This information comes from _Microprocessors and Programmed + Logic_, Second Edition, Kenneth L. Short, 1987, Prentice-Hall, + ISBN 0-13-580606-2. + + Provisions have been made for data spaces larger than 64 kBytes. + The above reference does not discuss them. I suspect there is + a start of segment type record, but I do not know how it is + implemented. + +---------------------------------------------------------------------------- + +/* This file contains source code to read a Motorola S-record file into +** a memory image. The size of the file cannot exceed BUFSIZE of data. +** The image is then written to disk either as binary data starting at +** address 0 with no data gaps, or as a C array of unsigned longs. +** Input lines must be no longer than MAXLINE. No check is made! +** +** Author: Eric McRae, Electro-Logic Machines, Inc. +** Date: Copyright 1994 +** +** This source code is made available to the public "as is". No +** warranty is given or implied for it's proper operation. This source +** code may be used in whole or in part as long as this copyright is +** included. +*/ +#include +#include +#include + +/* Comment the following line for non PC applications */ +#define PCDOS + +/* Uncomment the following line if you want a binary output instead of +** a structure +*/ +/* #define BINARY */ + +#ifdef PCDOS /* Intel x86 architecture */ +#define BUFSIZE 49152 /* 48K to avoid segment hopping */ +#else /* Any reasonable (non-segmented) arch... */ +#define BUFSIZE 65536 /* As big as you want */ +#endif + +#define MAXLINE 256 /* Length of longest input line + 1 */ +/* Globals */ +FILE *infilePH, *outfilePH; /* Handles for input and output files */ +unsigned char *bufAC, /* Allocated image buffer */ + *highestPC = NULL; /* Highest buffer address written */ + +/* Change this string to reflect the name of the output array */ +char headerAC[] = "unsigned long sRec[] =\n{\n"; + +/* Predeclarations */ +int parsebufN( char * ); /* Does the actual parsing */ + +void main(int argc, const char * argv[]) +{ + int c, /* Temp char storage */ + resN; /* result status */ + char *lbufPC, lbufAC[MAXLINE]; + int linectrN = 0; /* Used to correlate parse fail to input line */ + +#ifndef BINARY + int i; + unsigned long *codePL; + unsigned char *codePC; +#endif + + /* Check the argument count */ + if( argc != 3 ) /* If didn't specify input and output files */ + { + printf("Usage: %s: infile outfile\n", argv[0] ); + exit(1); + } + + /* OK, let's open some files */ + if( ( infilePH = fopen( argv[1], "r" ) )== NULL ) + { + printf("%s: Couldn't open input file %s\n", argv[0], argv[1] ); + exit(2); + } + + if( ( outfilePH = fopen( argv[2], "w" ) ) == NULL ) + { + printf("%s: Couldn't open output file %s\n", argv[0], argv[3] ); + exit(3); + } + + /* OK, get a buffer and clear it. */ + if( (bufAC = calloc( (size_t)BUFSIZE, (size_t)1 )) == NULL ) + { + printf("%s: Couldn't malloc memory for buffer\n", argv[0] ); + exit(4); + } + + lbufPC = lbufAC; /* Point at beginning of line buffer */ + while( c = fgetc( infilePH )) + { + if( (c == '\n') || (c == EOF) ) /* If found end of line or file */ + { /* Parse the Line */ + if( ( c == EOF ) && ( ferror( infilePH ) ) ) + { + printf("%s: Error reading input file\n", argv[0] ); + exit(5); + } + else + { /* OK, have a complete line in buffer */ + linectrN++; /* Increment line counter */ + if( lbufPC == lbufAC ) + break; /* ignore blank lines */ + *lbufPC = 0; /* Terminate the line string */ + if( resN = parsebufN( lbufAC ) ) /* Parse data record to mem */ + { + printf("%s: Error reading input file at line %d, return code = %d\n", + argv[0], linectrN, resN ); + exit( resN ); + } + lbufPC = lbufAC; /* Repoint line buffer pointer */ + } /* End of have a complete line */ + } + else + *lbufPC++ = c; /* Place char into line buffer */ + } + + /* At this point, the input file has been emptied. Now dispose of the + ** output data according to compilation mode. + */ + +#ifdef BINARY + + /* Write the buffer back to disk as a binary image */ + resN = fwrite( bufAC, 1, (size_t)((highestPC - bufAC) + 1), outfilePH ); + if( resN != (int)( (highestPC - bufAC) + 1) ) + { + printf("%s: Error writing output file\n", argv[0] ); + exit( 6 ); + } + +#else + /* Produce a file that can be included in a C program. Data is read + ** from buffer as bytes to avoid portability/endian problems with + ** this program. + */ + /* Output header first, then 1 long per line */ + fwrite( (void *)headerAC, 1, (size_t)(sizeof( headerAC )-1), outfilePH ); + + codePL = (unsigned long *)bufAC; + for( i = (highestPC - bufAC + 1) / 4; i; i-- ) /* for each long */ + { + codePC = (unsigned char *)codePL++; + sprintf(lbufAC, "0x%02x%02x%02x%02x%s", + *codePC, *(codePC + 1), *(codePC + 2), *(codePC + 3), + i == 1 ? "\n" : ",\n" ); /* No comma after final long */ + fwrite( lbufAC, 1, (size_t)(strlen( lbufAC )), outfilePH ); + } + /* OK, data has been written out, close end of array */ + fwrite( "};\n", 1, (size_t)3, outfilePH ); +#endif +} + +/* Function: parsebufV +** Parses an S-record in the buffer and writes it into the buffer +** if it is has a valid checksum. +** +** Args: pointer to character buffer for null terminated line +** Returns: int result code: 0 = success, else failure +*/ +int parsebufN( char *lbufPC ) +{ + unsigned long addrL; + unsigned char cksmB, /* checksum of addr, count, & data length */ + *bufPC; /* Pointer into memory array */ + int i, countN, /* Number of bytes represented in record */ + oheadN, /* Number of overhead (addr + chksum) bytes */ + tvalN; /* Temp for check checksum */ + + switch( *(lbufPC+1) ) /* examine 2nd character on the line */ + { + case '1': /* 16 bit address field */ + if( sscanf(lbufPC, "S1%2x%4lx", &countN, &addrL ) != 2 ) + return( 10 ); /* Flag error in S1 record */ + oheadN = 3; /* 2 address + 1 checksum */ + break; + + case '2': /* 24 bit address field */ + if( sscanf(lbufPC, "S2%2x%6lx", &countN, &addrL ) != 2 ) + return( 11 ); /* Flag error in S2 record */ + oheadN = 4; /* 3 address + 1 checksum */ + break; + + case '3': /* 32 bit address field */ + if( sscanf(lbufPC, "S3%2x%8lx", &countN, &addrL ) != 2 ) + return( 12 ); /* Flag error in S3 record */ + oheadN = 5; /* 4 address + 1 checksum */ + break; + + default: /* ignore all but S1,2,3 records. */ + return( 0 ); + } + + if( addrL > BUFSIZE ) return( 13 ); /* if address exceeds buffer size */ + bufPC = bufAC + addrL; /* otherwise, point to right spot in buffer */ + + /* OK now see if checksum is OK, while reading data to buffer */ + cksmB = 0; + countN++; /* Bump counter to read final checksum too */ + for( i = 1; i <= countN; i++ ) + { + sscanf( lbufPC + i*2, "%2x", &tvalN ); /* Scan a 2 hex digit byte */ + cksmB += (unsigned char)tvalN; + if( ( i > oheadN ) && ( i < countN ) ) /* If scanned a data byte */ + *bufPC++ = (unsigned char) tvalN; /* write it to the buffer */ + } + if( cksmB += 1 ) return( 14 ); /* flag checksum error */ + + if( (bufPC - 1) > highestPC ) + highestPC = bufPC - 1; /* track highest address loaded */ + + return( 0 ); /* Successful return */ +} + + + diff --git a/3rd party/tools/Hex2bin/example.bin b/3rd party/tools/Hex2bin/example.bin new file mode 100644 index 0000000..faafcaf Binary files /dev/null and b/3rd party/tools/Hex2bin/example.bin differ diff --git a/3rd party/tools/Hex2bin/example2.bin b/3rd party/tools/Hex2bin/example2.bin new file mode 100644 index 0000000..faafcaf Binary files /dev/null and b/3rd party/tools/Hex2bin/example2.bin differ diff --git a/3rd party/tools/Hex2bin/example2.s19 b/3rd party/tools/Hex2bin/example2.s19 new file mode 100644 index 0000000..33900b3 --- /dev/null +++ b/3rd party/tools/Hex2bin/example2.s19 @@ -0,0 +1,14 @@ +S0220000687474703A2F2F737265636F72642E736F75726365666F7267652E6E65742F1D +S1230100C397000A060D0500C3D4FF0000000000C3D8FF0000000000C3DCFF0000000000B3 +S1230120C3E0FF0000000000C3E4FF0000000000C3E8FF0000000000C3ECFF00000000001B +S1230140F1ED4100F1ED4100F1ED4100F1ED4100F1ED4100F1ED4100F1ED4100F1ED4100A3 +S1230160C9000000C9000000C9000000C9000000C9000000C3910000C338000007360410EE +S11B0180040002030215FF4D696E692076332E3100CDF703C33C073191 +S123021E7BB22007210000545D37C94D7C2100000610B7CB1117CB15CB14E5ED523F380191 +S123023EE3333310EEEBCB11691767B7C9B7ED52E07CCB1FEE40378FC9D3070707E603C697 +S123025E044FED69ED61C979C6044F0F0FE6C0D307ED68ED60C97DCD79027CF5DB02E60A1E +S121027E28FAF1D303C9DB02CB4728FADB03C9CD84026FCD840267C9CD840277230BB7 +S1230D520E0DCD630C3E44C37902E521F50BCD7D0CE1C9E521FA0BCD7D0CE1C9E521FE0B46 +S1110D72CD7D0CE1C9E521020CCD7D0CE1C95B +S503000BF1 +S9030000FC diff --git a/3rd party/tools/Hex2bin/hex2bin b/3rd party/tools/Hex2bin/hex2bin new file mode 100755 index 0000000..e9ecc3a Binary files /dev/null and b/3rd party/tools/Hex2bin/hex2bin differ diff --git a/3rd party/tools/Hex2bin/hex2bin-1.0.8.lsm b/3rd party/tools/Hex2bin/hex2bin-1.0.8.lsm new file mode 100644 index 0000000..c6561bc --- /dev/null +++ b/3rd party/tools/Hex2bin/hex2bin-1.0.8.lsm @@ -0,0 +1,30 @@ +Begin4 +Title: Intel/Motorola Hex file format to binary converter. +Version: 1.0.8 +Entered-date: April 2, 2010 +Description: This is a utility to convert file generated by many assemblers to binary files. + Written in ANSI-C from scratch, it can be easily ported to + other platforms(DOS, etc.) + It supports holes in data, unsorted records and the + Intel extended hex format. + Sources and sample results are included. + Also, a source for converting Motorola hex files + + Supports segmented and linear address (hex2bin) + and also 24 bit and 32 bit addresses (mot2bin) + possibility to change the padding byte + possibility to insert a checksum in the binary file + windows executable version included. +Keywords: extended Motorola Intel hex binary format converter +Author: jpelletier@ieee.org (Jacques Pelletier) +Maintained-by: jpelletier@ieee.org (Jacques Pelletier) +Primary-site: http://sourceforge.net/projects/hex2bin/ + 59 kB Hex2bin-1.0.8.tar.gz + 1.2 kB Hex2bin-1.0.8.lsm +Alternate-site: http://ibiblio.org /pub/linux/devel/lang/assemblers/ +Original-site: +Platforms: Any platform that uses an ANSI-C compiler. +Copying-policy: GPL +End + + diff --git a/3rd party/tools/Hex2bin/hex2bin.1 b/3rd party/tools/Hex2bin/hex2bin.1 new file mode 100644 index 0000000..cc69a35 --- /dev/null +++ b/3rd party/tools/Hex2bin/hex2bin.1 @@ -0,0 +1,225 @@ +.\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.07) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.ie \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.el \{\ +. de IX +.. +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "HEX2BIN 1" +.TH HEX2BIN 1 "2010-04-02" "perl v5.10.0" "User Contributed Perl Documentation" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +hex2bin/mot2bin \e\- converts Intel/Motorola hex files into binary +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +hex2bin [\-s address] [\-e extension] [\-c] [\-p pad byte] [\-k checksum type] + [\-r start end] [\-f address [value]] file +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBHex2bin\fR +is a program that converts an Intel hex format into binary. +It can handle the extended Intel hex format. Both the segmented +and linear address records are supported. +Records need not be sorted and there can be gaps between records. +Records are assumed to be non-overlapping. +Padding bytes may be specified and a checksum may be inserted in the +binary file. +.PP +\&\fBMot2bin\fR +does the same with Motorola hex files. It has the same features and command line +options. 24 bit and 32 bit records are supported. +.SH "OPTIONS" +.IX Header "OPTIONS" +\&\fB\-s [address]\fR +.PP +Normally, hex2bin will generate a binary file starting at the lowest address in the hex file. +If the lowest address isn't 0000, ex: 0100, the first byte that should be at 0100 +will be stored at address 0000 in the binary file. This may cause problems when using the +binary file to program an \s-1EPROM\s0. +If you can't specify the starting address (or offset) to your \s-1EPROM\s0 programmer, you can specify +a starting address on the command line: +.PP +\&\fBEx.: hex2bin \-s 0000 start_at_0100.hex\fR +.PP +The bytes will be stored in the binary file with a padding from 0000 to the +lowest addess (00FF in this case). Padding bytes are all \s-1FF\s0 by default so an \s-1EPROM\s0 +programmer can skip these bytes when programming. The padding value can be changed +with the \-p option. +.PP +\&\fB\-e [extension]\fR +.PP +By default, the output file will have an extension \fBfilename.bin\fR. +Another extension may be specified with this command: +.PP +\&\fBEx.: hex2bin \-e com example.hex\fR +.PP +The output file will be example.com +.PP +\&\fB\-c\fR +.PP +Enables checksum verification. +.PP +By default, it ignores checksum errors in the hex file, so that someone can change +by hand some bytes with a text editor, allowing quick fixes without recompiling a source +code all over again. This is useful when tweaking constants directly in the code or +something similar. If you want checksum error reporting, specify the option \-c. +.PP +\&\fBEx.: hex2bin \-c example.hex\fR +.PP +If there is a checksum error somewhere, the program will continue the +conversion anyway. +.PP +\&\fB\-p [pad_byte]\fR +.PP +Pads unused locations with the specified byte. +.PP +By default, this byte is \s-1FF\s0, which is the unprogrammed value for most EPROM/EEPROM/Flash. +.PP +\&\fBEx.: hex2bin \-p 3E example.hex\fR +.PP +\&\fB\-k [0|1|2]\fR +.PP +In many cases, someone needs to insert a checksum in the binary file. For example, +a boot rom is programmed with a checksum which is verified at power-up. This checksum +is not the same as the one above for the hex file. This feature uses also options +\&\fB\-r\fR and \fB\-f\fR described below. +.PP +Select the checksum type to insert into the binary file + 0 : 8\-bit + 1 : 16\-bit little endian + 2 : 16\-bit big endian +.PP +\&\fB\-r [start] [end]\fR +.PP +Range to compute binary checksum over (default is min and max addresses) +.PP +\&\fB\-f [address] [value]\fR +.PP +Address and value of checksum to insert (force) in the binary file +.SH "NOTES" +.IX Header "NOTES" +This program does minimal error checking since many hex files are +generated by known good assemblers. +.SH "AUTHOR Jacques Pelletier (jpelletier@ieee.org) \- version 1.0.8" +.IX Header "AUTHOR Jacques Pelletier (jpelletier@ieee.org) - version 1.0.8" diff --git a/3rd party/tools/Hex2bin/hex2bin.c b/3rd party/tools/Hex2bin/hex2bin.c new file mode 100644 index 0000000..e3f924d --- /dev/null +++ b/3rd party/tools/Hex2bin/hex2bin.c @@ -0,0 +1,631 @@ +/* + hex2bin converts an Intel hex file to binary. + Copyright (C) 1998,1999 Jacques Pelletier + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +20040617 Alf Lacis: Added pad byte (may not always want FF). + Added 'break;' to remove GNU compiler warning about label at + end of compound statement + Added PROGRAM & VERSION strings. + +20071005 PG: Improvements on options parsing +20091212 JP: Corrected crash on 0 byte length data records +20100402 JP: Corrected bug on physical address calculation for extended + linear address record. + ADDRESS_MASK is now calculated from MEMORY_SIZE +*/ + +#define PROGRAM "hex2bin" +#define VERSION "1.0.8" + +#include +#include +#include +#include + +/* size in bytes */ +#define MEMORY_SIZE 4096*1024 + +/* This mask is for mapping the target binary inside the +binary buffer. If for example, we are generating a binary +file with records starting at FFF00000, the bytes will be +stored at the beginning of the memory buffer. */ +#define ADDRESS_MASK (MEMORY_SIZE-1) + +/* We use buffer to speed disk access. */ +#ifdef USE_FILE_BUFFERS + #define BUFFSZ 4096 +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* FIXME how to get it from the system/OS? */ +#define MAX_FILE_NAME_SIZE 81 + +#ifdef DOS + #define MAX_EXTENSION_SIZE 4 +#else + #define MAX_EXTENSION_SIZE 16 +#endif + +/* The data records can contain 255 bytes: this means 512 characters. */ +#define MAX_LINE_SIZE 1024 + +#define NO_ADDRESS_TYPE_SELECTED 0 +#define LINEAR_ADDRESS 1 +#define SEGMENTED_ADDRESS 2 +#ifdef __linux__ + /* We don't accept an option beginning with a '/' because it could be a file name. */ + #define _COND_(x) (*(x) == '-') +#else + #define _COND_(x) ((*(x) == '-') || (*(x) == '/')) +#endif + +typedef char filetype[MAX_FILE_NAME_SIZE]; +typedef int boolean; +typedef unsigned char byte; +typedef unsigned short word; + +filetype Filename; /* string for opening files */ +char Extension[MAX_EXTENSION_SIZE]; /* filename extension for output files */ + +FILE *Filin, /* input files */ +*Filout; /* output files */ + +#ifdef USE_FILE_BUFFERS +char *FilinBuf, /* text buffer for file input */ +*FiloutBuf; /* text buffer for file output */ +#endif + +int PadByte = 0xFF; + +void usage(void); +void *NoFailMalloc (size_t size); +void NoFailOpenInputFile (char *Flnm); +void NoFailOpenOutputFile (char *Flnm); +void PutExtension(char *Flnm, char *Extension); + +void usage(void) +{ + fprintf (stderr, + "\n" + "usage: "PROGRAM" [OPTIONS] filename\n" + "Options:\n" + " -s [address] Starting address in hex\n" + " -e [ext] Output filename extension\n" + " -c Enable checksum verification\n" + " -p [value] Pad-byte value in hex (default==%x)\n\n" + " -k [0|1|2] Select checksum type\n" + " 0 = 8-bit,\n" + " 1 = 16-bit little endian,\n" + " 2 = 16-bit big endian\n" + " -r [start] [end] Range to compute checksum over (default is min and max addresses)\n" + " -f [address] [value] Address and value of checksum to force\n\n", PadByte); + exit(1); +} /* procedure USAGE */ + +void *NoFailMalloc (size_t size) +{ + void *result; + + if ((result = malloc (size)) == NULL) + { + fprintf (stderr,"Can't allocate memory.\n"); + exit(1); + } + return (result); +} + +/* Open the input file, with error checking */ +void NoFailOpenInputFile (char *Flnm) +{ + while ((Filin = fopen(Flnm,"r")) == NULL) + { + fprintf (stderr,"Input file %s cannot be opened. Enter new filename: ",Flnm); + fgets (Flnm,MAX_FILE_NAME_SIZE,stdin); + if (Flnm[0] == '\0') exit(1); + } + +#ifdef USE_FILE_BUFFERS + FilinBuf = (char *) NoFailMalloc (BUFFSZ); + setvbuf(Filin, FilinBuf, _IOFBF, BUFFSZ); +#endif +} /* procedure OPENFILIN */ + +/* Open the output file, with error checking */ +void NoFailOpenOutputFile (char *Flnm) +{ + while ((Filout = fopen(Flnm,"wb")) == NULL) + { + /* Failure to open the output file may be + simply due to an insufficiant permission setting. */ + + fprintf(stderr,"Output file %s cannot be opened. Enter new file name: ", Flnm); + fgets(Flnm,MAX_FILE_NAME_SIZE,stdin); + if (Flnm[0] == '\0') exit(1); + } +#ifdef USE_FILE_BUFFERS + FiloutBuf = (char *) NoFailMalloc (BUFFSZ); + setvbuf(Filout, FiloutBuf, _IOFBF, BUFFSZ); +#endif + +} /* procedure OPENFILOUT */ + +/* Adds an extension to a file name */ +void PutExtension(char *Flnm, char *Extension) +{ + char *Period; /* location of period in file name */ + boolean Samename; + + /* This assumes DOS like file names */ + /* Don't use strchr(): consider the following filename: + ../my.dir/file.hex + */ + if ((Period = strrchr(Flnm,'.')) != NULL) + *(Period) = '\0'; + + Samename = FALSE; + if (strcmp(Extension, Period+1)== 0) + Samename = TRUE; + + strcat(Flnm,"."); + strcat(Flnm, Extension); + if (Samename) + { + fprintf (stderr,"Input and output filenames (%s) are the same.", Flnm); + exit(1); + } +} + +int main (int argc, char *argv[]) +{ + /* line inputted from file */ + char Line[MAX_LINE_SIZE]; + + /* flag that a file was read */ + boolean Fileread; + boolean Enable_Checksum_Error = FALSE; + boolean Status_Checksum_Error = FALSE; + + /* cmd-line parameter # */ + char *c,*p; + + unsigned int Param; + unsigned int i; + + /* Application specific */ + + unsigned int Nb_Bytes; + unsigned int First_Word, Address, Segment, Upper_Address; + unsigned int Lowest_Address, Highest_Address, Starting_Address; + unsigned int Phys_Addr, Type; + unsigned int temp; + + /* We will assume that when one type of addressing is selected, it will be valid for all the + current file. Records for the other type will be ignored. */ + unsigned int Seg_Lin_Select = NO_ADDRESS_TYPE_SELECTED; + + boolean Starting_Address_Setted = FALSE; + + int temp2; + + byte Data_Str[MAX_LINE_SIZE]; + byte Checksum = 0; // 20040617+ Added initialisation to remove GNU compiler warning about possible uninitialised usage + +#define CKS_8 0 +#define CKS_16LE 1 +#define CKS_16BE 2 + + unsigned short int wCKS; + unsigned short int w; + unsigned int Cks_Type = CKS_8; + unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; + boolean Cks_range_set = FALSE; + boolean Cks_Addr_set = FALSE; + + /* This will hold binary codes translated from hex file. */ + byte *Memory_Block; + + fprintf (stdout,PROGRAM" v"VERSION", Copyright (C) 1998 Jacques Pelletier\n" + "checksum extensions Copyright (C) 2004 Rockwell Automation\n" + "improved P.G. 2007\n\n"); + + if (argc == 1) + usage(); + + strcpy(Extension, "bin"); /* default is for binary file extension */ + + /* read file */ + Param = 1; + + for (Param = 1; Param < argc; Param++) + { + c = p = argv[Param]; +//#ifdef __linux__ + /* We don't accept an option beginning with a '/' because it could be a file name. */ +// if(*c == '-') +//#else +// if((*c == '-') || (*c == '/')) +//#endif + if ( _COND_(c) ) { + p = c + 2; + /* Parameter may follow immediately after option */ + /* Skips after parameter to next option */ + if (*p == '\0') + p = argv[Param + 1]; + if ( !_COND_(p) ) + Param++; + + switch(tolower (*(++c))) + { + case 'e': + /* Last parameter was -E, so this parameter is the filename extension. */ + if (strlen(p) > MAX_EXTENSION_SIZE) + usage(); + + /* Check to see if the user put a period in the filename extension */ + if (strchr(p, '.') == NULL) + strcpy(Extension, p); + else + strcpy(Extension, p+1); + break; + + case 'c': + Enable_Checksum_Error = TRUE; + break; + case 's': + sscanf(p,"%x",&Starting_Address); + Starting_Address_Setted = TRUE; + break; + case 'p': + sscanf(p,"%x",&PadByte); + break; + case 'h': + usage(); + break; + /* New Checksum parameters */ + case 'k': + sscanf(p,"%x",&Cks_Type); + if (Cks_Type != CKS_8 && + Cks_Type != CKS_16LE && + Cks_Type != CKS_16BE ) + usage(); + break; + case 'r': + sscanf(p,"%x",&Cks_Start); + p = argv[ ++Param ]; + if ( _COND_(p) ) break; + sscanf(p,"%x",&Cks_End ); + Cks_range_set = TRUE; + break; + case 'f': + sscanf(p,"%x",&Cks_Addr); + p = argv[ ++Param ]; + if ( _COND_(p) ) break; + sscanf( p, "%x",&Cks_Value ); + Cks_Addr_set = TRUE; + break; + default: + usage(); + } /* switch */ + } else + break; + /* if option */ + + } /* for Param */ + + /* when user enters input file name */ + + /* Assume last parameter is filename */ + strcpy(Filename,argv[argc -1]); + + /* Just a normal file name */ + NoFailOpenInputFile (Filename); + PutExtension(Filename, Extension); + NoFailOpenOutputFile(Filename); + Fileread = TRUE; + + /* allocate a buffer */ + Memory_Block = (byte *) NoFailMalloc(MEMORY_SIZE); + + /* For EPROM or FLASH memory types, fill unused bytes with FF */ + memset (Memory_Block,PadByte,MEMORY_SIZE); + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Segment = 0; + Upper_Address = 0; + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + /* Now read the file & process the lines. */ + do /* repeat until EOF(Filin) */ + { + /* Read a line from input file. */ + fgets(Line,MAX_LINE_SIZE,Filin); + + /* Remove carriage return/line feed at the end of line. */ + i = strlen(Line)-1; + + if (Line[i] == '\n') Line[i] = '\0'; + + /* Scan the first two bytes and nb of bytes. + The two bytes are read in First_Word since its use depend on the + record type: if it's an extended address record or a data record. + */ + sscanf (Line, ":%2x%4x%2x%s",&Nb_Bytes,&First_Word,&Type,Data_Str); +// fprintf(stderr,"Read: %2x %4x %2x %s\n",Nb_Bytes, First_Word, Type, Data_Str); + + Checksum = Nb_Bytes + (First_Word >> 8) + (First_Word & 0xFF) + Type; + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (Type) + { + /* Data record */ + case 0: + if (Nb_Bytes == 0) + { + fprintf(stderr,"0 byte length Data record ignored\n"); + break; + } + + Address = First_Word; + + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + Phys_Addr = (Segment << 4) + Address; + else + /* LINEAR_ADDRESS or NO_ADDRESS_TYPE_SELECTED + Upper_Address = 0 as specified in the Intel spec. until an extended address + record is read. */ + Phys_Addr = ((Upper_Address << 16) + Address) & ADDRESS_MASK; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + /* Bytes are written in the Memory block even if checksum is wrong. */ + i = Nb_Bytes; + + do + { + sscanf (p, "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + } + while (--i != 0); + + /* Read the Checksum value. */ + sscanf (p, "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (Checksum + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + { + Status_Checksum_Error = TRUE; + } + } + else + { + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + fprintf(stderr,"Data record skipped at %4X:%4X\n",Segment,Address); + else + fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + + break; + + /* End of file record */ + case 1: + /* Simply ignore checksum errors in this line. */ + break; + + /* Extended segment address record */ + case 2: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended segment address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = SEGMENTED_ADDRESS; + + /* Then ignore subsequent extended linear address records */ + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + { + sscanf (p, "%4x%2x",&Segment,&temp2); + + /* Update the current address. */ + Phys_Addr = (Segment << 4) & ADDRESS_MASK; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = TRUE; + } + break; + + /* Start segment address record */ + case 3: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + + /* Extended linear address record */ + case 4: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended linear address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = LINEAR_ADDRESS; + + /* Then ignore subsequent extended segment address records */ + if (Seg_Lin_Select == LINEAR_ADDRESS) + { + sscanf (p, "%4x%2x",&Upper_Address,&temp2); + + /* Update the current address. */ + Phys_Addr = (Upper_Address << 16) & ADDRESS_MASK; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Upper_Address >> 8) + (Upper_Address & 0xFF) + temp2) + & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = TRUE; + } + break; + + /* Start linear address record */ + case 5: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + default: + fprintf(stderr,"Unknown record type\n"); + break; + } + } while (!feof (Filin)); + /*-----------------------------------------------------------------------------*/ + + fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); + fprintf(stdout,"Highest address = %08X\n",Highest_Address); + fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case CKS_8: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case CKS_16BE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((word)Memory_Block[i] << 8); + wCKS += w; + } + + fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((word)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (byte)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case CKS_16LE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((word)Memory_Block[i+1] << 8); + wCKS += w; + } + + fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((word)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (byte)(wCKS >> 8); + Memory_Block[Cks_Addr] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + /* This starting address is for the binary file, + + ex.: if the first record is :nn010000ddddd... + the data supposed to be stored at 0100 will start at 0000 in the binary file. + + Specifying this starting address will put FF bytes in the binary file so that + the data supposed to be stored at 0100 will start at the same address in the + binary file. + */ + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + /* write binary file */ + fwrite (&Memory_Block[Lowest_Address], + 1, + Highest_Address - Lowest_Address +1, + Filout); + + free (Memory_Block); + +#ifdef USE_FILE_BUFFERS + free (FilinBuf); + free (FiloutBuf); +#endif + + fclose (Filin); + fclose (Filout); + + if (Status_Checksum_Error && Enable_Checksum_Error) + { + fprintf(stderr,"Checksum error detected.\n"); + return 1; + } + + if (!Fileread) + usage(); + return 0; +} diff --git a/3rd party/tools/Hex2bin/hex2bin.pod b/3rd party/tools/Hex2bin/hex2bin.pod new file mode 100644 index 0000000..14e44c0 --- /dev/null +++ b/3rd party/tools/Hex2bin/hex2bin.pod @@ -0,0 +1,101 @@ +HEX2BIN 1 "2010 april 2nd" "Hex2bin Version 1.0.8" +=head1 NAME + +hex2bin/mot2bin \- converts Intel/Motorola hex files into binary + +=head1 SYNOPSIS + +hex2bin [-s address] [-e extension] [-c] [-p pad byte] [-k checksum type] + [-r start end] [-f address [value]] file + +=head1 DESCRIPTION + +B +is a program that converts an Intel hex format into binary. +It can handle the extended Intel hex format. Both the segmented +and linear address records are supported. +Records need not be sorted and there can be gaps between records. +Records are assumed to be non-overlapping. +Padding bytes may be specified and a checksum may be inserted in the +binary file. + +B +does the same with Motorola hex files. It has the same features and command line +options. 24 bit and 32 bit records are supported. + +=head1 OPTIONS + +B<-s [address]> + +Normally, hex2bin will generate a binary file starting at the lowest address in the hex file. +If the lowest address isn't 0000, ex: 0100, the first byte that should be at 0100 +will be stored at address 0000 in the binary file. This may cause problems when using the +binary file to program an EPROM. +If you can't specify the starting address (or offset) to your EPROM programmer, you can specify +a starting address on the command line: + +B + +The bytes will be stored in the binary file with a padding from 0000 to the +lowest addess (00FF in this case). Padding bytes are all FF by default so an EPROM +programmer can skip these bytes when programming. The padding value can be changed +with the -p option. + +B<-e [extension]> + +By default, the output file will have an extension B. +Another extension may be specified with this command: + +B + +The output file will be example.com + +B<-c> + +Enables checksum verification. + +By default, it ignores checksum errors in the hex file, so that someone can change +by hand some bytes with a text editor, allowing quick fixes without recompiling a source +code all over again. This is useful when tweaking constants directly in the code or +something similar. If you want checksum error reporting, specify the option -c. + +B + +If there is a checksum error somewhere, the program will continue the +conversion anyway. + +B<-p [pad_byte]> + +Pads unused locations with the specified byte. + +By default, this byte is FF, which is the unprogrammed value for most EPROM/EEPROM/Flash. + +B + +B<-k [0|1|2]> + +In many cases, someone needs to insert a checksum in the binary file. For example, +a boot rom is programmed with a checksum which is verified at power-up. This checksum +is not the same as the one above for the hex file. This feature uses also options +B<-r> and B<-f> described below. + +Select the checksum type to insert into the binary file + 0 : 8-bit + 1 : 16-bit little endian + 2 : 16-bit big endian + +B<-r [start] [end]> + +Range to compute binary checksum over (default is min and max addresses) + +B<-f [address] [value]> + +Address and value of checksum to insert (force) in the binary file + +=head1 NOTES + +This program does minimal error checking since many hex files are +generated by known good assemblers. + +=head1 AUTHOR +Jacques Pelletier (jpelletier@ieee.org) - version 1.0.8 diff --git a/3rd party/tools/Hex2bin/linear.bin b/3rd party/tools/Hex2bin/linear.bin new file mode 100644 index 0000000..317045b Binary files /dev/null and b/3rd party/tools/Hex2bin/linear.bin differ diff --git a/3rd party/tools/Hex2bin/mot2bin b/3rd party/tools/Hex2bin/mot2bin new file mode 100755 index 0000000..7257817 Binary files /dev/null and b/3rd party/tools/Hex2bin/mot2bin differ diff --git a/3rd party/tools/Hex2bin/mot2bin.c b/3rd party/tools/Hex2bin/mot2bin.c new file mode 100644 index 0000000..8119c6b --- /dev/null +++ b/3rd party/tools/Hex2bin/mot2bin.c @@ -0,0 +1,553 @@ +/* + mot2bin converts a Motorola hex file to binary. + Copyright (C) 1999 Jacques Pelletier + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +20040617 Alf Lacis: Added pad byte (may not always want FF). + Added initialisation to Checksum to remove GNU + compiler warning about possible uninitialised usage + Added 2x'break;' to remove GNU compiler warning about label at + end of compound statement + Added PROGRAM & VERSION strings. + +20071005 PG: Improvements on options parsing +20091212 JP: Corrected crash on 0 byte length data records +20100402 JP: ADDRESS_MASK is now calculated from MEMORY_SIZE +*/ + +#define PROGRAM "mot2bin" +#define VERSION "1.0.8" + +#include +#include +#include +#include + + +/* size in bytes */ +#define MEMORY_SIZE 4096*1024 +#define ADDRESS_MASK (MEMORY_SIZE-1) + +#ifdef USE_FILE_BUFFERS + #define BUFFSZ 4096 +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* FIXME how to get it from the system/OS? */ +#define MAX_FILE_NAME_SIZE 81 + +#ifdef DOS + #define MAX_EXTENSION_SIZE 4 +#else + #define MAX_EXTENSION_SIZE 16 +#endif + +#define MAX_LINE_SIZE 256 + +#ifdef __linux__ + /* We don't accept an option beginning with a '/' because it could be a file name. */ + #define _COND_(x) (*(x) == '-') +#else + #define _COND_(x) ((*(x) == '-') || (*(x) == '/')) +#endif + +typedef char filetype[MAX_FILE_NAME_SIZE]; +typedef int boolean; +typedef unsigned char byte; +typedef unsigned short word; + +filetype Filename; /* string for opening files */ +char Extension[MAX_EXTENSION_SIZE]; /* filename extension for output files */ + +FILE *Filin, /* input files */ + *Filout; /* output files */ + +#ifdef USE_FILE_BUFFERS +char *FilinBuf, /* text buffer for file input */ + *FiloutBuf; /* text buffer for file output */ +#endif + +int PadByte = 0xFF; + +void usage(void); +void *NoFailMalloc (size_t size); +void NoFailOpenInputFile (char *Flnm); +void NoFailOpenOutputFile (char *Flnm); +void PutExtension(char *Flnm, char *Extension); + +void usage(void) +{ + fprintf (stderr, + "\n" + "usage: "PROGRAM" [OPTIONS] filename\n" + "Options:\n" + " -s [address] Starting address in hex\n" + " -e [ext] Output filename extension\n" + " -c Enable checksum verification\n" + " -p [value] Pad-byte value in hex (default==%x)\n\n" + " -k [0|1|2] Select checksum type\n" + " 0 = 8-bit,\n" + " 1 = 16-bit little endian,\n" + " 2 = 16-bit big endian\n" + " -r [start] [end] Range to compute checksum over (default is min and max addresses)\n" + " -f [address] [value] Address and value of checksum to force\n\n", PadByte); + exit(1); +} /* procedure USAGE */ + +void *NoFailMalloc (size_t size) +{ +void *result; + + if ((result = malloc (size)) == NULL) + { + fprintf (stderr,"Can't allocate memory.\n"); + exit(1); + } + return (result); +} + +/* Open the input file, with error checking */ +void NoFailOpenInputFile (char *Flnm) +{ + while ((Filin = fopen(Flnm,"r")) == NULL) + { + fprintf (stderr,"Input file %s cannot be opened. Enter new filename: ",Flnm); + fgets (Flnm,MAX_FILE_NAME_SIZE,stdin); + if (Flnm[0] == '\0') exit(1); + } + +#ifdef USE_FILE_BUFFERS + FilinBuf = (char *) NoFailMalloc (BUFFSZ); + setvbuf(Filin, FilinBuf, _IOFBF, BUFFSZ); +#endif +} /* procedure OPENFILIN */ + +/* Open the output file, with error checking */ +void NoFailOpenOutputFile (char *Flnm) +{ + while ((Filout = fopen(Flnm,"wb")) == NULL) + { + /* Failure to open the output file may be + simply due to an insufficiant permission setting. */ + + fprintf(stderr,"Output file %s cannot be opened. Enter new file name: ", Flnm); + fgets(Flnm,MAX_FILE_NAME_SIZE,stdin); + if (Flnm[0] == '\0') exit(1); + } +#ifdef USE_FILE_BUFFERS + FiloutBuf = (char *) NoFailMalloc (BUFFSZ); + setvbuf(Filout, FiloutBuf, _IOFBF, BUFFSZ); +#endif + +} /* procedure OPENFILOUT */ + +/* Adds an extension to a file name */ +void PutExtension(char *Flnm, char *Extension) +{ +char *Period; /* location of period in file name */ +boolean Samename; + + /* This assumes DOS like file names */ + /* Don't use strchr(): consider the following filename: + ../my.dir/file.hex + */ + if ((Period = strrchr(Flnm,'.')) != NULL) + *(Period) = '\0'; + + Samename = FALSE; + if (strcmp(Extension, Period+1)== 0) + Samename = TRUE; + + strcat(Flnm,"."); + strcat(Flnm, Extension); + if (Samename) + { + fprintf (stderr,"Input and output filenames (%s) are the same.", Flnm); + exit(1); + } +} + +int main (int argc, char *argv[]) +{ + /* line inputted from file */ + char Line[MAX_LINE_SIZE]; + + /* flag that a file was read */ + boolean Fileread; + boolean Enable_Checksum_Error = FALSE; + boolean Status_Checksum_Error = FALSE; + + /* cmd-line parameter # */ + char *c, *p; + + unsigned int Param; + unsigned int i; + + /* Application specific */ + + unsigned int Nb_Bytes; + unsigned int Address, Lowest_Address, Highest_Address, Starting_Address; + unsigned int Phys_Addr, Type; + unsigned int temp; + + boolean Starting_Address_Setted = FALSE; + + int temp2; + + byte Data_Str[MAX_LINE_SIZE]; + byte Checksum = 0; + +#define CKS_8 0 +#define CKS_16LE 1 +#define CKS_16BE 2 + + unsigned short int wCKS; + unsigned short int w; + unsigned int Cks_Type = CKS_8; + unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; + boolean Cks_range_set = FALSE; + boolean Cks_Addr_set = FALSE; + + /* This will hold binary codes translated from hex file. */ + byte *Memory_Block; + + fprintf (stdout,PROGRAM" v"VERSION", Copyright (C) 1998 Jacques Pelletier\n" + "checksum extensions Copyright (C) 2004 Rockwell Automation\n" + "improved P.G. 2007\n\n"); + + if (argc == 1) + usage(); + + strcpy(Extension, "bin"); /* default is for binary file extension */ + + /* read file */ + Param = 1; + + for (Param = 1; Param < argc; Param++) + { + c = p = argv[Param]; +//#ifdef __linux__ + /* We don't accept an option beginning with a '/' because it could be a file name. */ +// if(*c == '-') +//#else +// if((*c == '-') || (*c == '/')) +//#endif + if ( _COND_(c) ) { + p = c + 2; + /* Parameter may follow immediately after option */ + /* Skips after parameter to next option */ + if (*p == '\0') + p = argv[Param + 1]; + if ( !_COND_(p) ) + Param++; + + switch(tolower (*(++c))) + { + case 'e': + /* Last parameter was -E, so this parameter is the filename extension. */ + if (strlen(p) > MAX_EXTENSION_SIZE) + usage(); + + /* Check to see if the user put a period in the filename extension */ + if (strchr(p, '.') == NULL) + strcpy(Extension, p); + else + strcpy(Extension, p+1); + break; + + case 'c': + Enable_Checksum_Error = TRUE; + break; + case 's': + sscanf(p,"%x",&Starting_Address); + Starting_Address_Setted = TRUE; + break; + case 'p': + sscanf(p,"%x",&PadByte); + break; + case 'h': + usage(); + break; + /* New Checksum parameters */ + case 'k': + sscanf(p,"%x",&Cks_Type); + if (Cks_Type != CKS_8 && + Cks_Type != CKS_16LE && + Cks_Type != CKS_16BE ) + usage(); + break; + case 'r': + sscanf(p,"%x",&Cks_Start); + p = argv[ ++Param ]; + if ( _COND_(p) ) break; + sscanf(p,"%x",&Cks_End ); + Cks_range_set = TRUE; + break; + case 'f': + sscanf(p,"%x",&Cks_Addr); + p = argv[ ++Param ]; + if ( _COND_(p) ) break; + sscanf( p, "%x",&Cks_Value ); + Cks_Addr_set = TRUE; + break; + default: + usage(); + } /* switch */ + } else + break; + /* if option */ + + } /* for Param */ + + /* when user enters input file name */ + + /* Assume last parameter is filename */ + strcpy(Filename,argv[argc -1]); + + /* Just a normal file name */ + NoFailOpenInputFile (Filename); + PutExtension(Filename, Extension); + NoFailOpenOutputFile(Filename); + Fileread = TRUE; + + /* allocate a buffer */ + Memory_Block = (byte *) NoFailMalloc(MEMORY_SIZE); + + /* For EPROM or FLASH memory types, fill unused bytes with the padding byte (FF by default) */ + memset (Memory_Block,PadByte,MEMORY_SIZE); + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + /* Now read the file & process the lines. */ + do /* repeat until EOF(Filin) */ + { + /* Read a line from input file. */ + fgets(Line,MAX_LINE_SIZE,Filin); + + /* Remove carriage return/line feed at the end of line. */ + i = strlen(Line)-1; + + if (Line[i] == '\n') Line[i] = '\0'; + + /* Scan starting address and nb of bytes. */ + /* Look at the record type after the 'S' */ + switch(Line[1]) + { + /* 16 bits address */ + case '1': + sscanf (Line,"S%1x%2x%4x%s",&Type,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 3; + break; + + /* 24 bits address */ + case '2': + sscanf (Line,"S%1x%2x%6x%s",&Type,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 4; + break; + + /* 32 bits address */ + case '3': + sscanf (Line,"S%1x%2x%8x%s",&Type,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 24) + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 5; + break; + + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (Type) + { + /* Data record */ + case 1: + case 2: + case 3: + if (Nb_Bytes == 0) + { + fprintf(stderr,"0 byte length Data record ignored\n"); + break; + } + + Phys_Addr = Address & ADDRESS_MASK; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + i = Nb_Bytes; + + do + { + sscanf (p, "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + } + while (--i != 0); + + /* Read the Checksum value. */ + sscanf (Data_Str, "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (0xFF - Checksum) & 0xFF; + + if ((temp2 != Checksum) && Enable_Checksum_Error) + { + Status_Checksum_Error = TRUE; + } + } + else + { + fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + break; + + /* Ignore all other records */ + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + } while (!feof (Filin)); + /*-----------------------------------------------------------------------------*/ + + fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); + fprintf(stdout,"Highest address = %08X\n",Highest_Address); + fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case CKS_8: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case CKS_16BE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((word)Memory_Block[i] << 8); + wCKS += w; + } + + fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((word)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (byte)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case CKS_16LE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((word)Memory_Block[i+1] << 8); + wCKS += w; + } + + fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((word)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (byte)(wCKS >> 8); + Memory_Block[Cks_Addr] = (byte)(wCKS & 0xff); + fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + /* write binary file */ + fwrite (&Memory_Block[Lowest_Address], + 1, + Highest_Address - Lowest_Address +1, + Filout); + + free (Memory_Block); + +#ifdef USE_FILE_BUFFERS + free (FilinBuf); + free (FiloutBuf); +#endif + + fclose (Filin); + fclose (Filout); + + if (Status_Checksum_Error && Enable_Checksum_Error) + { + fprintf(stderr,"Checksum error detected.\n"); + return 1; + } + + if (!Fileread) + usage(); + return 0; +} diff --git a/3rd party/tools/Hex2bin/nochecksum.bin b/3rd party/tools/Hex2bin/nochecksum.bin new file mode 100644 index 0000000..0b6dde8 --- /dev/null +++ b/3rd party/tools/Hex2bin/nochecksum.bin @@ -0,0 +1 @@ +‚—¤°¹¹¶ª–{\>'.MtŸÅáòðßÀ›tL/&?d’·Øêê׳‰[68]‰³Ôèê׳‡[4'Iw¨ÐéìÙ·ˆX4-Q}­ÒêåÌ£p?  Ct¨ÒéäÉšhf™ÂÔÇ nG7Dj˜¹Ä´‹^@7Lrš³¶Ÿ{XEIdˆª»²˜x]Vf‚£·¼¨ˆhUXr”³Ä¸—e3  +Ry˜«°¶¸¾ÁÇÉĺ«œŒ~tl^PC7,*-7ERbq| ²Æ×âäß×˸©—…lS>*(9Nc{•¬ÄÙçíêáÏ·›„iR=-!!0E`ž·Ë×ÜÚѧmM.$:Yx—¶ÍàëíâаŠcF-")8Oh \ No newline at end of file diff --git a/3rd party/tools/Hex2bin/segmented.bin b/3rd party/tools/Hex2bin/segmented.bin new file mode 100644 index 0000000..317045b Binary files /dev/null and b/3rd party/tools/Hex2bin/segmented.bin differ diff --git a/3rd party/tools/Hex2bin/test-end-memory.bin b/3rd party/tools/Hex2bin/test-end-memory.bin new file mode 100644 index 0000000..48791a2 Binary files /dev/null and b/3rd party/tools/Hex2bin/test-end-memory.bin differ diff --git a/3rd party/tools/Hex2bin/test.bin b/3rd party/tools/Hex2bin/test.bin new file mode 100644 index 0000000..c64d6b9 Binary files /dev/null and b/3rd party/tools/Hex2bin/test.bin differ diff --git a/Doc/AtXmegaRobo/download.sh b/Doc/AtXmegaRobo/download.sh new file mode 100755 index 0000000..497bef2 --- /dev/null +++ b/Doc/AtXmegaRobo/download.sh @@ -0,0 +1,10 @@ +#!/bin/bash +wget http://www.atmel.com/Images/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf +wget http://www.atmel.com/images/Atmel-8387-8-and16-bit-AVR-Microcontroller-XMEGA-A4U_Datasheet.pdf +wget http://www.seeedstudio.com/wiki/images/7/72/AT_Commands_v1.11.pdf +wget http://www.tme.eu/ch/Document/3428bae894bc311e83c44aca8a5e5174/sim900.pdf +wget https://www.sparkfun.com/datasheets/Robotics/TB6612FNG.pdf +wget http://www.st.com/content/ccc/resource/technical/document/datasheet/4e/55/f1/3b/07/ef/4e/02/CD00002851.pdf/files/CD00002851.pdf/jcr:content/translations/en.CD00002851.pdf +wget http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232D.pdf +wget http://www.seeedstudio.com/wiki/images/b/b0/HC-12_User_Manual.pdf +wget http://www.allegromicro.com/~/media/Files/Datasheets/ACS711-Datasheet.ashx?la=en diff --git a/Doc/DidacticSystem/Acucator module/diode.dia b/Doc/DidacticSystem/Acucator module/diode.dia new file mode 100644 index 0000000..62433dd Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/diode.dia differ diff --git a/Doc/DidacticSystem/Acucator module/em_lightCoroutine.dia b/Doc/DidacticSystem/Acucator module/em_lightCoroutine.dia new file mode 100644 index 0000000..e37a371 Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/em_lightCoroutine.dia differ diff --git a/Doc/DidacticSystem/Acucator module/em_lightFirmware.dia b/Doc/DidacticSystem/Acucator module/em_lightFirmware.dia new file mode 100644 index 0000000..a6cf81c Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/em_lightFirmware.dia differ diff --git a/Doc/DidacticSystem/Acucator module/em_rollerCoroutine.dia b/Doc/DidacticSystem/Acucator module/em_rollerCoroutine.dia new file mode 100644 index 0000000..8dd2f29 Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/em_rollerCoroutine.dia differ diff --git a/Doc/DidacticSystem/Acucator module/firmware.dia b/Doc/DidacticSystem/Acucator module/firmware.dia new file mode 100644 index 0000000..ac5c7e6 Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/firmware.dia differ diff --git a/Doc/DidacticSystem/Acucator module/hardware.dia b/Doc/DidacticSystem/Acucator module/hardware.dia new file mode 100644 index 0000000..24db7fc Binary files /dev/null and b/Doc/DidacticSystem/Acucator module/hardware.dia differ diff --git a/Doc/DidacticSystem/Main Controller/firmware.dia b/Doc/DidacticSystem/Main Controller/firmware.dia new file mode 100644 index 0000000..91bb8fe Binary files /dev/null and b/Doc/DidacticSystem/Main Controller/firmware.dia differ diff --git a/Doc/DidacticSystem/Main Controller/firmware.png b/Doc/DidacticSystem/Main Controller/firmware.png new file mode 100644 index 0000000..307f302 Binary files /dev/null and b/Doc/DidacticSystem/Main Controller/firmware.png differ diff --git a/Doc/DidacticSystem/Main Controller/hardware.dia b/Doc/DidacticSystem/Main Controller/hardware.dia new file mode 100644 index 0000000..90cb6d9 Binary files /dev/null and b/Doc/DidacticSystem/Main Controller/hardware.dia differ diff --git a/Doc/DidacticSystem/Main Controller/hardware.png b/Doc/DidacticSystem/Main Controller/hardware.png new file mode 100644 index 0000000..3254491 Binary files /dev/null and b/Doc/DidacticSystem/Main Controller/hardware.png differ diff --git a/Doc/DidacticSystem/Programmer/hardware.dia b/Doc/DidacticSystem/Programmer/hardware.dia new file mode 100644 index 0000000..284c67b Binary files /dev/null and b/Doc/DidacticSystem/Programmer/hardware.dia differ diff --git a/Doc/DidacticSystem/hardware.dia b/Doc/DidacticSystem/hardware.dia new file mode 100644 index 0000000..a93b015 Binary files /dev/null and b/Doc/DidacticSystem/hardware.dia differ diff --git a/Doc/DidacticSystem/hardware.png b/Doc/DidacticSystem/hardware.png new file mode 100644 index 0000000..46bc84f Binary files /dev/null and b/Doc/DidacticSystem/hardware.png differ diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/FreeRTOSConfig.h b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/FreeRTOSConfig.h new file mode 100644 index 0000000..67e8533 --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/FreeRTOSConfig.h @@ -0,0 +1,99 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 8000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 1500 ) ) +#define configMAX_TASK_NAME_LEN ( 8 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/ParTest/ParTest.c b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/ParTest/ParTest.c new file mode 100644 index 0000000..6524c03 --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/ParTest/ParTest.c @@ -0,0 +1,142 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V2.0.0 + + + Use scheduler suspends in place of critical sections. + +Changes from V2.6.0 + + + Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "partest.h" + +/*----------------------------------------------------------- + * Simple parallel port IO routines. + *-----------------------------------------------------------*/ + +#define partstALL_BITS_OUTPUT ( ( unsigned portCHAR ) 0xff ) +#define partstALL_OUTPUTS_OFF ( ( unsigned portCHAR ) 0xff ) +#define partstMAX_OUTPUT_LED ( ( unsigned portCHAR ) 7 ) + +static volatile unsigned portCHAR ucCurrentOutputValue = partstALL_OUTPUTS_OFF; /*lint !e956 File scope parameters okay here. */ + +/*-----------------------------------------------------------*/ + +void vParTestInitialise( void ) +{ + ucCurrentOutputValue = partstALL_OUTPUTS_OFF; + + /* Set port B direction to outputs. Start with all output off. */ + DDRB = partstALL_BITS_OUTPUT; + PORTB = ucCurrentOutputValue; +} +/*-----------------------------------------------------------*/ + +void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ) +{ +unsigned portCHAR ucBit = ( unsigned portCHAR ) 1; + + if( uxLED <= partstMAX_OUTPUT_LED ) + { + ucBit <<= uxLED; + + vTaskSuspendAll(); + { + if( xValue == pdTRUE ) + { + ucBit ^= ( unsigned portCHAR ) 0xff; + ucCurrentOutputValue &= ucBit; + } + else + { + ucCurrentOutputValue |= ucBit; + } + + PORTB = ucCurrentOutputValue; + } + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +void vParTestToggleLED( unsigned portBASE_TYPE uxLED ) +{ +unsigned portCHAR ucBit; + + if( uxLED <= partstMAX_OUTPUT_LED ) + { + ucBit = ( ( unsigned portCHAR ) 1 ) << uxLED; + + vTaskSuspendAll(); + { + if( ucCurrentOutputValue & ucBit ) + { + ucCurrentOutputValue &= ~ucBit; + } + else + { + ucCurrentOutputValue |= ucBit; + } + + PORTB = ucCurrentOutputValue; + } + xTaskResumeAll(); + } +} + + diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/main.c b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/main.c new file mode 100644 index 0000000..f88b6de --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/main.c @@ -0,0 +1,277 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * Creates all the demo application tasks, then starts the scheduler. The WEB + * documentation provides more details of the demo application tasks. + * + * Main. c also creates a task called "Check". This only executes every three + * seconds but has the highest priority so is guaranteed to get processor time. + * Its main function is to check that all the other tasks are still operational. + * Each task that does not flash an LED maintains a unique count that is + * incremented each time the task successfully completes its function. Should + * any error occur within such a task the count is permanently halted. The + * check task inspects the count of each task to ensure it has changed since + * the last time the check task executed. If all the count variables have + * changed all the tasks are still executing error free, and the check task + * toggles an LED. Should any task contain an error at any time the LED toggle + * will stop. + * + * The LED flash and communications test tasks do not maintain a count. + */ + +/* +Changes from V1.2.0 + + + Changed the baud rate for the serial test from 19200 to 57600. + +Changes from V1.2.3 + + + The integer and comtest tasks are now used when the cooperative scheduler + is being used. Previously they were only used with the preemptive + scheduler. + +Changes from V1.2.5 + + + Set the baud rate to 38400. This has a smaller error percentage with an + 8MHz clock (according to the manual). + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + +Changes from V2.6.1 + + + The IAR and WinAVR AVR ports are now maintained separately. + +Changes from V4.0.5 + + + Modified to demonstrate the use of co-routines. + +*/ + +#include +#include + +#ifdef GCC_MEGA_AVR + /* EEPROM routines used only with the WinAVR compiler. */ + #include +#endif + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Demo file headers. */ +#include "PollQ.h" +#include "integer.h" +#include "serial.h" +#include "comtest.h" +#include "crflash.h" +#include "print.h" +#include "partest.h" +#include "regtest.h" + +/* Priority definitions for most of the tasks in the demo application. Some +tasks just use the idle priority. */ +#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/* Baud rate used by the serial port tasks. */ +#define mainCOM_TEST_BAUD_RATE ( ( unsigned portLONG ) 38400 ) + +/* LED used by the serial port tasks. This is toggled on each character Tx, +and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ +#define mainCOM_TEST_LED ( 4 ) + +/* LED that is toggled by the check task. The check task periodically checks +that all the other tasks are operating without error. If no errors are found +the LED is toggled. If an error is found at any time the LED is never toggles +again. */ +#define mainCHECK_TASK_LED ( 7 ) + +/* The period between executions of the check task. */ +#define mainCHECK_PERIOD ( ( portTickType ) 3000 / portTICK_RATE_MS ) + +/* An address in the EEPROM used to count resets. This is used to check that +the demo application is not unexpectedly resetting. */ +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +/* The number of coroutines to create. */ +#define mainNUM_FLASH_COROUTINES ( 3 ) + +/* + * The task function for the "Check" task. + */ +static void vErrorChecks( void *pvParameters ); + +/* + * Checks the unique counts of other tasks to ensure they are still operational. + * Flashes an LED if everything is okay. + */ +static void prvCheckOtherTasksAreStillRunning( void ); + +/* + * Called on boot to increment a count stored in the EEPROM. This is used to + * ensure the CPU does not reset unexpectedly. + */ +static void prvIncrementResetCount( void ); + +/* + * The idle hook is used to scheduler co-routines. + */ +void vApplicationIdleHook( void ); + +/*-----------------------------------------------------------*/ + +portSHORT main( void ) +{ + prvIncrementResetCount(); + + /* Setup the LED's for output. */ + vParTestInitialise(); + + /* Create the standard demo tasks. */ + vStartIntegerMathTasks( tskIDLE_PRIORITY ); + vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartRegTestTasks(); + + /* Create the tasks defined within this file. */ + xTaskCreate( vErrorChecks, ( signed portCHAR * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); + + /* Create the co-routines that flash the LED's. */ + vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); + + /* In this port, to use preemptive scheduler define configUSE_PREEMPTION + as 1 in portmacro.h. To use the cooperative scheduler define + configUSE_PREEMPTION as 0. */ + vTaskStartScheduler(); + + return 0; +} +/*-----------------------------------------------------------*/ + +static void vErrorChecks( void *pvParameters ) +{ +static volatile unsigned portLONG ulDummyVariable = 3UL; + + /* The parameters are not used. */ + ( void ) pvParameters; + + /* Cycle for ever, delaying then checking all the other tasks are still + operating without error. */ + for( ;; ) + { + vTaskDelay( mainCHECK_PERIOD ); + + /* Perform a bit of 32bit maths to ensure the registers used by the + integer tasks get some exercise. The result here is not important - + see the demo application documentation for more info. */ + ulDummyVariable *= 3; + + prvCheckOtherTasksAreStillRunning(); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckOtherTasksAreStillRunning( void ) +{ +static portBASE_TYPE xErrorHasOccurred = pdFALSE; + + if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + xErrorHasOccurred = pdTRUE; + } + + if( xAreComTestTasksStillRunning() != pdTRUE ) + { + xErrorHasOccurred = pdTRUE; + } + + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + xErrorHasOccurred = pdTRUE; + } + + if( xAreRegTestTasksStillRunning() != pdTRUE ) + { + xErrorHasOccurred = pdTRUE; + } + + if( xErrorHasOccurred == pdFALSE ) + { + /* Toggle the LED if everything is okay so we know if an error occurs even if not + using console IO. */ + vParTestToggleLED( mainCHECK_TASK_LED ); + } +} +/*-----------------------------------------------------------*/ + +static void prvIncrementResetCount( void ) +{ +unsigned portCHAR ucCount; + + eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); + ucCount++; + eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + vCoRoutineSchedule(); +} + diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/makefile b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/makefile new file mode 100644 index 0000000..9bd557d --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/makefile @@ -0,0 +1,428 @@ +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega323 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = rtosdemo + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +DEMO_DIR = ../Common/Minimal +SOURCE_DIR = ../../Source +PORT_DIR = ../../Source/portable/GCC/ATMega323 + +SRC = \ +main.c \ +ParTest/ParTest.c \ +serial/serial.c \ +regtest.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(SOURCE_DIR)/portable/MemMang/heap_1.c \ +$(PORT_DIR)/port.c \ +$(DEMO_DIR)/crflash.c \ +$(DEMO_DIR)/integer.c \ +$(DEMO_DIR)/PollQ.c \ +$(DEMO_DIR)/comtest.c + + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../Source/include -I../Common/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500 + + +AVRDUDE_PORT = com1 # programmer connected to serial device +#AVRDUDE_PORT = lpt1 # programmer connected to parallel port + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +# Programming support using avrdude. +AVRDUDE = avrdude + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.c b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.c new file mode 100644 index 0000000..acd6f6c --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.c @@ -0,0 +1,381 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo file headers. */ +#include "regtest.h" + +/* + * Test tasks that sets registers to known values, then checks to ensure the + * values remain as expected. Test 1 and test 2 use different values. + */ +static void prvRegisterCheck1( void *pvParameters ); +static void prvRegisterCheck2( void *pvParameters ); + +/* Set to a non zero value should an error be found. */ +portBASE_TYPE xRegTestError = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartRegTestTasks( void ) +{ + xTaskCreate( prvRegisterCheck1, ( signed portCHAR * ) "Reg1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvRegisterCheck2, ( signed portCHAR * ) "Reg2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreRegTestTasksStillRunning( void ) +{ +portBASE_TYPE xReturn; + + /* If a register was found to contain an unexpected value then the + xRegTestError variable would have been set to a non zero value. */ + if( xRegTestError == pdFALSE ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvRegisterCheck1( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + asm( "LDI r31, 5" ); + asm( "MOV r0, r31" ); + asm( "LDI r31, 6" ); + asm( "MOV r1, r31" ); + asm( "LDI r31, 7" ); + asm( "MOV r2, r31" ); + asm( "LDI r31, 8" ); + asm( "MOV r3, r31" ); + asm( "LDI r31, 9" ); + asm( "MOV r4, r31" ); + asm( "LDI r31, 10" ); + asm( "MOV r5, r31" ); + asm( "LDI r31, 11" ); + asm( "MOV r6, r31" ); + asm( "LDI r31, 12" ); + asm( "MOV r7, r31" ); + asm( "LDI r31, 13" ); + asm( "MOV r8, r31" ); + asm( "LDI r31, 14" ); + asm( "MOV r9, r31" ); + asm( "LDI r31, 15" ); + asm( "MOV r10, r31" ); + asm( "LDI r31, 16" ); + asm( "MOV r11, r31" ); + asm( "LDI r31, 17" ); + asm( "MOV r12, r31" ); + asm( "LDI r31, 18" ); + asm( "MOV r13, r31" ); + asm( "LDI r31, 19" ); + asm( "MOV r14, r31" ); + asm( "LDI r31, 20" ); + asm( "MOV r15, r31" ); + asm( "LDI r16, 21" ); + asm( "LDI r17, 22" ); + asm( "LDI r18, 23" ); + asm( "LDI r19, 24" ); + asm( "LDI r20, 25" ); + asm( "LDI r21, 26" ); + asm( "LDI r22, 27" ); + asm( "LDI r23, 28" ); + asm( "LDI r24, 29" ); + asm( "LDI r25, 30" ); + asm( "LDI r26, 31" ); + asm( "LDI r27, 32" ); + asm( "LDI r30, 33" ); + + asm( "LDI r31, 5" ); + asm( "CPSE r31, r0" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 6" ); + asm( "CPSE r31, r1" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 7" ); + asm( "CPSE r31, r2" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 8" ); + asm( "CPSE r31, r3" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 9" ); + asm( "CPSE r31, r4" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 10" ); + asm( "CPSE r31, r5" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 11" ); + asm( "CPSE r31, r6" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 12" ); + asm( "CPSE r31, r7" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 13" ); + asm( "CPSE r31, r8" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 14" ); + asm( "CPSE r31, r9" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 15" ); + asm( "CPSE r31, r10" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 16" ); + asm( "CPSE r31, r11" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 17" ); + asm( "CPSE r31, r12" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 18" ); + asm( "CPSE r31, r13" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 19" ); + asm( "CPSE r31, r14" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 20" ); + asm( "CPSE r31, r15" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 21" ); + asm( "CPSE r31, r16" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 22" ); + asm( "CPSE r31, r17" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 23" ); + asm( "CPSE r31, r18" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 24" ); + asm( "CPSE r31, r19" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 25" ); + asm( "CPSE r31, r20" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 26" ); + asm( "CPSE r31, r21" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 27" ); + asm( "CPSE r31, r22" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 28" ); + asm( "CPSE r31, r23" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 29" ); + asm( "CPSE r31, r24" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 30" ); + asm( "CPSE r31, r25" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 31" ); + asm( "CPSE r31, r26" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 32" ); + asm( "CPSE r31, r27" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 33" ); + asm( "CPSE r31, r30" ); + asm( "STS xRegTestError, r0" ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRegisterCheck2( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + asm( "LDI r31, 1" ); + asm( "MOV r0, r31" ); + asm( "LDI r31, 2" ); + asm( "MOV r1, r31" ); + asm( "LDI r31, 3" ); + asm( "MOV r2, r31" ); + asm( "LDI r31, 4" ); + asm( "MOV r3, r31" ); + asm( "LDI r31, 5" ); + asm( "MOV r4, r31" ); + asm( "LDI r31, 6" ); + asm( "MOV r5, r31" ); + asm( "LDI r31, 7" ); + asm( "MOV r6, r31" ); + asm( "LDI r31, 8" ); + asm( "MOV r7, r31" ); + asm( "LDI r31, 9" ); + asm( "MOV r8, r31" ); + asm( "LDI r31, 10" ); + asm( "MOV r9, r31" ); + asm( "LDI r31, 11" ); + asm( "MOV r10, r31" ); + asm( "LDI r31, 12" ); + asm( "MOV r11, r31" ); + asm( "LDI r31, 13" ); + asm( "MOV r12, r31" ); + asm( "LDI r31, 14" ); + asm( "MOV r13, r31" ); + asm( "LDI r31, 15" ); + asm( "MOV r14, r31" ); + asm( "LDI r31, 16" ); + asm( "MOV r15, r31" ); + asm( "LDI r16, 17" ); + asm( "LDI r17, 18" ); + asm( "LDI r18, 19" ); + asm( "LDI r19, 20" ); + asm( "LDI r20, 21" ); + asm( "LDI r21, 22" ); + asm( "LDI r22, 23" ); + asm( "LDI r23, 24" ); + asm( "LDI r24, 25" ); + asm( "LDI r25, 26" ); + asm( "LDI r26, 27" ); + asm( "LDI r27, 28" ); + asm( "LDI r30, 29" ); + + asm( "LDI r31, 1" ); + asm( "CPSE r31, r0" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 2" ); + asm( "CPSE r31, r1" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 3" ); + asm( "CPSE r31, r2" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 4" ); + asm( "CPSE r31, r3" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 5" ); + asm( "CPSE r31, r4" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 6" ); + asm( "CPSE r31, r5" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 7" ); + asm( "CPSE r31, r6" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 8" ); + asm( "CPSE r31, r7" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 9" ); + asm( "CPSE r31, r8" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 10" ); + asm( "CPSE r31, r9" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 11" ); + asm( "CPSE r31, r10" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 12" ); + asm( "CPSE r31, r11" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 13" ); + asm( "CPSE r31, r12" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 14" ); + asm( "CPSE r31, r13" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 15" ); + asm( "CPSE r31, r14" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 16" ); + asm( "CPSE r31, r15" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 17" ); + asm( "CPSE r31, r16" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 18" ); + asm( "CPSE r31, r17" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 19" ); + asm( "CPSE r31, r18" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 20" ); + asm( "CPSE r31, r19" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 21" ); + asm( "CPSE r31, r20" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 22" ); + asm( "CPSE r31, r21" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 23" ); + asm( "CPSE r31, r22" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 24" ); + asm( "CPSE r31, r23" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 25" ); + asm( "CPSE r31, r24" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 26" ); + asm( "CPSE r31, r25" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 27" ); + asm( "CPSE r31, r26" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 28" ); + asm( "CPSE r31, r27" ); + asm( "STS xRegTestError, r0" ); + asm( "LDI r31, 29" ); + asm( "CPSE r31, r30" ); + asm( "STS xRegTestError, r0" ); + } +} + diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.h b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.h new file mode 100644 index 0000000..477ba3d --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/regtest.h @@ -0,0 +1,59 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef REG_TEST_H +#define REG_TEST_H + +void vStartRegTestTasks( void ); +portBASE_TYPE xAreRegTestTasksStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/serial/serial.c b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/serial/serial.c new file mode 100644 index 0000000..f09c1e5 --- /dev/null +++ b/FreeRtosCore/Demo/AVR_ATMega323_WinAVR/serial/serial.c @@ -0,0 +1,246 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + The function xPortInitMinimal() has been renamed to + xSerialPortInitMinimal() and the function xPortInit() has been renamed + to xSerialPortInit(). + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + + xQueueReceiveFromISR() used in place of xQueueReceive() within the ISR. + +Changes from V2.6.0 + + + Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. +*/ + +/* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. */ + + +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" + +#define serBAUD_DIV_CONSTANT ( ( unsigned portLONG ) 16 ) + +/* Constants for writing to UCSRB. */ +#define serRX_INT_ENABLE ( ( unsigned portCHAR ) 0x80 ) +#define serRX_ENABLE ( ( unsigned portCHAR ) 0x10 ) +#define serTX_ENABLE ( ( unsigned portCHAR ) 0x08 ) +#define serTX_INT_ENABLE ( ( unsigned portCHAR ) 0x20 ) + +/* Constants for writing to UCSRC. */ +#define serUCSRC_SELECT ( ( unsigned portCHAR ) 0x80 ) +#define serEIGHT_DATA_BITS ( ( unsigned portCHAR ) 0x06 ) + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + +#define vInterruptOn() \ +{ \ + unsigned portCHAR ucByte; \ + \ + ucByte = UCSRB; \ + ucByte |= serTX_INT_ENABLE; \ + UCSRB = ucByte; \ +} +/*-----------------------------------------------------------*/ + +#define vInterruptOff() \ +{ \ + unsigned portCHAR ucInByte; \ + \ + ucInByte = UCSRB; \ + ucInByte &= ~serTX_INT_ENABLE; \ + UCSRB = ucInByte; \ +} +/*-----------------------------------------------------------*/ + +xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) +{ +unsigned portLONG ulBaudRateCounter; +unsigned portCHAR ucByte; + + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + /* Calculate the baud rate register value from the equation in the + data sheet. */ + ulBaudRateCounter = ( configCPU_CLOCK_HZ / ( serBAUD_DIV_CONSTANT * ulWantedBaud ) ) - ( unsigned portLONG ) 1; + + /* Set the baud rate. */ + ucByte = ( unsigned portCHAR ) ( ulBaudRateCounter & ( unsigned portLONG ) 0xff ); + UBRRL = ucByte; + + ulBaudRateCounter >>= ( unsigned portLONG ) 8; + ucByte = ( unsigned portCHAR ) ( ulBaudRateCounter & ( unsigned portLONG ) 0xff ); + UBRRH = ucByte; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled + later. Also enable the Rx and Tx. */ + UCSRB = ( serRX_INT_ENABLE | serRX_ENABLE | serTX_ENABLE ); + + /* Set the data bits to 8. */ + UCSRC = ( serUCSRC_SELECT | serEIGHT_DATA_BITS ); + } + portEXIT_CRITICAL(); + + /* Unlike other ports, this serial code does not allow for more than one + com port. We therefore don't return a pointer to a port structure and can + instead just return NULL. */ + return NULL; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime ) +{ + /* Only one port is supported. */ + ( void ) pxPort; + + /* Get the next character from the buffer. Return false if no characters + are available, or arrive before xBlockTime expires. */ + if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) + { + return pdTRUE; + } + else + { + return pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime ) +{ + /* Only one port is supported. */ + ( void ) pxPort; + + /* Return false if after the block time there is no room on the Tx queue. */ + if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS ) + { + return pdFAIL; + } + + vInterruptOn(); + + return pdPASS; +} +/*-----------------------------------------------------------*/ + +void vSerialClose( xComPortHandle xPort ) +{ +unsigned portCHAR ucByte; + + /* The parameter is not used. */ + ( void ) xPort; + + /* Turn off the interrupts. We may also want to delete the queues and/or + re-install the original ISR. */ + + portENTER_CRITICAL(); + { + vInterruptOff(); + ucByte = UCSRB; + ucByte &= ~serRX_INT_ENABLE; + UCSRB = ucByte; + } + portEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +SIGNAL( SIG_UART_RECV ) +{ +signed portCHAR cChar; +signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + /* Get the character and post it on the queue of Rxed characters. + If the post causes a task to wake force a context switch as the woken task + may have a higher priority than the task we have interrupted. */ + cChar = UDR; + + xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken ); + + if( xHigherPriorityTaskWoken != pdFALSE ) + { + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +SIGNAL( SIG_UART_DATA ) +{ +signed portCHAR cChar, cTaskWoken; + + if( xQueueReceiveFromISR( xCharsForTx, &cChar, &cTaskWoken ) == pdTRUE ) + { + /* Send the next character queued for Tx. */ + UDR = cChar; + } + else + { + /* Queue empty, nothing to send. */ + vInterruptOff(); + } +} + diff --git a/FreeRtosCore/Demo/Common/Full/BlockQ.c b/FreeRtosCore/Demo/Common/Full/BlockQ.c new file mode 100644 index 0000000..aa33590 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/BlockQ.c @@ -0,0 +1,332 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + * \page BlockQC blockQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + Reversed the priority and block times of the second two demo tasks so + they operate as per the description above. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + +Changes from V4.0.2 + + + The second set of tasks were created the wrong way around. This has been + corrected. +*/ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" +#include "print.h" + +#define blckqSTACK_SIZE ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE ) +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + xQueueHandle xQueue; /*< The queue to be used by the task. */ + portTickType xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile portSHORT *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static void vBlockingQueueProducer( void *pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static void vBlockingQueueConsumer( void *pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( portSHORT ) 0, ( portSHORT ) 0, ( portSHORT ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( portSHORT ) 0, ( portSHORT ) 0, ( portSHORT ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; +const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS; +const portTickType xDontBlock = ( portTickType ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueProducer( void *pvParameters ) +{ +unsigned portSHORT usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const portCHAR * const pcTaskStartMsg = "Blocking queue producer started.\r\n"; +const portCHAR * const pcTaskErrorMsg = "Could not post on blocking queue\r\n"; +portSHORT sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xQueueSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueConsumer( void *pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const portCHAR * const pcTaskStartMsg = "Blocking queue consumer started.\r\n"; +const portCHAR * const pcTaskErrorMsg = "Incorrect value received on blocking queue.\r\n"; +portSHORT sErrorEverOccurred = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreBlockingQueuesStillRunning( void ) +{ +static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( portSHORT ) 0, ( portSHORT ) 0, ( portSHORT ) 0 }; +static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( portSHORT ) 0, ( portSHORT ) 0, ( portSHORT ) 0 }; +portBASE_TYPE xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/FreeRtosCore/Demo/Common/Full/PollQ.c b/FreeRtosCore/Demo/Common/Full/PollQ.c new file mode 100644 index 0000000..f1453e5 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/PollQ.c @@ -0,0 +1,244 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/** + * This is a very simple queue test. See the BlockQ. c documentation for a more + * comprehensive version. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + * + * \page PollQC pollQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "print.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE ) + +/* The task that posts the incrementing number onto the queue. */ +static void vPolledQueueProducer( void *pvParameters ); + +/* The task that empties the queue. */ +static void vPolledQueueConsumer( void *pvParameters ); + +/* Variables that are used to check that the tasks are still running with no errors. */ +static volatile portSHORT sPollingConsumerCount = 0, sPollingProducerCount = 0; +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +static xQueueHandle xPolledQueue; +const unsigned portBASE_TYPE uxQueueSize = 10; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueProducer( void *pvParameters ) +{ +unsigned portSHORT usValue = 0, usLoop; +xQueueHandle *pxQueue; +const portTickType xDelay = ( portTickType ) 200 / portTICK_RATE_MS; +const unsigned portSHORT usNumToProduce = 3; +const portCHAR * const pcTaskStartMsg = "Polled queue producer started.\r\n"; +const portCHAR * const pcTaskErrorMsg = "Could not post on polled queue.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( xQueueHandle * ) pvParameters; + + for( ;; ) + { + for( usLoop = 0; usLoop < usNumToProduce; ++usLoop ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( portTickType ) 0 ) != pdPASS ) + { + /* We should never find the queue full - this is an error. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + } + else + { + if( sError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + ++sPollingProducerCount; + } + + /* Update the value we are going to post next time around. */ + ++usValue; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueConsumer( void *pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = 0; +xQueueHandle *pxQueue; +const portTickType xDelay = ( portTickType ) 200 / portTICK_RATE_MS; +const portCHAR * const pcTaskStartMsg = "Polled queue consumer started.\r\n"; +const portCHAR * const pcTaskErrorMsg = "Incorrect value received on polled queue.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( xQueueHandle * ) pvParameters; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *pxQueue ) ) + { + if( xQueueReceive( *pxQueue, &usData, ( portTickType ) 0 ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + /* Catch-up to the value we received so our next expected value + should again be correct. */ + usExpectedValue = usData; + } + else + { + if( sError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + ++sPollingConsumerCount; + } + } + ++usExpectedValue; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +portBASE_TYPE xArePollingQueuesStillRunning( void ) +{ +static portSHORT sLastPollingConsumerCount = 0, sLastPollingProducerCount = 0; +portBASE_TYPE xReturn; + + if( ( sLastPollingConsumerCount == sPollingConsumerCount ) || + ( sLastPollingProducerCount == sPollingProducerCount ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastPollingConsumerCount = sPollingConsumerCount; + sLastPollingProducerCount = sPollingProducerCount; + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Full/comtest.c b/FreeRtosCore/Demo/Common/Full/comtest.c new file mode 100644 index 0000000..7893bc6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/comtest.c @@ -0,0 +1,370 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Creates two tasks that operate on an interrupt driven serial port. A loopback + * connector should be used so that everything that is transmitted is also received. + * The serial port does not use any flow control. On a standard 9way 'D' connector + * pins two and three should be connected together. + * + * The first task repeatedly sends a string to a queue, character at a time. The + * serial port interrupt will empty the queue and transmit the characters. The + * task blocks for a pseudo random period before resending the string. + * + * The second task blocks on a queue waiting for a character to be received. + * Characters received by the serial port interrupt routine are posted onto the + * queue - unblocking the task making it ready to execute. If this is then the + * highest priority task ready to run it will run immediately - with a context + * switch occurring at the end of the interrupt service routine. The task + * receiving characters is spawned with a higher priority than the task + * transmitting the characters. + * + * With the loop back connector in place, one task will transmit a string and the + * other will immediately receive it. The receiving task knows the string it + * expects to receive so can detect an error. + * + * This also creates a third task. This is used to test semaphore usage from an + * ISR and does nothing interesting. + * + * \page ComTestC comtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + The priority of the Rx task has been lowered. Received characters are + now processed (read from the queue) at the idle priority, allowing low + priority tasks to run evenly at times of a high communications overhead. + +Changes from V1.01: + + + The Tx task now waits a pseudo random time between transissions. + Previously a fixed period was used but this was not such a good test as + interrupts fired at regular intervals. + +Changes From V1.2.0: + + + Use vSerialPutString() instead of single character puts. + + Only stop the check variable incrementing after two consecutive errors. + +Changed from V1.2.5 + + + Made the Rx task 2 priorities higher than the Tx task. Previously it was + only 1. This is done to tie in better with the other demo application + tasks. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + + Slight modification to task priorities. + +*/ + + +/* Scheduler include files. */ +#include +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "print.h" + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( portTickType ) 0x15e ) +#define comTX_MIN_BLOCK_TIME ( ( portTickType ) 0xc8 ) + +#define comMAX_CONSECUTIVE_ERRORS ( 2 ) + +#define comSTACK_SIZE ( ( unsigned portSHORT ) 256 ) + +#define comRX_RELATIVE_PRIORITY ( 1 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort; + +/* The transmit function as described at the top of the file. */ +static void vComTxTask( void *pvParameters ); + +/* The receive function as described at the top of the file. */ +static void vComRxTask( void *pvParameters ); + +/* The semaphore test function as described at the top of the file. */ +static void vSemTestTask( void * pvParameters ); + +/* The string that is repeatedly transmitted. */ +const portCHAR * const pcMessageToExchange = "Send this message over and over again to check communications interrupts. " + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; + +/* Variables that are incremented on each cycle of each task. These are used to +check that both tasks are still executing. */ +volatile portSHORT sTxCount = 0, sRxCount = 0, sSemCount = 0; + +/* The handle to the semaphore test task. */ +static xTaskHandle xSemTestTaskHandle = NULL; + +/*-----------------------------------------------------------*/ + +void vStartComTestTasks( unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate ) +{ +const unsigned portBASE_TYPE uxBufferLength = 255; + + /* Initialise the com port then spawn both tasks. */ + xPort = xSerialPortInit( ePort, eBaudRate, serNO_PARITY, serBITS_8, serSTOP_1, uxBufferLength ); + xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority, NULL ); + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority + comRX_RELATIVE_PRIORITY, NULL ); + xTaskCreate( vSemTestTask, "ISRSem", comSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xSemTestTaskHandle ); +} +/*-----------------------------------------------------------*/ + +static void vComTxTask( void *pvParameters ) +{ +const portCHAR * const pcTaskStartMsg = "COM Tx task started.\r\n"; +portTickType xTimeToWait; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Send the string to the serial port. */ + vSerialPutString( xPort, pcMessageToExchange, strlen( pcMessageToExchange ) ); + + /* We have posted all the characters in the string - increment the variable + used to check that this task is still running, then wait before re-sending + the string. */ + sTxCount++; + + xTimeToWait = xTaskGetTickCount(); + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vComRxTask( void *pvParameters ) +{ +const portCHAR * const pcTaskStartMsg = "COM Rx task started.\r\n"; +const portCHAR * const pcTaskErrorMsg = "COM read error\r\n"; +const portCHAR * const pcTaskRestartMsg = "COM resynced\r\n"; +const portCHAR * const pcTaskTimeoutMsg = "COM Rx timed out\r\n"; +const portTickType xBlockTime = ( portTickType ) 0xffff / portTICK_RATE_MS; +const portCHAR *pcExpectedChar; +portBASE_TYPE xGotChar; +portCHAR cRxedChar; +portSHORT sResyncRequired, sConsecutiveErrors, sLatchedError; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The first expected character is the first character in the string. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + sConsecutiveErrors = 0; + sLatchedError = pdFALSE; + + for( ;; ) + { + /* Receive a message from the com port interrupt routine. If a message is + not yet available the call will block the task. */ + xGotChar = xSerialGetChar( xPort, &cRxedChar, xBlockTime ); + if( xGotChar == pdTRUE ) + { + if( sResyncRequired == pdTRUE ) + { + /* We got out of sequence and are waiting for the start of the next + transmission of the string. */ + if( cRxedChar == '\n' ) + { + /* This is the end of the message so we can start again - with + the first character in the string being the next thing we expect + to receive. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + + /* Queue a message for printing to say that we are going to try + again. */ + vPrintDisplayMessage( &pcTaskRestartMsg ); + + /* Stop incrementing the check variable, if consecutive errors occur. */ + sConsecutiveErrors++; + if( sConsecutiveErrors >= comMAX_CONSECUTIVE_ERRORS ) + { + sLatchedError = pdTRUE; + } + } + } + else + { + /* We have received a character, but is it the expected character? */ + if( cRxedChar != *pcExpectedChar ) + { + /* This was not the expected character so post a message for + printing to say that an error has occurred. We will then wait + to resynchronise. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sResyncRequired = pdTRUE; + } + else + { + /* This was the expected character so next time we will expect + the next character in the string. Wrap back to the beginning + of the string when the null terminator has been reached. */ + pcExpectedChar++; + if( *pcExpectedChar == '\0' ) + { + pcExpectedChar = pcMessageToExchange; + + /* We have got through the entire string without error. */ + sConsecutiveErrors = 0; + } + } + } + + /* Increment the count that is used to check that this task is still + running. This is only done if an error has never occurred. */ + if( sLatchedError == pdFALSE ) + { + sRxCount++; + } + } + else + { + vPrintDisplayMessage( &pcTaskTimeoutMsg ); + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vSemTestTask( void * pvParameters ) +{ +const portCHAR * const pcTaskStartMsg = "ISR Semaphore test started.\r\n"; +portBASE_TYPE xError = pdFALSE; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xSerialWaitForSemaphore( xPort ) ) + { + if( xError == pdFALSE ) + { + sSemCount++; + } + } + else + { + xError = pdTRUE; + } + } +} /*lint !e715 !e830 !e818 pvParameters not used but function prototype must be standard for task function. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreComTestTasksStillRunning( void ) +{ +static portSHORT sLastTxCount = 0, sLastRxCount = 0, sLastSemCount = 0; +portBASE_TYPE xReturn; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. */ + + if( ( sTxCount == sLastTxCount ) || ( sRxCount == sLastRxCount ) || ( sSemCount == sLastSemCount ) ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastTxCount = sTxCount; + sLastRxCount = sRxCount; + sLastSemCount = sSemCount; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vComTestUnsuspendTask( void ) +{ + /* The task that is suspended on the semaphore will be referenced from the + Suspended list as it is blocking indefinitely. This call just checks that + the kernel correctly detects this and does not attempt to unsuspend the + task. */ + xTaskResumeFromISR( xSemTestTaskHandle ); +} diff --git a/FreeRtosCore/Demo/Common/Full/death.c b/FreeRtosCore/Demo/Common/Full/death.c new file mode 100644 index 0000000..9071ca6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/death.c @@ -0,0 +1,227 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * four tasks. The original task is called the creator task, the four tasks it + * creates are called suicidal tasks. + * + * Two of the created suicidal tasks kill one other suicidal task before killing + * themselves - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" +#include "print.h" + +#define deathSTACK_SIZE ( ( unsigned portSHORT ) 512 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static void vCreateTasks( void *pvParameters ); + +/* The task function of the dynamically created tasks. */ +static void vSuicidalTask( void *pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile portSHORT sCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. */ +static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0; +static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5; + +/* Used to store a handle to the tasks that should be killed by a suicidal task, +before it kills itself. */ +xTaskHandle xCreatedTask1, xCreatedTask2; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE *puxPriority; + + /* Create the Creator tasks - passing in as a parameter the priority at which + the suicidal tasks should be created. */ + puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) ); + *puxPriority = uxPriority; + + xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = uxTaskGetNumberOfTasks(); +} +/*-----------------------------------------------------------*/ + +static void vSuicidalTask( void *pvParameters ) +{ +portDOUBLE d1, d2; +xTaskHandle xTaskToKill; +const portTickType xDelay = ( portTickType ) 500 / portTICK_RATE_MS; + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Tow created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( xTaskHandle* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + d1 = 2.4; + d2 = 89.2; + d2 *= d1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( portTickType ) 0 ); + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static void vCreateTasks( void *pvParameters ) +{ +const portTickType xDelay = ( portTickType ) 1000 / portTICK_RATE_MS; +unsigned portBASE_TYPE uxPriority; +const portCHAR * const pcTaskStartMsg = "Create task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + uxPriority = *( unsigned portBASE_TYPE * ) pvParameters; + vPortFree( pvParameters ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL ); + + ++sCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +portBASE_TYPE xIsCreateTaskStillRunning( void ) +{ +static portSHORT sLastCreationCount = 0; +portSHORT sReturn = pdTRUE; +unsigned portBASE_TYPE uxTasksRunningNow; + + if( sLastCreationCount == sCreationCount ) + { + sReturn = pdFALSE; + } + + uxTasksRunningNow = uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + sReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + sReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return sReturn; +} + + diff --git a/FreeRtosCore/Demo/Common/Full/dynamic.c b/FreeRtosCore/Demo/Common/Full/dynamic.c new file mode 100644 index 0000000..3fae88b --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/dynamic.c @@ -0,0 +1,602 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises it's priority above that of the controller task before each + * increment, lowering it again to it's original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of it's loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume (). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from it's suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + * + * The final set of two tasks implements a third test. This simply raises the + * priority of a task while the scheduler is suspended. Again this test was + * added to exercise parts of the code not covered by the first test. + * + * \page Priorities dynamic.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + + Added a second, simple test that uses the functions + vQueueReceiveWhenSuspendedTask() and vQueueSendWhenSuspendedTask(). + +Changes from V3.1.1 + + + Added a third simple test that uses the vTaskPrioritySet() function + while the scheduler is suspended. + + Modified the controller task slightly to test the calling of + vTaskResumeAll() while the scheduler is suspended. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" +#include "print.h" + +/* Function that implements the "limited count" task as described above. */ +static void vLimitedIncrementTask( void * pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static void vContinuousIncrementTask( void * pvParameters ); + +/* Function that implements the controller task as described above. */ +static void vCounterControlTask( void * pvParameters ); + +/* The simple test functions that check sending and receiving while the +scheduler is suspended. */ +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ); +static void vQueueSendWhenSuspendedTask( void *pvParameters ); + +/* The simple test functions that check raising and lowering of task priorities +while the scheduler is suspended. */ +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ); +static void prvChangePriorityHelperTask( void *pvParameters ); + + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME ( ( portTickType ) 50 ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( unsigned portLONG ) 0xff ) +#define priNO_BLOCK ( ( portTickType ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static xTaskHandle xContinuousIncrementHandle, xLimitedIncrementHandle, xChangePriorityWhenSuspendedHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static unsigned portLONG ulCounter; + +/* Variable used in a similar way by the test that checks the raising and +lowering of task priorities while the scheduler is suspended. */ +static unsigned portLONG ulPrioritySetCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static unsigned portSHORT usCheckVariable = ( unsigned portSHORT ) 0; +static portBASE_TYPE xSuspendedQueueSendError = pdFALSE; +static portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE; +static portBASE_TYPE xPriorityRaiseWhenSuspendedError = pdFALSE; + +/* Queue used by the second test. */ +xQueueHandle xSuspendedTestQueue; + +/*-----------------------------------------------------------*/ +/* + * Start the seven tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned portLONG ) ); + xTaskCreate( vContinuousIncrementTask, "CONT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_SEND", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RECV", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvChangePriorityWhenSuspendedTask, "1st_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL ); + xTaskCreate( prvChangePriorityHelperTask, "2nd_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle ); +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static void vLimitedIncrementTask( void * pvParameters ) +{ +unsigned portLONG *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned portLONG * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static void vContinuousIncrementTask( void * pvParameters ) +{ +unsigned portLONG *pulCounter; +unsigned portBASE_TYPE uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned portLONG * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise our priority above the controller task to ensure a context + switch does not occur while we are accessing this variable. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + ( *pulCounter )++; + vTaskPrioritySet( NULL, uxOurPriority ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static void vCounterControlTask( void * pvParameters ) +{ +unsigned portLONG ulLastCounter; +portSHORT sLoops; +portSHORT sError = pdFALSE; +const portCHAR * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( unsigned portLONG ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. */ + vTaskSuspend( xContinuousIncrementHandle ); + ulLastCounter = ulCounter; + vTaskResume( xContinuousIncrementHandle ); + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + } + xTaskResumeAll(); + } + + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared variable. */ + vTaskSuspend( xContinuousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( unsigned portLONG ) 0; + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. + The scheduler suspension is not necessary but is included for test + purposes. */ + vTaskSuspendAll(); + vTaskResume( xLimitedIncrementHandle ); + xTaskResumeAll(); + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinuousIncrementHandle ); + } +} +/*-----------------------------------------------------------*/ + +static void vQueueSendWhenSuspendedTask( void *pvParameters ) +{ +static unsigned portLONG ulValueToSend = ( unsigned portLONG ) 0; +const portCHAR * const pcTaskStartMsg = "Queue send while suspended task started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Queue send while suspended failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + if( xSuspendedQueueSendError == pdFALSE ) + { + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ) +{ +static unsigned portLONG ulExpectedValue = ( unsigned portLONG ) 0, ulReceivedValue; +const portCHAR * const pcTaskStartMsg = "Queue receive while suspended task started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Queue receive while suspended failed.\r\n"; +portBASE_TYPE xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + if( xSuspendedQueueReceiveError == pdFALSE ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + } + xSuspendedQueueReceiveError = pdTRUE; + } + + ++ulExpectedValue; + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ) +{ +const portCHAR * const pcTaskStartMsg = "Priority change when suspended task started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at 0 so we know what the counter should be + when we check it next. */ + ulPrioritySetCounter = ( unsigned portLONG ) 0; + + /* Resume the helper task. At this time it has a priority lower than + ours so no context switch should occur. */ + vTaskResume( xChangePriorityWhenSuspendedHandle ); + + /* Check to ensure the task just resumed has not executed. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned portLONG ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Now try raising the priority while the scheduler is suspended. */ + vTaskSuspendAll(); + { + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) ); + + /* Again, even though the helper task has a priority greater than + ours, it should not have executed yet because the scheduler is + suspended. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned portLONG ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + } + xTaskResumeAll(); + + /* Now the scheduler has been resumed the helper task should + immediately preempt us and execute. When it executes it will increment + the ulPrioritySetCounter exactly once before suspending itself. + + We should now always find the counter set to 1. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned portLONG ) 1 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Delay until we try this again. */ + vTaskDelay( priSLEEP_TIME * 2 ); + + /* Set the priority of the helper task back ready for the next + execution of this task. */ + vTaskSuspendAll(); + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY ); + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityHelperTask( void *pvParameters ) +{ + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This is the helper task for prvChangePriorityWhenSuspendedTask(). + It has it's priority raised and lowered. When it runs it simply + increments the counter then suspends itself again. This allows + prvChangePriorityWhenSuspendedTask() to know how many times it has + executed. */ + ulPrioritySetCounter++; + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static unsigned portSHORT usLastTaskCheck = ( unsigned portSHORT ) 0; +portBASE_TYPE xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xPriorityRaiseWhenSuspendedError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + return xReturn; +} + + + + diff --git a/FreeRtosCore/Demo/Common/Full/events.c b/FreeRtosCore/Demo/Common/Full/events.c new file mode 100644 index 0000000..488fe06 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/events.c @@ -0,0 +1,392 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * This file exercises the event mechanism whereby more than one task is + * blocked waiting for the same event. + * + * The demo creates five tasks - four 'event' tasks, and a controlling task. + * The event tasks have various different priorities and all block on reading + * the same queue. The controlling task writes data to the queue, then checks + * to see which of the event tasks read the data from the queue. The + * controlling task has the lowest priority of all the tasks so is guaranteed + * to always get preempted immediately upon writing to the queue. + * + * By selectively suspending and resuming the event tasks the controlling task + * can check that the highest priority task that is blocked on the queue is the + * task that reads the posted data from the queue. + * + * Two of the event tasks share the same priority. When neither of these tasks + * are suspended they should alternate - one reading one message from the queue, + * the other the next message, etc. + */ + +/* Standard includes. */ +#include +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "mevents.h" +#include "print.h" + +/* Demo specific constants. */ +#define evtSTACK_SIZE ( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE ) +#define evtNUM_TASKS ( 4 ) +#define evtQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 3 ) +#define evtNO_DELAY 0 + +/* Just indexes used to uniquely identify the tasks. Note that two tasks are +'highest' priority. */ +#define evtHIGHEST_PRIORITY_INDEX_2 3 +#define evtHIGHEST_PRIORITY_INDEX_1 2 +#define evtMEDIUM_PRIORITY_INDEX 1 +#define evtLOWEST_PRIORITY_INDEX 0 + +/* Each event task increments one of these counters each time it reads data +from the queue. */ +static volatile portBASE_TYPE xTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Each time the controlling task posts onto the queue it increments the +expected count of the task that it expected to read the data from the queue +(i.e. the task with the highest priority that should be blocked on the queue). + +xExpectedTaskCounters are incremented from the controlling task, and +xTaskCounters are incremented from the individual event tasks - therefore +comparing xTaskCounters to xExpectedTaskCounters shows whether or not the +correct task was unblocked by the post. */ +static portBASE_TYPE xExpectedTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Handles to the four event tasks. These are required to suspend and resume +the tasks. */ +static xTaskHandle xCreatedTasks[ evtNUM_TASKS ]; + +/* The single queue onto which the controlling task posts, and the four event +tasks block. */ +static xQueueHandle xQueue; + +/* Flag used to indicate whether or not an error has occurred at any time. +An error is either the queue being full when not expected, or an unexpected +task reading data from the queue. */ +static portBASE_TYPE xHealthStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* Function that implements the event task. This is created four times. */ +static void prvMultiEventTask( void *pvParameters ); + +/* Function that implements the controlling task. */ +static void prvEventControllerTask( void *pvParameters ); + +/* This is a utility function that posts data to the queue, then compares +xExpectedTaskCounters with xTaskCounters to ensure everything worked as +expected. + +The event tasks all have higher priorities the controlling task. Therefore +the controlling task will always get preempted between writhing to the queue +and checking the task counters. + +@param xExpectedTask The index to the task that the controlling task thinks + should be the highest priority task waiting for data, and + therefore the task that will unblock. + +@param xIncrement The number of items that should be written to the queue. +*/ +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ); + +/* This is just incremented each cycle of the controlling tasks function so +the main application can ensure the test is still running. */ +static portBASE_TYPE xCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartMultiEventTasks( void ) +{ + /* Create the queue to be used for all the communications. */ + xQueue = xQueueCreate( evtQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); + + /* Start the controlling task. This has the idle priority to ensure it is + always preempted by the event tasks. */ + xTaskCreate( prvEventControllerTask, "EvntCTRL", evtSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + + /* Start the four event tasks. Note that two have priority 3, one + priority 2 and the other priority 1. */ + xTaskCreate( prvMultiEventTask, "Event0", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 0 ] ), 1, &( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event1", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 1 ] ), 2, &( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event2", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 2 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ) ); + xTaskCreate( prvMultiEventTask, "Event3", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 3 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ) ); +} +/*-----------------------------------------------------------*/ + +static void prvMultiEventTask( void *pvParameters ) +{ +portBASE_TYPE *pxCounter; +unsigned portBASE_TYPE uxDummy; +const portCHAR * const pcTaskStartMsg = "Multi event task started.\r\n"; + + /* The variable this task will increment is passed in as a parameter. */ + pxCounter = ( portBASE_TYPE * ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Block on the queue. */ + if( xQueueReceive( xQueue, &uxDummy, portMAX_DELAY ) ) + { + /* We unblocked by reading the queue - so simply increment + the counter specific to this task instance. */ + ( *pxCounter )++; + } + else + { + xHealthStatus = pdFAIL; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvEventControllerTask( void *pvParameters ) +{ +const portCHAR * const pcTaskStartMsg = "Multi event controller task started.\r\n"; +portBASE_TYPE xDummy = 0; + + /* Just to stop warnings. */ + ( void ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* All tasks are blocked on the queue. When a message is posted one of + the two tasks that share the highest priority should unblock to read + the queue. The next message written should unblock the other task with + the same high priority, and so on in order. No other task should + unblock to read data as they have lower priorities. */ + + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* For the rest of these tests we don't need the second 'highest' + priority task - so it is suspended. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + + + /* Now suspend the other highest priority task. The medium priority + task will then be the task with the highest priority that remains + blocked on the queue. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + /* This time, when we post onto the queue we will expect the medium + priority task to unblock and preempt us. */ + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + /* Now try resuming the highest priority task while the scheduler is + suspended. The task should start executing as soon as the scheduler + is resumed - therefore when we post to the queue again, the highest + priority task should again preempt us. */ + vTaskSuspendAll(); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now we are going to suspend the high and medium priority tasks. The + low priority task should then preempt us. Again the task suspension is + done with the whole scheduler suspended just for test purposes. */ + vTaskSuspendAll(); + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + /* Do the same basic test another few times - selectively suspending + and resuming tasks and each time calling prvCheckTaskCounters() passing + to the function the number of the task we expected to be unblocked by + the post. */ + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for even more test. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + xTaskResumeAll(); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now a slight change, first suspend all tasks. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* Now when we resume the low priority task and write to the queue 3 + times. We expect the low priority task to service the queue three + times. */ + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH ); + + /* Again suspend all tasks (only the low priority task is not suspended + already). */ + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* This time we are going to suspend the scheduler, resume the low + priority task, then resume the high priority task. In this state we + will write to the queue three times. When the scheduler is resumed + we expect the high priority task to service all three messages. */ + vTaskSuspendAll(); + { + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + xHealthStatus = pdFAIL; + } + } + + /* The queue should not have been serviced yet!. The scheduler + is still suspended. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + } + xTaskResumeAll(); + + /* We should have been preempted by resuming the scheduler - so by the + time we are running again we expect the high priority task to have + removed three items from the queue. */ + xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH; + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + + /* The medium priority and second high priority tasks are still + suspended. Make sure to resume them before starting again. */ + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + /* Just keep incrementing to show the task is still executing. */ + xCheckVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ) +{ +portBASE_TYPE xDummy = 0; + + /* Write to the queue the requested number of times. The data written is + not important. */ + for( xDummy = 0; xDummy < xIncrement; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + /* Did not expect to ever find the queue full. */ + xHealthStatus = pdFAIL; + } + } + + /* All the tasks blocked on the queue have a priority higher than the + controlling task. Writing to the queue will therefore have caused this + task to be preempted. By the time this line executes the event task will + have executed and incremented its counter. Increment the expected counter + to the same value. */ + ( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement; + + /* Check the actual counts and expected counts really are the same. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + /* The counters were not the same. This means a task we did not expect + to unblock actually did unblock. */ + xHealthStatus = pdFAIL; + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreMultiEventTasksStillRunning( void ) +{ +static portBASE_TYPE xPreviousCheckVariable = 0; + + /* Called externally to periodically check that this test is still + operational. */ + + if( xPreviousCheckVariable == xCheckVariable ) + { + xHealthStatus = pdFAIL; + } + + xPreviousCheckVariable = xCheckVariable; + + return xHealthStatus; +} + + diff --git a/FreeRtosCore/Demo/Common/Full/flash.c b/FreeRtosCore/Demo/Common/Full/flash.c new file mode 100644 index 0000000..a0e5f9d --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/flash.c @@ -0,0 +1,152 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/** + * Creates eight tasks, each of which flash an LED at a different rate. The first + * LED flashes every 125ms, the second every 250ms, the third every 375ms, etc. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + * The PC port uses the standard parallel port for outputs, the Flashlite 186 port + * uses IO port F. + * + * \page flashC flash.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" +#include "print.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE + +/* Structure used to pass parameters to the LED tasks. */ +typedef struct LED_PARAMETERS +{ + unsigned portBASE_TYPE uxLED; /*< The output the task should use. */ + portTickType xFlashRate; /*< The rate at which the LED should flash. */ +} xLEDParameters; + +/* The task that is created eight times - each time with a different xLEDParaemtes +structure passed in as the parameter. */ +static void vLEDFlashTask( void *pvParameters ); + +/* String to print if USE_STDIO is defined. */ +const portCHAR * const pcTaskStartMsg = "LED flash task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE uxLEDTask; +xLEDParameters *pxLEDParameters; +const unsigned portBASE_TYPE uxNumOfLEDs = 8; +const portTickType xFlashRate = 125; + + /* Create the eight tasks. */ + for( uxLEDTask = 0; uxLEDTask < uxNumOfLEDs; ++uxLEDTask ) + { + /* Create and complete the structure used to pass parameters to the next + created task. */ + pxLEDParameters = ( xLEDParameters * ) pvPortMalloc( sizeof( xLEDParameters ) ); + pxLEDParameters->uxLED = uxLEDTask; + pxLEDParameters->xFlashRate = ( xFlashRate + ( xFlashRate * ( portTickType ) uxLEDTask ) ); + pxLEDParameters->xFlashRate /= portTICK_RATE_MS; + + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, ( void * ) pxLEDParameters, uxPriority, ( xTaskHandle * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void vLEDFlashTask( void *pvParameters ) +{ +xLEDParameters *pxParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxParameters = ( xLEDParameters * ) pvParameters; + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelay( pxParameters->xFlashRate / ( portTickType ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelay( pxParameters->xFlashRate / ( portTickType ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + } +} + diff --git a/FreeRtosCore/Demo/Common/Full/flop.c b/FreeRtosCore/Demo/Common/Full/flop.c new file mode 100644 index 0000000..fb8fdc6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/flop.c @@ -0,0 +1,355 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * Creates eight tasks, each of which loops continuously performing an (emulated) + * floating point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + * + * \page FlopC flop.c + * \ingroup DemoFiles + *
+ */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE ( ( unsigned portSHORT ) 512 ) +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static void vCompetingMathTask1( void *pvParameters ); +static void vCompetingMathTask2( void *pvParameters ); +static void vCompetingMathTask3( void *pvParameters ); +static void vCompetingMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile unsigned portSHORT usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask1( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned portSHORT *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222; +const portCHAR * const pcTaskStartMsg = "Math task 1 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Math task 1 failed.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask2( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned portSHORT *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001; +const portCHAR * const pcTaskStartMsg = "Math task 2 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Math task 2 failed.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask3( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned portSHORT *pusTaskCheckVariable; +const unsigned portSHORT usArraySize = 250; +unsigned portSHORT usPosition; +const portCHAR * const pcTaskStartMsg = "Math task 3 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Math task 3 failed.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5; + dTotal1 += ( portDOUBLE ) usPosition + 5.5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask4( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned portSHORT *pusTaskCheckVariable; +const unsigned portSHORT usArraySize = 250; +unsigned portSHORT usPosition; +const portCHAR * const pcTaskStartMsg = "Math task 4 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Math task 4 failed.\r\n"; +portSHORT sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123; + dTotal1 += ( portDOUBLE ) usPosition * 12.123; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned portSHORT usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/FreeRtosCore/Demo/Common/Full/integer.c b/FreeRtosCore/Demo/Common/Full/integer.c new file mode 100644 index 0000000..a312a1d --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/integer.c @@ -0,0 +1,351 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * This does the same as flop. c, but uses variables of type long instead of + * type double. + * + * As with flop. c, the tasks created in this file are a good test of the + * scheduler context switch mechanism. The processor has to access 32bit + * variables in two or four chunks (depending on the processor). The low + * priority of these tasks means there is a high probability that a context + * switch will occur mid calculation. See the flop. c documentation for + * more information. + * + * \page IntegerC integer.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.1 + + + The constants used in the calculations are larger to ensure the + optimiser does not truncate them to 16 bits. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "integer.h" + +#define intgSTACK_SIZE ( ( unsigned portSHORT ) 256 ) +#define intgNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different calculation on four byte +variables. Each of the four is created twice. */ +static void vCompeteingIntMathTask1( void *pvParameters ); +static void vCompeteingIntMathTask2( void *pvParameters ); +static void vCompeteingIntMathTask3( void *pvParameters ); +static void vCompeteingIntMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will stop incrementing its check variable. */ +static volatile unsigned portSHORT usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask1( void *pvParameters ) +{ +portLONG l1, l2, l3, l4; +portSHORT sError = pdFALSE; +volatile unsigned portSHORT *pusTaskCheckVariable; +const portLONG lAnswer = ( ( portLONG ) 74565L + ( portLONG ) 1234567L ) * ( portLONG ) -918L; +const portCHAR * const pcTaskStartMsg = "Integer math task 1 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Integer math task 1 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + l1 = ( portLONG ) 74565L; + l2 = ( portLONG ) 1234567L; + l3 = ( portLONG ) -918L; + + l4 = ( l1 + l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask2( void *pvParameters ) +{ +portLONG l1, l2, l3, l4; +portSHORT sError = pdFALSE; +volatile unsigned portSHORT *pusTaskCheckVariable; +const portLONG lAnswer = ( ( portLONG ) -389000L / ( portLONG ) 329999L ) * ( portLONG ) -89L; +const portCHAR * const pcTaskStartMsg = "Integer math task 2 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Integer math task 2 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + l1 = -389000L; + l2 = 329999L; + l3 = -89L; + + l4 = ( l1 / l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask3( void *pvParameters ) +{ +portLONG *plArray, lTotal1, lTotal2; +portSHORT sError = pdFALSE; +volatile unsigned portSHORT *pusTaskCheckVariable; +const unsigned portSHORT usArraySize = ( unsigned portSHORT ) 250; +unsigned portSHORT usPosition; +const portCHAR * const pcTaskStartMsg = "Integer math task 3 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Integer math task 3 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( portLONG * ) pvPortMalloc( ( size_t ) 250 * sizeof( portLONG ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( portLONG ) 0; + lTotal2 = ( portLONG ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( portLONG ) usPosition + ( portLONG ) 5; + lTotal1 += ( portLONG ) usPosition + ( portLONG ) 5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask4( void *pvParameters ) +{ +portLONG *plArray, lTotal1, lTotal2; +portSHORT sError = pdFALSE; +volatile unsigned portSHORT *pusTaskCheckVariable; +const unsigned portSHORT usArraySize = 250; +unsigned portSHORT usPosition; +const portCHAR * const pcTaskStartMsg = "Integer math task 4 started.\r\n"; +const portCHAR * const pcTaskFailMsg = "Integer math task 4 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( portLONG * ) pvPortMalloc( ( size_t ) 250 * sizeof( portLONG ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( portLONG ) 0; + lTotal2 = ( portLONG ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( portLONG ) usPosition * ( portLONG ) 12; + lTotal1 += ( portLONG ) usPosition * ( portLONG ) 12; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreIntegerMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned portSHORT usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Full/print.c b/FreeRtosCore/Demo/Common/Full/print.c new file mode 100644 index 0000000..5d6de45 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/print.c @@ -0,0 +1,130 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Manages a queue of strings that are waiting to be displayed. This is used to + * ensure mutual exclusion of console output. + * + * A task wishing to display a message will call vPrintDisplayMessage (), with a + * pointer to the string as the parameter. The pointer is posted onto the + * xPrintQueue queue. + * + * The task spawned in main. c blocks on xPrintQueue. When a message becomes + * available it calls pcPrintGetNextMessage () to obtain a pointer to the next + * string, then uses the functions defined in the portable layer FileIO. c to + * display the message. + * + * NOTE: + * Using console IO can disrupt real time performance - depending on the port. + * Standard C IO routines are not designed for real time applications. While + * standard IO is useful for demonstration and debugging an alternative method + * should be used if you actually require console IO as part of your application. + * + * \page PrintC print.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "queue.h" + +/* Demo program include files. */ +#include "print.h" + +static xQueueHandle xPrintQueue; + +/*-----------------------------------------------------------*/ + +void vPrintInitialise( void ) +{ +const unsigned portBASE_TYPE uxQueueSize = 20; + + /* Create the queue on which errors will be reported. */ + xPrintQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( portCHAR * ) ); +} +/*-----------------------------------------------------------*/ + +void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ) +{ + #ifdef USE_STDIO + xQueueSend( xPrintQueue, ( void * ) ppcMessageToSend, ( portTickType ) 0 ); + #else + /* Stop warnings. */ + ( void ) ppcMessageToSend; + #endif +} +/*-----------------------------------------------------------*/ + +const portCHAR *pcPrintGetNextMessage( portTickType xPrintRate ) +{ +portCHAR *pcMessage; + + if( xQueueReceive( xPrintQueue, &pcMessage, xPrintRate ) == pdPASS ) + { + return pcMessage; + } + else + { + return NULL; + } +} + + diff --git a/FreeRtosCore/Demo/Common/Full/semtest.c b/FreeRtosCore/Demo/Common/Full/semtest.c new file mode 100644 index 0000000..10ddee3 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Full/semtest.c @@ -0,0 +1,309 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + * \page SemTestC semtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.0: + + + The tasks that operate at the idle priority now use a lower expected + count than those running at a higher priority. This prevents the low + priority tasks from signaling an error because they have not been + scheduled enough time for each of them to count the shared variable to + the high value. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" +#include "print.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned portLONG ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned portLONG ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( portTickType ) 10 ) + +/* The task function as described at the top of the file. */ +static void prvSemaphoreTest( void *pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + xSemaphoreHandle xSemaphore; + volatile unsigned portLONG *pulSharedVariable; + portTickType xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile portSHORT sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile portSHORT sNextCheckVariable = 0; + +/* Strings to print if USE_STDIO is defined. */ +const portCHAR * const pcPollingSemaphoreTaskError = "Guarded shared variable in unexpected state.\r\n"; +const portCHAR * const pcSemaphoreTaskStart = "Guarded shared variable task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const portTickType xBlockTime = ( portTickType ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore ); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned portLONG * ) pvPortMalloc( sizeof( unsigned portLONG ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( portTickType ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL ); + xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore ); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned portLONG * ) pvPortMalloc( sizeof( unsigned portLONG ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS; + + xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL ); + xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSemaphoreTest( void *pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile unsigned portLONG *pulSharedVariable, ulExpectedValue; +unsigned portLONG ulCounter; +portSHORT sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcSemaphoreTaskStart ); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( portTickType ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( unsigned portLONG ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + if( sError == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + } + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( portTickType ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreSemaphoreTasksStillRunning( void ) +{ +static portSHORT sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +portBASE_TYPE xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/FreeRtosCore/Demo/Common/Minimal/AltBlckQ.c b/FreeRtosCore/Demo/Common/Minimal/AltBlckQ.c new file mode 100644 index 0000000..315f924 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/AltBlckQ.c @@ -0,0 +1,318 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is a version of BlockQ.c that uses the alternative (Alt) API. + * + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "AltBlckQ.h" + +#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + xQueueHandle xQueue; /*< The queue to be used by the task. */ + portTickType xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile portSHORT *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; +const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS; +const portTickType xDontBlock = ( portTickType ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) +{ +unsigned portSHORT usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +portSHORT sErrorEverOccurred = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt blocking queue producer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueAltSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +portSHORT sErrorEverOccurred = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueAltReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreAltBlockingQueuesStillRunning( void ) +{ +static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; +static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; +portBASE_TYPE xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable to and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/AltBlock.c b/FreeRtosCore/Demo/Common/Minimal/AltBlock.c new file mode 100644 index 0000000..0a4cc87 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/AltBlock.c @@ -0,0 +1,535 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is a version of BlockTim.c that uses the light weight API. + * + * This file contains some test scenarios that ensure tasks do not exit queue + * send or receive functions prematurely. A description of the tests is + * included within the code. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "AltBlock.h" + +/* Task priorities. */ +#define bktPRIMARY_PRIORITY ( 3 ) +#define bktSECONDARY_PRIORITY ( 2 ) + +/* Task behaviour. */ +#define bktQUEUE_LENGTH ( 5 ) +#define bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS ) +#define bktPRIMARY_BLOCK_TIME ( 10 ) +#define bktALLOWABLE_MARGIN ( 12 ) +#define bktTIME_TO_BLOCK ( 175 ) +#define bktDONT_BLOCK ( ( portTickType ) 0 ) +#define bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 ) + +/* The queue on which the tasks block. */ +static xQueueHandle xTestQueue; + +/* Handle to the secondary task is required by the primary task for calls +to vTaskSuspend/Resume(). */ +static xTaskHandle xSecondary; + +/* Used to ensure that tasks are still executing without error. */ +static portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0; +static portBASE_TYPE xErrorOccurred = pdFALSE; + +/* Provides a simple mechanism for the primary task to know when the +secondary task has executed. */ +static volatile unsigned portBASE_TYPE xRunIndicator; + +/* The two test tasks. Their behaviour is commented within the files. */ +static void vPrimaryBlockTimeTestTask( void *pvParameters ); +static void vSecondaryBlockTimeTestTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +void vCreateAltBlockTimeTasks( void ) +{ + /* Create the queue on which the two tasks block. */ + xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xTestQueue, ( signed portCHAR * ) "AltBlockQueue" ); + + + /* Create the two test tasks. */ + xTaskCreate( vPrimaryBlockTimeTestTask, ( signed portCHAR * )"FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); + xTaskCreate( vSecondaryBlockTimeTestTask, ( signed portCHAR * )"FBTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); +} +/*-----------------------------------------------------------*/ + +static void vPrimaryBlockTimeTestTask( void *pvParameters ) +{ +portBASE_TYPE xItem, xData; +portTickType xTimeWhenBlocking; +portTickType xTimeToBlock, xBlockedTime; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt primary block time test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 + + Simple block time wakeup test on queue receives. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is empty. Attempt to read from the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + /* A critical section is used to minimise the jitter in the time + measurements. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /********************************************************************* + Test 2 + + Simple block time wakeup test on queue sends. + + First fill the queue. It should be empty so all sends should pass. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is full. Attempt to write to the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /********************************************************************* + Test 3 + + Wake the other task, it will block attempting to post to the queue. + When we read from the queue the other task will wake, but before it + can run we will post to the queue again. When the other task runs it + will find the queue still full, even though it was woken. It should + recognise that its block time has not expired and return to block for + the remains of its block time. + + Wake the other task so it blocks attempting to post to the already + full queue. */ + xRunIndicator = 0; + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + /* The other task has not yet executed. */ + vTaskDelay( bktSHORT_WAIT ); + } + /* Make sure the other task is blocked on the queue. */ + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we make space on the queue the other task should wake + but not execute as this task has higher priority. */ + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now fill the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + full ourselves, and the other task have set xRunIndicator. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + + /* Set the priority back down. */ + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /********************************************************************* + Test 4 + + As per test 3 - but with the send and receive the other way around. + The other task blocks attempting to read from the queue. + + Empty the queue. We should find that it is full. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Wake the other task so it blocks attempting to read from the + already empty queue. */ + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we place an item on the queue the other task should + wake but not execute as this task has higher priority. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now empty the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + empty ourselves, and the other task would be suspended. */ + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + + xPrimaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void vSecondaryBlockTimeTestTask( void *pvParameters ) +{ +portTickType xTimeWhenBlocking, xBlockedTime; +portBASE_TYPE xData; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt secondary block time test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 and 2 + + This task does does not participate in these tests. */ + vTaskSuspend( NULL ); + + /********************************************************************* + Test 3 + + The first thing we do is attempt to read from the queue. It should be + full so we block. Note the time before we block so we can check the + wake time is as per that expected. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xData = 0; + xRunIndicator = bktRUN_INDICATOR; + if( xQueueAltSendToBack( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we inside the send function? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as + soon as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Suspend ready for test 3. */ + xRunIndicator = bktRUN_INDICATOR; + vTaskSuspend( NULL ); + + /********************************************************************* + Test 4 + + As per test three, but with the send and receive reversed. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xRunIndicator = bktRUN_INDICATOR; + if( xQueueAltReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as soon + as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + xRunIndicator = bktRUN_INDICATOR; + + xSecondaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning( void ) +{ +static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; +portBASE_TYPE xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xPrimaryCycles == xLastPrimaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xSecondaryCycles == xLastSecondaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastSecondaryCycleCount = xSecondaryCycles; + xLastPrimaryCycleCount = xPrimaryCycles; + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Minimal/AltPollQ.c b/FreeRtosCore/Demo/Common/Minimal/AltPollQ.c new file mode 100644 index 0000000..6906eee --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/AltPollQ.c @@ -0,0 +1,261 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is a version of PollQ.c that uses the alternative (Alt) API. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "AltPollQ.h" + +#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE +#define pollqQUEUE_SIZE ( 10 ) +#define pollqPRODUCER_DELAY ( ( portTickType ) 200 / portTICK_RATE_MS ) +#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) ) +#define pollqNO_DELAY ( ( portTickType ) 0 ) +#define pollqVALUES_TO_PRODUCE ( ( signed portBASE_TYPE ) 3 ) +#define pollqINITIAL_VALUE ( ( signed portBASE_TYPE ) 0 ) + +/* The task that posts the incrementing number onto the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters ); + +/* The task that empties the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters ); + +/* Variables that are used to check that the tasks are still running with no +errors. */ +static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE; + +/*-----------------------------------------------------------*/ + +void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +static xQueueHandle xPolledQueue; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xPolledQueue, ( signed portCHAR * ) "AltPollQueue" ); + + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, ( signed portCHAR * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL ); + xTaskCreate( vPolledQueueProducer, ( signed portCHAR * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueProducer, pvParameters ) +{ +unsigned portSHORT usValue = ( unsigned portSHORT ) 0; +signed portBASE_TYPE xError = pdFALSE, xLoop; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt polling queue producer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + for( ;; ) + { + for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueAltSendToBack( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS ) + { + /* We should never find the queue full so if we get here there + has been an error. */ + xError = pdTRUE; + } + else + { + if( xError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + portENTER_CRITICAL(); + xPollingProducerCount++; + portEXIT_CRITICAL(); + } + + /* Update the value we are going to post next time around. */ + usValue++; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( pollqPRODUCER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = ( unsigned portSHORT ) 0; +signed portBASE_TYPE xError = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) ) + { + if( xQueueAltReceive( *( ( xQueueHandle * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + xError = pdTRUE; + + /* Catch-up to the value we received so our next expected + value should again be correct. */ + usExpectedValue = usData; + } + else + { + if( xError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + portENTER_CRITICAL(); + xPollingConsumerCount++; + portEXIT_CRITICAL(); + } + } + + /* Next time round we would expect the number to be one higher. */ + usExpectedValue++; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( pollqCONSUMER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +portBASE_TYPE xAreAltPollingQueuesStillRunning( void ) +{ +portBASE_TYPE xReturn; + + /* Check both the consumer and producer poll count to check they have both + been changed since out last trip round. We do not need a critical section + around the check variables as this is called from a higher priority than + the other tasks that access the same variables. */ + if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) || + ( xPollingProducerCount == pollqINITIAL_VALUE ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Set the check variables back down so we know if they have been + incremented the next time around. */ + xPollingConsumerCount = pollqINITIAL_VALUE; + xPollingProducerCount = pollqINITIAL_VALUE; + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Minimal/AltQTest.c b/FreeRtosCore/Demo/Common/Minimal/AltQTest.c new file mode 100644 index 0000000..5d1f1ba --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/AltQTest.c @@ -0,0 +1,573 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * This file implements the same demo and test as GenQTest.c, but uses the + * light weight API in place of the fully featured API. + * + * See the comments at the top of GenQTest.c for a description. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "AltQTest.h" + +#define genqQUEUE_LENGTH ( 5 ) +#define genqNO_BLOCK ( 0 ) + +#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) +#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * Tests the behaviour of the xQueueAltSendToFront() and xQueueAltSendToBack() + * macros by using both to fill a queue, then reading from the queue to + * check the resultant queue order is as expected. Queue data is also + * peeked. + */ +static void prvSendFrontAndBackTest( void *pvParameters ); + +/* + * The following three tasks are used to demonstrate the mutex behaviour. + * Each task is given a different priority to demonstrate the priority + * inheritance mechanism. + * + * The low priority task obtains a mutex. After this a high priority task + * attempts to obtain the same mutex, causing its priority to be inherited + * by the low priority task. The task with the inherited high priority then + * resumes a medium priority task to ensure it is not blocked by the medium + * priority task while it holds the inherited high priority. Once the mutex + * is returned the task with the inherited priority returns to its original + * low priority, and is therefore immediately preempted by first the high + * priority task and then the medium prioroity task before it can continue. + */ +static void prvLowPriorityMutexTask( void *pvParameters ); +static void prvMediumPriorityMutexTask( void *pvParameters ); +static void prvHighPriorityMutexTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static portBASE_TYPE xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile unsigned portLONG ulLoopCounter = 0; +static volatile unsigned portLONG ulLoopCounter2 = 0; + +/* The variable that is guarded by the mutex in the mutex demo tasks. */ +static volatile unsigned portLONG ulGuardedVariable = 0; + +/* Handles used in the mutext test to suspend and resume the high and medium +priority mutex test tasks. */ +static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask; + +/*-----------------------------------------------------------*/ + +void vStartAltGenericQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xQueueHandle xQueue; +xSemaphoreHandle xMutex; + + /* Create the queue that we are going to use for the + prvSendFrontAndBackTest demo. */ + xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Alt_Gen_Test_Queue" ); + + /* Create the demo task and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * ) "FGenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); + + /* Create the mutex used by the prvMutexTest task. */ + xMutex = xSemaphoreCreateMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Alt_Q_Mutex" ); + + /* Create the mutex demo tasks and pass it the mutex just created. We are + passing the mutex handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * ) "FMuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * ) "FMuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * ) "FMuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void *pvParameters ) +{ +unsigned portLONG ulData, ulData2; +xQueueHandle xQueue; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Alt queue SendToFront/SendToBack/Peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + xQueue = ( xQueueHandle ) pvParameters; + + for( ;; ) + { + /* The queue is empty, so sending an item to the back of the queue + should have the same efect as sending it to the front of the queue. + + First send to the front and check everything is as expected. */ + xQueueAltSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + /* Then do the same, sending the data to the back, checking everything + is as expected. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + xQueueAltSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + + /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ + for( ulData = 2; ulData < 5; ulData++ ) + { + xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + } + + /* Now the order in the queue should be 2, 3, 4, with 2 being the first + thing to be read out. Now add 1 then 0 to the front of the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 3 ) + { + xErrorDetected = pdTRUE; + } + ulData = 1; + xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + ulData = 0; + xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + + /* Now the queue should be full, and when we read the data out we + should receive 0, 1, 2, 3, 4. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) + { + /* Try peeking the data first. */ + if( xQueueAltPeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + + + /* Now try receiving the data for real. The value should be the + same. Clobber the value first so we know we really received it. */ + ulData2 = ~ulData2; + if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + /* The queue should now be empty again. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /* Our queue is empty once more, add 10, 11 to the back. */ + ulData = 10; + if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + ulData = 11; + if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 2 ) + { + xErrorDetected = pdTRUE; + } + + /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the + front. */ + for( ulData = 9; ulData >= 7; ulData-- ) + { + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } + + /* Now check that the queue is full, and that receiving data provides + the expected sequence of 7, 8, 9, 10, 11. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) + { + if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityMutexTask( void *pvParameters ) +{ +xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Fast mutex with priority inheritance test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + + for( ;; ) + { + /* Take the mutex. It should be available now. */ + if( xSemaphoreAltTake( xMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set our guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* Our priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + /* We should now have inherited the prioritoy of the high priority task, + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* We can attempt to set our priority to the test priority - between the + idle priority and the medium/high test priorities, but our actual + prioroity should remain at the high priority. */ + vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as our + inherited priority is above that of the medium priority task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the did run then it will have incremented our guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* When we give back the semaphore our priority should be disinherited + back to the priority to which we attempted to set ourselves. This means + that when the high priority task next blocks, the medium priority task + should execute and increment the guarded variable. When we next run + both the high and medium priority tasks will have been suspended again. */ + if( xSemaphoreAltGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Check that the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that our priority has been disinherited to + genqMUTEX_TEST_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Set our priority back to our original priority ready for the next + loop around this test. */ + vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); + + /* Just to show we are still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityMutexTask( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + /* The medium priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is increment the guarded + variable, this is so the low priority task knows that it has + executed. */ + ulGuardedVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityMutexTask( void *pvParameters ) +{ +xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; + + ( void ) pvParameters; + + for( ;; ) + { + /* The high priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is attempt to obtain + the mutex. It should find the mutex is not available so a + block time is specified. */ + if( xSemaphoreAltTake( xMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When we eventually obtain the mutex we just give it back then + return to suspend ready for the next test. */ + if( xSemaphoreAltGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreAltGenericQueueTasksStillRunning( void ) +{ +static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; + + /* If the demo task is still running then we expect the loopcounters to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + if( ulLastLoopCounter2 == ulLoopCounter2 ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + ulLastLoopCounter2 = ulLoopCounter2; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return !xErrorDetected; +} + + diff --git a/FreeRtosCore/Demo/Common/Minimal/BlockQ.c b/FreeRtosCore/Demo/Common/Minimal/BlockQ.c new file mode 100644 index 0000000..daa96a6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/BlockQ.c @@ -0,0 +1,306 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + */ + +/* + +Changes from V4.1.1 + + + The second set of tasks were created the wrong way around. This has been + corrected. +*/ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" + +#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + xQueueHandle xQueue; /*< The queue to be used by the task. */ + portTickType xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile portSHORT *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile portSHORT sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; +const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS; +const portTickType xDontBlock = ( portTickType ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) +{ +unsigned portSHORT usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +portSHORT sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +portSHORT sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreBlockingQueuesStillRunning( void ) +{ +static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; +static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; +portBASE_TYPE xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable to and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/GenQTest.c b/FreeRtosCore/Demo/Common/Minimal/GenQTest.c new file mode 100644 index 0000000..337379b --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/GenQTest.c @@ -0,0 +1,570 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - + * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and + * mutex behaviour. + * + * See the comments above the prvSendFrontAndBackTest() and + * prvLowPriorityMutexTask() prototypes below for more information. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "GenQTest.h" + +#define genqQUEUE_LENGTH ( 5 ) +#define genqNO_BLOCK ( 0 ) + +#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) +#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack() + * macros by using both to fill a queue, then reading from the queue to + * check the resultant queue order is as expected. Queue data is also + * peeked. + */ +static void prvSendFrontAndBackTest( void *pvParameters ); + +/* + * The following three tasks are used to demonstrate the mutex behaviour. + * Each task is given a different priority to demonstrate the priority + * inheritance mechanism. + * + * The low priority task obtains a mutex. After this a high priority task + * attempts to obtain the same mutex, causing its priority to be inherited + * by the low priority task. The task with the inherited high priority then + * resumes a medium priority task to ensure it is not blocked by the medium + * priority task while it holds the inherited high priority. Once the mutex + * is returned the task with the inherited priority returns to its original + * low priority, and is therefore immediately preempted by first the high + * priority task and then the medium prioroity task before it can continue. + */ +static void prvLowPriorityMutexTask( void *pvParameters ); +static void prvMediumPriorityMutexTask( void *pvParameters ); +static void prvHighPriorityMutexTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static portBASE_TYPE xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile unsigned portLONG ulLoopCounter = 0; +static volatile unsigned portLONG ulLoopCounter2 = 0; + +/* The variable that is guarded by the mutex in the mutex demo tasks. */ +static volatile unsigned portLONG ulGuardedVariable = 0; + +/* Handles used in the mutext test to suspend and resume the high and medium +priority mutex test tasks. */ +static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask; + +/*-----------------------------------------------------------*/ + +void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xQueueHandle xQueue; +xSemaphoreHandle xMutex; + + /* Create the queue that we are going to use for the + prvSendFrontAndBackTest demo. */ + xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" ); + + /* Create the demo task and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); + + /* Create the mutex used by the prvMutexTest task. */ + xMutex = xSemaphoreCreateMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutexes and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" ); + + /* Create the mutex demo tasks and pass it the mutex just created. We are + passing the mutex handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void *pvParameters ) +{ +unsigned portLONG ulData, ulData2; +xQueueHandle xQueue; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + xQueue = ( xQueueHandle ) pvParameters; + + for( ;; ) + { + /* The queue is empty, so sending an item to the back of the queue + should have the same efect as sending it to the front of the queue. + + First send to the front and check everything is as expected. */ + xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + /* Then do the same, sending the data to the back, checking everything + is as expected. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + + /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ + for( ulData = 2; ulData < 5; ulData++ ) + { + xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + } + + /* Now the order in the queue should be 2, 3, 4, with 2 being the first + thing to be read out. Now add 1 then 0 to the front of the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 3 ) + { + xErrorDetected = pdTRUE; + } + ulData = 1; + xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + ulData = 0; + xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + + /* Now the queue should be full, and when we read the data out we + should receive 0, 1, 2, 3, 4. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) + { + /* Try peeking the data first. */ + if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + + + /* Now try receiving the data for real. The value should be the + same. Clobber the value first so we know we really received it. */ + ulData2 = ~ulData2; + if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + /* The queue should now be empty again. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /* Our queue is empty once more, add 10, 11 to the back. */ + ulData = 10; + if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + ulData = 11; + if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 2 ) + { + xErrorDetected = pdTRUE; + } + + /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the + front. */ + for( ulData = 9; ulData >= 7; ulData-- ) + { + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } + + /* Now check that the queue is full, and that receiving data provides + the expected sequence of 7, 8, 9, 10, 11. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) + { + if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityMutexTask( void *pvParameters ) +{ +xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + for( ;; ) + { + /* Take the mutex. It should be available now. */ + if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set our guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* Our priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + /* We should now have inherited the prioritoy of the high priority task, + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* We can attempt to set our priority to the test priority - between the + idle priority and the medium/high test priorities, but our actual + prioroity should remain at the high priority. */ + vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as our + inherited priority is above that of the medium priority task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the did run then it will have incremented our guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* When we give back the semaphore our priority should be disinherited + back to the priority to which we attempted to set ourselves. This means + that when the high priority task next blocks, the medium priority task + should execute and increment the guarded variable. When we next run + both the high and medium priority tasks will have been suspended again. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Check that the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that our priority has been disinherited to + genqMUTEX_TEST_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Set our priority back to our original priority ready for the next + loop around this test. */ + vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); + + /* Just to show we are still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityMutexTask( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + /* The medium priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is increment the guarded + variable, this is so the low priority task knows that it has + executed. */ + ulGuardedVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityMutexTask( void *pvParameters ) +{ +xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; + + for( ;; ) + { + /* The high priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is attempt to obtain + the mutex. It should find the mutex is not available so a + block time is specified. */ + if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When we eventually obtain the mutex we just give it back then + return to suspend ready for the next test. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreGenericQueueTasksStillRunning( void ) +{ +static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; + + /* If the demo task is still running then we expect the loopcounters to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + if( ulLastLoopCounter2 == ulLoopCounter2 ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + ulLastLoopCounter2 = ulLoopCounter2; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return !xErrorDetected; +} + + diff --git a/FreeRtosCore/Demo/Common/Minimal/IntQueue.c b/FreeRtosCore/Demo/Common/Minimal/IntQueue.c new file mode 100644 index 0000000..b5a0fe0 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/IntQueue.c @@ -0,0 +1,720 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This file defines one of the more complex set of demo/test tasks. They are + * designed to stress test the queue implementation though pseudo simultaneous + * multiple reads and multiple writes from both tasks of varying priority and + * interrupts. The interrupts are prioritised such to ensure that nesting + * occurs (for those ports that support it). + * + * The test ensures that, while being accessed from three tasks and two + * interrupts, all the data sent to the queues is also received from + * the same queue, and that no duplicate items are either sent or received. + * The tests also ensure that a low priority task is never able to successfully + * read from or write to a queue when a task of higher priority is attempting + * the same operation. + */ + +/* Standard includes. */ +#include + +/* SafeRTOS includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" + +/* Demo app includes. */ +#include "IntQueue.h" +#include "IntQueueTimer.h" + +/* Priorities used by test tasks. */ +#define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 2 ) +#define intqLOWER_PRIORITY ( tskIDLE_PRIORITY ) + +/* The number of values to send/receive before checking that all values were +processed as expected. */ +#define intqNUM_VALUES_TO_LOG ( 200 ) +#define intqSHORT_DELAY ( 75 ) + +/* The value by which the value being sent to or received from a queue should +increment past intqNUM_VALUES_TO_LOG before we check that all values have been +sent/received correctly. This is done to ensure that all tasks and interrupts +accessing the queue have completed their accesses with the +intqNUM_VALUES_TO_LOG range. */ +#define intqVALUE_OVERRUN ( 50 ) + +/* The delay used by the polling task. A short delay is used for code +coverage. */ +#define intqONE_TICK_DELAY ( 1 ) + +/* Each task and interrupt is given a unique identifier. This value is used to +identify which task sent or received each value. The identifier is also used +to distinguish between two tasks that are running the same task function. */ +#define intqHIGH_PRIORITY_TASK1 ( ( unsigned portBASE_TYPE ) 1 ) +#define intqHIGH_PRIORITY_TASK2 ( ( unsigned portBASE_TYPE ) 2 ) +#define intqLOW_PRIORITY_TASK ( ( unsigned portBASE_TYPE ) 3 ) +#define intqFIRST_INTERRUPT ( ( unsigned portBASE_TYPE ) 4 ) +#define intqSECOND_INTERRUPT ( ( unsigned portBASE_TYPE ) 5 ) +#define intqQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 10 ) + +/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received +from each queue by each task, otherwise an error is detected. */ +#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 ) + +/* Send the next value to the queue that is normally empty. This is called +from within the interrupts. */ +#define timerNORMALLY_EMPTY_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \ + { \ + unsigned portBASE_TYPE uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyEmptyQueue++; \ + xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ); \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Send the next value to the queue that is normally full. This is called +from within the interrupts. */ +#define timerNORMALLY_FULL_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \ + { \ + unsigned portBASE_TYPE uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyFullQueue++; \ + xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ); \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Receive a value from the normally empty queue. This is called from within +an interrupt. */ +#define timerNORMALLY_EMPTY_RX() \ + if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + prvQueueAccessLogError( __LINE__ ); \ + } \ + else \ + { \ + prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \ + } + +/* Receive a value from the normally full queue. This is called from within +an interrupt. */ +#define timerNORMALLY_FULL_RX() \ + if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \ + { \ + prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \ + } \ + + +/*-----------------------------------------------------------*/ + +/* The two queues used by the test. */ +static xQueueHandle xNormallyEmptyQueue, xNormallyFullQueue; + +/* Variables used to detect a stall in one of the tasks. */ +static unsigned portBASE_TYPE uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0; + +/* Any unexpected behaviour sets xErrorStatus to fail and log the line that +caused the error in xErrorLine. */ +static portBASE_TYPE xErrorStatus = pdPASS; +static unsigned portBASE_TYPE xErrorLine = ( unsigned portBASE_TYPE ) 0; + +/* Used for sequencing between tasks. */ +static portBASE_TYPE xWasSuspended = pdFALSE; + +/* The values that are sent to the queues. An incremented value is sent each +time to each queue. */ +volatile unsigned portBASE_TYPE uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0; + +/* A handle to some of the tasks is required so they can be suspended/resumed. */ +xTaskHandle xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2; + +/* When a value is received in a queue the value is ticked off in the array +the array position of the value is set to a the identifier of the task or +interrupt that accessed the queue. This way missing or duplicate values can be +detected. */ +static unsigned portCHAR ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; +static unsigned portCHAR ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; + +/* The test tasks themselves. */ +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ); +static void prvLowerPriorityNormallyFullTask( void *pvParameters ); +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ); +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ); +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ); + +/* Used to mark the positions within the ucNormallyEmptyReceivedValues and +ucNormallyFullReceivedValues arrays, while checking for duplicates. */ +static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ); +static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ); + +/* Logs the line on which an error occurred. */ +static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine ); + +/*-----------------------------------------------------------*/ + +void vStartInterruptQueueTasks( void ) +{ + /* Start the test tasks. */ + xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 ); + xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 ); + xTaskCreate( prvLowerPriorityNormallyEmptyTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + xTaskCreate( prv1stHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 ); + xTaskCreate( prv2ndHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 ); + xTaskCreate( prvLowerPriorityNormallyFullTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + + /* Create the queues that are accessed by multiple tasks and multiple + interrupts. */ + xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); + xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xNormallyFullQueue, ( signed portCHAR * ) "NormallyFull" ); + vQueueAddToRegistry( xNormallyEmptyQueue, ( signed portCHAR * ) "NormallyEmpty" ); +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyFullReceivedValues[ uxValue ] = uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyEmptyReceivedValues[ uxValue ] = uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine ) +{ + /* Latch the line number that caused the error. */ + xErrorLine = uxLine; + xErrorStatus = pdFAIL; +} +/*-----------------------------------------------------------*/ + +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ) +{ +unsigned portBASE_TYPE uxRxed, ux, uxTask1, uxTask2, uxErrorCount1 = 0, uxErrorCount2 = 0; + + /* The timer should not be started until after the scheduler has started. + More than one task is running this code so we check the parameter value + to determine which task should start the timer. */ + if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + vInitialiseTimerForIntQueueTest(); + } + + for( ;; ) + { + /* Block waiting to receive a value from the normally empty queue. + Interrupts will write to the queue so we should receive a value. */ + if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + /* Note which value was received so we can check all expected + values are received and no values are duplicated. */ + prvRecordValue_NormallyEmpty( uxRxed, ( unsigned portBASE_TYPE ) pvParameters ); + } + + /* Ensure the other task running this code gets a chance to execute. */ + taskYIELD(); + + if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + /* Have we received all the expected values? */ + if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + vTaskSuspend( xHighPriorityNormallyEmptyTask2 ); + + uxTask1 = 0; + uxTask2 = 0; + + /* Loop through the array, checking that both tasks have + placed values into the array, and that no values are missing. + Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyEmptyReceivedValues[ ux ] == 0 ) + { + /* A value is missing. */ + prvQueueAccessLogError( __LINE__ ); + } + else + { + if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK1 ) + { + /* Value was placed into the array by task 1. */ + uxTask1++; + } + else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK2 ) + { + /* Value was placed into the array by task 2. */ + uxTask2++; + } + } + } + + if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 2 seemed to log any values. */ + uxErrorCount1++; + if( uxErrorCount1 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount1 = 0; + } + + if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 1 seemed to log any values. */ + uxErrorCount2++; + if( uxErrorCount2 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount2 = 0; + } + + /* Clear the array again, ready to start a new cycle. */ + memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) ); + + uxHighPriorityLoops1++; + uxValueForNormallyEmptyQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyEmptyTask2 ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ) +{ +unsigned portBASE_TYPE uxValue, uxRxed; +portBASE_TYPE xQueueStatus; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( ( xQueueStatus = xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) ) != errQUEUE_EMPTY ) + { + /* We should only obtain a value when the high priority task is + suspended. */ + if( xTaskIsTaskSuspended( xHighPriorityNormallyEmptyTask1 ) == pdFALSE ) + { + prvQueueAccessLogError( __LINE__ ); + } + + prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIORITY_TASK ); + + /* Wake the higher priority task again. */ + vTaskResume( xHighPriorityNormallyEmptyTask1 ); + uxLowPriorityLoops1++; + } + else + { + /* Raise our priority while we send so we can preempt the higher + priority task, and ensure we get the Tx value into the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + portENTER_CRITICAL(); + { + uxValueForNormallyEmptyQueue++; + uxValue = uxValueForNormallyEmptyQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ) +{ +unsigned portBASE_TYPE uxValueToTx, ux; +portBASE_TYPE xQueueStatus; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS ) + { + /* intqHIGH_PRIORITY_TASK2 is never suspended so we would not + expect it to ever time out. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Allow the other task running this code to run. */ + taskYIELD(); + + /* Have all the expected values been sent to the queue? */ + if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + /* Make sure the other high priority task completes its send of + any values below intqNUM_VALUE_TO_LOG. */ + vTaskDelay( intqSHORT_DELAY ); + + vTaskSuspend( xHighPriorityNormallyFullTask2 ); + + if( xWasSuspended == pdTRUE ) + { + /* We would have expected the other high priority task to have + set this back to false by now. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Set the suspended flag so an error is not logged if the other + task recognises a time out when it is unsuspended. */ + xWasSuspended = pdTRUE; + + /* Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyFullReceivedValues[ ux ] == 0 ) + { + /* A value was missing. */ + prvQueueAccessLogError( __LINE__ ); + } + } + + /* Reset the array ready for the next cycle. */ + memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) ); + + uxHighPriorityLoops2++; + uxValueForNormallyFullQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyFullTask2 ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ) +{ +unsigned portBASE_TYPE uxValueToTx, ux; +portBASE_TYPE xQueueStatus; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS ) + { + if( xWasSuspended != pdTRUE ) + { + /* It is ok to time out if the task has been suspended. */ + prvQueueAccessLogError( __LINE__ ); + } + } + + xWasSuspended = pdFALSE; + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyFullTask( void *pvParameters ) +{ +unsigned portBASE_TYPE uxValue, uxTxed = 9999; +portBASE_TYPE xQueueStatus; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) ) != errQUEUE_FULL ) + { + /* We would only expect to succeed when the higher priority task + is suspended. */ + if( xTaskIsTaskSuspended( xHighPriorityNormallyFullTask1 ) == pdFALSE ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskResume( xHighPriorityNormallyFullTask1 ); + uxLowPriorityLoops2++; + } + else + { + /* Raise our priority while we receive so we can preempt the higher + priority task, and ensure we get the value from the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + prvRecordValue_NormallyFull( uxValue, intqLOW_PRIORITY_TASK ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xFirstTimerHandler( void ) +{ +portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, uxRxedValue; +static unsigned portBASE_TYPE uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xSecondTimerHandler( void ) +{ +unsigned portBASE_TYPE uxRxedValue; +portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; +static unsigned portBASE_TYPE uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + + timerNORMALLY_EMPTY_RX(); + timerNORMALLY_EMPTY_RX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + + +portBASE_TYPE xAreIntQueueTasksStillRunning( void ) +{ +static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0; + + /* xErrorStatus can be set outside of this function. This function just + checks that all the tasks are still cycling. */ + + if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 ) + { + /* The high priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops1 = uxHighPriorityLoops1; + + if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 ) + { + /* The high priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops2 = uxHighPriorityLoops2; + + if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 ) + { + /* The low priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops1 = uxLowPriorityLoops1; + + if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 ) + { + /* The low priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops2 = uxLowPriorityLoops2; + + return xErrorStatus; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/PollQ.c b/FreeRtosCore/Demo/Common/Minimal/PollQ.c new file mode 100644 index 0000000..b1ff33b --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/PollQ.c @@ -0,0 +1,244 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This version of PollQ. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + portTickType rather than unsigned portLONG. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE +#define pollqQUEUE_SIZE ( 10 ) +#define pollqPRODUCER_DELAY ( ( portTickType ) 200 / portTICK_RATE_MS ) +#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) ) +#define pollqNO_DELAY ( ( portTickType ) 0 ) +#define pollqVALUES_TO_PRODUCE ( ( signed portBASE_TYPE ) 3 ) +#define pollqINITIAL_VALUE ( ( signed portBASE_TYPE ) 0 ) + +/* The task that posts the incrementing number onto the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters ); + +/* The task that empties the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters ); + +/* Variables that are used to check that the tasks are still running with no +errors. */ +static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE; + +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +static xQueueHandle xPolledQueue; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xPolledQueue, ( signed portCHAR * ) "Poll_Test_Queue" ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, ( signed portCHAR * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL ); + xTaskCreate( vPolledQueueProducer, ( signed portCHAR * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueProducer, pvParameters ) +{ +unsigned portSHORT usValue = ( unsigned portSHORT ) 0; +signed portBASE_TYPE xError = pdFALSE, xLoop; + + for( ;; ) + { + for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSend( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS ) + { + /* We should never find the queue full so if we get here there + has been an error. */ + xError = pdTRUE; + } + else + { + if( xError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + portENTER_CRITICAL(); + xPollingProducerCount++; + portEXIT_CRITICAL(); + } + + /* Update the value we are going to post next time around. */ + usValue++; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( pollqPRODUCER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters ) +{ +unsigned portSHORT usData, usExpectedValue = ( unsigned portSHORT ) 0; +signed portBASE_TYPE xError = pdFALSE; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) ) + { + if( xQueueReceive( *( ( xQueueHandle * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + xError = pdTRUE; + + /* Catch-up to the value we received so our next expected + value should again be correct. */ + usExpectedValue = usData; + } + else + { + if( xError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + portENTER_CRITICAL(); + xPollingConsumerCount++; + portEXIT_CRITICAL(); + } + } + + /* Next time round we would expect the number to be one higher. */ + usExpectedValue++; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( pollqCONSUMER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +portBASE_TYPE xArePollingQueuesStillRunning( void ) +{ +portBASE_TYPE xReturn; + + /* Check both the consumer and producer poll count to check they have both + been changed since out last trip round. We do not need a critical section + around the check variables as this is called from a higher priority than + the other tasks that access the same variables. */ + if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) || + ( xPollingProducerCount == pollqINITIAL_VALUE ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Set the check variables back down so we know if they have been + incremented the next time around. */ + xPollingConsumerCount = pollqINITIAL_VALUE; + xPollingProducerCount = pollqINITIAL_VALUE; + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Minimal/QPeek.c b/FreeRtosCore/Demo/Common/Minimal/QPeek.c new file mode 100644 index 0000000..ba5db29 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/QPeek.c @@ -0,0 +1,444 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * Tests the behaviour when data is peeked from a queue when there are + * multiple tasks blocked on the queue. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "QPeek.h" + +#define qpeekQUEUE_LENGTH ( 5 ) +#define qpeekNO_BLOCK ( 0 ) +#define qpeekSHORT_DELAY ( 10 ) + +#define qpeekLOW_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define qpeekMEDIUM_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define qpeekHIGH_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define qpeekHIGHEST_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * The following three tasks are used to demonstrate the peeking behaviour. + * Each task is given a different priority to demonstrate the order in which + * tasks are woken as data is peeked from a queue. + */ +static void prvLowPriorityPeekTask( void *pvParameters ); +static void prvMediumPriorityPeekTask( void *pvParameters ); +static void prvHighPriorityPeekTask( void *pvParameters ); +static void prvHighestPriorityPeekTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile portBASE_TYPE xErrorDetected = pdFALSE; + +/* Counter that is incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile unsigned portLONG ulLoopCounter = 0; + +/* Handles to the test tasks. */ +xTaskHandle xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask; +/*-----------------------------------------------------------*/ + +void vStartQueuePeekTasks( void ) +{ +xQueueHandle xQueue; + + /* Create the queue that we are going to use for the test/demo. */ + xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( unsigned portLONG ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "QPeek_Test_Queue" ); + + /* Create the demo tasks and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityPeekTask, ( signed portCHAR * )"PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityPeekTask, ( signed portCHAR * )"PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask ); + xTaskCreate( prvHighPriorityPeekTask, ( signed portCHAR * )"PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask ); + xTaskCreate( prvHighestPriorityPeekTask, ( signed portCHAR * )"PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask ); +} +/*-----------------------------------------------------------*/ + +static void prvHighestPriorityPeekTask( void *pvParameters ) +{ +xQueueHandle xQueue = ( xQueueHandle ) pvParameters; +unsigned portLONG ulValue; + + #ifdef USE_STDIO + { + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Queue peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + } + #endif + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the high priority task to execute. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we reach here the high and medium priority tasks should still + be blocked on the queue. We unblocked because the low priority task + wrote a value to the queue, which we should have peeked. Peeking the + data (rather than receiving it) will leave the data on the queue, so + the high priority task should then have also been unblocked, but not + yet executed. */ + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Now we are going to actually receive the data, so when the high + priority task runs it will find the queue empty and return to the + blocked state. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the value. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value - which should have been + the same value as was peeked. */ + xErrorDetected = pdTRUE; + } + + /* Now we will block again as the queue is once more empty. The low + priority task can then execute again. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the low priority task should have again written to the + queue. */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the high priority task to also peek the data. The high priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + + /* This time we are going to do the same as the above test, but the + high priority task is going to receive the data, rather than peek it. + This means that the medium priority task should never peek the value. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityPeekTask( void *pvParameters ) +{ +xQueueHandle xQueue = ( xQueueHandle ) pvParameters; +unsigned portLONG ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the medium priority task to execute. Both the high + and highest priority tasks will then be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the highest priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the medium priority task to also peek the data. The medium priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + /* This time we are going actually receive the value, so the medium + priority task will never peek the data - we removed it from the queue. */ + if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityPeekTask( void *pvParameters ) +{ +xQueueHandle xQueue = ( xQueueHandle ) pvParameters; +unsigned portLONG ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the low priority task to execute. The highest, high + and medium priority tasks will then all be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the high priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Just so we know the test is still running. */ + ulLoopCounter++; + + /* Now we can suspend ourselves so the low priority task can execute + again. */ + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityPeekTask( void *pvParameters ) +{ +xQueueHandle xQueue = ( xQueueHandle ) pvParameters; +unsigned portLONG ulValue; + + for( ;; ) + { + /* Write some data to the queue. This should unblock the highest + priority task that is waiting to peek data from the queue. */ + ulValue = 0x11223344; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + /* By the time we get here the data should have been removed from + the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Write another value to the queue, again waking the highest priority + task that is blocked on the queue. */ + ulValue = 0x01234567; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + /* All the other tasks should now have successfully peeked the data. + The data is still in the queue so we should be able to receive it. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + } + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + + /* Unsuspend the other tasks so we can repeat the test - this time + however not all the other tasks will peek the data as the high + priority task is actually going to remove it from the queue. Send + to front is used just to be different. As the queue is empty it + makes no difference to the result. */ + vTaskResume( xMediumPriorityTask ); + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + ulValue = 0xaabbaabb; + if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + /* This time we should find that the queue is empty. The high priority + task actually removed the data rather than just peeking it. */ + if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + /* Unsuspend the highest and high priority tasks so we can go back + and repeat the whole thing. The medium priority task should not be + suspended as it was not able to peek the data in this last case. */ + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreQueuePeekTasksStillRunning( void ) +{ +static unsigned portLONG ulLastLoopCounter = 0; + + /* If the demo task is still running then we expect the loopcounter to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return !xErrorDetected; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/blocktim.c b/FreeRtosCore/Demo/Common/Minimal/blocktim.c new file mode 100644 index 0000000..1d71343 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/blocktim.c @@ -0,0 +1,491 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This file contains some test scenarios that ensure tasks do not exit queue + * send or receive functions prematurely. A description of the tests is + * included within the code. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "blocktim.h" + +/* Task priorities. Allow these to be overridden. */ +#ifndef bktPRIMARY_PRIORITY + #define bktPRIMARY_PRIORITY ( 3 ) +#endif + +#ifndef bktSECONDARY_PRIORITY + #define bktSECONDARY_PRIORITY ( 2 ) +#endif + +/* Task behaviour. */ +#define bktQUEUE_LENGTH ( 5 ) +#define bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS ) +#define bktPRIMARY_BLOCK_TIME ( 10 ) +#define bktALLOWABLE_MARGIN ( 15 ) +#define bktTIME_TO_BLOCK ( 175 ) +#define bktDONT_BLOCK ( ( portTickType ) 0 ) +#define bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 ) + +/* The queue on which the tasks block. */ +static xQueueHandle xTestQueue; + +/* Handle to the secondary task is required by the primary task for calls +to vTaskSuspend/Resume(). */ +static xTaskHandle xSecondary; + +/* Used to ensure that tasks are still executing without error. */ +static volatile portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0; +static volatile portBASE_TYPE xErrorOccurred = pdFALSE; + +/* Provides a simple mechanism for the primary task to know when the +secondary task has executed. */ +static volatile unsigned portBASE_TYPE xRunIndicator; + +/* The two test tasks. Their behaviour is commented within the files. */ +static void vPrimaryBlockTimeTestTask( void *pvParameters ); +static void vSecondaryBlockTimeTestTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +void vCreateBlockTimeTasks( void ) +{ + /* Create the queue on which the two tasks block. */ + xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xTestQueue, ( signed portCHAR * ) "Block_Time_Queue" ); + + /* Create the two test tasks. */ + xTaskCreate( vPrimaryBlockTimeTestTask, ( signed portCHAR * )"BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); + xTaskCreate( vSecondaryBlockTimeTestTask, ( signed portCHAR * )"BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); +} +/*-----------------------------------------------------------*/ + +static void vPrimaryBlockTimeTestTask( void *pvParameters ) +{ +portBASE_TYPE xItem, xData; +portTickType xTimeWhenBlocking; +portTickType xTimeToBlock, xBlockedTime; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 + + Simple block time wakeup test on queue receives. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is empty. Attempt to read from the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 2 + + Simple block time wakeup test on queue sends. + + First fill the queue. It should be empty so all sends should pass. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is full. Attempt to write to the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 3 + + Wake the other task, it will block attempting to post to the queue. + When we read from the queue the other task will wake, but before it + can run we will post to the queue again. When the other task runs it + will find the queue still full, even though it was woken. It should + recognise that its block time has not expired and return to block for + the remains of its block time. + + Wake the other task so it blocks attempting to post to the already + full queue. */ + xRunIndicator = 0; + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + /* The other task has not yet executed. */ + vTaskDelay( bktSHORT_WAIT ); + } + /* Make sure the other task is blocked on the queue. */ + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we make space on the queue the other task should wake + but not execute as this task has higher priority. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now fill the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + full ourselves, and the other task have set xRunIndicator. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + + /* Set the priority back down. */ + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + + /********************************************************************* + Test 4 + + As per test 3 - but with the send and receive the other way around. + The other task blocks attempting to read from the queue. + + Empty the queue. We should find that it is full. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Wake the other task so it blocks attempting to read from the + already empty queue. */ + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we place an item on the queue the other task should + wake but not execute as this task has higher priority. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now empty the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + empty ourselves, and the other task would be suspended. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + + xPrimaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void vSecondaryBlockTimeTestTask( void *pvParameters ) +{ +portTickType xTimeWhenBlocking, xBlockedTime; +portBASE_TYPE xData; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 and 2 + + This task does does not participate in these tests. */ + vTaskSuspend( NULL ); + + /********************************************************************* + Test 3 + + The first thing we do is attempt to read from the queue. It should be + full so we block. Note the time before we block so we can check the + wake time is as per that expected. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not sent + anything to the queue. */ + xData = 0; + xRunIndicator = bktRUN_INDICATOR; + if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we inside the send function? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as + soon as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Suspend ready for test 3. */ + xRunIndicator = bktRUN_INDICATOR; + vTaskSuspend( NULL ); + + /********************************************************************* + Test 4 + + As per test three, but with the send and receive reversed. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xRunIndicator = bktRUN_INDICATOR; + if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as soon + as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + xRunIndicator = bktRUN_INDICATOR; + + xSecondaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void ) +{ +static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; +portBASE_TYPE xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xPrimaryCycles == xLastPrimaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xSecondaryCycles == xLastSecondaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastSecondaryCycleCount = xSecondaryCycles; + xLastPrimaryCycleCount = xPrimaryCycles; + + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Minimal/comtest.c b/FreeRtosCore/Demo/Common/Minimal/comtest.c new file mode 100644 index 0000000..3775b9e --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/comtest.c @@ -0,0 +1,289 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * This version of comtest. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that operate on an interrupt driven serial port. A + * loopback connector should be used so that everything that is transmitted is + * also received. The serial port does not use any flow control. On a + * standard 9way 'D' connector pins two and three should be connected together. + * + * The first task posts a sequence of characters to the Tx queue, toggling an + * LED on each successful post. At the end of the sequence it sleeps for a + * pseudo-random period before resending the same sequence. + * + * The UART Tx end interrupt is enabled whenever data is available in the Tx + * queue. The Tx end ISR removes a single character from the Tx queue and + * passes it to the UART for transmission. + * + * The second task blocks on the Rx queue waiting for a character to become + * available. When the UART Rx end interrupt receives a character it places + * it in the Rx queue, waking the second task. The second task checks that the + * characters removed from the Rx queue form the same sequence as those posted + * to the Tx queue, and toggles an LED for each correct character. + * + * The receiving task is spawned with a higher priority than the transmitting + * task. The receiver will therefore wake every time a character is + * transmitted so neither the Tx or Rx queue should ever hold more than a few + * characters. + * + */ + +/* Scheduler include files. */ +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "partest.h" + +#define comSTACK_SIZE configMINIMAL_STACK_SIZE +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) +#define comTOTAL_PERMISSIBLE_ERRORS ( 2 ) + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( portTickType ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( portTickType ) 0x32 ) +#define comOFFSET_TIME ( ( portTickType ) 3 ) + +/* We should find that each character can be queued for Tx immediately and we +don't have to block to send. */ +#define comNO_BLOCK ( ( portTickType ) 0 ) + +/* The Rx task will block on the Rx queue for a long period. */ +#define comRX_BLOCK_TIME ( ( portTickType ) 0xffff ) + +/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */ +#define comFIRST_BYTE ( 'A' ) +#define comLAST_BYTE ( 'X' ) + +#define comBUFFER_LEN ( ( unsigned portBASE_TYPE ) ( comLAST_BYTE - comFIRST_BYTE ) + ( unsigned portBASE_TYPE ) 1 ) +#define comINITIAL_RX_COUNT_VALUE ( 0 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The transmit task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters ); + +/* The receive task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters ); + +/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will +toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED +( uxBaseLED + comTX_LED_OFFSET ). */ +static unsigned portBASE_TYPE uxBaseLED = 0; + +/* Check variable used to ensure no error have occurred. The Rx task will +increment this variable after every successfully received sequence. If at any +time the sequence is incorrect the the variable will stop being incremented. */ +static volatile unsigned portBASE_TYPE uxRxLoops = comINITIAL_RX_COUNT_VALUE; + +/*-----------------------------------------------------------*/ + +void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned portLONG ulBaudRate, unsigned portBASE_TYPE uxLED ) +{ + /* Initialise the com port then spawn the Rx and Tx tasks. */ + uxBaseLED = uxLED; + xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN ); + + /* The Tx task is spawned with a lower priority than the Rx task. */ + xTaskCreate( vComTxTask, ( signed portCHAR * ) "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( xTaskHandle * ) NULL ); + xTaskCreate( vComRxTask, ( signed portCHAR * ) "COMRx", comSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComTxTask, pvParameters ) +{ +signed portCHAR cByteToSend; +portTickType xTimeToWait; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Simply transmit a sequence of characters from comFIRST_BYTE to + comLAST_BYTE. */ + for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ ) + { + if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS ) + { + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE ); + + /* We have posted all the characters in the string - wait before + re-sending. Wait a pseudo-random time as this will provide a better + test. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComRxTask, pvParameters ) +{ +signed portCHAR cExpectedByte, cByteRxed; +portBASE_TYPE xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* We expect to receive the characters from comFIRST_BYTE to + comLAST_BYTE in an incrementing order. Loop to receive each byte. */ + for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ ) + { + /* Block on the queue that contains received bytes until a byte is + available. */ + if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) + { + /* Was this the byte we were expecting? If so, toggle the LED, + otherwise we are out on sync and should break out of the loop + until the expected character sequence is about to restart. */ + if( cByteRxed == cExpectedByte ) + { + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + else + { + xResyncRequired = pdTRUE; + break; /*lint !e960 Non-switch break allowed. */ + } + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); + + /* Did we break out of the loop because the characters were received in + an unexpected order? If so wait here until the character sequence is + about to restart. */ + if( xResyncRequired == pdTRUE ) + { + while( cByteRxed != comLAST_BYTE ) + { + /* Block until the next char is available. */ + xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ); + } + + /* Note that an error occurred which caused us to have to resync. + We use this to stop incrementing the loop counter so + sAreComTestTasksStillRunning() will return false - indicating an + error. */ + xErrorOccurred++; + + /* We have now resynced with the Tx task and can continue. */ + xResyncRequired = pdFALSE; + } + else + { + if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) + { + /* Increment the count of successful loops. As error + occurring (i.e. an unexpected character being received) will + prevent this counter being incremented for the rest of the + execution. Don't worry about mutual exclusion on this + variable - it doesn't really matter as we just want it + to change. */ + uxRxLoops++; + } + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreComTestTasksStillRunning( void ) +{ +portBASE_TYPE xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and we will return false. */ + if( uxRxLoops == comINITIAL_RX_COUNT_VALUE ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again we expect this to have been incremented. */ + uxRxLoops = comINITIAL_RX_COUNT_VALUE; + + return xReturn; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/countsem.c b/FreeRtosCore/Demo/Common/Minimal/countsem.c new file mode 100644 index 0000000..97b3f91 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/countsem.c @@ -0,0 +1,308 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * Simple demonstration of the usage of counting semaphore. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "countsem.h" + +/* The maximum count value that the semaphore used for the demo can hold. */ +#define countMAX_COUNT_VALUE ( 200 ) + +/* Constants used to indicate whether or not the semaphore should have been +created with its maximum count value, or its minimum count value. These +numbers are used to ensure that the pointers passed in as the task parameters +are valid. */ +#define countSTART_AT_MAX_COUNT ( 0xaa ) +#define countSTART_AT_ZERO ( 0x55 ) + +/* Two tasks are created for the test. One uses a semaphore created with its +count value set to the maximum, and one with the count value set to zero. */ +#define countNUM_TEST_TASKS ( 2 ) +#define countDONT_BLOCK ( 0 ) + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile portBASE_TYPE xErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +/* + * The demo task. This simply counts the semaphore up to its maximum value, + * the counts it back down again. The result of each semaphore 'give' and + * 'take' is inspected, with an error being flagged if it is found not to be + * the expected result. + */ +static void prvCountingSemaphoreTask( void *pvParameters ); + +/* + * Utility function to increment the semaphore count value up from zero to + * countMAX_COUNT_VALUE. + */ +static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter ); + +/* + * Utility function to decrement the semaphore count value up from + * countMAX_COUNT_VALUE to zero. + */ +static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter ); + +/*-----------------------------------------------------------*/ + +/* The structure that is passed into the task as the task parameter. */ +typedef struct COUNT_SEM_STRUCT +{ + /* The semaphore to be used for the demo. */ + xSemaphoreHandle xSemaphore; + + /* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with + its count value set to its max count value, or countSTART_AT_ZERO if it + should have been created with its count value set to 0. */ + unsigned portBASE_TYPE uxExpectedStartCount; + + /* Incremented on each cycle of the demo task. Used to detect a stalled + task. */ + unsigned portBASE_TYPE uxLoopCounter; +} xCountSemStruct; + +/* Two structures are defined, one is passed to each test task. */ +static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ]; + +/*-----------------------------------------------------------*/ + +void vStartCountingSemaphoreTasks( void ) +{ + /* Create the semaphores that we are going to use for the test/demo. The + first should be created such that it starts at its maximum count value, + the second should be created such that it starts with a count value of zero. */ + xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE ); + xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT; + xParameters[ 0 ].uxLoopCounter = 0; + + xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 ); + xParameters[ 1 ].uxExpectedStartCount = 0; + xParameters[ 1 ].uxLoopCounter = 0; + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 0 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_1" ); + vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 1 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_2" ); + + + /* Were the semaphores created? */ + if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) ) + { + /* Create the demo tasks, passing in the semaphore to use as the parameter. */ + xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter ) +{ +unsigned portBASE_TYPE ux; + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter ) +{ +unsigned portBASE_TYPE ux; + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + if( xSemaphoreGive( xSemaphore ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvCountingSemaphoreTask( void *pvParameters ) +{ +xCountSemStruct *pxParameter; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); + + const portCHAR * const pcTaskStartMsg = "Counting semaphore demo started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + /* The semaphore to be used was passed as the parameter. */ + pxParameter = ( xCountSemStruct * ) pvParameters; + + /* Did we expect to find the semaphore already at its max count value, or + at zero? */ + if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT ) + { + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } + + /* Now we expect the semaphore count to be 0, so this time there is an + error if we can take the semaphore. */ + if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + for( ;; ) + { + prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void ) +{ +static unsigned portBASE_TYPE uxLastCount0 = 0, uxLastCount1 = 0; +portBASE_TYPE xReturn = pdPASS; + + /* Return fail if any 'give' or 'take' did not result in the expected + behaviour. */ + if( xErrorDetected != pdFALSE ) + { + xReturn = pdFAIL; + } + + /* Return fail if either task is not still incrementing its loop counter. */ + if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount0 = xParameters[ 0 ].uxLoopCounter; + } + + if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount1 = xParameters[ 1 ].uxLoopCounter; + } + + return xReturn; +} + + diff --git a/FreeRtosCore/Demo/Common/Minimal/crflash.c b/FreeRtosCore/Demo/Common/Minimal/crflash.c new file mode 100644 index 0000000..7ee88ea --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/crflash.c @@ -0,0 +1,232 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This demo application file demonstrates the use of queues to pass data + * between co-routines. + * + * N represents the number of 'fixed delay' co-routines that are created and + * is set during initialisation. + * + * N 'fixed delay' co-routines are created that just block for a fixed + * period then post the number of an LED onto a queue. Each such co-routine + * uses a different block period. A single 'flash' co-routine is also created + * that blocks on the same queue, waiting for the number of the next LED it + * should flash. Upon receiving a number it simply toggle the instructed LED + * then blocks on the queue once more. In this manner each LED from LED 0 to + * LED N-1 is caused to flash at a different rate. + * + * The 'fixed delay' co-routines are created with co-routine priority 0. The + * flash co-routine is created with co-routine priority 1. This means that + * the queue should never contain more than a single item. This is because + * posting to the queue will unblock the 'flash' co-routine, and as this has + * a priority greater than the tasks posting to the queue it is guaranteed to + * have emptied the queue and blocked once again before the queue can contain + * any more date. An error is indicated if an attempt to post data to the + * queue fails - indicating that the queue is already full. + * + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "partest.h" +#include "crflash.h" + +/* The queue should only need to be of length 1. See the description at the +top of the file. */ +#define crfQUEUE_LENGTH 1 + +#define crfFIXED_DELAY_PRIORITY 0 +#define crfFLASH_PRIORITY 1 + +/* Only one flash co-routine is created so the index is not significant. */ +#define crfFLASH_INDEX 0 + +/* Don't allow more than crfMAX_FLASH_TASKS 'fixed delay' co-routines to be +created. */ +#define crfMAX_FLASH_TASKS 8 + +/* We don't want to block when posting to the queue. */ +#define crfPOSTING_BLOCK_TIME 0 + +/* + * The 'fixed delay' co-routine as described at the top of the file. + */ +static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ); + +/* + * The 'flash' co-routine as described at the top of the file. + */ +static void prvFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ); + +/* The queue used to pass data between the 'fixed delay' co-routines and the +'flash' co-routine. */ +static xQueueHandle xFlashQueue; + +/* This will be set to pdFALSE if we detect an error. */ +static portBASE_TYPE xCoRoutineFlashStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* + * See the header file for details. + */ +void vStartFlashCoRoutines( unsigned portBASE_TYPE uxNumberToCreate ) +{ +unsigned portBASE_TYPE uxIndex; + + if( uxNumberToCreate > crfMAX_FLASH_TASKS ) + { + uxNumberToCreate = crfMAX_FLASH_TASKS; + } + + /* Create the queue used to pass data between the co-routines. */ + xFlashQueue = xQueueCreate( crfQUEUE_LENGTH, sizeof( unsigned portBASE_TYPE ) ); + + if( xFlashQueue ) + { + /* Create uxNumberToCreate 'fixed delay' co-routines. */ + for( uxIndex = 0; uxIndex < uxNumberToCreate; uxIndex++ ) + { + xCoRoutineCreate( prvFixedDelayCoRoutine, crfFIXED_DELAY_PRIORITY, uxIndex ); + } + + /* Create the 'flash' co-routine. */ + xCoRoutineCreate( prvFlashCoRoutine, crfFLASH_PRIORITY, crfFLASH_INDEX ); + } +} +/*-----------------------------------------------------------*/ + +static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) +{ +/* Even though this is a co-routine the xResult variable does not need to be +static as we do not need it to maintain its state between blocks. */ +signed portBASE_TYPE xResult; +/* The uxIndex parameter of the co-routine function is used as an index into +the xFlashRates array to obtain the delay period to use. */ +static const portTickType xFlashRates[ crfMAX_FLASH_TASKS ] = { 150 / portTICK_RATE_MS, + 200 / portTICK_RATE_MS, + 250 / portTICK_RATE_MS, + 300 / portTICK_RATE_MS, + 350 / portTICK_RATE_MS, + 400 / portTICK_RATE_MS, + 450 / portTICK_RATE_MS, + 500 / portTICK_RATE_MS }; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + + for( ;; ) + { + /* Post our uxIndex value onto the queue. This is used as the LED to + flash. */ + crQUEUE_SEND( xHandle, xFlashQueue, ( void * ) &uxIndex, crfPOSTING_BLOCK_TIME, &xResult ); + + if( xResult != pdPASS ) + { + /* For the reasons stated at the top of the file we should always + find that we can post to the queue. If we could not then an error + has occurred. */ + xCoRoutineFlashStatus = pdFAIL; + } + + crDELAY( xHandle, xFlashRates[ uxIndex ] ); + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +static void prvFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) +{ +/* Even though this is a co-routine the variable do not need to be +static as we do not need it to maintain their state between blocks. */ +signed portBASE_TYPE xResult; +unsigned portBASE_TYPE uxLEDToFlash; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + ( void ) uxIndex; + + for( ;; ) + { + /* Block to wait for the number of the LED to flash. */ + crQUEUE_RECEIVE( xHandle, xFlashQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + + if( xResult != pdPASS ) + { + /* We would not expect to wake unless we received something. */ + xCoRoutineFlashStatus = pdFAIL; + } + else + { + /* We received the number of an LED to flash - flash it! */ + vParTestToggleLED( uxLEDToFlash ); + } + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreFlashCoRoutinesStillRunning( void ) +{ + /* Return pdPASS or pdFAIL depending on whether an error has been detected + or not. */ + return xCoRoutineFlashStatus; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/crhook.c b/FreeRtosCore/Demo/Common/Minimal/crhook.c new file mode 100644 index 0000000..24948eb --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/crhook.c @@ -0,0 +1,256 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This demo file demonstrates how to send data between an ISR and a + * co-routine. A tick hook function is used to periodically pass data between + * the RTOS tick and a set of 'hook' co-routines. + * + * hookNUM_HOOK_CO_ROUTINES co-routines are created. Each co-routine blocks + * to wait for a character to be received on a queue from the tick ISR, checks + * to ensure the character received was that expected, then sends the number + * back to the tick ISR on a different queue. + * + * The tick ISR checks the numbers received back from the 'hook' co-routines + * matches the number previously sent. + * + * If at any time a queue function returns unexpectedly, or an incorrect value + * is received either by the tick hook or a co-routine then an error is + * latched. + * + * This demo relies on each 'hook' co-routine to execute between each + * hookTICK_CALLS_BEFORE_POST tick interrupts. This and the heavy use of + * queues from within an interrupt may result in an error being detected on + * slower targets simply due to timing. + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "crhook.h" + +/* The number of 'hook' co-routines that are to be created. */ +#define hookNUM_HOOK_CO_ROUTINES ( 4 ) + +/* The number of times the tick hook should be called before a character is +posted to the 'hook' co-routines. */ +#define hookTICK_CALLS_BEFORE_POST ( 500 ) + +/* There should never be more than one item in any queue at any time. */ +#define hookHOOK_QUEUE_LENGTH ( 1 ) + +/* Don't block when initially posting to the queue. */ +#define hookNO_BLOCK_TIME ( 0 ) + +/* The priority relative to other co-routines (rather than tasks) that the +'hook' co-routines should take. */ +#define mainHOOK_CR_PRIORITY ( 1 ) +/*-----------------------------------------------------------*/ + +/* + * The co-routine function itself. + */ +static void prvHookCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ); + + +/* + * The tick hook function. This receives a number from each 'hook' co-routine + * then sends a number to each co-routine. An error is flagged if a send or + * receive fails, or an unexpected number is received. + */ +void vApplicationTickHook( void ); + +/*-----------------------------------------------------------*/ + +/* Queues used to send data FROM a co-routine TO the tick hook function. +The hook functions received (Rx's) on these queues. One queue per +'hook' co-routine. */ +static xQueueHandle xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Queues used to send data FROM the tick hook TO a co-routine function. +The hood function transmits (Tx's) on these queues. One queue per +'hook' co-routine. */ +static xQueueHandle xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Set to true if an error is detected at any time. */ +static portBASE_TYPE xCoRoutineErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartHookCoRoutines( void ) +{ +unsigned portBASE_TYPE uxIndex, uxValueToPost = 0; + + for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ ) + { + /* Create a queue to transmit to and receive from each 'hook' + co-routine. */ + xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( unsigned portBASE_TYPE ) ); + xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( unsigned portBASE_TYPE ) ); + + /* To start things off the tick hook function expects the queue it + uses to receive data to contain a value. */ + xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME ); + + /* Create the 'hook' co-routine itself. */ + xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex ); + } +} +/*-----------------------------------------------------------*/ + +static unsigned portBASE_TYPE uxCallCounter = 0, uxNumberToPost = 0; +void vApplicationTickHook( void ) +{ +unsigned portBASE_TYPE uxReceivedNumber; +signed portBASE_TYPE xIndex, xCoRoutineWoken; + + /* Is it time to talk to the 'hook' co-routines again? */ + uxCallCounter++; + if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST ) + { + uxCallCounter = 0; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + xCoRoutineWoken = pdFALSE; + if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS ) + { + /* There is no reason why we would not expect the queue to + contain a value. */ + xCoRoutineErrorDetected = pdTRUE; + } + else + { + /* Each queue used to receive data from the 'hook' co-routines + should contain the number we last posted to the same co-routine. */ + if( uxReceivedNumber != uxNumberToPost ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Nothing should be blocked waiting to post to the queue. */ + if( xCoRoutineWoken != pdFALSE ) + { + xCoRoutineErrorDetected = pdTRUE; + } + } + } + + /* Start the next cycle by posting the next number onto each Tx queue. */ + uxNumberToPost++; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE ) + { + /* Posting to the queue should have woken the co-routine that + was blocked on the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvHookCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) +{ +static unsigned portBASE_TYPE uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ]; +portBASE_TYPE xResult; + + /* Each co-routine MUST start with a call to crSTART(); */ + crSTART( xHandle ); + + for( ;; ) + { + /* Wait to receive a value from the tick hook. */ + xResult = pdFAIL; + crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult ); + + /* There is no reason why we should not have received something on + the queue. */ + if( xResult != pdPASS ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Send the same number back to the idle hook so it can verify it. */ + xResult = pdFAIL; + crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult ); + if( xResult != pdPASS ) + { + /* There is no reason why we should not have been able to post to + the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + + /* Each co-routine MUST end with a call to crEND(). */ + crEND(); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreHookCoRoutinesStillRunning( void ) +{ + if( xCoRoutineErrorDetected ) + { + return pdFALSE; + } + else + { + return pdTRUE; + } +} + + + diff --git a/FreeRtosCore/Demo/Common/Minimal/death.c b/FreeRtosCore/Demo/Common/Minimal/death.c new file mode 100644 index 0000000..7c9753e --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/death.c @@ -0,0 +1,246 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * two tasks. The original task is called the creator task, the two tasks it + * creates are called suicidal tasks. + * + * One of the created suicidal tasks kill one other suicidal task before killing + * itself - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V3.0.0 + + CreationCount sizes changed from unsigned portBASE_TYPE to + unsigned portSHORT to minimize the risk of overflowing. + + + Reset of usLastCreationCount added + +Changes from V3.1.0 + + Changed the dummy calculation to use variables of type long, rather than + float. This allows the file to be used with ports that do not support + floating point. + +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" + +#define deathSTACK_SIZE ( configMINIMAL_STACK_SIZE + 60 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static portTASK_FUNCTION_PROTO( vCreateTasks, pvParameters ); + +/* The task function of the dynamically created tasks. */ +static portTASK_FUNCTION_PROTO( vSuicidalTask, pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile unsigned portSHORT usCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. +*/ +static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0; + +/* Tasks are deleted by the idle task. Under heavy load the idle task might +not get much processing time, so it would be legitimate for several tasks to +remain undeleted for a short period. */ +static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 2; + +/* Used to store a handle to the task that should be killed by a suicidal task, +before it kills itself. */ +xTaskHandle xCreatedTask; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE *puxPriority; + + /* Create the Creator tasks - passing in as a parameter the priority at which + the suicidal tasks should be created. */ + puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) ); + *puxPriority = uxPriority; + + xTaskCreate( vCreateTasks, ( signed portCHAR * ) "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = ( unsigned portBASE_TYPE ) uxTaskGetNumberOfTasks(); + + /* FreeRTOS.org versions before V3.0 started the idle-task as the very + first task. The idle task was then already included in uxTasksRunningAtStart. + From FreeRTOS V3.0 on, the idle task is started when the scheduler is + started. Therefore the idle task is not yet accounted for. We correct + this by increasing uxTasksRunningAtStart by 1. */ + uxTasksRunningAtStart++; +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vSuicidalTask, pvParameters ) +{ +volatile portLONG l1, l2; +xTaskHandle xTaskToKill; +const portTickType xDelay = ( portTickType ) 200 / portTICK_RATE_MS; + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Two created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( xTaskHandle* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + l1 = 2; + l2 = 89; + l2 *= l1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( portTickType ) 0 ); + + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCreateTasks, pvParameters ) +{ +const portTickType xDelay = ( portTickType ) 1000 / portTICK_RATE_MS; +unsigned portBASE_TYPE uxPriority; + + uxPriority = *( unsigned portBASE_TYPE * ) pvParameters; + vPortFree( pvParameters ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xCreatedTask = NULL; + + xTaskCreate( vSuicidalTask, ( signed portCHAR * ) "SUICID1", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xCreatedTask ); + xTaskCreate( vSuicidalTask, ( signed portCHAR * ) "SUICID2", configMINIMAL_STACK_SIZE, &xCreatedTask, uxPriority, NULL ); + + ++usCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +portBASE_TYPE xIsCreateTaskStillRunning( void ) +{ +static unsigned portSHORT usLastCreationCount = 0xfff; +portBASE_TYPE xReturn = pdTRUE; +static unsigned portBASE_TYPE uxTasksRunningNow; + + if( usLastCreationCount == usCreationCount ) + { + xReturn = pdFALSE; + } + else + { + usLastCreationCount = usCreationCount; + } + + uxTasksRunningNow = ( unsigned portBASE_TYPE ) uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + xReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + xReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return xReturn; +} + + diff --git a/FreeRtosCore/Demo/Common/Minimal/dynamic.c b/FreeRtosCore/Demo/Common/Minimal/dynamic.c new file mode 100644 index 0000000..ab77841 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/dynamic.c @@ -0,0 +1,425 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises it's priority above that of the controller task before each + * increment, lowering it again to it's original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of it's loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume (). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from it's suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" + +/* Function that implements the "limited count" task as described above. */ +static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters ); + +/* Function that implements the controller task as described above. */ +static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters ); + +static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters ); +static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters ); + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME ( ( portTickType ) 128 / portTICK_RATE_MS ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( unsigned portLONG ) 0xff ) +#define priNO_BLOCK ( ( portTickType ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static xTaskHandle xContinousIncrementHandle, xLimitedIncrementHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static unsigned portLONG ulCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static volatile unsigned portSHORT usCheckVariable = ( unsigned portSHORT ) 0; +static volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE; +static volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE; + +/* Queue used by the second test. */ +xQueueHandle xSuspendedTestQueue; + +/*-----------------------------------------------------------*/ +/* + * Start the three tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned portLONG ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xSuspendedTestQueue, ( signed portCHAR * ) "Suspended_Test_Queue" ); + + xTaskCreate( vContinuousIncrementTask, ( signed portCHAR * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, ( signed portCHAR * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, ( signed portCHAR * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, ( signed portCHAR * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, ( signed portCHAR * ) "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters ) +{ +unsigned portLONG *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned portLONG * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters ) +{ +unsigned portLONG *pulCounter; +unsigned portBASE_TYPE uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned portLONG * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise our priority above the controller task to ensure a context + switch does not occur while we are accessing this variable. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + ( *pulCounter )++; + vTaskPrioritySet( NULL, uxOurPriority ); + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static portTASK_FUNCTION( vCounterControlTask, pvParameters ) +{ +unsigned portLONG ulLastCounter; +portSHORT sLoops; +portSHORT sError = pdFALSE; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( unsigned portLONG ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. */ + vTaskSuspend( xContinousIncrementHandle ); + ulLastCounter = ulCounter; + vTaskResume( xContinousIncrementHandle ); + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + } + } + xTaskResumeAll(); + } + + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared variable. */ + vTaskSuspend( xContinousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( unsigned portLONG ) 0; + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. */ + vTaskResume( xLimitedIncrementHandle ); + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinousIncrementHandle ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters ) +{ +static unsigned portLONG ulValueToSend = ( unsigned portLONG ) 0; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters ) +{ +static unsigned portLONG ulExpectedValue = ( unsigned portLONG ) 0, ulReceivedValue; +portBASE_TYPE xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + + ++ulExpectedValue; + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static unsigned portSHORT usLastTaskCheck = ( unsigned portSHORT ) 0; +portBASE_TYPE xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + return xReturn; +} diff --git a/FreeRtosCore/Demo/Common/Minimal/flash.c b/FreeRtosCore/Demo/Common/Minimal/flash.c new file mode 100644 index 0000000..87ad3bc --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/flash.c @@ -0,0 +1,143 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/** + * This version of flash .c is for use on systems that have limited stack space + * and no display facilities. The complete version can be found in the + * Demo/Common/Full directory. + * + * Three tasks are created, each of which flash an LED at a different rate. The first + * LED flashes every 200ms, the second every 400ms, the third every 600ms. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE +#define ledNUMBER_OF_LEDS ( 3 ) +#define ledFLASH_RATE_BASE ( ( portTickType ) 333 ) + +/* Variable used by the created tasks to calculate the LED number to use, and +the rate at which they should flash the LED. */ +static volatile unsigned portBASE_TYPE uxFlashTaskNumber = 0; + +/* The task that is created three times. */ +static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority ) +{ +signed portBASE_TYPE xLEDTask; + + /* Create the three tasks. */ + for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask ) + { + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, ( signed portCHAR * ) "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vLEDFlashTask, pvParameters ) +{ +portTickType xFlashRate, xLastFlashTime; +unsigned portBASE_TYPE uxLED; + + /* The parameters are not used. */ + ( void ) pvParameters; + + /* Calculate the LED and flash rate. */ + portENTER_CRITICAL(); + { + /* See which of the eight LED's we should use. */ + uxLED = uxFlashTaskNumber; + + /* Update so the next task uses the next LED. */ + uxFlashTaskNumber++; + } + portEXIT_CRITICAL(); + + xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) uxLED ); + xFlashRate /= portTICK_RATE_MS; + + /* We will turn the LED on and off again in the delay period, so each + delay is only half the total period. */ + xFlashRate /= ( portTickType ) 2; + + /* We need to initialise xLastFlashTime prior to the first call to + vTaskDelayUntil(). */ + xLastFlashTime = xTaskGetTickCount(); + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + } +} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */ + diff --git a/FreeRtosCore/Demo/Common/Minimal/flop.c b/FreeRtosCore/Demo/Common/Minimal/flop.c new file mode 100644 index 0000000..223b5a2 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/flop.c @@ -0,0 +1,349 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * Creates eight tasks, each of which loops continuously performing an (emulated) + * floating point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE configMINIMAL_STACK_SIZE +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile unsigned portSHORT usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, ( signed portCHAR * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, ( signed portCHAR * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, ( signed portCHAR * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, ( signed portCHAR * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, ( signed portCHAR * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, ( signed portCHAR * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, ( signed portCHAR * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, ( signed portCHAR * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile unsigned portSHORT *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +portSHORT sError = pdFALSE; + + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + dAnswer = ( d1 + d2 ) * d3; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile unsigned portSHORT *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +portSHORT sError = pdFALSE; + + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + dAnswer = ( d1 / d2 ) * d3; + + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned portSHORT *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +portSHORT sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5; + dTotal1 += ( portDOUBLE ) xPosition + 5.5; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned portSHORT *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +portSHORT sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123; + dTotal1 += ( portDOUBLE ) xPosition * 12.123; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned portSHORT usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/FreeRtosCore/Demo/Common/Minimal/integer.c b/FreeRtosCore/Demo/Common/Minimal/integer.c new file mode 100644 index 0000000..0e3c012 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/integer.c @@ -0,0 +1,210 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This version of integer. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * As with the full version, the tasks created in this file are a good test + * of the scheduler context switch mechanism. The processor has to access + * 32bit variables in two or four chunks (depending on the processor). The low + * priority of these tasks means there is a high probability that a context + * switch will occur mid calculation. See flop. c documentation for + * more information. + * + */ + +/* +Changes from V1.2.1 + + + The constants used in the calculations are larger to ensure the + optimiser does not truncate them to 16 bits. + +Changes from V1.2.3 + + + uxTaskCheck is now just used as a boolean. Instead of incrementing + the variable each cycle of the task, the variable is simply set to + true. sAreIntegerMathsTaskStillRunning() sets it back to false and + expects it to have been set back to true by the time it is called + again. + + A division has been included in the calculation. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "integer.h" + +/* The constants used in the calculation. */ +#define intgCONST1 ( ( portLONG ) 123 ) +#define intgCONST2 ( ( portLONG ) 234567 ) +#define intgCONST3 ( ( portLONG ) -3 ) +#define intgCONST4 ( ( portLONG ) 7 ) +#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 ) + +#define intgSTACK_SIZE configMINIMAL_STACK_SIZE + +/* As this is the minimal version, we will only create one task. */ +#define intgNUMBER_OF_TASKS ( 1 ) + +/* The task function. Repeatedly performs a 32 bit calculation, checking the +result against the expected result. If the result is incorrect then the +context switch must have caused some corruption. */ +static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters ); + +/* Variables that are set to true within the calculation task to indicate +that the task is still executing. The check task sets the variable back to +false, flagging an error if the variable is still false the next time it +is called. */ +static volatile signed portBASE_TYPE xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( signed portBASE_TYPE ) pdFALSE }; + +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority ) +{ +portSHORT sTask; + + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + xTaskCreate( vCompeteingIntMathTask, ( signed portCHAR * ) "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( xTaskHandle * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters ) +{ +/* These variables are all effectively set to constants so they are volatile to +ensure the compiler does not just get rid of them. */ +volatile portLONG lValue; +portSHORT sError = pdFALSE; +volatile signed portBASE_TYPE *pxTaskHasExecuted; + + /* Set a pointer to the variable we are going to set to true each + iteration. This is also a good test of the parameter passing mechanism + within each port. */ + pxTaskHasExecuted = ( volatile signed portBASE_TYPE * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + /* Perform the calculation. This will store partial value in + registers, resulting in a good test of the context switch mechanism. */ + lValue = intgCONST1; + lValue += intgCONST2; + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + /* Finish off the calculation. */ + lValue *= intgCONST3; + lValue /= intgCONST4; + + /* If the calculation is found to be incorrect we stop setting the + TaskHasExecuted variable so the check task can see an error has + occurred. */ + if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */ + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* We have not encountered any errors, so set the flag that show + we are still executing. This will be periodically cleared by + the check task. */ + portENTER_CRITICAL(); + *pxTaskHasExecuted = pdTRUE; + portEXIT_CRITICAL(); + } + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreIntegerMathsTaskStillRunning( void ) +{ +portBASE_TYPE xReturn = pdTRUE; +portSHORT sTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still being set to true. */ + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + if( xTaskCheck[ sTask ] == pdFALSE ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + /* Reset the check variable so we can tell if it has been set by + the next time around. */ + xTaskCheck[ sTask ] = pdFALSE; + } + + return xReturn; +} + diff --git a/FreeRtosCore/Demo/Common/Minimal/recmutex.c b/FreeRtosCore/Demo/Common/Minimal/recmutex.c new file mode 100644 index 0000000..6df8a05 --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/recmutex.c @@ -0,0 +1,367 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + The tasks defined on this page demonstrate the use of recursive mutexes. + + For recursive mutex functionality the created mutex should be created using + xSemaphoreCreateRecursiveMutex(), then be manipulated + using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API + functions. + + This demo creates three tasks all of which access the same recursive mutex: + + prvRecursiveMutexControllingTask() has the highest priority so executes + first and grabs the mutex. It then performs some recursive accesses - + between each of which it sleeps for a short period to let the lower + priority tasks execute. When it has completed its demo functionality + it gives the mutex back before suspending itself. + + prvRecursiveMutexBlockingTask() attempts to access the mutex by performing + a blocking 'take'. The blocking task has a lower priority than the + controlling task so by the time it executes the mutex has already been + taken by the controlling task, causing the blocking task to block. It + does not unblock until the controlling task has given the mutex back, + and it does not actually run until the controlling task has suspended + itself (due to the relative priorities). When it eventually does obtain + the mutex all it does is give the mutex back prior to also suspending + itself. At this point both the controlling task and the blocking task are + suspended. + + prvRecursiveMutexPollingTask() runs at the idle priority. It spins round + a tight loop attempting to obtain the mutex with a non-blocking call. As + the lowest priority task it will not successfully obtain the mutex until + both the controlling and blocking tasks are suspended. Once it eventually + does obtain the mutex it first unsuspends both the controlling task and + blocking task prior to giving the mutex back - resulting in the polling + task temporarily inheriting the controlling tasks priority. +*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "recmutex.h" + +/* Priorities assigned to the three tasks. */ +#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/* The recursive call depth. */ +#define recmuMAX_COUNT ( 10 ) + +/* Misc. */ +#define recmuSHORT_DELAY ( 20 / portTICK_RATE_MS ) +#define recmuNO_DELAY ( ( portTickType ) 0 ) +#define recmuTWO_TICK_DELAY ( ( portTickType ) 2 ) + +/* The three tasks as described at the top of this file. */ +static void prvRecursiveMutexControllingTask( void *pvParameters ); +static void prvRecursiveMutexBlockingTask( void *pvParameters ); +static void prvRecursiveMutexPollingTask( void *pvParameters ); + +/* The mutex used by the demo. */ +static xSemaphoreHandle xMutex; + +/* Variables used to detect and latch errors. */ +static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE; +static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles, uxPollingCycles = 0; + +/* Handles of the two higher priority tasks, required so they can be resumed +(unsuspended). */ +static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle; + +/*-----------------------------------------------------------*/ + +void vStartRecursiveMutexTasks( void ) +{ + /* Just creates the mutex and the three tasks. */ + + xMutex = xSemaphoreCreateRecursiveMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Recursive_Mutex" ); + + + if( xMutex != NULL ) + { + xTaskCreate( prvRecursiveMutexControllingTask, ( signed portCHAR * ) "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); + xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); + xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexControllingTask( void *pvParameters ) +{ +unsigned portBASE_TYPE ux; + + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Should not be able to 'give' the mutex, as we have not yet 'taken' + it. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* We should now be able to take the mutex as many times as + we like. A one tick delay is used so the polling task will + inherit our priority on all but the first cycle of this task. + If we did not block attempting to receive the mutex then no + priority inheritance would occur. */ + if( xSemaphoreTakeRecursive( xMutex, recmuTWO_TICK_DELAY ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute. */ + vTaskDelay( recmuSHORT_DELAY ); + } + + /* For each time we took the mutex, give it back. */ + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute. */ + vTaskDelay( recmuSHORT_DELAY ); + + /* We should now be able to give the mutex as many times as we + took it. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Having given it back the same number of times as it was taken, we + should no longer be the mutex owner, so the next give sh ould fail. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxControllingCycles++; + + /* Suspend ourselves to the blocking task can execute. */ + xControllingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xControllingIsSuspended = pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexBlockingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Attempt to obtain the mutex. We should block until the + controlling task has given up the mutex, and not actually execute + past this call until the controlling task is suspended. */ + if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS ) + { + if( xControllingIsSuspended != pdTRUE ) + { + /* Did not expect to execute until the controlling task was + suspended. */ + xErrorOccurred = pdTRUE; + } + else + { + /* Give the mutex back before suspending ourselves to allow + the polling task to obtain the mutex. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + xBlockingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xBlockingIsSuspended = pdFALSE; + } + } + else + { + /* We should not leave the xSemaphoreTakeRecursive() function + until the mutex was obtained. */ + xErrorOccurred = pdTRUE; + } + + /* The controlling and blocking tasks should be in lock step. */ + if( uxControllingCycles != ( uxBlockingCycles + 1 ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxBlockingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexPollingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Keep attempting to obtain the mutex. We should only obtain it when + the blocking task has suspended itself. */ + if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS ) + { + /* Is the blocking task suspended? */ + if( xBlockingIsSuspended != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + else + { + /* Keep count of the number of cycles this task has performed so + a stall can be detected. */ + uxPollingCycles++; + + /* We can resume the other tasks here even though they have a + higher priority than the polling task. When they execute they + will attempt to obtain the mutex but fail because the polling + task is still the mutex holder. The polling task (this task) + will then inherit the higher priority. */ + vTaskResume( xBlockingTaskHandle ); + vTaskResume( xControllingTaskHandle ); + + /* Release the mutex, disinheriting the higher priority again. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + } + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void ) +{ +portBASE_TYPE xReturn; +static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0; + + /* Is the controlling task still cycling? */ + if( uxLastControllingCycles == uxControllingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastControllingCycles = uxControllingCycles; + } + + /* Is the blocking task still cycling? */ + if( uxLastBlockingCycles == uxBlockingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastBlockingCycles = uxBlockingCycles; + } + + /* Is the polling task still cycling? */ + if( uxLastPollingCycles == uxPollingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastPollingCycles = uxPollingCycles; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + + + + diff --git a/FreeRtosCore/Demo/Common/Minimal/semtest.c b/FreeRtosCore/Demo/Common/Minimal/semtest.c new file mode 100644 index 0000000..f4bdb1f --- /dev/null +++ b/FreeRtosCore/Demo/Common/Minimal/semtest.c @@ -0,0 +1,282 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned portLONG ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned portLONG ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( portTickType ) 10 ) + +/* The task function as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + xSemaphoreHandle xSemaphore; + volatile unsigned portLONG *pulSharedVariable; + portTickType xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile portSHORT sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile portSHORT sNextCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const portTickType xBlockTime = ( portTickType ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore ); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned portLONG * ) pvPortMalloc( sizeof( unsigned portLONG ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( portTickType ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, ( signed portCHAR * ) "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL ); + xTaskCreate( prvSemaphoreTest, ( signed portCHAR * ) "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore ); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned portLONG * ) pvPortMalloc( sizeof( unsigned portLONG ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS; + + xTaskCreate( prvSemaphoreTest, ( signed portCHAR * ) "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL ); + xTaskCreate( prvSemaphoreTest, ( signed portCHAR * ) "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL ); + } + } + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) pxFirstSemaphoreParameters->xSemaphore, ( signed portCHAR * ) "Counting_Sem_1" ); + vQueueAddToRegistry( ( xQueueHandle ) pxSecondSemaphoreParameters->xSemaphore, ( signed portCHAR * ) "Counting_Sem_2" ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvSemaphoreTest, pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile unsigned portLONG *pulSharedVariable, ulExpectedValue; +unsigned portLONG ulCounter; +portSHORT sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( portTickType ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( unsigned portLONG ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( portTickType ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreSemaphoreTasksStillRunning( void ) +{ +static portSHORT sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +portBASE_TYPE xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/FreeRtosCore/Demo/Common/include/AltBlckQ.h b/FreeRtosCore/Demo/Common/include/AltBlckQ.h new file mode 100644 index 0000000..b2d9df8 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/AltBlckQ.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef ALT_BLOCK_Q_H +#define ALT_BLOCK_Q_H + +void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreAltBlockingQueuesStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/AltBlock.h b/FreeRtosCore/Demo/Common/include/AltBlock.h new file mode 100644 index 0000000..978ef1d --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/AltBlock.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FAST_BLOCK_TIME_TEST_H +#define FAST_BLOCK_TIME_TEST_H + +void vCreateAltBlockTimeTasks( void ); +portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/AltPollQ.h b/FreeRtosCore/Demo/Common/include/AltPollQ.h new file mode 100644 index 0000000..b83f0dd --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/AltPollQ.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef ALT_POLLED_Q_H +#define ALT_POLLED_Q_H + +void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreAltPollingQueuesStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/AltQTest.h b/FreeRtosCore/Demo/Common/include/AltQTest.h new file mode 100644 index 0000000..2d19870 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/AltQTest.h @@ -0,0 +1,61 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FAST_GEN_Q_TEST_H +#define FAST_GEN_Q_TEST_H + +void vStartAltGenericQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreAltGenericQueueTasksStillRunning( void ); + +#endif /* GEN_Q_TEST_H */ + + + diff --git a/FreeRtosCore/Demo/Common/include/BlockQ.h b/FreeRtosCore/Demo/Common/include/BlockQ.h new file mode 100644 index 0000000..cd22444 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/BlockQ.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef BLOCK_Q_H +#define BLOCK_Q_H + +void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreBlockingQueuesStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/GenQTest.h b/FreeRtosCore/Demo/Common/include/GenQTest.h new file mode 100644 index 0000000..f53316c --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/GenQTest.h @@ -0,0 +1,61 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef GEN_Q_TEST_H +#define GEN_Q_TEST_H + +void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreGenericQueueTasksStillRunning( void ); + +#endif /* GEN_Q_TEST_H */ + + + diff --git a/FreeRtosCore/Demo/Common/include/IntQueue.h b/FreeRtosCore/Demo/Common/include/IntQueue.h new file mode 100644 index 0000000..9371813 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/IntQueue.h @@ -0,0 +1,66 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef QUEUE_ACCESS_TEST +#define QUEUE_ACCESS_TEST + +void vStartInterruptQueueTasks( void ); +portBASE_TYPE xAreIntQueueTasksStillRunning( void ); +portBASE_TYPE xFirstTimerHandler( void ); +portBASE_TYPE xSecondTimerHandler( void ); + +#endif /* QUEUE_ACCESS_TEST */ + + + + + + diff --git a/FreeRtosCore/Demo/Common/include/PollQ.h b/FreeRtosCore/Demo/Common/include/PollQ.h new file mode 100644 index 0000000..7085b52 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/PollQ.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef POLLED_Q_H +#define POLLED_Q_H + +void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xArePollingQueuesStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/QPeek.h b/FreeRtosCore/Demo/Common/include/QPeek.h new file mode 100644 index 0000000..797bf8d --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/QPeek.h @@ -0,0 +1,61 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef Q_PEEK_TEST_H +#define Q_PEEK_TEST_H + +void vStartQueuePeekTasks( void ); +portBASE_TYPE xAreQueuePeekTasksStillRunning( void ); + +#endif /* Q_PEEK_TEST_H */ + + + diff --git a/FreeRtosCore/Demo/Common/include/blocktim.h b/FreeRtosCore/Demo/Common/include/blocktim.h new file mode 100644 index 0000000..6c17edb --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/blocktim.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef BLOCK_TIME_TEST_H +#define BLOCK_TIME_TEST_H + +void vCreateBlockTimeTasks( void ); +portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/comtest.h b/FreeRtosCore/Demo/Common/include/comtest.h new file mode 100644 index 0000000..e181eb6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/comtest.h @@ -0,0 +1,61 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned portLONG ulBaudRate, unsigned portBASE_TYPE uxLED ); +void vStartComTestTasks( unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate ); +portBASE_TYPE xAreComTestTasksStillRunning( void ); +void vComTestUnsuspendTask( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/comtest2.h b/FreeRtosCore/Demo/Common/include/comtest2.h new file mode 100644 index 0000000..811e061 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/comtest2.h @@ -0,0 +1,59 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned portLONG ulBaudRate, unsigned portBASE_TYPE uxLED ); +portBASE_TYPE xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/countsem.h b/FreeRtosCore/Demo/Common/include/countsem.h new file mode 100644 index 0000000..3af5500 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/countsem.h @@ -0,0 +1,59 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef COUNT_SEMAPHORE_TEST_H +#define COUNT_SEMAPHORE_TEST_H + +void vStartCountingSemaphoreTasks( void ); +portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/crflash.h b/FreeRtosCore/Demo/Common/include/crflash.h new file mode 100644 index 0000000..c425118 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/crflash.h @@ -0,0 +1,71 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef CRFLASH_LED_H +#define CRFLASH_LED_H + +/* + * Create the co-routines used to flash the LED's at different rates. + * + * @param uxPriority The number of 'fixed delay' co-routines to create. This + * also effects the number of LED's that will be utilised. For example, + * passing in 3 will cause LED's 0 to 2 to be utilised. + */ +void vStartFlashCoRoutines( unsigned portBASE_TYPE uxPriority ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +portBASE_TYPE xAreFlashCoRoutinesStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/crhook.h b/FreeRtosCore/Demo/Common/include/crhook.h new file mode 100644 index 0000000..efbdc90 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/crhook.h @@ -0,0 +1,67 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef CRHOOK_H +#define CRHOOK_H + +/* + * Create the co-routines used to communicate wit the tick hook. + */ +void vStartHookCoRoutines( void ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +portBASE_TYPE xAreHookCoRoutinesStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/death.h b/FreeRtosCore/Demo/Common/include/death.h new file mode 100644 index 0000000..10cef70 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/death.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef SUICIDE_TASK_H +#define SUICIDE_TASK_H + +void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xIsCreateTaskStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/dynamic.h b/FreeRtosCore/Demo/Common/include/dynamic.h new file mode 100644 index 0000000..17a71e7 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/dynamic.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef DYNAMIC_MANIPULATION_H +#define DYNAMIC_MANIPULATION_H + +void vStartDynamicPriorityTasks( void ); +portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/fileIO.h b/FreeRtosCore/Demo/Common/include/fileIO.h new file mode 100644 index 0000000..0118087 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/fileIO.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FILE_IO_H +#define FILE_OI_H + +void vDisplayMessage( const portCHAR * const pcMessageToPrint ); +void vWriteMessageToDisk( const portCHAR * const pcMessage ); +void vWriteBufferToDisk( const portCHAR * const pcBuffer, unsigned portLONG ulBufferLength ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/flash.h b/FreeRtosCore/Demo/Common/include/flash.h new file mode 100644 index 0000000..8d37db6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/flash.h @@ -0,0 +1,58 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FLASH_LED_H +#define FLASH_LED_H + +void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/flop.h b/FreeRtosCore/Demo/Common/include/flop.h new file mode 100644 index 0000000..f091384 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/flop.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FLOP_TASKS_H +#define FLOP_TASKS_H + +void vStartMathTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreMathsTaskStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/integer.h b/FreeRtosCore/Demo/Common/include/integer.h new file mode 100644 index 0000000..1d4de92 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/integer.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INTEGER_TASKS_H +#define INTEGER_TASKS_H + +void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreIntegerMathsTaskStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/mevents.h b/FreeRtosCore/Demo/Common/include/mevents.h new file mode 100644 index 0000000..594b0e6 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/mevents.h @@ -0,0 +1,60 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef EVENTS_TEST_H +#define EVENTS_TEST_H + +void vStartMultiEventTasks( void ); +portBASE_TYPE xAreMultiEventTasksStillRunning( void ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/partest.h b/FreeRtosCore/Demo/Common/include/partest.h new file mode 100644 index 0000000..9881c06 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/partest.h @@ -0,0 +1,62 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef PARTEST_H +#define PARTEST_H + +#define partstDEFAULT_PORT_ADDRESS ( ( unsigned portSHORT ) 0x378 ) + +void vParTestInitialise( void ); +void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); +void vParTestToggleLED( unsigned portBASE_TYPE uxLED ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/print.h b/FreeRtosCore/Demo/Common/include/print.h new file mode 100644 index 0000000..049794e --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/print.h @@ -0,0 +1,61 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef PRINT_H +#define PRINT_H + +void vPrintInitialise( void ); +void vPrintDisplayMessage( const portCHAR * const * pcMessageToSend ); +const portCHAR *pcPrintGetNextMessage( portTickType xPrintRate ); + +#endif + + diff --git a/FreeRtosCore/Demo/Common/include/recmutex.h b/FreeRtosCore/Demo/Common/include/recmutex.h new file mode 100644 index 0000000..5938ff1 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/recmutex.h @@ -0,0 +1,59 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef RECURSIVE_MUTEX_TEST_H +#define RECURSIVE_MUTEX_TEST_H + +void vStartRecursiveMutexTasks( void ); +portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/semtest.h b/FreeRtosCore/Demo/Common/include/semtest.h new file mode 100644 index 0000000..45de10b --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/semtest.h @@ -0,0 +1,59 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef SEMAPHORE_TEST_H +#define SEMAPHORE_TEST_H + +void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority ); +portBASE_TYPE xAreSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/FreeRtosCore/Demo/Common/include/serial.h b/FreeRtosCore/Demo/Common/include/serial.h new file mode 100644 index 0000000..6206852 --- /dev/null +++ b/FreeRtosCore/Demo/Common/include/serial.h @@ -0,0 +1,122 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef SERIAL_COMMS_H +#define SERIAL_COMMS_H + +typedef void * xComPortHandle; + +typedef enum +{ + serCOM1, + serCOM2, + serCOM3, + serCOM4, + serCOM5, + serCOM6, + serCOM7, + serCOM8 +} eCOMPort; + +typedef enum +{ + serNO_PARITY, + serODD_PARITY, + serEVEN_PARITY, + serMARK_PARITY, + serSPACE_PARITY +} eParity; + +typedef enum +{ + serSTOP_1, + serSTOP_2 +} eStopBits; + +typedef enum +{ + serBITS_5, + serBITS_6, + serBITS_7, + serBITS_8 +} eDataBits; + +typedef enum +{ + ser50, + ser75, + ser110, + ser134, + ser150, + ser200, + ser300, + ser600, + ser1200, + ser1800, + ser2400, + ser4800, + ser9600, + ser19200, + ser38400, + ser57600, + ser115200 +} eBaud; + +xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ); +xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength ); +void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength ); +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime ); +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime ); +portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); +void vSerialClose( xComPortHandle xPort ); + +#endif + diff --git a/FreeRtosCore/License/license.txt b/FreeRtosCore/License/license.txt new file mode 100644 index 0000000..a03bc5a --- /dev/null +++ b/FreeRtosCore/License/license.txt @@ -0,0 +1,856 @@ +The FreeRTOS.org source code is licensed by the modified GNU General Public +License (GPL) text provided below. The FreeRTOS download also includes +demo application source code, some of which is provided by third parties +AND IS LICENSED SEPARATELY FROM FREERTOS.ORG. + +For the avoidance of any doubt refer to the comment included at the top +of each source and header file for license and copyright information. + +This is a list of files for which Richard Barry is not the copyright owner +and are NOT COVERED BY THE GPL. + + +1) Various header files provided by silicon manufacturers and tool vendors + that define processor specific memory addresses and utility macros. + Permission has been granted by the various copyright holders for these + files to be included in the FreeRTOS download. Users must ensure license + conditions are adhered to for any use other than compilation of the + FreeRTOS demo application. + +2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels. + Users must ensure the open source license conditions stated at the top + of each uIP source file is understood and adhered to. + +3) The lwIP TCP/IP stack the copyright of which is held by the Swedish + Institute of Computer Science. Users must ensure the open source license + conditions stated at the top of each lwIP source file is understood and + adhered to. + +4) All files contained within the FreeRTOS\Demo\CORTEX_LM3S102_GCC\hw_include + and FreeRTOS\Demo\CORTEX_LM3S316_IAR\hw_include directories. The + copyright of these files is owned by Luminary Micro. Permission has been + granted by Luminary Micro for these files to be included in the FreeRTOS + download. Users must ensure the license conditions stated in the EULA.txt + file located in the same directories is understood and adhered at all + times for all files in those directories. + +5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code, + which are slightly modified versions of code provided by and copyright to + Tern Inc. + +Errors and omissions should be reported to Richard Barry, contact details for +whom can be obtained from http://www.FreeRTOS.org. + + + + + +The GPL license text follows. + +A special exception to the GPL is included to allow you to distribute a +combined work that includes FreeRTOS.org without being obliged to provide +the source code for any proprietary components. See the licensing section +of http://www.FreeRTOS.org for full details. The exception text is also +included at the bottom of this file. + +-------------------------------------------------------------------- + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License** as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +---------------------------------------------------------------------------- + +GPL Exception + +EXCEPTION TEXT: +Clause 1 + +Linking FreeRTOS statically or dynamically with other modules is making a combined work based on FreeRTOS. Thus, the terms and conditions of the GNU General Public License cover the whole combination. + +As a special exception, the copyright holder of FreeRTOS gives you permission to link FreeRTOS with independent modules that communicate with FreeRTOS solely through the FreeRTOS API interface, regardless of the license terms of these independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that + +Every copy of the combined work is accompanied by a written statement that details to the recipient the version of FreeRTOS used and an offer by yourself to provide the FreeRTOS source code should the recipient request it. +The combined work is not itself an RTOS, scheduler, kernel or related product. +The combined work is not itself a library intended for linking into other software applications. +Any FreeRTOS source code, whether modified or in it's original release form, or whether in whole or in part, can only be distributed by you under the terms of the GNU General Public License plus this exception. An independent module is a module which is not derived from or based on FreeRTOS. +Note that people who make modified versions of FreeRTOS are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU General Public License gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception. + +Clause 2 + +FreeRTOS.org may not be used for any competitive or comparative purpose, including the publication of any form of run time or compile time metric, without the express permission of Richard Barry (this is the norm within the industry and is intended to ensure information accuracy). +The FreeRTOS.org source code is licensed by the modified GNU General Public +License (GPL) text provided below. The FreeRTOS download also includes +demo application source code, some of which is provided by third parties +AND IS LICENSED SEPARATELY FROM FREERTOS.ORG. + +For the avoidance of any doubt refer to the comment included at the top +of each source and header file for license and copyright information. + +This is a list of files for which Richard Barry is not the copyright owner +and are NOT COVERED BY THE GPL. + + +1) Various header files provided by silicon manufacturers and tool vendors + that define processor specific memory addresses and utility macros. + Permission has been granted by the various copyright holders for these + files to be included in the FreeRTOS download. Users must ensure license + conditions are adhered to for any use other than compilation of the + FreeRTOS demo application. + +2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels. + Users must ensure the open source license conditions stated at the top + of each uIP source file is understood and adhered to. + +3) The lwIP TCP/IP stack the copyright of which is held by the Swedish + Institute of Computer Science. Users must ensure the open source license + conditions stated at the top of each lwIP source file is understood and + adhered to. + +4) All files contained within the FreeRTOS\Demo\CORTEX_LM3S102_GCC\hw_include + and FreeRTOS\Demo\CORTEX_LM3S316_IAR\hw_include directories. The + copyright of these files is owned by Luminary Micro. Permission has been + granted by Luminary Micro for these files to be included in the FreeRTOS + download. Users must ensure the license conditions stated in the EULA.txt + file located in the same directories is understood and adhered at all + times for all files in those directories. + +5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code, + which are slightly modified versions of code provided by and copyright to + Tern Inc. + +Errors and omissions should be reported to Richard Barry, contact details for +whom can be obtained from http://www.FreeRTOS.org. + + + + + +The GPL license text follows. + +A special exception to the GPL is included to allow you to distribute a +combined work that includes FreeRTOS.org without being obliged to provide +the source code for any proprietary components. See the licensing section +of http://www.FreeRTOS.org for full details. The exception text is also +included at the bottom of this file. + +-------------------------------------------------------------------- + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License** as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +---------------------------------------------------------------------------- + +The FreeRTOS GPL Exception Text: + +Any FreeRTOS source code, whether modified or in it's original release form, +or whether in whole or in part, can only be distributed by you under the terms +of the GNU General Public License plus this exception. An independent module is +a module which is not derived from or based on FreeRTOS. + +Clause 1: + +Linking FreeRTOS statically or dynamically with other modules is making a +combined work based on FreeRTOS. Thus, the terms and conditions of the GNU +General Public License cover the whole combination. + +As a special exception, the copyright holder of FreeRTOS gives you permission +to link FreeRTOS with independent modules that communicate with FreeRTOS +solely through the FreeRTOS API interface, regardless of the license terms of +these independent modules, and to copy and distribute the resulting combined +work under terms of your choice, provided that + + + Every copy of the combined work is accompanied by a written statement that + details to the recipient the version of FreeRTOS used and an offer by yourself + to provide the FreeRTOS source code should the recipient request it. + + + The combined work is not itself an RTOS, scheduler, kernel or related product. + + + The combined work is not itself a library intended for linking into other + software applications. + +Clause 2: + +FreeRTOS.org may not be used for any competitive or comparative purpose, including +the publication of any form of run time or compile time metric, without the express +permission of Richard Barry (this is the norm within the industry and is intended +to ensure information accuracy). \ No newline at end of file diff --git a/FreeRtosCore/Source/croutine.c b/FreeRtosCore/Source/croutine.c new file mode 100644 index 0000000..d6f1162 --- /dev/null +++ b/FreeRtosCore/Source/croutine.c @@ -0,0 +1,371 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +corCRCB * pxCurrentCoRoutine = NULL; +static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0; +static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) +{ +signed portBASE_TYPE xReturn; +corCRCB *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the xListItem. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) +{ +portTickType xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) ) + { + corCRCB *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + xList * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) + { + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + vListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) +{ +corCRCB *pxUnblockedCRCB; +signed portBASE_TYPE xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. */ + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + diff --git a/FreeRtosCore/Source/include/FreeRTOS.h b/FreeRtosCore/Source/include/FreeRTOS.h new file mode 100644 index 0000000..ee02592 --- /dev/null +++ b/FreeRtosCore/Source/include/FreeRTOS.h @@ -0,0 +1,420 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + + +/* Defines the prototype to which the application task hook function must +conform. */ +typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); + + + + + +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelete + #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskCleanUpResources + #error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskSuspend + #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelay + #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #undef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 1 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#if ( configUSE_MUTEXES == 1 ) + /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism + within the mutex implementation so must be available if mutexes are used. */ + #undef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 1 +#else + #ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 + #endif +#endif + + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0 +#endif + +#if configQUEUE_REGISTRY_SIZE < 1 + #define configQUEUE_REGISTRY_SIZE 0 + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) +#endif + + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED() +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED( pxNewTCB ) +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL() +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined. portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base. + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef pvPortMallocAligned + #define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) ) +#endif + +#ifndef vPortFreeAligned + #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree ) +#endif + +#endif /* INC_FREERTOS_H */ + diff --git a/FreeRtosCore/Source/include/StackMacros.h b/FreeRtosCore/Source/include/StackMacros.h new file mode 100644 index 0000000..a7514d7 --- /dev/null +++ b/FreeRtosCore/Source/include/StackMacros.h @@ -0,0 +1,173 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 0 ) + + /* FreeRTOSConfig.h is not set to check for stack overflows. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 1 ) + + /* FreeRTOSConfig.h is only set to use the first method of + overflow checking. */ + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#endif /* STACK_MACROS_H */ + diff --git a/FreeRtosCore/Source/include/croutine.h b/FreeRtosCore/Source/include/croutine.h new file mode 100644 index 0000000..c189a1e --- /dev/null +++ b/FreeRtosCore/Source/include/croutine.h @@ -0,0 +1,749 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include croutine.h" +#endif + + + + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * xCoRoutineHandle; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + unsigned short uxState; /*< Used internally by the co-routine implementation. */ +} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */ + +/** + * croutine. h + *
+ portBASE_TYPE xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 unsigned portBASE_TYPE uxPriority,
+                                 unsigned portBASE_TYPE uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how long to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+		
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( xCoRoutineHandle xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( xTicksToDelay > 0 ) \ + { \ + vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \ + } \ + crSET_STATE0( xHandle ); + +/** + *
+ crQUEUE_SEND(
+                  xCoRoutineHandle xHandle,
+                  xQueueHandle pxQueue,
+                  void *pvItemToQueue,
+                  portTickType xTicksToWait,
+                  portBASE_TYPE *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \ + if( *pxResult == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( xHandle ); \ + *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( xHandle ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     xCoRoutineHandle xHandle,
+                     xQueueHandle pxQueue,
+                     void *pvBuffer,
+                     portTickType xTicksToWait,
+                     portBASE_TYPE *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \ + if( *pxResult == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( xHandle ); \ + *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( xHandle ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvItemToQueue,
+                            portBASE_TYPE xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ char cRxedChar;
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvBuffer,
+                            portBASE_TYPE * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/FreeRtosCore/Source/include/list.h b/FreeRtosCore/Source/include/list.h new file mode 100644 index 0000000..6571283 --- /dev/null +++ b/FreeRtosCore/Source/include/list.h @@ -0,0 +1,305 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * xLists can only store pointers to xListItems. Each xListItem contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +/* + Changes from V4.3.1 + + + Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist + compiler with optimisation. Thanks B.R. +*/ + +#ifndef LIST_H +#define LIST_H + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST_ITEM +{ + portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */ + volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ +}; +typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + portTickType xItemValue; + volatile struct xLIST_ITEM *pxNext; + volatile struct xLIST_ITEM *pxPrevious; +}; +typedef struct xMINI_LIST_ITEM xMiniListItem; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + volatile unsigned portBASE_TYPE uxNumberOfItems; + volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */ + volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ +} xList; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue + +/* + * Access macro the retrieve the value of the list item. The value can + * represent anything - for example a the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entries pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +xList * const pxConstList = pxList; \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + pxTCB = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE is the list item is in the list, otherwise pdFALSE. + * pointer against + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( xList *pxList ); + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( xListItem *pxItem ); + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item to that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( xList *pxList, xListItem *pxNewListItem ); + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pvIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pvIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pvIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ); + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param vListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * \page vListRemove vListRemove + * \ingroup LinkedList + */ +void vListRemove( xListItem *pxItemToRemove ); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/FreeRtosCore/Source/include/mpu_wrappers.h b/FreeRtosCore/Source/include/mpu_wrappers.h new file mode 100644 index 0000000..e197d50 --- /dev/null +++ b/FreeRtosCore/Source/include/mpu_wrappers.h @@ -0,0 +1,135 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + #define xTaskGenericCreate MPU_xTaskGenericCreate + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define vTaskDelay MPU_vTaskDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define vTaskStartTrace MPU_vTaskStartTrace + #define ulTaskEndTrace MPU_ulTaskEndTrace + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + #define xQueueCreate MPU_xQueueCreate + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueAltGenericSend MPU_xQueueAltGenericSend + #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive + #define xQueueGenericReceive MPU_xQueueGenericReceive + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define vQueueDelete MPU_vQueueDelete + + #define pvPortMalloc MPU_pvPortMalloc + #define vPortFree MPU_vPortFree + #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize + #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks + + #if configQUEUE_REGISTRY_SIZE > 0 + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #endif + + /* Remove the privileged function macro. */ + #define PRIVILEGED_FUNCTION + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + //#define PRIVILEGED_DATA + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/FreeRtosCore/Source/include/portable.h b/FreeRtosCore/Source/include/portable.h new file mode 100644 index 0000000..a439537 --- /dev/null +++ b/FreeRtosCore/Source/include/portable.h @@ -0,0 +1,390 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Include the macro file relevant to the port being used. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +/* Catch all to ensure portmacro.h is included in the build. Newer demos +have the path as part of the project options, rather than as relative from +the project location. If portENTER_CRITICAL() has not been defined then +portmacro.h has not yet been included - as every portmacro.h provides a +portENTER_CRITICAL() definition. Check the demo application for your demo +to find the path to the correct portmacro.h file. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ); +#endif + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/FreeRtosCore/Source/include/projdefs.h b/FreeRtosCore/Source/include/projdefs.h new file mode 100644 index 0000000..25e9560 --- /dev/null +++ b/FreeRtosCore/Source/include/projdefs.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* Defines the prototype to which task functions must conform. */ +typedef void (*pdTASK_CODE)( void * ); + +#define pdTRUE ( 1 ) +#define pdFALSE ( 0 ) + +#define pdPASS ( 1 ) +#define pdFAIL ( 0 ) +#define errQUEUE_EMPTY ( 0 ) +#define errQUEUE_FULL ( 0 ) + +/* Error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errNO_TASK_TO_RUN ( -2 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +#endif /* PROJDEFS_H */ + + + diff --git a/FreeRtosCore/Source/include/queue.h b/FreeRtosCore/Source/include/queue.h new file mode 100644 index 0000000..8759ddb --- /dev/null +++ b/FreeRtosCore/Source/include/queue.h @@ -0,0 +1,1321 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include queue.h" +#endif + + + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "mpu_wrappers.h" + + +typedef void * xQueueHandle; + + +/* For internal use only. */ +#define queueSEND_TO_BACK ( 0 ) +#define queueSEND_TO_FRONT ( 1 ) + + +/** + * queue. h + *
+ xQueueHandle xQueueCreate(
+							  unsigned portBASE_TYPE uxQueueLength,
+							  unsigned portBASE_TYPE uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance. This allocates the storage required by the + * new queue and returns a handle for the queue. + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); + + +/** + * queue. h + *
+ xQueueHandle xQueueCreateExternal(
+							  unsigned portBASE_TYPE uxQueueLength,
+							  unsigned portBASE_TYPE uxItemSize
+							  memory address
+						  );
+ * 
+ * + * Creates a new queue instance. This allocates in external, specyfied by user memory the storage required by the + * new queue and returns a handle for the queue. + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreateExternal( 10, sizeof( unsigned long ), 0x8000 );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreateExternal( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +xQueueHandle xQueueCreateExternal( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, void *address); + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToToFront(
+								   xQueueHandle	xQueue,
+								   const	void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBack(
+								   xQueueHandle	xQueue,
+								   const	void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSend(
+							  xQueueHandle xQueue,
+							  const void * pvItemToQueue,
+							  portTickType xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSend(
+									xQueueHandle xQueue,
+									const void * pvItemToQueue,
+									portTickType xTicksToWait
+									portBASE_TYPE xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); + +/** + * queue. h + *
+ portBASE_TYPE xQueuePeek(
+							 xQueueHandle xQueue,
+							 void *pvBuffer,
+							 portTickType xTicksToWait
+						 );
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceive(
+								 xQueueHandle xQueue,
+								 void *pvBuffer,
+								 portTickType xTicksToWait
+							);
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_RATE_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericReceive(
+									   xQueueHandle	xQueue,
+									   void	*pvBuffer,
+									   portTickType	xTicksToWait
+									   portBASE_TYPE	xJustPeek
+									);
+ * + * It is preferred that the macro xQueueReceive() be used rather than calling + * this function directly. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueueGenericReceive() will return immediately if the queue is empty and + * xTicksToWait is 0. + * + * @param xJustPeek When set to true, the item received from the queue is not + * actually removed from the queue - meaning a subsequent call to + * xQueueReceive() will return the same item. When set to false, the item + * being received from the queue is also removed from the queue. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ); + +/** + * queue. h + *
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \page uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ); + +/** + * queue. h + *
void vQueueDelete( xQueueHandle xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \page vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( xQueueHandle xQueue ); + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToFrontFromISR(
+										 xQueueHandle pxQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBackFromISR(
+										 xQueueHandle pxQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendFromISR(
+									 xQueueHandle pxQueue,
+									 const void *pvItemToQueue,
+									 portBASE_TYPE *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		taskYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSendFromISR(
+										   xQueueHandle	pxQueue,
+										   const	void	*pvItemToQueue,
+										   portBASE_TYPE	*pxHigherPriorityTaskWoken,
+										   portBASE_TYPE	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ); + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceiveFromISR(
+									   xQueueHandle	pxQueue,
+									   void	*pvBuffer,
+									   portBASE_TYPE	*pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xBlockTime ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ); + +/* + * Utilities to query queue that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ); +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ); +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ); + + +/* + * xQueueAltGenericSend() is an alternative version of xQueueGenericSend(). + * Likewise xQueueAltGenericReceive() is an alternative version of + * xQueueGenericReceive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); +signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); +#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT ) +#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) +#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE ) +#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE ) + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ); +signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ); +signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ); +signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting() instead of calling these functions directly. + */ +xQueueHandle xQueueCreateMutex( void ); +xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ); + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/FreeRtosCore/Source/include/semphr.h b/FreeRtosCore/Source/include/semphr.h new file mode 100644 index 0000000..3984e4b --- /dev/null +++ b/FreeRtosCore/Source/include/semphr.h @@ -0,0 +1,711 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h" +#endif + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#include "queue.h" + +typedef xQueueHandle xSemaphoreHandle; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 ) +#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
+ * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#define vSemaphoreCreateBinary( xSemaphore ) { \ + xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \ + if( xSemaphore != NULL ) \ + { \ + xSemaphoreGive( xSemaphore ); \ + } \ + } + +/** + * semphr. h + *
xSemaphoreTake( 
+ *                   xSemaphoreHandle xSemaphore, 
+ *                   portTickType xBlockTime 
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the 
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * xSemaphoreHandle xMutex, + * portTickType xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, but instead buried in a more complex
+			// call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime ) + + +/* + * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) + +/** + * semphr. h + *
xSemaphoreGive( xSemaphoreHandle xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex ) + +/* + * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR( 
+                          xSemaphoreHandle xSemaphore, 
+                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore 
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute 
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned char ucLocalTickCount = 0;
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateMutex( void )
+ * + * Macro that implements a mutex semaphore by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros should not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateMutex() xQueueCreateMutex() + + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
+ * + * Macro that implements a recursive mutex by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros should not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex() + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
+ * + * Macro that creates a counting semaphore by using the existing + * queue mechanism. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ xSemaphoreHandle xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount ) + + +#endif /* SEMAPHORE_H */ + + diff --git a/FreeRtosCore/Source/include/task.h b/FreeRtosCore/Source/include/task.h new file mode 100644 index 0000000..df059e0 --- /dev/null +++ b/FreeRtosCore/Source/include/task.h @@ -0,0 +1,1263 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include task.h" +#endif + + + +#ifndef TASK_H +#define TASK_H + +#include "portable.h" +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V6.0.4" + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an xTaskHandle variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \page xTaskHandle xTaskHandle + * \ingroup Tasks + */ +typedef void * xTaskHandle; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + portBASE_TYPE xOverflowCount; + portTickType xTimeOnEntering; +} xTimeOutType; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + unsigned long ulLengthInBytes; + unsigned long ulParameters; +} xMemoryRegion; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMTERS +{ + pdTASK_CODE pvTaskCode; + const signed char * const pcName; + unsigned short usStackDepth; + void *pvParameters; + unsigned portBASE_TYPE uxPriority; + portSTACK_TYPE *puxStackBuffer; + xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} xTaskParameters; + +/* + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \page taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \page taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \page taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() + +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). */ +#define taskSCHEDULER_NOT_STARTED 0 +#define taskSCHEDULER_RUNNING 1 +#define taskSCHEDULER_SUSPENDED 2 + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ portBASE_TYPE xTaskCreate(
+							  pdTASK_CODE pvTaskCode,
+							  const char * const pcName,
+							  unsigned short usStackDepth,
+							  void *pvParameters,
+							  unsigned portBASE_TYPE uxPriority,
+							  xTaskHandle *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) + +/** + * task. h + *
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+// Create an xTaskParameters structure that defines the task to be created.
+static const xTaskParameters xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{											
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+xTaskHandle xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) + +/** + * task. h + *
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an xMemoryRegion structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of xMemoryRegion structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{											
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is 
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+	
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( xTaskHandle pxTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernels management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param pxTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION; + + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( portTickType xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a cyclical task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const portTickType xDelay = 500 / portTICK_RATE_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by cyclical + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
+ * + * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param pxTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of pxTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param pxTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( xTaskHandle pxTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( xTaskHandle pxTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param pxTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with it priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( xTaskHandle pxTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * @param pxTaskToResume Handle to the task being readied. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. This function + * does not return until an executing task calls vTaskEndScheduler (). + * + * At least one task should be created via a call to xTaskCreate () + * before calling vTaskStartScheduler (). The idle task is created + * automatically when the first application task is created. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends all real time kernel activity while keeping interrupts (including the + * kernel tick) enabled. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char xTaskResumeAll( void );
+ * + * Resumes real time kernel activity following a call to vTaskSuspendAll (). + * After a call to vTaskSuspendAll () the kernel will take control of which + * task is executing at any time. + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
+ * + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + * + */ +signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
volatile portTickType xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \page xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned short uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * NOTE: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ascii form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \page vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function + * to be available. The application must also then provide definitions + * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter + * and return the timers current count value respectively. The counter + * should be at least 10 times the frequency of the tick count. + * + * NOTE: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ascii form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \page vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );
+ * + * Starts a real time kernel activity trace. The trace logs the identity of + * which task is running when. + * + * The trace file is stored in binary format. A separate DOS utility called + * convtrce.exe is used to convert this into a tab delimited text file which + * can be viewed and plotted in a spread sheet. + * + * @param pcBuffer The buffer into which the trace will be written. + * + * @param ulBufferSize The size of pcBuffer in bytes. The trace will continue + * until either the buffer in full, or ulTaskEndTrace () is called. + * + * \page vTaskStartTrace vTaskStartTrace + * \ingroup TaskUtils + */ +void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned long ulTaskEndTrace( void );
+ * + * Stops a kernel activity trace. See vTaskStartTrace (). + * + * @return The number of bytes that have been written into the trace buffer. + * + * \page usTaskEndTrace usTaskEndTrace + * \ingroup TaskUtils + */ +unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in bytes) since the task + * started. The smaller the returned number the closer the task has come + * to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in bytes) + * since the task referenced by xTask was created. + */ +unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ +void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
void xTaskGetApplicationTaskTag( xTaskHandle xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ +pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. + */ +portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. + */ +void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_RATE_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList () will be called if either an event occurs to + * unblock a task, or the block timeout period expires. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1 + * for this function to be available. + * See the configuration section for more information. + * + * Empties the ready and delayed queues of task control blocks, freeing the + * memory allocated for the task control block and task stacks as it goes. + */ +void vTaskCleanUpResources( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Generic version of the task creation function which is in turn called by the + * xTaskCreate() and xTaskCreateRestricted() macros. + */ +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TASK_H */ + + + diff --git a/FreeRtosCore/Source/list.c b/FreeRtosCore/Source/list.c new file mode 100644 index 0000000..fe61f05 --- /dev/null +++ b/FreeRtosCore/Source/list.c @@ -0,0 +1,173 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( xList *pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); + pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd ); + + pxList->uxNumberOfItems = 0; +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( xListItem *pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ) +{ +volatile xListItem * pxIndex; + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by + the pxIndex member. */ + pxIndex = pxList->pxIndex; + + pxNewListItem->pxNext = pxIndex->pxNext; + pxNewListItem->pxPrevious = pxList->pxIndex; + pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem; + pxList->pxIndex = ( volatile xListItem * ) pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( xList *pxList, xListItem *pxNewListItem ) +{ +volatile xListItem *pxIterator; +portTickType xValueOfInsertion; + + /* Insert the new list item into the list, sorted in ulListItem order. */ + xValueOfInsertion = pxNewListItem->xItemValue; + + /* If the list already contains a list item with the same item value then + the new list item should be placed after it. This ensures that TCB's which + are stored in ready lists (all of which have the same ulListItem value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) + { + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListRemove( xListItem *pxItemToRemove ) +{ +xList * pxList; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* The list item knows which list it is in. Obtain the list from the list + item. */ + pxList = ( xList * ) pxItemToRemove->pvContainer; + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + + pxItemToRemove->pvContainer = NULL; + ( pxList->uxNumberOfItems )--; +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRtosCore/Source/queue.c b/FreeRtosCore/Source/queue.c new file mode 100644 index 0000000..65cd3c1 --- /dev/null +++ b/FreeRtosCore/Source/queue.c @@ -0,0 +1,1515 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) + +#define queueERRONEOUS_UNBLOCK ( -1 ) + +/* For internal use only. */ +#define queueSEND_TO_BACK ( 0 ) +#define queueSEND_TO_FRONT ( 1 ) + +/* Effectively make a union out of the xQUEUE structure. */ +#define pxMutexHolder pcTail +#define uxQueueType pcHead +#define uxRecursiveCallCount pcReadFrom +#define queueQUEUE_IS_MUTEX NULL + +/* Semaphores do not actually store or copy data, so have an items size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 ) +#define queueDONT_BLOCK ( ( portTickType ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 ) + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. + */ +typedef struct QueueDefinition +{ + signed char *pcHead; /*< Points to the beginning of the queue storage area. */ + signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + + signed char *pcWriteTo; /*< Points to the free next place in the storage area. */ + signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */ + + xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */ + unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */ + + signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + +} xQUEUE; +/*-----------------------------------------------------------*/ + +/* + * Inside this file xQueueHandle is a pointer to a xQUEUE structure. + * To keep the definition private the API header file defines it as a + * pointer to void. + */ +typedef xQUEUE * xQueueHandle; + +/* + * Prototypes for public functions are included here so we don't have to + * include the API header file (as it defines xQueueHandle differently). These + * functions are documented in the API header file. + */ +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueCreateExternal( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, void *address ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; +void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION; +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION; +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Co-routine queue functions differ from task queue functions. Co-routines are + * an optional component. + */ +#if configUSE_CO_ROUTINES == 1 + signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + signed char *pcQueueName; + xQueueHandle xHandle; + } xQueueRegistryItem; + + /* The queue registry is simply an array of xQueueRegistryItem structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + + /* Removes a queue from the registry by simply setting the pcQueueName + member to NULL. */ + static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION; +#endif + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ +{ \ + taskENTER_CRITICAL(); \ + { \ + if( pxQueue->xRxLock == queueUNLOCKED ) \ + { \ + pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( pxQueue->xTxLock == queueUNLOCKED ) \ + { \ + pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL(); \ +} +/*-----------------------------------------------------------*/ + + +/*----------------------------------------------------------- + * PUBLIC QUEUE MANAGEMENT API documented in queue.h + *----------------------------------------------------------*/ + +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) +{ +xQUEUE *pxNewQueue; +size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + if( pxNewQueue != NULL ) + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + + pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes ); + if( pxNewQueue->pcHead != NULL ) + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + pxNewQueue->uxMessagesWaiting = 0; + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + } + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; +} + +xQueueHandle xQueueCreateExternal( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, void *address ) +{ + xQUEUE *pxNewQueue; + //size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + if( pxNewQueue != NULL ) + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + //xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + + pxNewQueue->pcHead = ( signed char * ) (address); + if( pxNewQueue->pcHead != NULL ) + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + pxNewQueue->uxMessagesWaiting = 0; + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + } + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + xQueueHandle xQueueCreateMutex( void ) + { + xQUEUE *pxNewQueue; + + /* Allocate the new queue structure. */ + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + if( pxNewQueue != NULL ) + { + /* Information required for priority inheritance. */ + pxNewQueue->pxMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* Queues used as a mutex no data is actually copied into or out + of the queue. */ + pxNewQueue->pcWriteTo = NULL; + pxNewQueue->pcReadFrom = NULL; + + /* Each mutex has a length of 1 (like a binary semaphore) and + an item size of 0 as nothing is actually copied into or out + of the mutex. */ + pxNewQueue->uxMessagesWaiting = 0; + pxNewQueue->uxLength = 1; + pxNewQueue->uxItemSize = 0; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + /* Ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + + /* Start with the semaphore in the expected state. */ + xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK ); + + traceCREATE_MUTEX( pxNewQueue ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + + portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) + { + portBASE_TYPE xReturn; + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->uxRecursiveCallCount )--; + + /* Have we unwound the call count? */ + if( pxMutex->uxRecursiveCallCount == 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + + xReturn = pdPASS; + } + else + { + /* We cannot give the mutex because we are not the holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + + portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime ) + { + portBASE_TYPE xReturn; + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE ); + + /* pdPASS will only be returned if we successfully obtained the mutex, + we may have blocked to reach here. */ + if( xReturn == pdPASS ) + { + ( pxMutex->uxRecursiveCallCount )++; + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_COUNTING_SEMAPHORES == 1 + + xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) + { + xQueueHandle pxHandle; + + pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH ); + + if( pxHandle != NULL ) + { + pxHandle->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return pxHandle; + } + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) +{ +signed portBASE_TYPE xEntryTimeSet = pdFALSE; +xTimeOutType xTimeOut; + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + portYIELD_WITHIN_API(); + } + } + + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting the + function. */ + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( !xTaskResumeAll() ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } +} +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + + signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) + { + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. */ + portYIELD_WITHIN_API(); + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + taskEXIT_CRITICAL(); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } + taskEXIT_CRITICAL(); + } + } + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + + signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) + { + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + signed char *pcOriginalReadPosition; + + for( ;; ) + { + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API(); + } + } + + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + portENTER_CRITICAL(); + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } + taskEXIT_CRITICAL(); + } + } + + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) +{ +signed portBASE_TYPE xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; + + /* Similar to xQueueGenericSend, except we don't block if there is no room + in the queue. Also we don't directly wake a task that was blocked on a + queue read, instead we return a flag to say whether a context switch is + required or not (i.e. has a task with a higher priority than us been woken + by this post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If the queue is locked we do not alter the event list. This will + be done when the queue is unlocked later. */ + if( pxQueue->xTxLock == queueUNLOCKED ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++( pxQueue->xTxLock ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) +{ +signed portBASE_TYPE xEntryTimeSet = pdFALSE; +xTimeOutType xTimeOut; +signed char *pcOriginalReadPosition; + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API(); + } + } + + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + portENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( !xTaskResumeAll() ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) +{ +signed portBASE_TYPE xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* We cannot block from an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + --( pxQueue->uxMessagesWaiting ); + + /* If the queue is locked we will not modify the event list. Instead + we update the lock count so the task that unlocks the queue will know + that an ISR has removed data while the queue was locked. */ + if( pxQueue->xRxLock == queueUNLOCKED ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + *pxTaskWoken = pdTRUE; + } + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++( pxQueue->xRxLock ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + taskENTER_CRITICAL(); + uxReturn = pxQueue->uxMessagesWaiting; + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +void vQueueDelete( xQueueHandle pxQueue ) +{ + traceQUEUE_DELETE( pxQueue ); + vQueueUnregisterQueue( pxQueue ); + vPortFree( pxQueue->pcHead ); + vPortFree( pxQueue ); +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) +{ + if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); + pxQueue->pxMutexHolder = NULL; + } + } + #endif + } + else if( xPosition == queueSEND_TO_BACK ) + { + memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + pxQueue->pcWriteTo += pxQueue->uxItemSize; + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + } + else + { + memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + pxQueue->pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->pcReadFrom < pxQueue->pcHead ) + { + pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + } + } + + ++( pxQueue->uxMessagesWaiting ); +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) +{ + if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) + { + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( xQueueHandle pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + /* See if data was added to the queue while it was locked. */ + while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + + --( pxQueue->xTxLock ); + } + else + { + break; + } + } + + pxQueue->xTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + + --( pxQueue->xRxLock ); + } + else + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) +{ +signed portBASE_TYPE xReturn; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( portTickType ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portNOP(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) +{ +signed portBASE_TYPE xReturn; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( portTickType ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portNOP(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + --( pxQueue->uxMessagesWaiting ); + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + + + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) +{ + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( !xCoRoutinePreviouslyWoken ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + } + } + } + + return xCoRoutinePreviouslyWoken; +} +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken ) +{ +signed portBASE_TYPE xReturn; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + --( pxQueue->uxMessagesWaiting ); + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( !( *pxCoRoutineWoken ) ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + } + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) + { + unsigned portBASE_TYPE ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + break; + } + } + } + +#endif + /*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + + static void vQueueUnregisterQueue( xQueueHandle xQueue ) + { + unsigned portBASE_TYPE ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + break; + } + } + + } + +#endif + diff --git a/FreeRtosCore/Source/readme.txt b/FreeRtosCore/Source/readme.txt new file mode 100644 index 0000000..01a8781 --- /dev/null +++ b/FreeRtosCore/Source/readme.txt @@ -0,0 +1,15 @@ +Each real time kernel port consists of three files that contain the core kernel +components and are common to every port, and one or more files that are +specific to a particular microcontroller and or compiler. + ++ The FreeRTOS/Source directory contains the three files that are common to +every port. The kernel is contained within these three files. + ++ The FreeRTOS/Source/Portable directory contains the files that are specific to +a particular microcontroller and or compiler. + ++ The FreeRTOS/Source/include directory contains the real time kernel header +files. + +See the readme file in the FreeRTOS/Source/Portable directory for more +information. \ No newline at end of file diff --git a/FreeRtosCore/Source/tasks.c b/FreeRtosCore/Source/tasks.c new file mode 100644 index 0000000..26a587c --- /dev/null +++ b/FreeRtosCore/Source/tasks.c @@ -0,0 +1,2318 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "StackMacros.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* + * Macro to define the amount of stack available to the idle task. + */ +#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE + +/* + * Task control block. A task control block (TCB) is allocated to each task, + * and stores the context of the task. + */ +typedef struct tskTaskControlBlock +{ + volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */ + #endif + + xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */ + xListItem xEventListItem; /*< List item used to place the TCB in event lists. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */ + portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */ + signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ + + #if ( portSTACK_GROWTH > 0 ) + portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + unsigned portBASE_TYPE uxCriticalNesting; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + pdTASK_HOOK_CODE pxTaskTag; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */ + #endif + +} tskTCB; + + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/*lint -e956 */ +PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. --------------------*/ + +PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */ + +#if ( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */ + PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */ + +#endif + +/* File private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0; +PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0; +PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0; +PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE; +PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; +PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + PRIVILEGED_DATA static char pcStatsString[ 50 ] ; + PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION; + +#endif + +/* Debugging and trace facilities private variables and macros. ------------*/ + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5 ) + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskBLOCKED_CHAR ( ( signed char ) 'B' ) +#define tskREADY_CHAR ( ( signed char ) 'R' ) +#define tskDELETED_CHAR ( ( signed char ) 'D' ) +#define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) + +/* + * Macros and private variables used by the trace facility. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + #define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) ) + PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer; + PRIVILEGED_DATA static signed char *pcTraceBufferStart; + PRIVILEGED_DATA static signed char *pcTraceBufferEnd; + PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE; + static unsigned portBASE_TYPE uxPreviousTask = 255; + PRIVILEGED_DATA static char pcStatusString[ 50 ]; + +#endif + +/*-----------------------------------------------------------*/ + +/* + * Macro that writes a trace of scheduler activity to a buffer. This trace + * shows which task is running when and is very useful as a debugging tool. + * As this macro is called each context switch it is a good idea to undefine + * it if not using the facility. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + #define vWriteTraceToBuffer() \ + { \ + if( xTracing ) \ + { \ + if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \ + { \ + if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \ + { \ + uxPreviousTask = pxCurrentTCB->uxTCBNumber; \ + *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \ + pcTraceBuffer += sizeof( unsigned long ); \ + *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \ + pcTraceBuffer += sizeof( unsigned long ); \ + } \ + else \ + { \ + xTracing = pdFALSE; \ + } \ + } \ + } \ + } + +#else + + #define vWriteTraceToBuffer() + +#endif +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready queue for + * the task. It is inserted at the end of the list. One quirk of this is + * that if the task being inserted is at the same priority as the currently + * executing task, then it will only be rescheduled after the currently + * executing task has been rescheduled. + */ +#define prvAddTaskToReadyQueue( pxTCB ) \ +{ \ + if( pxTCB->uxPriority > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = pxTCB->uxPriority; \ + } \ + vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \ +} +/*-----------------------------------------------------------*/ + +/* + * Macro that looks at the list of tasks that are currently delayed to see if + * any require waking. + * + * Tasks are stored in the queue in the order of their wake time - meaning + * once one tasks has been found whose timer has not expired we need not look + * any further down the list. + */ +#define prvCheckDelayedTasks() \ +{ \ +register tskTCB *pxTCB; \ + \ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \ + { \ + if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \ + { \ + break; \ + } \ + vListRemove( &( pxTCB->xGenericListItem ) ); \ + /* Is the task waiting on an event also? */ \ + if( pxTCB->xEventListItem.pvContainer ) \ + { \ + vListRemove( &( pxTCB->xEventListItem ) ); \ + } \ + prvAddTaskToReadyQueue( pxTCB ); \ + } \ +} +/*-----------------------------------------------------------*/ + +/* + * Several functions take an xTaskHandle parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle ) + + +/* File private functions. --------------------------------*/ + +/* + * Utility to ready a TCB for a given task. Mainly just copies the parameters + * into the TCB structure. + */ +static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) ) + + static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * Allocates memory from the heap for a TCB and associated stack. Checks the + * allocation was successful. + */ +static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION; + +/* + * Called from vTaskList. vListTasks details all the tasks currently under + * control of the scheduler. The tasks may be in one of a number of lists. + * prvListTaskWithinSingleList accepts a list and details the tasks from + * within just that list. + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + + +/*lint +e956 */ + + + +/*----------------------------------------------------------- + * TASK CREATION API documented in task.h + *----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ +signed portBASE_TYPE xReturn; +tskTCB * pxNewTCB; + + /* Allocate the memory required by the TCB and stack for the new task, + checking that the allocation was successful. */ + pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer ); + + if( pxNewTCB != NULL ) + { + portSTACK_TYPE *pxTopOfStack; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + portBASE_TYPE xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0x00 ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Calculate the top of stack address. This depends on whether the + stack grows from high memory to low (as per the 80x86) or visa versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); +// pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) ); + pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( uint16_t ) pxTopOfStack ) & ( ( uint16_t ) ~portBYTE_ALIGNMENT_MASK ) ); + } + #else + { + pxTopOfStack = pxNewTCB->pxStack; + + /* If we want to use stack checking on architectures that use + a positive stack growth direction then we also need to store the + other extreme of the stack space. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + } + #endif + + /* Setup the newly allocated TCB with the initial state of the task. */ + prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth ); + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif + + /* We are going to manipulate the task queues to add this task to a + ready list, so must make sure no interrupts occur. */ + portENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) + { + /* As this is the first task it must also be the current task. */ + pxCurrentTCB = pxNewTCB; + + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + } + } + + /* Remember the top priority to make context switching faster. Use + the priority in pxNewTCB as this has been capped to a valid value. */ + if( pxNewTCB->uxPriority > uxTopUsedPriority ) + { + uxTopUsedPriority = pxNewTCB->uxPriority; + } + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif + uxTaskNumber++; + + prvAddTaskToReadyQueue( pxNewTCB ); + + xReturn = pdPASS; + traceTASK_CREATE( pxNewTCB ); + } + portEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + traceTASK_CREATE_FAILED( pxNewTCB ); + } + + if( xReturn == pdPASS ) + { + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( xTaskHandle ) pxNewTCB; + } + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + { + portYIELD_WITHIN_API(); + } + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( xTaskHandle pxTaskToDelete ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + /* Ensure a yield is performed if the current task is being + deleted. */ + if( pxTaskToDelete == pxCurrentTCB ) + { + pxTaskToDelete = NULL; + } + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToDelete ); + + /* Remove task from the ready list and place in the termination list. + This will stop the task from be scheduled. The idle task will check + the termination list and free up any memory allocated by the + scheduler for the TCB and stack. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxTasksDeleted; + + /* Increment the uxTaskNumberVariable also so kernel aware debuggers + can detect that the task lists need re-generating. */ + uxTaskNumber++; + + traceTASK_DELETE( pxTCB ); + } + portEXIT_CRITICAL(); + + /* Force a reschedule if we have just deleted the current task. */ + if( xSchedulerRunning != pdFALSE ) + { + if( ( void * ) pxTaskToDelete == NULL ) + { + portYIELD_WITHIN_API(); + } + } + } + +#endif + + + + + + +/*----------------------------------------------------------- + * TASK CONTROL API documented in task.h + *----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + portTickType xTimeToWake; + portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; + + vTaskSuspendAll(); + { + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay ) + { + traceTASK_DELAY_UNTIL(); + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + { + portYIELD_WITHIN_API(); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( portTickType xTicksToDelay ) + { + portTickType xTimeToWake; + signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( portTickType ) 0 ) + { + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + xAlreadyYielded = xTaskResumeAll(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + { + portYIELD_WITHIN_API(); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxReturn; + + portENTER_CRITICAL(); + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + uxReturn = pxTCB->uxPriority; + } + portEXIT_CRITICAL(); + + return uxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE; + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= configMAX_PRIORITIES ) + { + uxNewPriority = configMAX_PRIORITIES - 1; + } + + portENTER_CRITICAL(); + { + if( pxTask == pxCurrentTCB ) + { + pxTask = NULL; + } + + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + + traceTASK_PRIORITY_SET( pxTask, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentPriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentPriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentPriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentPriority ) + { + if( pxTask != NULL ) + { + /* The priority of another task is being raised. If we + were raising the priority of the currently running task + there would be no need to switch as it must have already + been the highest priority task. */ + xYieldRequired = pdTRUE; + } + } + else if( pxTask == NULL ) + { + /* Setting our own priority down means there may now be another + task of higher priority that is ready to execute. */ + xYieldRequired = pdTRUE; + } + + + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the queue appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) ) + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + } + + if( xYieldRequired == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + portEXIT_CRITICAL(); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + /* Ensure a yield is performed if the current task is being + suspended. */ + if( pxTaskToSuspend == pxCurrentTCB ) + { + pxTaskToSuspend = NULL; + } + + /* If null is passed in here then we are suspending ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the suspended list. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + } + portEXIT_CRITICAL(); + + /* We may have just suspended the current task. */ + if( ( void * ) pxTaskToSuspend == NULL ) + { + portYIELD_WITHIN_API(); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) + { + portBASE_TYPE xReturn = pdFALSE; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + /* Is the task we are attempting to resume actually in the + suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) + { + /* Is it in the suspended list because it is in the + Suspended state? It is possible to be in the suspended + list because it is blocked on a task with no timeout + specified. */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE ) + { + xReturn = pdTRUE; + } + } + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( xTaskHandle pxTaskToResume ) + { + tskTCB *pxTCB; + + /* Remove the task from whichever list it is currently in, and place + it in the ready list. */ + pxTCB = ( tskTCB * ) pxTaskToResume; + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + { + portENTER_CRITICAL(); + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + portYIELD_WITHIN_API(); + } + } + } + portEXIT_CRITICAL(); + } + } + +#endif + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + pxTCB = ( tskTCB * ) pxTaskToResume; + + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be performed if necessary. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + + return xYieldRequired; + } + +#endif + + + + +/*----------------------------------------------------------- + * PUBLIC SCHEDULER CONTROL documented in task.h + *----------------------------------------------------------*/ + + +void vTaskStartScheduler( void ) +{ +portBASE_TYPE xReturn; + + /* Add the idle task at the lowest priority. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL ); + + if( xReturn == pdPASS ) + { + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. + + STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE + DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ + portDISABLE_INTERRUPTS(); + + xSchedulerRunning = pdTRUE; + xTickCount = ( portTickType ) 0; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} +/*-----------------------------------------------------------*/ + +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + portBASE_TYPE. */ + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ +register tskTCB *pxTCB; +signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + portENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + vTaskIncrementTick(); + --uxMissedTicks; + } + + /* As we have processed some ticks it is appropriate to yield + to ensure the highest priority task that is ready to run is + the task actually running. */ + #if configUSE_PREEMPTION == 1 + { + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + { + xAlreadyYielded = pdTRUE; + xMissedYield = pdFALSE; + portYIELD_WITHIN_API(); + } + } + } + } + portEXIT_CRITICAL(); + + return xAlreadyYielded; +} + + + + + + +/*----------------------------------------------------------- + * PUBLIC TASK UTILITIES documented in task.h + *----------------------------------------------------------*/ + + + +portTickType xTaskGetTickCount( void ) +{ +portTickType xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portEXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + portBASE_TYPE. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskList( signed char *pcWriteBuffer ) + { + unsigned portBASE_TYPE uxQueue; + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + { + /* Run through all the lists that could potentially contain a TCB and + report the task name, state and stack high water mark. */ + + pcWriteBuffer[ 0 ] = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + 1; + + do + { + uxQueue--; + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( !listLIST_IS_EMPTY( pxDelayedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); + } + + if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR ); + } + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR ); + } + } + #endif + } + xTaskResumeAll(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) + { + unsigned portBASE_TYPE uxQueue; + unsigned long ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + { + /* Run through all the lists that could potentially contain a TCB, + generating a table of run timer percentages in the provided + buffer. */ + + pcWriteBuffer[ 0 ] = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + 1; + + do + { + uxQueue--; + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( !listLIST_IS_EMPTY( pxDelayedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime ); + } + + if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime ); + } + + #if ( INCLUDE_vTaskDelete == 1 ) + { + if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime ); + } + } + #endif + } + xTaskResumeAll(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) + { + portENTER_CRITICAL(); + { + pcTraceBuffer = ( signed char * )pcBuffer; + pcTraceBufferStart = pcBuffer; + pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); + xTracing = pdTRUE; + } + portEXIT_CRITICAL(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned long ulTaskEndTrace( void ) + { + unsigned long ulBufferLength; + + portENTER_CRITICAL(); + xTracing = pdFALSE; + portEXIT_CRITICAL(); + + ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); + + return ulBufferLength; + } + +#endif + + + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + * documented in task.h + *----------------------------------------------------------*/ + + +void vTaskIncrementTick( void ) +{ + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + ++xTickCount; + if( xTickCount == ( portTickType ) 0 ) + { + xList *pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. + If there are any items in pxDelayedTaskList here then there is + an error! */ + pxTemp = pxDelayedTaskList; + pxDelayedTaskList = pxOverflowDelayedTaskList; + pxOverflowDelayedTaskList = pxTemp; + xNumOfOverflows++; + } + + /* See if this tick has made a timeout expire. */ + prvCheckDelayedTasks(); + } + else + { + ++uxMissedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + extern void vApplicationTickHook( void ); + + vApplicationTickHook(); + } + #endif + } + + #if ( configUSE_TICK_HOOK == 1 ) + { + extern void vApplicationTickHook( void ); + + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked. */ + if( uxMissedTicks == 0 ) + { + vApplicationTickHook(); + } + } + #endif + + traceTASK_INCREMENT_TICK( xTickCount ); +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + void vTaskCleanUpResources( void ) + { + unsigned short usQueue; + volatile tskTCB *pxTCB; + + usQueue = ( unsigned short ) uxTopUsedPriority + ( unsigned short ) 1; + + /* Remove any TCB's from the ready queues. */ + do + { + usQueue--; + + while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + }while( usQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + /* Remove any TCB's from the delayed queue. */ + while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + + /* Remove any TCB's from the overflow delayed queue. */ + while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + + while( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xSuspendedTaskList ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue ) + { + tskTCB *xTCB; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + portENTER_CRITICAL(); + xTCB->pxTaskTag = pxTagValue; + portEXIT_CRITICAL(); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) + { + tskTCB *xTCB; + pdTASK_HOOK_CODE xReturn; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + portENTER_CRITICAL(); + xReturn = xTCB->pxTaskTag; + portEXIT_CRITICAL(); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) + { + tskTCB *xTCB; + portBASE_TYPE xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xMissedYield = pdTRUE; + return; + } + + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + unsigned long ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE(); + + /* Add the amount of time the task has been running to the accumulated + time so far. The time the task started running was stored in + ulTaskSwitchedInTime. Note that there is no overflow protection here + so count values are only valid until the timer overflows. Generally + this will be about 1 hour assuming a 1uS timer increment. */ + pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime ); + ulTaskSwitchedInTime = ulTempCounter; + } + #endif + + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + /* Find the highest priority queue that contains ready tasks. */ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) + { + --uxTopReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the + same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); + + traceTASK_SWITCHED_IN(); + vWriteTraceToBuffer(); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) +{ +portTickType xTimeToWake; + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. */ + vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove ourselves from the ready list before adding ourselves + to the blocked list as the same list item is used for both lists. We have + exclusive access to the ready lists as the scheduler is locked. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + } + #else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) +{ +tskTCB *pxUnblockedTCB; +portBASE_TYPE xReturn; + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. It can also be called from within an ISR. */ + + /* The event list is sorted in priority order, so we can remove the + first in the list, remove the TCB from the delayed list, and add + it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means we can always expect exclusive access to the event list here. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + vListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + vListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxUnblockedTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) +{ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + portENTER_CRITICAL(); + { + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) ) + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait ) + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ); + vTaskSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + portEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xMissedYield = pdTRUE; +} + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* See if any tasks have been deleted. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 ) + { + taskYIELD(); + } + } + #endif + + #if ( configUSE_IDLE_HOOK == 1 ) + { + extern void vApplicationIdleHook( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif + } +} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */ + + + + + + + +/*----------------------------------------------------------- + * File private functions documented at the top of the file. + *----------------------------------------------------------*/ + + + +static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) +{ + /* Store the function name in the TCB. */ + #if configMAX_TASK_NAME_LEN > 1 + { + /* Don't bring strncpy into the build unnecessarily. */ + strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN ); + } + #else + (void) pcName; + #endif + pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= configMAX_PRIORITIES ) + { + uxPriority = configMAX_PRIORITIES - 1; + } + + pxTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxTCB->uxBasePriority = uxPriority; + } + #endif + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + /* Set the pxTCB as a link back from the xListItem. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0; + } + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxTCB->pxTaskTag = NULL; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTCB->ulRunTimeCounter = 0UL; + } + #endif + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); + } + #else + { + ( void ) xRegions; + ( void ) usStackDepth; + } + #endif +} +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions ) + { + tskTCB *pxTCB; + + if( xTaskToModify == pxCurrentTCB ) + { + xTaskToModify = NULL; + } + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + /*-----------------------------------------------------------*/ +#endif + +static void prvInitialiseTaskLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( ( xList * ) &xDelayedTaskList1 ); + vListInitialise( ( xList * ) &xDelayedTaskList2 ); + vListInitialise( ( xList * ) &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( ( xList * ) &xTasksWaitingTermination ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( ( xList * ) &xSuspendedTaskList ); + } + #endif + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + #if ( INCLUDE_vTaskDelete == 1 ) + { + portBASE_TYPE xListIsEmpty; + + /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called + too often in the idle task. */ + if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0 ) + { + vTaskSuspendAll(); + xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); + xTaskResumeAll(); + + if( !xListIsEmpty ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + --uxCurrentNumberOfTasks; + --uxTasksDeleted; + } + portEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + } + #endif +} +/*-----------------------------------------------------------*/ + +static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) +{ +tskTCB *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + else + { + /* Just to help debugging. */ + memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) ); + } + } + + return pxNewTCB; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned short usStackRemaining; + + /* Write the details of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + #if ( portSTACK_GROWTH > 0 ) + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); + } + #else + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + } + #endif + + sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber ); + strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString ); + + } while( pxNextTCB != pxFirstTCB ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned long ulStatsAsPercentage; + + /* Write the run time stats of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + /* Get next TCB in from the list. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + /* Divide by zero check. */ + if( ulTotalRunTime > 0UL ) + { + /* Has the task run at all? */ + if( pxNextTCB->ulRunTimeCounter == 0 ) + { + /* The task has used no CPU time at all. */ + sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName ); + } + else + { + /* What percentage of the total run time as the task used? + This will always be rounded down to the nearest integer. */ + ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime; + + if( ulStatsAsPercentage > 0UL ) + { + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter ); + } + } + + strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString ); + } + + } while( pxNextTCB != pxFirstTCB ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) + { + register unsigned short usCount = 0; + + while( *pucStackByte == tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + usCount++; + } + + usCount /= sizeof( portSTACK_TYPE ); + + return usCount; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) + { + tskTCB *pxTCB; + unsigned char *pcEndOfStack; + unsigned portBASE_TYPE uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxStack; + } + #else + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack ); + + return uxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) ) + + static void prvDeleteTCB( tskTCB *pxTCB ) + { + /* Free up the memory allocated by the scheduler for the task. It is up to + the task to free any memory allocated at the application level. */ + vPortFreeAligned( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + +#endif + + +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + + xTaskHandle xTaskGetCurrentTaskHandle( void ) + { + xTaskHandle xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif + +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + portBASE_TYPE xTaskGetSchedulerState( void ) + { + portBASE_TYPE xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new priority. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); + + /* If the task being modified is in the ready state it will need to + be moved in to a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) ) + { + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Inherit the priority before being moved into the new list. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyQueue( pxTCB ); + } + else + { + /* Just inherit the priority. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + } + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + if( pxMutexHolder != NULL ) + { + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* We must be the running task to be able to give the mutex back. + Remove ourselves from the ready list we currently appear in. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Disinherit the priority before adding ourselves into the new + ready list. */ + pxTCB->uxPriority = pxTCB->uxBasePriority; + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); + prvAddTaskToReadyQueue( pxTCB ); + } + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + pxCurrentTCB->uxCriticalNesting++; + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + +void vTaskExitCritical( void ) +{ + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0 ) + { + pxCurrentTCB->uxCriticalNesting--; + + if( pxCurrentTCB->uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + } + } +} + +#endif +/*-----------------------------------------------------------*/ + + + + diff --git a/FreeRtosCore/portable/GCC/ATMega168/port.c b/FreeRtosCore/portable/GCC/ATMega168/port.c new file mode 100644 index 0000000..b218826 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega168/port.c @@ -0,0 +1,448 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + +Changes from V2.6.0 + + + AVR port - Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. +*/ + +#include +#include + +#include "FreeRTOS.h" +#include "task.h" + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the AVR port. + *----------------------------------------------------------*/ + +/* Start tasks with interrupts enables. */ +#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 ) + +/* Hardware constants for timer 1. */ +#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned portCHAR ) 0x08 ) +#define portPRESCALE_64 ( ( unsigned portCHAR ) 0x03 ) +#define portCLOCK_PRESCALER ( ( unsigned portLONG ) 64 ) +#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x02 ) + +/*-----------------------------------------------------------*/ + +/* We require the address of the pxCurrentTCB variable, but don't want to know +any details of its type. */ +typedef void tskTCB; +extern volatile tskTCB * volatile pxCurrentTCB; + +/*-----------------------------------------------------------*/ + +/* + * Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + * + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + * + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + * + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. + */ + +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, 0x3d \n\t" \ + "st x+, r0 \n\t" \ + "in r0, 0x3e \n\t" \ + "st x+, r0 \n\t" \ + ); + +/* + * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. + */ + +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" \ + ); + +/*-----------------------------------------------------------*/ + +/* + * Perform hardware setup to enable ticks from timer 1, compare match A. + */ +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ +unsigned portSHORT usAddress; + + /* Place a few bytes of known values on the bottom of the stack. + This is just useful for debugging. */ + + *pxTopOfStack = 0x11; + pxTopOfStack--; + *pxTopOfStack = 0x22; + pxTopOfStack--; + *pxTopOfStack = 0x33; + pxTopOfStack--; + + /* Simulate how the stack would look after a call to vPortYield() generated by + the compiler. */ + + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* The start of the task code will be popped off the stack last, so place + it on first. */ + usAddress = ( unsigned portSHORT ) pxCode; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + portSAVE_CONTEXT places the flags on the stack immediately after r0 + to ensure the interrupts get disabled as soon as possible, and so ensuring + the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + pxTopOfStack--; + + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */ + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( unsigned portSHORT ) pvParameters; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + *pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */ + pxTopOfStack--; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + + /* Simulate a function call end as generated by the compiler. We will now + jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + + /* Should not get here. */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the AVR port will get stopped. If required simply + disable the tick interrupt here. */ +} +/*-----------------------------------------------------------*/ + +/* + * Manual context switch. The first thing we do is save the registers so we + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__ ( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Context switch function used by the tick. This must be identical to + * vPortYield() from the call to vTaskSwitchContext() onwards. The only + * difference from vPortYield() is the tick count is incremented as the + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + vTaskIncrementTick(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup timer 1 compare match A to generate a tick interrupt. + */ +static void prvSetupTimerInterrupt( void ) +{ +unsigned portLONG ulCompareMatch; +unsigned portCHAR ucHighByte, ucLowByte; + + /* Using 16bit timer 1 to generate the tick. Correct fuses must be + selected for the configCPU_CLOCK_HZ clock. */ + + ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; + + /* We only have 16 bits so have to scale to get our required tick rate. */ + ulCompareMatch /= portCLOCK_PRESCALER; + + /* Adjust for correct value. */ + ulCompareMatch -= ( unsigned portLONG ) 1; + + /* Setup compare match value for compare match A. Interrupts are disabled + before this is called so we need not worry here. */ + ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + ulCompareMatch >>= 8; + ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + OCR1AH = ucHighByte; + OCR1AL = ucLowByte; + + /* Setup clock source and compare match behaviour. */ + ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64; + TCCR1B = ucLowByte; + + /* Enable the interrupt - this is okay as interrupt are currently globally + disabled. */ + ucLowByte = TIMSK1; + ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE; + TIMSK1 = ucLowByte; +} +/*-----------------------------------------------------------*/ + +#if configUSE_PREEMPTION == 1 + + /* + * Tick ISR for preemptive scheduler. We can use a naked attribute as + * the context is saved at the start of vPortYieldFromTick(). The tick + * count is incremented after the context is saved. + */ + void TIMER1_COMPA_vect( void ) __attribute__ ( ( signal, naked ) ); + void TIMER1_COMPA_vect( void ) + { + vPortYieldFromTick(); + asm volatile ( "reti" ); + } +#else + + /* + * Tick ISR for the cooperative scheduler. All this does is increment the + * tick count. We don't need to switch context, this can only be done by + * manual calls to taskYIELD(); + */ + void TIMER1_COMPA_vect( void ) __attribute__ ( ( signal ) ); + void TIMER1_COMPA_vect( void ) + { + vTaskIncrementTick(); + } +#endif + + + diff --git a/FreeRtosCore/portable/GCC/ATMega168/portmacro.h b/FreeRtosCore/portable/GCC/ATMega168/portmacro.h new file mode 100644 index 0000000..05cb819 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega168/portmacro.h @@ -0,0 +1,129 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it + base 16. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT int +#define portSTACK_TYPE unsigned portCHAR +#define portBASE_TYPE char + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portENTER_CRITICAL() \ + asm volatile ( "in __tmp_reg__, __SREG__" :: ); \ + asm volatile ( "cli" :: ); \ + asm volatile ( "push __tmp_reg__" :: ) + +#define portEXIT_CRITICAL() \ + asm volatile ( "pop __tmp_reg__" :: ); \ + asm volatile ( "out __SREG__, __tmp_reg__" :: ) + +#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: ); +#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: ); +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 1 +#define portNOP() asm volatile ( "nop" ); +/*-----------------------------------------------------------*/ + +/* Kernel utilities. */ +extern void vPortYield( void ) __attribute__ ( ( naked ) ); +#define portYIELD() vPortYield() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/FreeRtosCore/portable/GCC/ATMega323/port.c b/FreeRtosCore/portable/GCC/ATMega323/port.c new file mode 100644 index 0000000..76b84c7 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega323/port.c @@ -0,0 +1,450 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + +Changes from V2.6.0 + + + AVR port - Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. +*/ + +#include +#include + +#include "FreeRTOS.h" +#include "task.h" + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the AVR port. + *----------------------------------------------------------*/ + +/* Start tasks with interrupts enables. */ +#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 ) + +/* Hardware constants for timer 1. */ +#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned char ) 0x08 ) +#define portPRESCALE_64 ( ( unsigned char ) 0x03 ) +#define portCLOCK_PRESCALER ( ( unsigned long ) 64 ) +#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned char ) 0x10 ) + +/*-----------------------------------------------------------*/ + +/* We require the address of the pxCurrentTCB variable, but don't want to know +any details of its type. */ +typedef void tskTCB; +extern volatile tskTCB * volatile pxCurrentTCB; + +/*-----------------------------------------------------------*/ + +/* + * Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + * + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + * + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + * + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. + */ + +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, 0x3d \n\t" \ + "st x+, r0 \n\t" \ + "in r0, 0x3e \n\t" \ + "st x+, r0 \n\t" \ + ); + +/* + * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. + */ + +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" \ + ); + +/*-----------------------------------------------------------*/ + +/* + * Perform hardware setup to enable ticks from timer 1, compare match A. + */ +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ +unsigned short usAddress; + + /* Place a few bytes of known values on the bottom of the stack. + This is just useful for debugging. */ + + *pxTopOfStack = 0x11; + pxTopOfStack--; + *pxTopOfStack = 0x22; + pxTopOfStack--; + *pxTopOfStack = 0x33; + pxTopOfStack--; + + /* Simulate how the stack would look after a call to vPortYield() generated by + the compiler. */ + + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* The start of the task code will be popped off the stack last, so place + it on first. */ + usAddress = ( unsigned short ) pxCode; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); + pxTopOfStack--; + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + portSAVE_CONTEXT places the flags on the stack immediately after r0 + to ensure the interrupts get disabled as soon as possible, and so ensuring + the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + pxTopOfStack--; + + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */ + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( unsigned short ) pvParameters; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); + pxTopOfStack--; + + *pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */ + pxTopOfStack--; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + + /* Simulate a function call end as generated by the compiler. We will now + jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + + /* Should not get here. */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the AVR port will get stopped. If required simply + disable the tick interrupt here. */ +} +/*-----------------------------------------------------------*/ + +/* + * Manual context switch. The first thing we do is save the registers so we + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__ ( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Context switch function used by the tick. This must be identical to + * vPortYield() from the call to vTaskSwitchContext() onwards. The only + * difference from vPortYield() is the tick count is incremented as the + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + vTaskIncrementTick(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup timer 1 compare match A to generate a tick interrupt. + */ +static void prvSetupTimerInterrupt( void ) +{ +unsigned long ulCompareMatch; +unsigned char ucHighByte, ucLowByte; + + /* Using 16bit timer 1 to generate the tick. Correct fuses must be + selected for the configCPU_CLOCK_HZ clock. */ + + ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; + + /* We only have 16 bits so have to scale to get our required tick rate. */ + ulCompareMatch /= portCLOCK_PRESCALER; + + /* Adjust for correct value. */ + ulCompareMatch -= ( unsigned long ) 1; + + /* Setup compare match value for compare match A. Interrupts are disabled + before this is called so we need not worry here. */ + ucLowByte = ( unsigned char ) ( ulCompareMatch & ( unsigned long ) 0xff ); + ulCompareMatch >>= 8; + ucHighByte = ( unsigned char ) ( ulCompareMatch & ( unsigned long ) 0xff ); + OCR1AH = ucHighByte; + OCR1AL = ucLowByte; + + /* Setup clock source and compare match behaviour. */ + ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64; + TCCR1B = ucLowByte; + + /* Enable the interrupt - this is okay as interrupt are currently globally + disabled. */ + ucLowByte = TIMSK; + ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE; + TIMSK = ucLowByte; +} +/*-----------------------------------------------------------*/ + +#if configUSE_PREEMPTION == 1 + + /* + * Tick ISR for preemptive scheduler. We can use a naked attribute as + * the context is saved at the start of vPortYieldFromTick(). The tick + * count is incremented after the context is saved. + */ + void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) ); + void SIG_OUTPUT_COMPARE1A( void ) + { + vPortYieldFromTick(); + asm volatile ( "reti" ); + } +#else + + /* + * Tick ISR for the cooperative scheduler. All this does is increment the + * tick count. We don't need to switch context, this can only be done by + * manual calls to taskYIELD(); + */ + void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) ); + void SIG_OUTPUT_COMPARE1A( void ) + { + vTaskIncrementTick(); + } +#endif + + + diff --git a/FreeRtosCore/portable/GCC/ATMega323/portmacro.h b/FreeRtosCore/portable/GCC/ATMega323/portmacro.h new file mode 100644 index 0000000..5025981 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega323/portmacro.h @@ -0,0 +1,129 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it + base 16. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT int +#define portSTACK_TYPE unsigned portCHAR +#define portBASE_TYPE char + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \ + asm volatile ( "cli" :: ); \ + asm volatile ( "push __tmp_reg__" :: ) + +#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \ + asm volatile ( "out __SREG__, __tmp_reg__" :: ) + +#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: ); +#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: ); +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 1 +#define portNOP() asm volatile ( "nop" ); +/*-----------------------------------------------------------*/ + +/* Kernel utilities. */ +extern void vPortYield( void ) __attribute__ ( ( naked ) ); +#define portYIELD() vPortYield() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/FreeRtosCore/portable/GCC/ATMega64/port.c b/FreeRtosCore/portable/GCC/ATMega64/port.c new file mode 100644 index 0000000..ba15d7c --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega64/port.c @@ -0,0 +1,448 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + +Changes from V2.6.0 + + + AVR port - Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. +*/ + +#include +#include + +#include "FreeRTOS.h" +#include "task.h" + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the AVR port. + *----------------------------------------------------------*/ + +/* Start tasks with interrupts enables. */ +#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 ) + +/* Hardware constants for timer 1. */ +#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned portCHAR ) 0x08 ) +#define portPRESCALE_64 ( ( unsigned portCHAR ) 0x03 ) +#define portCLOCK_PRESCALER ( ( unsigned portLONG ) 64 ) +#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x10 ) + +/*-----------------------------------------------------------*/ + +/* We require the address of the pxCurrentTCB variable, but don't want to know +any details of its type. */ +typedef void tskTCB; +extern volatile tskTCB * volatile pxCurrentTCB; + +/*-----------------------------------------------------------*/ + +/* + * Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + * + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + * + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + * + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. + */ + +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, 0x3d \n\t" \ + "st x+, r0 \n\t" \ + "in r0, 0x3e \n\t" \ + "st x+, r0 \n\t" \ + ); + +/* + * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. + */ + +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" \ + ); + +/*-----------------------------------------------------------*/ + +/* + * Perform hardware setup to enable ticks from timer 1, compare match A. + */ +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ +unsigned portSHORT usAddress; + + /* Place a few bytes of known values on the bottom of the stack. + This is just useful for debugging. */ + + *pxTopOfStack = 0x11; + pxTopOfStack--; + *pxTopOfStack = 0x22; + pxTopOfStack--; + *pxTopOfStack = 0x33; + pxTopOfStack--; + + /* Simulate how the stack would look after a call to vPortYield() generated by + the compiler. */ + + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* The start of the task code will be popped off the stack last, so place + it on first. */ + usAddress = ( unsigned portSHORT ) pxCode; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + portSAVE_CONTEXT places the flags on the stack immediately after r0 + to ensure the interrupts get disabled as soon as possible, and so ensuring + the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + pxTopOfStack--; + + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */ + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( unsigned portSHORT ) pvParameters; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + pxTopOfStack--; + + *pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */ + pxTopOfStack--; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + + /* Simulate a function call end as generated by the compiler. We will now + jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + + /* Should not get here. */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the AVR port will get stopped. If required simply + disable the tick interrupt here. */ +} +/*-----------------------------------------------------------*/ + +/* + * Manual context switch. The first thing we do is save the registers so we + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__ ( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Context switch function used by the tick. This must be identical to + * vPortYield() from the call to vTaskSwitchContext() onwards. The only + * difference from vPortYield() is the tick count is incremented as the + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + vTaskIncrementTick(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup timer 1 compare match A to generate a tick interrupt. + */ +static void prvSetupTimerInterrupt( void ) +{ +unsigned portLONG ulCompareMatch; +unsigned portCHAR ucHighByte, ucLowByte; + + /* Using 16bit timer 1 to generate the tick. Correct fuses must be + selected for the configCPU_CLOCK_HZ clock. */ + + ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; + + /* We only have 16 bits so have to scale to get our required tick rate. */ + ulCompareMatch /= portCLOCK_PRESCALER; + + /* Adjust for correct value. */ + ulCompareMatch -= ( unsigned portLONG ) 1; + + /* Setup compare match value for compare match A. Interrupts are disabled + before this is called so we need not worry here. */ + ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + ulCompareMatch >>= 8; + ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + OCR1AH = ucHighByte; + OCR1AL = ucLowByte; + + /* Setup clock source and compare match behaviour. */ + ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64; + TCCR1B = ucLowByte; + + /* Enable the interrupt - this is okay as interrupt are currently globally + disabled. */ + ucLowByte = TIMSK; + ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE; + TIMSK = ucLowByte; +} +/*-----------------------------------------------------------*/ + +#if configUSE_PREEMPTION == 1 + + /* + * Tick ISR for preemptive scheduler. We can use a naked attribute as + * the context is saved at the start of vPortYieldFromTick(). The tick + * count is incremented after the context is saved. + */ + void TIMER1_COMPA_vect ( void ) __attribute__ ( ( signal, naked ) ); + void TIMER1_COMPA_vect ( void ) + { + vPortYieldFromTick(); + asm volatile ( "reti" ); + } +#else + + /* + * Tick ISR for the cooperative scheduler. All this does is increment the + * tick count. We don't need to switch context, this can only be done by + * manual calls to taskYIELD(); + */ + void TIMER1_COMPA_vect ( void ) __attribute__ ( ( signal ) ); + void TIMER1_COMPA_vect ( void ) + { + vTaskIncrementTick(); + } +#endif + + + diff --git a/FreeRtosCore/portable/GCC/ATMega64/portmacro.h b/FreeRtosCore/portable/GCC/ATMega64/portmacro.h new file mode 100644 index 0000000..e7d8838 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATMega64/portmacro.h @@ -0,0 +1,127 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* +Changes from V1.2.3 + + + portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it + base 16. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT int +#define portSTACK_TYPE unsigned portCHAR +#define portBASE_TYPE char + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \ + asm volatile ( "cli" :: ); \ + asm volatile ( "push __tmp_reg__" :: ) + +#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \ + asm volatile ( "out __SREG__, __tmp_reg__" :: ) + +#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: ); +#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: ); +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 1 +#define portNOP() asm volatile ( "nop" ); +/*-----------------------------------------------------------*/ + +/* Kernel utilities. */ +extern void vPortYield( void ) __attribute__ ( ( naked ) ); +#define portYIELD() vPortYield() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/FreeRtosCore/portable/GCC/ATXmega/port.c b/FreeRtosCore/portable/GCC/ATXmega/port.c new file mode 100644 index 0000000..2153fd1 --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATXmega/port.c @@ -0,0 +1,389 @@ +/* This file has been prepared for Doxygen automatic documentation generation.*/ +/* +* Copyright (C) 2012 Yuriy Kulikov +* Universitaet Erlangen-Nuernberg +* LS Informationstechnik (Kommunikationselektronik) +* Support email: Yuriy.Kulikov.87@googlemail.com +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* Compiler definitions include file. */ +#include "avr_compiler.h" +#include "FreeRTOSConfig.h" +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +//#include "TC_driver.h" +//#include "pmic_driver.h" + +/*----------------------------------------------------------- +* Implementation of functions defined in portable.h for the AVR XMEGA port. +*----------------------------------------------------------*/ + +/* Start tasks with interrupts enables. */ +#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 ) + +/*-----------------------------------------------------------*/ + +/* We require the address of the pxCurrentTCB variable, but don't want to know +any details of its type. */ +typedef void tskTCB; +extern volatile tskTCB * volatile pxCurrentTCB; + +/*-----------------------------------------------------------*/ + +/* +* Macro to save all the general purpose registers, the save the stack pointer +* into the TCB. +* +* The first thing we do is save the flags then disable interrupts. This is to +* guard our stack against having a context switch interrupt after we have already +* pushed the registers onto the stack - causing the 32 registers to be on the +* stack twice. +* +* r1 is set to zero as the compiler expects it to be thus, however some +* of the math routines make use of R1. +* +* The interrupts will have been disabled during the call to portSAVE_CONTEXT() +* so we need not worry about reading/writing to the stack pointer. +*/ + +#define portSAVE_CONTEXT() \ +asm volatile ( "push r0 \n\t" \ +"in r0, __SREG__ \n\t" \ +"cli \n\t" \ +"push r0 \n\t" \ +"push r1 \n\t" \ +"clr r1 \n\t" \ +"push r2 \n\t" \ +"push r3 \n\t" \ +"push r4 \n\t" \ +"push r5 \n\t" \ +"push r6 \n\t" \ +"push r7 \n\t" \ +"push r8 \n\t" \ +"push r9 \n\t" \ +"push r10 \n\t" \ +"push r11 \n\t" \ +"push r12 \n\t" \ +"push r13 \n\t" \ +"push r14 \n\t" \ +"push r15 \n\t" \ +"push r16 \n\t" \ +"push r17 \n\t" \ +"push r18 \n\t" \ +"push r19 \n\t" \ +"push r20 \n\t" \ +"push r21 \n\t" \ +"push r22 \n\t" \ +"push r23 \n\t" \ +"push r24 \n\t" \ +"push r25 \n\t" \ +"push r26 \n\t" \ +"push r27 \n\t" \ +"push r28 \n\t" \ +"push r29 \n\t" \ +"push r30 \n\t" \ +"push r31 \n\t" \ +"lds r26, pxCurrentTCB \n\t" \ +"lds r27, pxCurrentTCB + 1 \n\t" \ +"in r0, 0x3d \n\t" \ +"st x+, r0 \n\t" \ +"in r0, 0x3e \n\t" \ +"st x+, r0 \n\t" \ +); + +/* +* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during +* the context save so we can write to the stack pointer. +*/ +#define portRESTORE_CONTEXT() \ +asm volatile ( "lds r26, pxCurrentTCB \n\t" \ +"lds r27, pxCurrentTCB + 1 \n\t" \ +"ld r28, x+ \n\t" \ +"out __SP_L__, r28 \n\t" \ +"ld r29, x+ \n\t" \ +"out __SP_H__, r29 \n\t" \ +"pop r31 \n\t" \ +"pop r30 \n\t" \ +"pop r29 \n\t" \ +"pop r28 \n\t" \ +"pop r27 \n\t" \ +"pop r26 \n\t" \ +"pop r25 \n\t" \ +"pop r24 \n\t" \ +"pop r23 \n\t" \ +"pop r22 \n\t" \ +"pop r21 \n\t" \ +"pop r20 \n\t" \ +"pop r19 \n\t" \ +"pop r18 \n\t" \ +"pop r17 \n\t" \ +"pop r16 \n\t" \ +"pop r15 \n\t" \ +"pop r14 \n\t" \ +"pop r13 \n\t" \ +"pop r12 \n\t" \ +"pop r11 \n\t" \ +"pop r10 \n\t" \ +"pop r9 \n\t" \ +"pop r8 \n\t" \ +"pop r7 \n\t" \ +"pop r6 \n\t" \ +"pop r5 \n\t" \ +"pop r4 \n\t" \ +"pop r3 \n\t" \ +"pop r2 \n\t" \ +"pop r1 \n\t" \ +"pop r0 \n\t" \ +"out __SREG__, r0 \n\t" \ +"pop r0 \n\t" \ +); + +/*-----------------------------------------------------------*/ + +/* +* Perform hardware setup to enable ticks from timer 1, compare match A. +*/ +static void prvSetupTimerInterrupt(void); +/*-----------------------------------------------------------*/ + +/* +* See header file for description. +*/portSTACK_TYPE *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, + pdTASK_CODE pxCode, void *pvParameters) { + /*The addresses are 16 or 24 bit depending on the xmega memory, so use 32 bit variable but put only a +* part to stack.*/ + uint16_t usAddress; + /* Place a few bytes of known values on the bottom of the stack. +This is just useful for debugging. */ + *pxTopOfStack = 0x11; + pxTopOfStack--; + *pxTopOfStack = 0x22; + pxTopOfStack--; + *pxTopOfStack = 0x33; + pxTopOfStack--; + /* Simulate how the stack would look after a call to vPortYield() generated by +the compiler. */ + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + /* The start of the task code will be popped off the stack last, so place +it on first. */ + /* Original code +* For 16-bit program counter (128K program memory or less) +usAddress = ( unsigned short ) pxCode; +*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); +pxTopOfStack--; +usAddress >>= 8; +*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff ); +pxTopOfStack--;*/ + /* end of original code block */ + + /* The way it should be done for xmega with probably more than 128K program memory. +* Warning is OK here - type incompatibility does not matter - usAddress is only +* used as temporary storage */ + usAddress = (uint16_t)pxCode; + + *pxTopOfStack = (portSTACK_TYPE ) (usAddress & (uint16_t) 0x00ff); + pxTopOfStack--; + usAddress >>= 8; + + *pxTopOfStack = (portSTACK_TYPE ) (usAddress & (uint16_t) 0x00ff); + pxTopOfStack--; + + +#if defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__ + *pxTopOfStack = (portSTACK_TYPE ) 0; + pxTopOfStack--; +#endif + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). +portSAVE_CONTEXT places the flags on the stack immediately after r0 +to ensure the interrupts get disabled as soon as possible, and so ensuring +the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = (portSTACK_TYPE ) 0x00; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + pxTopOfStack--; + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = (portSTACK_TYPE ) 0x00; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x02; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x03; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x04; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x05; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x06; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x07; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x08; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x09; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x10; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x11; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x12; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x13; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x14; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x15; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x16; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x17; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x18; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x19; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x20; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x21; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x22; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x23; /* R23 */ + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = (unsigned short) pvParameters; + *pxTopOfStack = (portSTACK_TYPE ) (usAddress & (unsigned short) 0x00ff); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = (portSTACK_TYPE ) (usAddress & (unsigned short) 0x00ff); + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE ) 0x26; /* R26 X */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x27; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x28; /* R28 Y */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x29; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x30; /* R30 Z */ + pxTopOfStack--; + *pxTopOfStack = (portSTACK_TYPE ) 0x31; /* R31 */ + pxTopOfStack--; + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ +portBASE_TYPE xPortStartScheduler(void) { + + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + + /* Simulate a function call end as generated by the compiler. We will now +jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + + /* Should not get here. */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler(void) { + /* It is unlikely that the AVR port will get stopped. If required simply +disable the tick interrupt here. */ +} +/*-----------------------------------------------------------*/ + +/* +* Manual context switch. The first thing we do is save the registers so we +* can use a naked attribute. +*/ +void vPortYield(void) __attribute__ ( ( naked ) ); +void vPortYield(void) { + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + + +/*-----------------------------------------------------------*/ + +/* +* Setup timer 1 compare match A to generate a tick interrupt. +*/ +static void prvSetupTimerInterrupt(void) { + //select the clock source and pre-scale by 64 + //void TC0_ConfigClockSource( volatile TC0_t * tc, TC_CLKSEL_t clockSelection ) + // tc->CTRLA = ( tc->CTRLA & ~TC0_CLKSEL_gm ) | clockSelection; + //TC0_ConfigClockSource(tickTimer, TC_CLKSEL_DIV64_gc); + TCC1.CTRLA = (TCC1.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV256_gc; + + //set period of counter + TCC1.PER = (configCPU_CLOCK_HZ / configTICK_RATE_HZ / 256) - 1; + + //enable interrupt and set low level + TCC1.INTCTRLA = (TCC1.INTCTRLA & ~TC1_OVFINTLVL_gm ) | TC_OVFINTLVL_LO_gc; + //TC0_SetOverflowIntLevel(tickTimer, TC_OVFINTLVL_LO_gc); + //void TC0_SetOverflowIntLevel( volatile TC0_t * tc, TC_OVFINTLVL_t intLevel ) + // tc->INTCTRLA = ( tc->INTCTRLA & ~TC0_OVFINTLVL_gm ) | intLevel; + //enable low level interrupts + PMIC.CTRL |= PMIC_LOLVLEN_bm; //PMIC_EnableLowLevel(); +} +/*-----------------------------------------------------------*/ + +#if configUSE_PREEMPTION == 1 + +/* +* Tick ISR for preemptive scheduler. We can use a naked attribute as +* the context is saved at the start of vPortYieldFromTick(). The tick +* count is incremented after the context is saved. +*/ + +ISR (TCC1_OVF_vect, ISR_NAKED) { + /* +* Context switch function used by the tick. This must be identical to +* vPortYield() from the call to vTaskSwitchContext() onwards. The only +* difference from vPortYield() is the tick count is incremented as the +* call comes from the tick ISR. +*/ + portSAVE_CONTEXT(); + vTaskIncrementTick(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + asm volatile ( "reti" ); +} + +#else + +/* +* Tick ISR for the cooperative scheduler. All this does is increment the +* tick count. We don't need to switch context, this can only be done by +* manual calls to taskYIELD(); +*/ +ISR (TCC1_OVF_vect) +{ + vTaskIncrementTick(); +} +#endif diff --git a/FreeRtosCore/portable/GCC/ATXmega/portmacro.h b/FreeRtosCore/portable/GCC/ATXmega/portmacro.h new file mode 100644 index 0000000..82a3f3e --- /dev/null +++ b/FreeRtosCore/portable/GCC/ATXmega/portmacro.h @@ -0,0 +1,89 @@ +/* This file has been prepared for Doxygen automatic documentation generation.*/ +/* +* Copyright (C) 2012 Yuriy Kulikov +* Universitaet Erlangen-Nuernberg +* LS Informationstechnik (Kommunikationselektronik) +* Support email: Yuriy.Kulikov.87@googlemail.com +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H +#include "avr_compiler.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- +* Port specific definitions. +* +* The settings in this file configure FreeRTOS correctly for the +* given hardware and compiler. +* +* These settings should not be altered. +*----------------------------------------------------------- +*/ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT int +//#define portSTACK_TYPE unsigned portCHAR +#define portSTACK_TYPE uint_fast8_t +#define portBASE_TYPE char + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \ +asm volatile ( "cli" :: ); \ +asm volatile ( "push __tmp_reg__" :: ) + +#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \ +asm volatile ( "out __SREG__, __tmp_reg__" :: ) + +#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: ); +#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: ); +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 1 +#define portNOP() asm volatile ( "nop" ); +/*-----------------------------------------------------------*/ + +/* Kernel utilities. */ +extern void vPortYield( void ) __attribute__ ( ( naked ) ); +#define portYIELD() vPortYield() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ \ No newline at end of file diff --git a/FreeRtosCore/portable/MemMang/heap_1.c b/FreeRtosCore/portable/MemMang/heap_1.c new file mode 100644 index 0000000..76742f9 --- /dev/null +++ b/FreeRtosCore/portable/MemMang/heap_1.c @@ -0,0 +1,152 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * The simplest possible implementation of pvPortMalloc(). Note that this + * implementation does NOT allow allocated memory to be freed again. + * + * See heap_2.c and heap_3.c for alternative implementations, and the memory + * management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Allocate the memory for the heap. The struct is used to force byte +alignment without using any non-portable code. */ +static union xRTOS_HEAP +{ + #if portBYTE_ALIGNMENT == 8 + volatile portDOUBLE dDummy; + #else + volatile unsigned long ulDummy; + #endif + unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +} xHeap; + +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if portBYTE_ALIGNMENT != 1 + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + #endif + + vTaskSuspendAll(); + { + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + xNextFreeByte += xWantedSize; + } + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c + for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configTOTAL_HEAP_SIZE - xNextFreeByte ); +} + + + diff --git a/FreeRtosCore/portable/MemMang/heap_2.c b/FreeRtosCore/portable/MemMang/heap_2.c new file mode 100644 index 0000000..891405d --- /dev/null +++ b/FreeRtosCore/portable/MemMang/heap_2.c @@ -0,0 +1,280 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block. + * + * See heap_1.c and heap_3.c for alternative implementations, and the memory + * management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Allocate the memory for the heap. The struct is used to force byte +alignment without using any non-portable code. */ +static union xRTOS_HEAP +{ + #if portBYTE_ALIGNMENT == 8 + volatile portDOUBLE dDummy; + #else + volatile unsigned long ulDummy; + #endif + unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +} xHeap; + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} xBlockLink; + + +static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static xBlockLink xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +xBlockLink *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ + +#define prvHeapInit() \ +{ \ +xBlockLink *pxFirstFreeBlock; \ + \ + /* xStart is used to hold a pointer to the first item in the list of free */ \ + /* blocks. The void cast is used to prevent compiler warnings. */ \ + xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \ + xStart.xBlockSize = ( size_t ) 0; \ + \ + /* xEnd is used to mark the end of the list of free blocks. */ \ + xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \ + xEnd.pxNextFreeBlock = NULL; \ + \ + /* To start with there is a single free block that is sized to take up the \ + entire heap space. */ \ + pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \ + pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \ + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \ + \ + xFreeBytesRemaining = configTOTAL_HEAP_SIZE; \ +} +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a xBlockLink + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the xBlockLink structure + at its start. */ + pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken our of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= xWantedSize; + } + } + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +unsigned char *puc = ( unsigned char * ) pv; +xBlockLink *pxLink; + + if( pv ) + { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + } + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} diff --git a/FreeRtosCore/portable/MemMang/heap_3.c b/FreeRtosCore/portable/MemMang/heap_3.c new file mode 100644 index 0000000..e4fd22f --- /dev/null +++ b/FreeRtosCore/portable/MemMang/heap_3.c @@ -0,0 +1,117 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * Implementation of pvPortMalloc() and vPortFree() that relies on the + * compilers own malloc() and free() implementations. + * + * This file can only be used if the linker is configured to to generate + * a heap memory area. + * + * See heap_2.c and heap_1.c for alternative implementations, and the memory + * management pages of http://www.FreeRTOS.org for more information. + */ + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn; + + vTaskSuspendAll(); + { + pvReturn = malloc( xWantedSize ); + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + if( pv ) + { + vTaskSuspendAll(); + { + free( pv ); + } + xTaskResumeAll(); + } +} + + + diff --git a/FreeRtosCore/portable/MemMang/heap_avr.c b/FreeRtosCore/portable/MemMang/heap_avr.c new file mode 100644 index 0000000..ae7345c --- /dev/null +++ b/FreeRtosCore/portable/MemMang/heap_avr.c @@ -0,0 +1,149 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * AVR implementation of pvPortMalloc(). + * Modified by Adam Kaliszan + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Allocate the memory for the heap. The struct is used to force byte +alignment without using any non-portable code. */ +static union xRTOS_HEAP +{ + #if portBYTE_ALIGNMENT == 8 + volatile portDOUBLE dDummy; + #else + volatile unsigned long ulDummy; + #endif + unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +} xHeap; + +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ + void *pvReturn = NULL; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if portBYTE_ALIGNMENT != 1 + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + #endif + + vTaskSuspendAll(); + { + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + xNextFreeByte += xWantedSize; + } + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c + for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configTOTAL_HEAP_SIZE - xNextFreeByte ); +} + + + diff --git a/Hardware/DidacticSystem/Box/bottom.dia b/Hardware/DidacticSystem/Box/bottom.dia new file mode 100644 index 0000000..3ba5941 Binary files /dev/null and b/Hardware/DidacticSystem/Box/bottom.dia differ diff --git a/Hardware/DidacticSystem/Box/top.dia b/Hardware/DidacticSystem/Box/top.dia new file mode 100644 index 0000000..fcc8c75 Binary files /dev/null and b/Hardware/DidacticSystem/Box/top.dia differ diff --git a/Hardware/download.sh b/Hardware/download.sh new file mode 100644 index 0000000..5992a19 --- /dev/null +++ b/Hardware/download.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd DidacticSystem +wget + +cd ../AtXmegaRobo + +cd .. diff --git a/Lib/.kdev_include_paths_student b/Lib/.kdev_include_paths_student new file mode 100644 index 0000000..e91bf6c --- /dev/null +++ b/Lib/.kdev_include_paths_student @@ -0,0 +1,4 @@ +/home/student/akme/FreeRtos/freeRtos/Lib/include +/home/student/akme/FreeRtos/freeRtos/Lib/net/include +/home/student/akme/FreeRtos/freeRtos/Source/include +/usr/lib/avr/include diff --git a/Lib/Fat/doc/00index_e.html b/Lib/Fat/doc/00index_e.html new file mode 100644 index 0000000..b1a6b5b --- /dev/null +++ b/Lib/Fat/doc/00index_e.html @@ -0,0 +1,105 @@ + + + + + + + + + + +ELM - FAT File System Module + + + +

FAT File System Module

+
+ +
+layer +

FatFs is a generic FAT file system module for small embedded systems. The FatFs is written in compliance with ANSI C and completely separated from the disk I/O layer. Therefore it is independent of hardware architecture. It can be incorporated into low cost microcontrollers, such as AVR, 8051, PIC, ARM, Z80, 68k and etc..., without any change. Petit FatFs module is also available here.

+ +

Features

+
    +
  • Windows compatible FAT file system.
  • +
  • Platform independent. Easy to port.
  • +
  • Very small footprint for code and work area.
  • +
  • Various configuration options: +
      +
    • Multiple volumes (physical drives and partitions).
    • +
    • Multiple ANSI/OEM code pages including DBCS.
    • +
    • Long file name support in SBCS/DBCS or Unicode.
    • +
    • RTOS support.
    • +
    • Multiple sector size support.
    • +
    • Read-only, minimized API, I/O buffer and etc...
    • +
    +
  • +
+
+ + +
+

Application Interface

+

FatFs module provides following functions to the applications. In other words, this list describes what FatFs can do to access the FAT volumes.

+ +
+ + +
+

Disk I/O Interface

+

Since the FatFs module is completely separated from disk I/O layer, it requires following functions at least to access the physical media. When O/S related feature is enabled, it will require process/memory functions in addition. However the low level disk I/O module is not a part of FatFs module so that it must be provided by user. The sample drivers are also available in the resources.

+ +
+ + +
+

Resources

+

The FatFs module is a free software opened for education, research and development. You can use, modify and/or redistribute it for personal projects or commercial products without any restriction under your responsibility. For further information, refer to the application note.

+ +
+ + +
+ + diff --git a/Lib/Fat/doc/00index_j.html b/Lib/Fat/doc/00index_j.html new file mode 100644 index 0000000..dc8ac93 --- /dev/null +++ b/Lib/Fat/doc/00index_j.html @@ -0,0 +1,105 @@ + + + + + + + + + + +ELM - ”Ä—pFATƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€Eƒ‚ƒWƒ…[ƒ‹ + + + +

FATƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€Eƒ‚ƒWƒ…[ƒ‹

+
+ +
+layer +

FatFs‚ͬ‹K–Í‚È‘g‚Ýž‚݃VƒXƒeƒ€Œü‚¯‚̔ėpFATƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€Eƒ‚ƒWƒ…[ƒ‹‚Å‚·BANSI C€‹’‚Ńn[ƒhƒEƒFƒAEƒA[ƒLƒeƒNƒ`ƒƒ‚ɂ͈ˑ¶‚µ‚È‚¢‚Ì‚ÅA•K—v‚ȃ[ƒNEƒGƒŠƒA‚ªŠm•Û‚Å‚«‚ê‚ÎA8051, PIC, AVR, SH, Z80, 68k, H8, ARM‚ȂLjÀ‰¿‚ȃ}ƒCƒRƒ“‚Å‚àŽg—p‰Â”\‚Å‚·BFatFs‚ðƒVƒ…ƒŠƒ“ƒN‚µ‚½‚Õ‚¿FatFs‚à‚ ‚è‚Ü‚·B

+

FatFsƒ‚ƒWƒ…[ƒ‹‚Ì“Á’¥

+
    +
  • WindowsŒÝŠ· FATƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€
  • +
  • ƒvƒ‰ƒbƒgƒtƒH[ƒ€”ñˆË‘¶
  • +
  • ƒRƒ“ƒpƒNƒg‚ȃR[ƒh‚ÆRAMŽg—p—Ê
  • +
  • ‘½‚­‚Ì\¬ƒIƒvƒVƒ‡ƒ“: +
      +
    • •¡”‚̃{ƒŠƒ…[ƒ€(•¨—ƒhƒ‰ƒCƒuE‹æ‰æ)
    • +
    • DBCS‚ðŠÜ‚Þ•¡”‚ÌANSI/OEMƒR[ƒhEƒy[ƒW
    • +
    • ’·‚¢ƒtƒ@ƒCƒ‹–¼(LFN) (Unicode API‚à‘I‘ð‰Â)
    • +
    • ƒ}ƒ‹ƒ`ƒ^ƒXƒNŠÖ˜A
    • +
    • ƒ}ƒ‹ƒ`EƒZƒNƒ^EƒTƒCƒY
    • +
    • ƒŠ[ƒhEƒIƒ“ƒŠ[\¬Aˆê•”API‚ÌíœAƒoƒbƒtƒ@\¬A‚»‚Ì‘¼c
    • +
    +
  • +
+
+ + +
+

ãˆÊƒŒƒCƒ„EƒCƒ“ƒ^[ƒtƒF[ƒX

+

FatFsƒ‚ƒWƒ…[ƒ‹‚ÍAŽŸ‚̃tƒ@ƒCƒ‹‘€ìŠÖ”(API)‚ð’ñ‹Ÿ‚µ‚Ü‚·B‚‚܂èA‚±‚̃ŠƒXƒg‚ÍFatFs‚É‚Å‚«‚邱‚Æ‚ðƒVƒ“ƒvƒ‹‚ÉŽ¦‚µ‚Ä‚¢‚Ü‚·B

+
    +
  • f_mount - ƒ[ƒNƒGƒŠƒA‚Ì“o˜^Eíœ
  • +
  • f_open - ƒtƒ@ƒCƒ‹‚̃I[ƒvƒ“Eì¬
  • +
  • f_close - ƒtƒ@ƒCƒ‹‚̃Nƒ[ƒY
  • +
  • f_read - ƒtƒ@ƒCƒ‹‚Ì“Ç‚Ýž‚Ý
  • +
  • f_write - ƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚Ý
  • +
  • f_lseek - R/Wƒ|ƒCƒ“ƒ^‚̈ړ®, ƒtƒ@ƒCƒ‹EƒTƒCƒY‚ÌŠg’£
  • +
  • f_truncate - ƒtƒ@ƒCƒ‹EƒTƒCƒY‚ÌØ‚è‹l‚ß
  • +
  • f_sync - ƒLƒƒƒbƒVƒ…‚³‚ꂽƒf[ƒ^‚̃tƒ‰ƒbƒVƒ…
  • +
  • f_opendir - ƒfƒBƒŒƒNƒgƒŠ‚̃I[ƒvƒ“
  • +
  • f_readdir - ƒfƒBƒŒƒNƒgƒŠ‚Ì“Ç‚Ýo‚µ
  • +
  • f_getfree - ƒfƒBƒXƒN‹ó‚«—̈æ‚̎擾
  • +
  • f_stat - ƒtƒ@ƒCƒ‹EƒXƒe[ƒ^ƒX‚̎擾
  • +
  • f_mkdir - ƒfƒBƒŒƒNƒgƒŠ‚Ìì¬
  • +
  • f_unlink - ƒtƒ@ƒCƒ‹/ƒfƒBƒŒƒNƒgƒŠ‚Ìíœ
  • +
  • f_chmod - ƒtƒ@ƒCƒ‹/ƒfƒBƒŒƒNƒgƒŠ‚Ì‘®«‚Ì•ÏX
  • +
  • f_utime - ƒtƒ@ƒCƒ‹/ƒfƒBƒŒƒNƒgƒŠ‚̃^ƒCƒ€ƒXƒ^ƒ“ƒv‚Ì•ÏX
  • +
  • f_rename - ƒtƒ@ƒCƒ‹/ƒfƒBƒŒƒNƒgƒŠ‚Ì–¼‘O•ÏXEˆÚ“®
  • +
  • f_mkfs - ƒfƒBƒXƒN‚̃tƒH[ƒ}ƒbƒg
  • +
  • f_chdir - ƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚Ì•ÏX
  • +
  • f_chdrive - ƒJƒŒƒ“ƒgEƒhƒ‰ƒCƒu‚Ì•ÏX
  • +
  • f_forward - ƒtƒ@ƒCƒ‹Eƒf[ƒ^‚ðƒXƒgƒŠ[ƒ€ŠÖ”‚É’¼Ú“]‘—‚·‚é
  • +
  • f_gets - •¶Žš—ñ‚Ì“Ç‚Ýž‚Ý
  • +
  • f_putc - •¶Žš‚Ì‘‚«ž‚Ý
  • +
  • f_puts - •¶Žš—ñ‚Ì‘‚«ž‚Ý
  • +
  • f_printf - ‘Ž®‰»•¶Žš—ñ‚Ì‘‚«ž‚Ý
  • +
+
+ + +
+

‰ºˆÊƒŒƒCƒ„EƒCƒ“ƒ^[ƒtƒF[ƒX

+

FatFsƒ‚ƒWƒ…[ƒ‹‚ÍA•¨—ƒhƒ‰ƒCƒu“™‚ւ̃AƒNƒZƒX‚Ì‚½‚ßA‰ºˆÊƒŒƒCƒ„‚É­‚È‚­‚Æ‚àŽŸ‚̃Cƒ“ƒ^[ƒtƒF[ƒX‚ð—v‹‚µ‚Ü‚·BŽg—p‚·‚é‹L˜^ƒƒfƒBƒA‚ɑΉž‚µ‚½ƒfƒBƒXƒNI/Oƒ‚ƒWƒ…[ƒ‹‚ÍAƒ†[ƒU‚É‚æ‚Á‚Ä—pˆÓ‚³‚ê‚é•K—v‚ª‚ ‚è‚Ü‚·BOSŠÖ˜A‹@”\‚ð—LŒø‚É‚µ‚½‚Æ‚«‚ÍA‰Á‚¦‚ăvƒƒZƒXEƒƒ‚ƒŠŠÖ˜AŠÖ”‚à•K—v‚É‚È‚è‚Ü‚·BŽ‘—¿‚Ƀhƒ‰ƒCƒo‚ðŠÜ‚ÞƒTƒ“ƒvƒ‹EƒvƒƒWƒFƒNƒg‚ ‚èB

+
    +
  • disk_initialize - ƒfƒBƒXƒNEƒhƒ‰ƒCƒu‚̉Šú‰»
  • +
  • disk_status - ƒfƒBƒXƒNEƒhƒ‰ƒCƒu‚Ìó‘Ԏ擾
  • +
  • disk_read - ƒfƒBƒXƒN‚©‚ç‚Ì“Ç‚Ýž‚Ý
  • +
  • disk_write - ƒfƒBƒXƒN‚Ö‚Ì‘‚«ž‚Ý
  • +
  • disk_ioctl - ‚»‚Ì‘¼‚̃hƒ‰ƒCƒu§Œä
  • +
  • get_fattime - “ú•tEŽž‚̎擾
  • +
+
+ + +
+

Ž‘—¿

+

FatFsƒ‚ƒWƒ…[ƒ‹‚̓tƒŠ[Eƒ\ƒtƒgƒEƒFƒA‚Æ‚µ‚Ä‹³ˆçEŒ¤‹†EŠJ”­—p‚ÉŒöŠJ‚µ‚Ä‚¢‚Ü‚·B‚ǂ̂悤‚È—˜—p–Ú“IiŒÂl—˜—p‚©‚礗p‚Ü‚Åj‚Å‚àŽg—pE‰ü•ÏE”z•z‚ɂ‚¢‚Ĉê؂̧ŒÀ‚Í‚ ‚è‚Ü‚¹‚ñ‚ªA‘S‚Ä—˜—pŽÒ‚ÌÓ”C‚̉º‚Å‚Ì—˜—p‚Æ‚µ‚Ü‚·BÚ‚µ‚­‚̓AƒvƒŠƒP[ƒVƒ‡ƒ“Eƒm[ƒg‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B

+ +
+ + +
+ + diff --git a/Lib/Fat/doc/css_e.css b/Lib/Fat/doc/css_e.css new file mode 100644 index 0000000..6f00e6a --- /dev/null +++ b/Lib/Fat/doc/css_e.css @@ -0,0 +1,57 @@ +* {margin: 0; padding: 0; border-width: 0;} +body {margin: 8px; background-color: #e0ffff; font-color: black; font-family: serif; line-height: 133%; max-width: 1024px;} +a:link {color: blue;} +a:visited {color: darkmagenta;} +a:hover {background-color: #a0ffff;} +a:active {color: darkmagenta; position: relative; top: 1px; left: 1px;} +abbr {border-width: 1px;} + +p {margin: 0 0 0.3em 1em;} +em {font-style: normal; font-weight: bold; margin: 0 0.1em;} +pre em {font-style: italic; font-weight: normal;} +strong {} +pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; background-color: white;} +pre span {color: green;} +tt {margin: 0 0.2em;} +ol {margin: 0 2.5em;} +ul {margin: 0 2em;} +dl {margin: 0 1em;} +dt {font-family: monospace;} +dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; } +dl.ret dt {margin: 0.5em 0 0 0 ; font-weight: bold;} +dd {margin: 0 2em;} +hr {border-width: 1px; margin: 1em;} +div.abst {font-family: sans-serif;} +div.para {clear: both; font-family: serif;} +.equ {text-indent: 0; margin: 1em 2em 1em;} +.indent {margin-left: 2em;} +.rset {float: right; margin: 0 0 0.5em 0.5em;} +.lset {float: left; margin: 0 0.5em 0.5em 0.5em;} +ul.flat li {list-style-type: none; margin: 0;} +a.imglnk img {border: 1px solid;} +.iequ {white-space: nowrap; font-weight: bold;} +.clr {clear: both;} +.it {font-style: italic;} +.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} + +h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} +p.hdd {float: right; text-align: right; margin-top: 0.5em;} +hr.hds {clear: both; margin-bottom: 1em;} + +h2 {font-size: 1.5em; color: blueviolet; font-family: sans-serif; margin: 0 0 0.5em;} +h3 {font-size: 1.5em; font-family: sans-serif; margin: 1.5em 0 0.5em;} +h4 {font-size: 1.2em; font-family: sans-serif; margin: 1em 0 0.2em;} +h5 {font-size: 1em; font-family: sans-serif; margin: 0.5em 0 0em;} +small {font-size: 80%;} +.indent {margin-left: 2em;} + +/* Tables */ +table {margin: 0.5em 1em; border-collapse: collapse; border-style: solid; border-width: 2px; border-color: black; } +th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top; white-space: nowrap;} +td {background-color: white; border-style: solid; border-width: 1px; border-color: black; padding: 0 3px; vertical-align: top; line-height: 1.3em;} +table.lst td:first-child {font-family: monospace;} +table.lst2 td {font-family: monospace;} +table caption {font-family: sans-serif; font-weight: bold;} +tr.lst3 td { border-width: 2px 1px 1px; } + +p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} diff --git a/Lib/Fat/doc/css_j.css b/Lib/Fat/doc/css_j.css new file mode 100644 index 0000000..bc7bec0 --- /dev/null +++ b/Lib/Fat/doc/css_j.css @@ -0,0 +1,60 @@ +@charset "Shift_JIS"; +/* Common style sheet for Tech Notes */ + +* {margin: 0; padding: 0; border-width: 0;} +body {margin: 8px; background-color: #e0ffff; font-color: black; font-family:"‚l‚r ‚o–¾’©", serif; line-height: 150%; letter-spacing: 1px; max-width: 1024px;} +a:link {color: blue;} +a:visited {color: darkmagenta;} +a:hover {background-color: #a0ffff;} +a:active {color: darkmagenta; position: relative; top: 1px; left: 1px;} +abbr {border-width: 1px;} + +p {text-indent: 1em; margin: 0 0 0.3em 0.5em;} +em {font-style: normal; font-weight: bold; margin: 0 0.1em;} +pre em {font-style: italic; font-weight: normal;} +strong {} +pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; letter-spacing: 0; background-color: white;} +pre span {color: green;} +tt {margin: 0 0.2em; letter-spacing: 0;} +ol {margin: 0 2.5em;} +ul {margin: 0 2em;} +dl {margin: 0 1em;} +dt {font-family: monospace;} +dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; letter-spacing: 0;} +dl.ret dt {margin: 0.5em 0 0 0 ; font-family: monospace; letter-spacing: 0; font-weight: bold;} +dd {margin: 0 2em;} +hr {border-width: 1px; margin: 1em;} +div.abst {font-family: "‚l‚r ‚oƒSƒVƒbƒN",sans-serif;} +div.para {clear: both; font-family: "‚l‚r ‚o–¾’©",serif;} +.equ {text-indent: 0; margin: 1em 2em 1em;} +.indent {margin-left: 2em;} +.rset {float: right; margin: 0 0 0.5em 0.5em;} +.lset {float: left; margin: 0 0.5em 0.5em 0.5em;} +ul.flat li {list-style-type: none; margin: 0;} +a.imglnk img {border: 1px solid;} +.iequ {white-space: nowrap; font-weight: bold;} +.clr {clear: both;} +.it {font-style: italic;} +.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} + +h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} +p.hdd {float: right; text-align: right; margin-top: 0.5em;} +hr.hds {clear: both; margin-bottom: 1em;} + +h2 {font-size: 1.5em; color: blueviolet; font-family: "‚l‚r ‚oƒSƒVƒbƒN",sans-serif; margin: 0 0 0.5em;} +h3 {font-size: 1.5em; font-family: "‚l‚r ‚oƒSƒVƒbƒN",sans-serif; margin: 1.5em 0 0.5em;} +h4 {font-size: 1.2em; font-family: "‚l‚r ‚oƒSƒVƒbƒN",sans-serif; margin: 1em 0 0.2em;} +h5 {font-size: 1em; font-family: "‚l‚r ‚oƒSƒVƒbƒN",sans-serif; margin: 0.5em 0 0em;} +small {font-size: 80%;} +.indent {margin-left: 2em;} + +/* Tables */ +table {margin: 0.5em 1em; border-collapse: collapse; border-style: solid; border-width: 2px; border-color: black; letter-spacing: 0;} +th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top;} +td {background-color: white; border-style: solid; border-width: 1px; border-color: black; padding: 0 3px; vertical-align: top; line-height: 1.3em;} +table.lst td:first-child {font-family: monospace; white-space: nowrap;} +table.lst2 td {font-family: monospace; white-space: nowrap;} +table caption {font-family: sans-serif; font-weight: bold;} +tr.lst3 td { border-width: 2px 1px 1px; } + +p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} diff --git a/Lib/Fat/doc/en/appnote.html b/Lib/Fat/doc/en/appnote.html new file mode 100644 index 0000000..613f218 --- /dev/null +++ b/Lib/Fat/doc/en/appnote.html @@ -0,0 +1,229 @@ + + + + + + + + +FatFs Module Application Note + + + +

FatFs Module Application Note

+
+ +
+

How to port

+ +

Basic considerations

+

The FatFs module is assuming following conditions on portability.

+
    +
  • ANSI C
    +The FatFs module is a middleware which is written in ANSI C. There is no platform dependence, so long as the compiler is in compliance with ANSI C.
  • +
  • Size of integer types
    +The FatFs module assumes that size of char/short/long are 8/16/32 bit and int is 16 or 32 bit. These correspondence are defined in integer.h. This will not be a problem on most compilers. When any conflict with existing definitions is occured, you must resolve it with care.
  • +
+ +

Which function is required?

+

You need to provide only low level disk I/O functions that required by FatFs module and nothing else. If a working disk module for the target is already existing, you need to write only glue functions to attach it to the FatFs module. If not, you need to port any other disk module or write it from scratch. All defined functions are not that always required. For example, disk write function is not required in read-only configuration. Following table shows which function is required depends on configuration options.

+ + + + + + + + + + + + + + + + + + + +
FunctionRequired when:Note
disk_initializeAlwaysSamples available in ffsample.zip.
There are many implementations on the web.
disk_statusAlways
disk_readAlways
disk_write_FS_READONLY == 0
disk_ioctl (CTRL_SYNC)_FS_READONLY == 0
disk_ioctl (GET_SECTOR_COUNT)_USE_MKFS == 1
disk_ioctl (GET_SECTOR_SIZE)_MAX_SS >= 1024
disk_ioctl (GET_BLOCK_SIZE)_USE_MKFS == 1
get_fattime_FS_READONLY == 0
ff_convert_USE_LFN >= 1Available in option/cc*.c.
ff_wtoupper_USE_LFN >= 1
ff_cre_syncobj_FS_REENTRANT == 1Samples available in option/syscall.c.
ff_del_syncobj_FS_REENTRANT == 1
ff_req_grant_FS_REENTRANT == 1
ff_rel_grant_FS_REENTRANT == 1
ff_mem_alloc_USE_LFN == 3
ff_mem_free_USE_LFN == 3
+
+ +
+

Limits

+
    +
  • FAT sub-types: FAT12, FAT16 and FAT32.
  • +
  • Number of open files: Unlimited, depends on available memory.
  • +
  • Number of volumes: Upto 10.
  • +
  • File size: Depends on FAT specs. (upto 4G-1 bytes)
  • +
  • Volume size: Depends on FAT specs. (upto 2T bytes on 512 bytes/sector)
  • +
  • Cluster size: Depends on FAT specs. (upto 64K bytes on 512 bytes/sector)
  • +
  • Sector size: Depends on FAT specs. (upto 4K bytes)
  • +
+
+ +
+

Memory Usage (R0.08)

+ + + + + + + + + + + +
AVRH8/300HPIC24V850ESSH-2AARM7x86
CompilerWinAVR(gcc)CH38C30(gcc)CA850SHCWinARM(gcc)VC6
_WORD_ACCESS1001001
text (Full, R/W)12700106861137677308592105207545
text (Min, R/W)8386698073954930560066364923
text (Full, R/O)6012487452503556384846563450
text (Min, R/O)4384377439392684299634162664
bssD*2 + 2D*4 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
D*560 +
F*544
D*560 +
F*550
D*560 +
F*544
D*560 +
F*550
D*560 +
F*550
D*560 +
F*550
D*560 +
F*550
Work area
(_FS_TINY == 1)
D*560 +
F*32
D*560 +
F*36
D*560 +
F*32
D*560 +
F*36
D*560 +
F*36
D*560 +
F*36
D*560 +
F*36
+

These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, D means number of volumes and F means number of open files. All samples are optimezed in code size.

+
+_FS_READONLY     0 (R/W), 1 (R/O)
+_FS_MINIMIZE     0 (Full function), 3 (Minimized function)
+_USE_STRFUNC     0 (Disable string functions)
+_USE_MKFS        0 (Disable f_mkfs function)
+_USE_FORWARD     0 (Disable f_forward function)
+_USE_FASTSEEK    0 (Disable fast seek feature)
+_CODE_PAGE       932 (Japanese Shift-JIS)
+_USE_LFN         0 (Disable LFN)
+_MAX_SS          512 (Fixed sector size)
+_FS_RPATH        0 (Disable relative path)
+_MULTI_PARTITION 0 (Single partition per drive)
+_FS_REENTRANT    0 (Disable reentrancy)
+_FS_SHARE        0 (Disable shareing control)
+
+
+ +
+

Module Size Reduction

+

Follwing table shows which function is removed by configuration options for the module size reduction.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Function_FS_MINIMIZE_FS_READONLY_USE_STRFUNC_FS_RPATH_USE_MKFS_USE_FORWARD
12310000
f_mount
f_open
f_close
f_read
f_writex
f_syncx
f_lseekx
f_opendirxx
f_readdirxx
f_statxxx
f_getfreexxxx
f_truncatexxxx
f_unlinkxxxx
f_mkdirxxxx
f_chmodxxxx
f_utimexxxx
f_renamexxxx
f_chdirx
f_chdrivex
f_mkfsxx
f_forwardx
f_putcxx
f_putsxx
f_printfxx
f_getsx
+
+ +
+

Long File Name

+

The FatFs module has started to support long file name (LFN) at revision 0.07. The two different file names, SFN and LFN, of a file is transparent in the file functions except for f_readdir function. To enable LFN feature, set _USE_LFN to 1, 2 or 3, and add a Unicode code conversion function ff_convert() and ff_wtoupper() to the project. The LFN feature requiers a certain working buffer in addition. The buffer size can be configured by _MAX_LFN corresponding to the available memory size. The size of long file name will reach up to 255 characters so that the _MAX_LFN should be set to 255 for full featured LFN operation. If the size of working buffer is insufficient for the given file name, the file function fails with FR_INVALID_NAME. When enable the LFN feature with re-entrant feature, _USE_LFN must be set to 2 or 3. In this case, the file function allocates the working buffer on the stack or heap. The working buffer occupies (_MAX_LFN + 1) * 2 bytes.

+ + + + + + + + +
LFN cfg on ARM7
Code pageProgram size
SBCS+3.7K
932(Shift-JIS)+62K
936(GBK)+177K
949(Korean)+139K
950(Big5)+111K
+

When the LFN feature is enabled, the module size will be increased depends on the selected code page. Right table shows how many bytes increased when LFN feature is enabled with some code pages. We are the Japanese, Chinese and Korean have tens of thousands of characters. Unfortunately, it requires a huge OEM-Unicode bidirectional conversion table and the module size will be drastically increased that shown in the table. As the result, the FatFs with LFN feature with DBCS will not able to be implemented to most 8-bit microcontrollers. This is the reason why I had not been interested in implementing the LFN feature for a long time :-)

+

Note that the LFN feature on the FAT file system is a patent of Microsoft Corporation. When enable it on the commercial products, a license from Microsoft may be required depends on the final destination.

+
+ +
+

Unicode API

+

FatFs supports ANSI/OEM code set on the API in default but FatFs can also switch the code set to Unicode. For more information, refer to the description in the file name.

+
+ +
+

Re-entrancy

+

The file operations to the different volume can always work simultaneously regardless of re-entrancy setting. The re-entrancy to the same volume can be enabled with _FS_REENTRANT option. In this case, also the OS dependent synchronization object control functions, ff_cre_syncobj, ff_del_syncobj, ff_req_grant and ff_rel_grant must be added to the project.

+

When a file function is called while the volume is in use by any other task, the access is blocked until the task leaves file function. If wait time exceeded a period defined by _TIMEOUT, the file function will abort with FR_TIMEOUT. The timeout feature might not be supported on some RTOS.

+

There is an exception on f_mount and f_mkfs function. These functions are not re-entrant to the same volume. When use these functions, all other task must close the corresponding file on the volume and avoid to access the volume.

+

Note that this section describes on the re-entrancy of the FatFs module itself. There is no assumtion on the re-entrancy of low level disk I/O module.

+
+ +
+

Duplicated file access

+

FatFs module does not support the shareing controls of duplicated file access in default. It is permitted when open method to a file is only read mode. The duplicated open in write mode to a file is always prohibited and open file must not be renamed, deleted, otherwise the FAT structure on the volume can be collapted. Also current directory must not be deleted.

+

The file shareing control can also be available when _FS_SHARE is set to 1 or grater. In this case, if any open, rename or remove that violating the file shareing rule that described above is attempted, the file function will fail with FR_LOCKED.

+
+ +
+

Performance effective file access

+

For good performance on reading/writing files on the small embedded system, application programmer should consider what process is done in the FatFs module. The file data on the disk is transferred in following sequence by f_read function.

+

Figure 1. Sector miss-aligned read (short)
+ +

+

Figure 2. Sector miss-aligned read (long)
+ +

+

Figure 3. Sector aligned read
+ +

+

The file I/O buffer means a sector buffer to read/write a partial data on the sector. The sector buffer is either file private sector buffer on each file object or shared sector buffer on the file system object. The buffer configuration option _FS_TINY determins which sector buffer is used for the file data transfer. When tiny buffer (1) is selected, data memory consumption is reduced 512 bytes each file object. In this case, FatFs module uses only a sector buffer on the file system object for file data transfer and FAT/directory access. The disadvantage of the tiny buffer configuration is: the FAT data cached in the sector buffer will be lost by file data transfer and it must be reloaded at every cluster boundary. However it will be suitable for most application from view point of the decent performance and low memory comsumption.

+

Figure 1 shows that partial sector data is transferred via the file I/O buffer. On long data transfer shown in Figure 2, middle of transfer data that covers one or more sector is transferred to application buffer directly. Figure 3 shows that the case of entier transfer data is aligned to the sector boundary. In this case, file I/O buffer is not used. On the direct transfer, the maximum extent of sectors are read with disk_read function at a time but the multi sector transfer never across the cluster boundary even if it is contiguous.

+

Therefore taking effort to sector aligned read/write accesss avoids buffered data transfer and the read/write performance will be improved. Besides the effect, cached FAT data will not be flushed by file data transfer on the tiny configuration so that it can achieve same performance as non-tiny configuration with small memory footprint.

+
+ +
+

Critical Section

+

If a write operation to the FAT file system is interrupted due to any accidental failure, such as sudden blackout, incorrect disk removal and unrecoverable disk error, the FAT structure can be collapted. Following images shows the critical section on the FatFs application.

+
+Figure 4. Long critical section
+fig.4 +
+
+Figure 5. Minimized critical section
+fig.5 +
+
+

An interruption in the red section can cause a cross link; as a result, the object being changed may be lost. There is one or more possibility listed below when an interruption in the yellow section is occured.

+
    +
  • File data being rewrited is collapted.
  • +
  • A file being appended returns initial state.
  • +
  • A file created as new is gone.
  • +
  • A file created as new or in overwritten remains with no content.
  • +
  • Efficiency of disk use gets worse due to lost chain.
  • +
+

Each case does not affect the files that not in write mode open. To minimize risk of data loss, the critical section can be minimized like shown in Figure 5 by minimizing the time that file is opened in write mode or using f_sync function properly.

+
+ +
+

About FatFs License

+

This is a copy of the FatFs license document that included in the source codes.

+
/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.08                     (C)ChaN, 2010
+/-----------------------------------------------------------------------------/
+/ FatFs module is a generic FAT file system module for small embedded systems.
+/ This is a free software that opened for education, research and commercial
+/ developments under license policy of following trems.
+/
+/  Copyright (C) 2010, ChaN, all right reserved.
+/
+/ * The FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-----------------------------------------------------------------------------/
+

Therefore FatFs license is one of the BSD-style license but there is a big difference. Because FatFs is for embedded projects, the conditions for redistributions in binary form, such as embedded code, hex file and binary library, are not specified to increase its usability. The documentation of the distributions need not include about FatFs and its license document, and it may also. Of course FatFs is compatible with the projects under GNU GPL. When redistribute it with any modification, the license can also be changed to GNU GPL or BSD-style license.

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/chdir.html b/Lib/Fat/doc/en/chdir.html new file mode 100644 index 0000000..fdeed82 --- /dev/null +++ b/Lib/Fat/doc/en/chdir.html @@ -0,0 +1,88 @@ + + + + + + + + +FatFs - f_chdir + + + + +
+

f_chdir

+

The f_chdir function changes the current directory of a drive.

+
+FRESULT f_chdir (
+  const TCHAR* Path /* Pointer to the path name */
+);
+
+
+ +
+

Parameters

+
+
Path
+
Pointer to the null-terminated string that specifies a directory to go.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The path name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_chdir function changes the current directory of the logical drive. The current directory of a drive is initialized to the root directory when the drive is auto-mounted. Note that the current directory is retained in the each file system object so that it also affects other tasks that using the drive.

+
+ + +
+

QuickInfo

+

Available when _FS_RPATH == 1.

+
+ + +
+

Example

+
+    /* Change current direcoty of the current drive (dir1 under root dir) */
+    f_chdir("/dir1");
+
+    /* Change current direcoty of drive 2 (parent dir) */
+    f_chdir("2:..");
+
+
+ +
+

See Also

+

f_chdrive

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/chdrive.html b/Lib/Fat/doc/en/chdrive.html new file mode 100644 index 0000000..105045c --- /dev/null +++ b/Lib/Fat/doc/en/chdrive.html @@ -0,0 +1,62 @@ + + + + + + + + +FatFs - f_chdrive + + + + +
+

f_chdrive

+

The f_chdrive function changes the current drive.

+
+FRESULT f_chdrive (
+  BYTE Drive /* Logical drive number */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Specifies the logical drive number to be set as the current drive.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
+
+ + +
+

Description

+

The f_chdrive function changes the current drive. The initial value of the current drive number is 0. Note that the current drive is retained in a static variable so that it also affects other tasks that using the file functions.

+
+ +
+

QuickInfo

+

Available when _FS_RPATH == 1.

+
+ + +
+

See Also

+

f_chdir

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/chmod.html b/Lib/Fat/doc/en/chmod.html new file mode 100644 index 0000000..78b7961 --- /dev/null +++ b/Lib/Fat/doc/en/chmod.html @@ -0,0 +1,98 @@ + + + + + + + + +FatFs - f_chmod + + + + +
+

f_chmod

+

The f_chmod function changes the attribute of a file or directory.

+
+FRESULT f_chmod (
+  const TCHAR* FileName, /* Pointer to the file or directory */
+  BYTE Attribute,        /* Attribute flags */
+  BYTE AttributeMask     /* Attribute masks */
+);
+
+
+ +
+

Parameters

+
+
FileName
+
Pointer to the null-terminated string that specifies a file or directory to be changed
+
Attribute
+
Attribute flags to be set in one or more combination of the following flags. The specified flags are set and others are cleard.
+ + + + + + +
AttributeDescription
AM_RDORead only
AM_ARCArchive
AM_SYSSystem
AM_HIDHidden
+
+
AttributeMask
+
Attribute mask that specifies which attribute is changed. The specified aattributes are set or cleard.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_FILE
+
Could not find the file.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The file name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_WRITE_PROTECTED
+
The medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_chmod function changes the attribute of a file or directory.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

Example

+
+    /* Set read-only flag, clear archive flag and others are retained. */
+    f_chmod("file.txt", AR_RDO, AR_RDO | AR_ARC);
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/close.html b/Lib/Fat/doc/en/close.html new file mode 100644 index 0000000..cf3bbaa --- /dev/null +++ b/Lib/Fat/doc/en/close.html @@ -0,0 +1,69 @@ + + + + + + + + +FatFs - f_close + + + + +
+

f_close

+

The f_close function closes an open file.

+
+FRESULT f_close (
+  FIL* FileObject     /* Pointer to the file object structure */
+);
+
+
+ +
+

Parameter

+
+
FileObject
+
Pointer to the open file object structure to be closed.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The file object has been closed successfuly.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The f_close function closes an open file object. If any data has been written to the file, the cached information of the file is written back to the disk. After the function succeeded, the file object is no longer valid and it can be discarded. If the file object has been opened in read-only mode, it may be discarded without closing process by this function but not recommended.

+
+ + +
+

QuickInfo

+

Always available.

+
+ + +
+

See Also

+

f_open, f_read, f_write, f_sync, FIL, FATFS

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/dinit.html b/Lib/Fat/doc/en/dinit.html new file mode 100644 index 0000000..cad27ce --- /dev/null +++ b/Lib/Fat/doc/en/dinit.html @@ -0,0 +1,46 @@ + + + + + + + + +FatFs - disk_initialize + + + + +
+

disk_initialize

+

The disk_initialize function initializes the disk drive.

+
+DSTATUS disk_initialize (
+  BYTE Drive           /* Physical drive number */
+);
+
+
+ +
+

Parameter

+
+
Drive
+
Specifies the physical drive number to initialize.
+
+
+ + +
+

Return Values

+

This function returns a disk status as the result. For details of the disk status, refer to the disk_status function.

+
+ +
+

Description

+

The disk_initialize function initializes a physical drive. When the function succeeded, STA_NOINIT flag in the return value is cleard.

+

This function is called on volume mount process in the FatFs module to manage the media change. Application program should not call this function, or FAT structure on the volume can be collapted. To re-initialize the file system, use f_mount function.

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/dioctl.html b/Lib/Fat/doc/en/dioctl.html new file mode 100644 index 0000000..946f397 --- /dev/null +++ b/Lib/Fat/doc/en/dioctl.html @@ -0,0 +1,68 @@ + + + + + + + + +FatFs - disk_ioctl + + + + +
+

disk_ioctl

+

The disk_ioctl function cntrols device specified features and miscellaneous functions other than disk read/write.

+
+DRESULT disk_ioctl (
+  BYTE Drive,      /* Drive number */
+  BYTE Command,    /* Control command code */
+  void* Buffer     /* Parameter and data buffer */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Specifies the drive number (0-9).
+
Command
+
Specifies the command code.
+
Buffer
+
Pointer to the parameter buffer depends on the command code. When it is not used, specify a NULL pointer.
+
+
+ + +
+

Return Value

+
+
RES_OK (0)
+
The function succeeded.
+
RES_ERROR
+
Any error occured.
+
RES_PARERR
+
Invalid command code.
+
RES_NOTRDY
+
The disk drive has not been initialized.
+
+
+ + +
+

Description

+

The FatFs module uses only device independent commands described below. Any device dependent function is not used.

+ + + + + + +
CommandDescription
CTRL_SYNCMake sure that the disk drive has finished pending write process. When the disk I/O module has a write back cache, flush the dirty sector immediately. This command is not required in read-only configuration.
GET_SECTOR_SIZEReturns sector size of the drive into the WORD variable pointed by Buffer. This command is not required in single sector size configuration, _MAX_SS is 512.
GET_SECTOR_COUNTReturns total sectors on the drive into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function to determine the volume size to be created.
GET_BLOCK_SIZEReturns erase block size of the flash memory in unit of sector into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function and it attempts to align data area to the erase block boundary. The allowable value is 1 to 32768 in power of 2. Return 1 if the erase block size is unknown or disk devices.
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/dread.html b/Lib/Fat/doc/en/dread.html new file mode 100644 index 0000000..011dd3a --- /dev/null +++ b/Lib/Fat/doc/en/dread.html @@ -0,0 +1,59 @@ + + + + + + + + +FatFs - disk_read + + + + +
+

disk_read

+

The disk_read function reads sector(s) from the disk drive.

+
+DRESULT disk_read (
+  BYTE Drive,          /* Physical drive number */
+  BYTE* Buffer,        /* Pointer to the read data buffer */
+  DWORD SectorNumber,  /* Start sector number */
+  BYTE SectorCount     /* Number of sectros to read */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Specifies the physical drive number.
+
Buffer
+
Pointer to the byte array to store the read data. The buffer size of number of bytes to be read, sector size * sector count, is required. The memory address specified by upper layer may or may not be aligned to word boundary.
+
SectorNumber
+
Specifies the start sector number in logical block address (LBA).
+
SectorCount
+
Specifies number of sectors to read. The value can be 1 to 255.
+
+
+ + +
+

Return Value

+
+
RES_OK (0)
+
The function succeeded.
+
RES_ERROR
+
Any hard error occured during the read operation and could not recover it.
+
RES_PARERR
+
Invalid parameter.
+
RES_NOTRDY
+
The disk drive has not been initialized.
+
+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/dstat.html b/Lib/Fat/doc/en/dstat.html new file mode 100644 index 0000000..72ae576 --- /dev/null +++ b/Lib/Fat/doc/en/dstat.html @@ -0,0 +1,48 @@ + + + + + + + + +FatFs - disk_status + + + + +
+

disk_status

+

The disk_status function returns the current disk status.

+
+DSTATUS disk_status (
+  BYTE Drive     /* Physical drive number */
+);
+
+
+ +
+

Parameter

+
+
Drive
+
Specifies the physical drive number to be confirmed.
+
+
+ + +
+

Return Values

+

The disk status is returned in combination of following flags. FatFs refers only STA_NOINIT and STA_PROTECTED.

+
+
STA_NOINIT
+
Indicates that the disk drive has not been initialized. This flag is set on: system reset, disk removal and disk_initialize function failed, and cleared on: disk_initialize function succeeded.
+
STA_NODISK
+
Indicates that no medium in the drive. This is always cleared on fixed disk drive.
+
STA_PROTECTED
+
Indicates that the medium is write protected. This is always cleared on the drive that does not support write protect notch. Not valid when STA_NODISK is set.
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/dwrite.html b/Lib/Fat/doc/en/dwrite.html new file mode 100644 index 0000000..cbe43d8 --- /dev/null +++ b/Lib/Fat/doc/en/dwrite.html @@ -0,0 +1,67 @@ + + + + + + + + +FatFs - disk_write + + + + +
+

disk_write

+

The disk_write writes sector(s) to the disk.

+
+DRESULT disk_write (
+  BYTE Drive,          /* Physical drive number */
+  const BYTE* Buffer,  /* Pointer to the write data (may be non aligned) */
+  DWORD SectorNumber,  /* Sector number to write */
+  BYTE SectorCount     /* Number of sectors to write */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Specifies the physical drive number.
+
Buffer
+
Pointer to the byte array to be written. The memory address specified by upper layer may or may not be aligned to word boundary.
+
SectorNumber
+
Specifies the start sector number in logical block address (LBA).
+
SectorCount
+
Specifies the number of sectors to write. The value can be 1 to 255.
+
+
+ + +
+

Return Values

+
+
RES_OK (0)
+
The function succeeded.
+
RES_ERROR
+
Any hard error occured during the write operation and could not recover it.
+
RES_WRPRT
+
The medium is write protected.
+
RES_PARERR
+
Invalid parameter.
+
RES_NOTRDY
+
The disk drive has not been initialized.
+
+
+ + +
+

Description

+

This function is not required in read only configuration.

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/fattime.html b/Lib/Fat/doc/en/fattime.html new file mode 100644 index 0000000..e726731 --- /dev/null +++ b/Lib/Fat/doc/en/fattime.html @@ -0,0 +1,51 @@ + + + + + + + + +FatFs - get_fattime + + + + +
+

get_fattime

+

The get_fattime function gets current time.

+
+DWORD get_fattime (void);
+
+
+ + +
+

Return Value

+

Currnet time is returned with packed into a DWORD value. The bit field is as follows:

+
+
bit31:25
+
Year from 1980 (0..127)
+
bit24:21
+
Month (1..12)
+
bit20:16
+
Day in month(1..31)
+
bit15:11
+
Hour (0..23)
+
bit10:5
+
Minute (0..59)
+
bit4:0
+
Second / 2 (0..29)
+
+
+ + +
+

Description

+

The get_fattime function must return any valid time even if the system does not support a real time clock. If a zero is returned, the file will not have a valid time. This fucntion is not required in read only configuration.

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/filename.html b/Lib/Fat/doc/en/filename.html new file mode 100644 index 0000000..e18dc67 --- /dev/null +++ b/Lib/Fat/doc/en/filename.html @@ -0,0 +1,73 @@ + + + + + + + + +FatFs - Path Names + + + + +
+

Format of the path names

+

The path name format on the FatFs module is similer to the filename specs of DOS/Windos as follows:

+

"[drive#:][/]directory/file"

+

The FatFs module supports long file name (LFN) and 8.3 format file name (SFN). The LFN can be used when LFN feature is enabled (_USE_LFN > 0). The differences between FatFs and DOS/Windows are directory separator and logical drive number. The sub directories are separated with a / or \. The logical drive is specified in a numeral with a colon. When the drive number is omitted, it is assumed as default drive (0 or current drive).

+

Nul character and control characters (\0 to \x1F) are recognized as end of the path name. Leading/embedded spaces in the path name are valid as a part of the name on LFN configuration but they are recognized as end of the path name on non-LFN configuration.

+

In default configuration (_FS_RPATH == 0), it does not have a concept of current directory like OS oriented file system. All objects on the volume are always specified in full path name that follows from the root directory. Dot directory names are not allowed. Heading separator is ignored and it can be exist or omitted. The default drive number is fixed to 0.

+

When relative path feature is enabled (_FS_RPATH == 1), specified path is followed from the root directory if a heading separator is exist. If not, the path is followed from the current directory set with f_chdir function. Dot names are also allowed for the directory name. The default drive number is the current drive number set with f_chdrive function.

+ + + + + + + + + + + + + +
Path name_FS_RPATH == 0_FS_RPATH == 1
file.txtA file in the root directory on the drive 0A file in the current directory on the current drive
/file.txtA file in the root directory on the drive 0A file in the root directory on the current drive
The root directory on the drive 0The current directory on the current drive
2:The root directory on the drive 2The current directory on the drive 2
2:file.txtA file in the root directory on the drive 2A file in the current directory on the drive 2
2:/The root directory on the drive 2The root directory on the drive 2
../file.txtInvalid nameA file in the parent directory
.Invalid nameThis directory
..Invalid nameParent directory of the current directory
dir1/..Invalid nameThe current directory
/..Invalid nameThe root directory (sticks the top level)
+
+ +


+
+

Unicode API

+

The path names are input/output in either ANSI/OEM code (SBCS/DBCS) or Unicode depends on the configuration options. The type of arguments that specifies the file names are defined as TCHAR which is an alias of char in default. The code set of the file name string is the ANSI/OEM code set specifid by _CODE_PAGE. When _LFN_UNICODE is set to 1 under LFN configuration, the type of the TCHAR is switched to unsigned short (UCS-2 character) to support Unicode. In this case, the LFN feature is fully supported and the Unicode specific characters, such as âœâ˜ªâœ¡â˜¸â˜­, can also be used for the path name. It also affects data types and encoding of the string I/O functions. To define literal strings, _T(s) and _TEXT(s) macro are available to select either ANSI/OEM or Unicode automatically. The code shown below is an example to define the literal strings.

+
+ f_open(fp, "filename.txt", FA_READ);      /* ANSI/OEM only */
+ f_open(fp, L"filename.txt", FA_READ);     /* Unicode only */
+ f_open(fp, _T("filename.txt"), FA_READ);  /* Changed automatically */
+
+
+ +


+
+

Correspondence between logical and physical drives

+

The FatFs module has work areas that called file system object for each volume (logical drive). In default, the logical drive is bound to the physical drive that has same drive number, and the first partition is mounted. When _MULTI_PARTITION == 1 is specified in configuration option, each individual logical drive can be bound to any physical drive/partition. In this case, a drive number resolution table must be defined as follows:

+
+Example: Logical drive 0-2 are assigned to three pri-partitions on the physical drive 0 (fixed disk)
+         Logical drive 3 is assigned to physical drive 1 (removable disk)
+
+const PARTITION Drives[] = {
+    {0, 0},     /* Logical drive 0 ==> Physical drive 0, 1st partition */
+    {0, 1},     /* Logical drive 1 ==> Physical drive 0, 2nd partition */
+    {0, 2},     /* Logical drive 2 ==> Physical drive 0, 3rd partition */
+    {1, 0}      /* Logical drive 3 ==> Physical drive 1 */
+};
+
+

There are some considerations when use _MULTI_PARTITION configuration.

+
    +
  • Only pri-partition (0-3) can be mounted.
  • +
  • When the physical drive has no partition table (SFD format), the partition number is ignored.
  • +
  • The physical drive that has two or more logical drives must be a fixed drive.
  • +
+
+ + + diff --git a/Lib/Fat/doc/en/forward.html b/Lib/Fat/doc/en/forward.html new file mode 100644 index 0000000..5286b58 --- /dev/null +++ b/Lib/Fat/doc/en/forward.html @@ -0,0 +1,145 @@ + + + + + + + + +FatFs - f_forward + + + + +
+

f_forward

+

The f_forward function reads the file data and forward it to the data streaming device.

+
+FRESULT f_forward (
+  FIL* FileObject,                 /* File object */
+  UINT (*Func)(const BYTE*,UINT),  /* Data streaming function */
+  UINT ByteToFwd,                  /* Number of bytes to forward */
+  UINT* ByteFwd                    /* Number of bytes forwarded */
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the open file object.
+
Func
+
Pointer to the user-defined data streaming function. For details, refer to the sample code.
+
ByteToFwd
+
Number of bytes to forward in range of UINT.
+
ByteFwd
+
Pointer to the UINT variable to return number of bytes forwarded.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DENIED
+
The function denied due to the file has been opened in non-read mode.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The f_forward function reads the data from the file and forward it to the outgoing stream without data buffer. This is suitable for small memory system because it does not require any data buffer at application module. The file pointer of the file object increases in number of bytes forwarded. In case of *ByteFwd < ByteToFwd without error, it means the requested bytes could not be transferred due to end of file or stream goes busy during data transfer.

+
+ + +
+

QuickInfo

+

Available when _USE_FORWARD == 1 and _FS_TINY == 1.

+
+ + +
+

Example (Audio playback)

+
+/*------------------------------------------------------------------------*/
+/* Sample code of data transfer function to be called back from f_forward */
+/*------------------------------------------------------------------------*/
+
+UINT out_stream (   /* Returns number of bytes sent or stream status */
+    const BYTE *p,  /* Pointer to the data block to be sent */
+    UINT btf        /* >0: Transfer call (Number of bytes to be sent). 0: Sense call */
+)
+{
+    UINT cnt = 0;
+
+
+    if (btf == 0) {     /* Sense call */
+        /* Return stream status (0: Busy, 1: Ready) */
+        /* When once it returned ready to sense call, it must accept a byte at least */
+        /* at subsequent transfer call, or f_forward will fail with FR_INT_ERROR. */
+        if (FIFO_READY) cnt = 1;
+    }
+    else {              /* Transfer call */
+        do {    /* Repeat while there is any data to be sent and the stream is ready */
+            FIFO_PORT = *p++;
+            cnt++;
+        } while (cnt < btf && FIFO_READY);
+    }
+
+    return cnt;
+}
+
+
+/*------------------------------------------------------------------------*/
+/* Sample code using f_forward function                                   */
+/*------------------------------------------------------------------------*/
+
+FRESULT play_file (
+    char *fn        /* Pointer to the audio file name to be played */
+)
+{
+    FRESULT rc;
+    FIL fil;
+    UINT dmy;
+
+    /* Open the audio file in read only mode */
+    rc = f_open(&fil, fn, FA_READ);
+    if (rc) return rc;
+
+    /* Repeat until the file pointer reaches end of the file */
+    while (rc == FR_OK && fil.fptr < fil.fsize) {
+
+        /* any other processes... */
+
+        /* Fill output stream periodicaly or on-demand */
+        rc = f_forward(&fil, out_stream, 1000, &dmy);
+    }
+
+    /* Close the file and return */
+    f_close(&fil);
+    return rc;
+}
+
+
+ + +
+

See Also

+

f_open, fgets, f_write, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/getfree.html b/Lib/Fat/doc/en/getfree.html new file mode 100644 index 0000000..479f870 --- /dev/null +++ b/Lib/Fat/doc/en/getfree.html @@ -0,0 +1,102 @@ + + + + + + + + +FatFs - f_getfree + + + + +
+

f_getfree

+

The f_getfree function gets number of the free clusters.

+
+FRESULT f_getfree (
+  const TCHAR* Path,        /* Logical drive number */
+  DWORD* Clusters,          /* Pointer to the variable to store number of free clusters */
+  FATFS** FileSystemObject  /* Pointer to pointer to file system object */
+);
+
+
+ +
+

Parameters

+
+
Path
+
Pinter to the null-terminated string that specifies the logical drive.
+
Clusters
+
Pointer to the DWORD variable to store number of free clusters.
+
FileSystemObject
+
Pointer to pointer that to store a pointer to the corresponding file system object.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded. The *Clusters has number of free clusters and *FileSystemObject points the file system object.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT partition on the drive.
+
+
+ + +
+

Descriptions

+

The f_getfree function gets number of free clusters on the drive. The member csize in the file system object is refrecting number of sectors per cluster, so that the free space in unit of sector can be calcurated with this. When FSInfo structure on FAT32 volume is not in sync, this function can return an incorrect free cluster count.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

Example

+
+    FATFS *fs;
+    DWORD fre_clust, fre_sect, tot_sect;
+
+
+    /* Get volume information and free clusters of drive 1 */
+    res = f_getfree("1:", &fre_clust, &fs);
+    if (res) die(res);
+
+    /* Get total sectors and free sectors */
+    tot_sect = (fs->max_clust - 2) * fs->csize;
+    fre_sect = fre_clust * fs->csize;
+
+    /* Print free space in unit of KB (assuming 512 bytes/sector) */
+    printf("%lu KB total drive space.\n"
+           "%lu KB available.\n",
+           fre_sect / 2, tot_sect / 2);
+
+
+ + +
+

See Also

+

FATFS

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/gets.html b/Lib/Fat/doc/en/gets.html new file mode 100644 index 0000000..dcb1790 --- /dev/null +++ b/Lib/Fat/doc/en/gets.html @@ -0,0 +1,65 @@ + + + + + + + + +FatFs - f_gets + + + + +
+

f_gets

+

The f_gets reads a string from the file.

+
+TCHAR* f_gets (
+  TCHAR* Str,       /* Read buffer */
+  int Size,         /* Size of the read buffer */
+  FIL* FileObject   /* File object */
+);
+
+
+ +
+

Parameters

+
+
Str
+
Pointer to read buffer to store the read string.
+
Size
+
Size of the read buffer in unit of character.
+
FileObject
+
Pointer to the open file object structure.
+
+
+ + +
+

Return Values

+

When the function succeeded, Str will be returuned.

+
+ + +
+

Description

+

The f_gets() is a wrapper function of f_read(). The read operation continues until a '\n' is stored, reached end of the file or the buffer is filled with Size - 1 characters. The read string is terminated with a '\0'. When no character to read or any error occured during read operation, f_gets() returns a null pointer. The end of file and error status can be examined with f_eof() and f_error() macros.

+

When the FatFs is configured to Unicode API (_LFN_UNICODE == 1), the file is read in UTF-8 encoding and stored it to the buffer in UCS-2. If not the case, the file will be read in one byte per character without any code conversion.

+
+ + +
+

QuickInfo

+

Available when _USE_STRFUNC is 1 or 2. When it is set to 2, '\r's contained in the file are stripped out.

+
+ + + + +

Return

+ + diff --git a/Lib/Fat/doc/en/lseek.html b/Lib/Fat/doc/en/lseek.html new file mode 100644 index 0000000..bcda346 --- /dev/null +++ b/Lib/Fat/doc/en/lseek.html @@ -0,0 +1,129 @@ + + + + + + + + +FatFs - f_lseek + + + + +
+

f_lseek

+

The f_lseek function moves the file read/write pointer of an open file object. It can also be used to increase the file size (cluster pre-allocation).

+ +
+FRESULT f_lseek (
+  FIL* FileObject,   /* Pointer to the file object structure */
+  DWORD Offset       /* File offset in unit of byte */
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the open file object.
+
Offset
+
Number of bytes where from start of the file
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
FR_NOT_ENOUGH_CORE
+
Insufficient size of link map table for the file.
+
+
+ + +
+

Description

+

The f_lseek function moves the file read/write pointer of an open file. The offset can be specified in only origin from top of the file. When an offset above the file size is specified in write mode, the file size is increased and the data in the expanded area is undefined. This is suitable to create a large file quickly, for fast write operation. After the f_lseek function succeeded, member fptr in the file object should be checked in order to make sure the read/write pointer has been moved correctry. In case of fptr is not the expected value, either of followings has been occured.

+
    +
  • End of file. The specified Offset was clipped at the file size because the file has been opened in read-only mode.
  • +
  • Disk full. There is insufficient free space on the volume to expand the file size.
  • +
+

When _USE_FASTSEEK is set to 1 and cltbl member in the file object is not NULL, the fast seek feature is enabled. This feature enables fast backward/long seek operations without FAT access by cluster link information stored on the user defined table. The cluster link information must be created prior to do the fast seek. The required size of the table is (number of fragments + 1) * 2 items. For example, when the file is fragmented in 5, 12 items will be required to store the cluster link information. The file size cannot be expanded when the fast seek feature is enabled.

+
+ + +
+

QuickInfo

+

Available when _FS_MINIMIZE <= 2.

+
+ + +
+

Example

+
+    /* Move to offset of 5000 from top of the file */
+    res = f_lseek(file, 5000);
+
+    /* Move to end of the file to append data */
+    res = f_lseek(file, file->fsize);
+
+    /* Forward 3000 bytes */
+    res = f_lseek(file, file->fptr + 3000);
+
+    /* Rewind 2000 bytes (take care on overflow) */
+    res = f_lseek(file, file->fptr - 2000);
+
+
+    /* Cluster pre-allocation (to prevent buffer overrun on streaming write) */
+
+    res = f_open(file, recfile, FA_CREATE_NEW | FA_WRITE); /* Create a file */
+
+    res = f_lseek(file, PRE_SIZE);         /* Pre-allocate clusters */
+    if (res || file->fptr != PRE_SIZE) ... /* Check if the file size has been increased correctly */
+
+    res = f_lseek(file, DATA_START);       /* Record data stream without cluster allocation delay */
+    ...
+
+    res = f_truncate(file);                /* Truncate unused area */
+    res = f_lseek(file, 0);                /* Put file header */
+    ...
+
+    res = f_close(file);
+
+
+    /* Using fast seek feature */
+
+    DWORD lktbl[SZ_TBL];                   /* Link map table buffer */
+
+    res = f_lseek(&file, ofs1);            /* This is normal seek (file.cltbl == NULL on file open) */
+
+    file.cltbl = lktbl;                    /* Enable fast seek feature */
+    lktbl[0] = SZ_TBL;                     /* Set table size to the first item */
+    res = f_lseek(&file, CREATE_LINKMAP);  /* Create cluster link map table */
+    ...
+
+    res = f_lseek(&file, ofs2);            /* This is fast seek (file.cltbl != NULL) */
+
+
+ + +
+

See Also

+

f_open, f_truncate, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/mkdir.html b/Lib/Fat/doc/en/mkdir.html new file mode 100644 index 0000000..3427cd8 --- /dev/null +++ b/Lib/Fat/doc/en/mkdir.html @@ -0,0 +1,90 @@ + + + + + + + + +FatFs - f_mkdir + + + + +
+

f_mkdir

+

The f_mkdir function creates a new directory.

+
+FRESULT f_mkdir (
+  const TCHAR* DirName /* Pointer to the directory name */
+);
+
+
+ +
+

Parameter

+
+
DirName
+
Pointer to the null-terminated string that specifies the directory name to create.
+
+
+ + +
+

Return Value

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The path name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_DENIED
+
The directory cannot be created due to directory table or disk is full.
+
FR_EXIST
+
A file or directory that has same name is already existing.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_WRITE_PROTECTED
+
The medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_mkdir function creates a new directory.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

Example

+
+    res = f_mkdir("sub1");
+    if (res) die(res);
+    res = f_mkdir("sub1/sub2");
+    if (res) die(res);
+    res = f_mkdir("sub1/sub2/sub3");
+    if (res) die(res);
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/mkfs.html b/Lib/Fat/doc/en/mkfs.html new file mode 100644 index 0000000..314fc94 --- /dev/null +++ b/Lib/Fat/doc/en/mkfs.html @@ -0,0 +1,79 @@ + + + + + + + + +FatFs - f_mkfs + + + + +
+

f_mkfs

+

The f_mkfs fucntion creates a file system on the drive.

+
+FRESULT f_mkfs (
+  BYTE  Drive,            /* Logical drive number */
+  BYTE  PartitioningRule, /* Partitioning rule */
+  UINT  AllocSize         /* Size of the allocation unit */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Logical drive number (0-9) to be formatted.
+
PartitioningRule
+
When 0 is given, a partition table is created into the master boot record and a primary DOS partition is created and then an FAT volume is created on the partition. This is called FDISK format and used for harddisk and memory cards. When 1 is given, the FAT volume starts from the first sector on the drive without partition table. This is called SFD format and used for floppy disk and most optical disk.
+
AllocSize
+
Force the allocation unit (cluter) size in unit of byte. The value must be power of 2 and between the sector size and 128 times sector size. When invalid value is specified, the cluster size is determined depends on the volume size.
+
+
+ +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The drive cannot work due to any reason.
+
FR_WRITE_PROTECTED
+
The drive is write protected.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_MKFS_ABORTED
+
The function aborted before start in format due to a reason as follows. +
    +
  • The disk size is too small.
  • +
  • Invalid parameter was given to any parameter.
  • +
  • Not allowable cluster size for this drive. This can occure when number of clusters becomes around 0xFF7 and 0xFFF7.
  • +
+
+
+
+ +
+

Description

+

The f_mkfs function creates an FAT volume on the drive. There are two partitioning rules, FDISK and SFD, for removable media. The FDISK format is recommended for the most case. This function currently does not support multiple partition, so that existing partitions on the physical dirve will be deleted and re-created a new partition occupies entire disk space.

+

The FAT sub-type, FAT12/FAT16/FAT32, is determined by number of clusters on the volume and nothing else, according to the FAT specification issued by Microsoft. Thus which FAT sub-type is selected, is depends on the volume size and the specified cluster size. The cluster size affects performance of the file system and large cluster increases the performance.

+
+ + +
+

QuickInfo

+

Available when _FS_READOLNY == 0 and _USE_MKFS == 1.

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/mount.html b/Lib/Fat/doc/en/mount.html new file mode 100644 index 0000000..98bcd17 --- /dev/null +++ b/Lib/Fat/doc/en/mount.html @@ -0,0 +1,66 @@ + + + + + + + + +FatFs - f_mount + + + + +
+

f_mount

+

The f_mount fucntion registers/unregisters a work area to the FatFs module.

+
+FRESULT f_mount (
+  BYTE  Drive,              /* Logical drive number */
+  FATFS*  FileSystemObject  /* Pointer to the work area */
+);
+
+
+ +
+

Parameters

+
+
Drive
+
Logical drive number (0-9) to register/unregister the work area.
+
FileSystemObject
+
Pointer to the work area (file system object) to be registered.
+
+
+ +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
+
+ + +
+

Description

+

The f_mount function registers/unregisters a work area to the FatFs module. The work area must be given to the each volume with this function prior to use any other file function. To unregister a work area, specify a NULL to the FileSystemObject, and then the work area can be discarded.

+

This function only initializes the given work area and registers its address to the internal table, any access to the disk I/O layer does not occure. The volume mount process is performed on first file access after f_mount function or media change.

+
+ + +
+

QuickInfo

+

Always available.

+
+ + +
+

See Also

+

FATFS

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/open.html b/Lib/Fat/doc/en/open.html new file mode 100644 index 0000000..8fcea28 --- /dev/null +++ b/Lib/Fat/doc/en/open.html @@ -0,0 +1,152 @@ + + + + + + + + +FatFs - f_open + + + + +
+

f_open

+

The f_open function creates a file object to be used to access the file.

+
+FRESULT f_open (
+  FIL* FileObject,       /* Pointer to the blank file object structure */
+  const TCHAR* FileName, /* Pointer to the file neme */
+  BYTE ModeFlags         /* Mode flags */
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the file object structure to be created.
+
FileName
+
Pointer to a null-terminated string that specifies the file name to create or open.
+
ModeFlags
+
Specifies the type of access and open method for the file. It is specified by a combination of following flags.
+ + + + + + + + +
ValueDescription
FA_READSpecifies read access to the object. Data can be read from the file.
Combine with FA_WRITE for read-write access.
FA_WRITESpecifies write access to the object. Data can be written to the file.
Combine with FA_READ for read-write access.
FA_OPEN_EXISTINGOpens the file. The function fails if the file is not existing. (Default)
FA_OPEN_ALWAYSOpens the file if it is existing. If not, a new file is created.
+To append data to the file, use f_lseek function after file open in this method.
FA_CREATE_NEWCreates a new file. The function fails if the file is already existing.
FA_CREATE_ALWAYSCreates a new file. If the file is existing, it is truncated and overwritten.
+
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded and the file object is valid.
+
FR_NO_FILE
+
Could not find the file.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The file name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_EXIST
+
The file is already existing.
+
FR_DENIED
+
The required access was denied due to one of the following reasons: +
  • Write mode open against a read-only file.
  • +
  • File cannot be created due to a read-only file or same directory name is existing.
  • +
  • File cannot be created due to the directory table or volume is full.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_WRITE_PROTECTED
+
Write mode open or creation under the medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
FR_LOCKED
+
The function was rejected due to file shareing policy.
+
+
+ + +
+

Description

+

A file object is created when the function succeeded. The file object is used for subsequent read/write functions to refer to the file. When close an open file object, use f_close function. If the modified file is not closed, the file data can be collapsed.

+

Before using any file function, a work area (file system object) must be given to the logical drive with f_mount function. All file functions can work after this procedure.

+
+ + +
+

QuickInfo

+

Always available. The mode flags, FA_WRITE, FA_CREATE_ALWAYS, FA_CREATE_NEW and FA_OPEN_ALWAYS, are not available when _FS_READONLY == 1.

+
+ + +
+

Example (File Copy)

+
+void main (void)
+{
+    FATFS fs[2];         /* Work area (file system object) for logical drives */
+    FIL fsrc, fdst;      /* file objects */
+    BYTE buffer[4096];   /* file copy buffer */
+    FRESULT res;         /* FatFs function common result code */
+    UINT br, bw;         /* File read/write count */
+
+
+    /* Register work area for logical drives */
+    f_mount(0, &fs[0]);
+    f_mount(1, &fs[1]);
+
+    /* Open source file on the drive 1 */
+    res = f_open(&fsrc, "1:srcfile.dat", FA_OPEN_EXISTING | FA_READ);
+    if (res) die(res);
+
+    /* Create destination file on the drive 0 */
+    res = f_open(&fdst, "0:dstfile.dat", FA_CREATE_ALWAYS | FA_WRITE);
+    if (res) die(res);
+
+    /* Copy source to destination */
+    for (;;) {
+        res = f_read(&fsrc, buffer, sizeof(buffer), &br);    /* Read a chunk of src file */
+        if (res || br == 0) break; /* error or eof */
+        res = f_write(&fdst, buffer, br, &bw);               /* Write it to the dst file */
+        if (res || bw < br) break; /* error or disk full */
+    }
+
+    /* Close open files */
+    f_close(&fsrc);
+    f_close(&fdst);
+
+    /* Unregister work area prior to discard it */
+    f_mount(0, NULL);
+    f_mount(1, NULL);
+}
+
+
+ + +
+

See Also

+

f_read, f_write, f_close, FIL, FATFS

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/opendir.html b/Lib/Fat/doc/en/opendir.html new file mode 100644 index 0000000..7e9b029 --- /dev/null +++ b/Lib/Fat/doc/en/opendir.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_opendir + + + + +
+

f_opendir

+

The f_opendir function opens a directory.

+
+FRESULT f_opendir (
+  DIR* DirObject,       /* Pointer to the blank directory object structure */
+  const TCHAR* DirName  /* Pointer to the directory name */
+);
+
+
+ +
+

Parameters

+
+
DirObject
+
Pointer to the blank directory object to be created.
+
DirName
+
Pinter to the null-terminated string that specifies the directory name to be opened.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded and the directory object is created. It is used for subsequent calls to read the directory entries.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The path name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_opendir function opens an exsisting directory and creates the directory object for subsequent calls. The directory object structure can be discarded at any time without any procedure.

+
+ + +
+

QuickInfo

+

Available when _FS_MINIMIZE <= 1.

+
+ + +
+

See Also

+

f_readdir, DIR

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/printf.html b/Lib/Fat/doc/en/printf.html new file mode 100644 index 0000000..fe62ab4 --- /dev/null +++ b/Lib/Fat/doc/en/printf.html @@ -0,0 +1,85 @@ + + + + + + + + +FatFs - f_printf + + + + +
+

f_printf

+

The f_printf function writes formatted string to the file.

+
+int f_printf (
+  FIL* FileObject,      /* File object */
+  const TCHAR* Foramt,  /* Format stirng */
+  ...
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the open file object structure.
+
Format
+
Pointer to the null terminated format string.
+
...
+
Optional arguments.
+ +
+
+ + +
+

Return Values

+

When the function succeeded, number of characters written is returned. When the function failed due to disk full or any error, an EOF (-1) will be returned.

+
+ + +
+

Description

+

The f_printf() is a wrapper function of f_putc() and f_puts(). The format control directive is a sub-set of standard library shown as follos:

+
    +
  • Type: c C s S d D u U x X b B
  • +
  • Size: l L
  • +
  • Flag: 0
  • +
+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _USE_STRFUNC is 1 or 2. When it is set to 2, '\n's contained in the output are converted to "\r\n".

+

When the FatFs is configured to Unicode API (_LFN_UNICODE == 1), the generated UCS-2 characters are written to the file in UTF-8 encoding. If not the case, the byte characters will be written directly.

+
+ + +
+

Example

+
+    f_printf(&fil, "%6d", -200);         /* "  -200" */
+    f_printf(&fil, "%02u", 5);           /* "05" */
+    f_printf(&fil, "%ld", 12345678L);    /* "12345678" */
+    f_printf(&fil, "%08lX", 1194684UL);  /* "00123ABC" */
+    f_printf(&fil, "%08b", 0x55);        /* "01010101" */
+    f_printf(&fil, "%s", "String");      /* "String" */
+    f_printf(&fil, "%c", 'a');           /* "a" */
+
+
+ + +
+

See Also

+

f_open, f_putc, f_puts, f_gets, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/putc.html b/Lib/Fat/doc/en/putc.html new file mode 100644 index 0000000..486e77f --- /dev/null +++ b/Lib/Fat/doc/en/putc.html @@ -0,0 +1,62 @@ + + + + + + + + +FatFs - f_putc + + + + +
+

f_putc

+

The f_putc funciton puts a character to the file.

+
+int f_putc (
+  TCHAR Chr,        /* A character to put */
+  FIL* FileObject   /* File object */
+);
+
+
+ +
+

Parameters

+
+
Chr
+
A character to be put.
+
FileObject
+
Pointer to the open file object structuer.
+
+
+ + +
+

Return Values

+

When the character was written successfuly, the function returns the character. When the function failed due to disk full or any error, an EOF (-1) will be returned.

+

When the FatFs is configured to Unicode API (_LFN_UNICODE == 1), the UCS-2 character is written to the file in UTF-8 encoding. If not the case, the byte will be written directly.

+
+ + +
+

Description

+

The f_putc() is a wrapper function of f_write().

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _USE_STRFUNC is 1 or 2. When it is set to 2, a '\n' is converted to "\r\n".

+
+ + +
+

See Also

+

f_open, f_puts, f_printf, f_gets, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/puts.html b/Lib/Fat/doc/en/puts.html new file mode 100644 index 0000000..15d9a30 --- /dev/null +++ b/Lib/Fat/doc/en/puts.html @@ -0,0 +1,62 @@ + + + + + + + + +FatFs - f_puts + + + + +
+

f_puts

+

The f_puts function writes a string to the file.

+
+int f_puts (
+  const TCHAR* Str,  /* String */
+  FIL* FileObject    /* File object */
+);
+
+
+ +
+

Parameters

+
+
Str
+
Pointer to the null terminated string to be written. The null character will not be written.
+
FileObject
+
Pointer to the open file object structure.
+
+
+ + +
+

Return Value

+

When the function succeeded, number of characters written that is not minus value is returned. When the function failed due to disk full or any error, an EOF (-1) will be returned.

+

When the FatFs is configured to Unicode API (_LFN_UNICODE == 1), the UCS-2 string is written to the file in UTF-8 encoding. If not the case, the byte stream will be written directly.

+
+ + +
+

Description

+

The f_puts() is a wrapper function of f_putc().

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _USE_STRFUNC is 1 or 2. When it is set to 2, '\n's contained in the string are converted to "\r\n".

+
+ + +
+

See Also

+

f_open, f_putc, f_printf, f_gets, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/read.html b/Lib/Fat/doc/en/read.html new file mode 100644 index 0000000..9e454fc --- /dev/null +++ b/Lib/Fat/doc/en/read.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_read + + + + +
+

f_read

+

The f_read function reads data from a file.

+
+FRESULT f_read (
+  FIL* FileObject,    /* Pointer to the file object structure */
+  void* Buffer,       /* Pointer to the buffer to store read data */
+  UINT ByteToRead,    /* Number of bytes to read */
+  UINT* ByteRead      /* Pointer to the variable to return number of bytes read */
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the open file object.
+
Buffer
+
Pointer to the buffer to store read data
+
ByteToRead
+
Number of bytes to read in range of UINT.
+
ByteRead
+
Pointer to the UINT variable to return number of bytes read. The value is always valid after the function call regardless of the result.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DENIED
+
The function denied due to the file has been opened in non-read mode.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The file pointer of the file object increases in number of bytes read. After the function succeeded, *ByteRead should be checked to detect the end of file. In case of *ByteRead < ByteToRead, it means the read/write pointer reached end of the file during read operation.

+
+ + +
+

QuickInfo

+

Always available.

+
+ + +
+

See Also

+

f_open, fgets, f_write, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/readdir.html b/Lib/Fat/doc/en/readdir.html new file mode 100644 index 0000000..cec8f61 --- /dev/null +++ b/Lib/Fat/doc/en/readdir.html @@ -0,0 +1,120 @@ + + + + + + + + +FatFs - f_readdir + + + + +
+

f_readdir

+

The f_readdir function reads directory entries.

+
+FRESULT f_readdir (
+  DIR* DirObject,    /* Pointer to the open directory object */
+  FILINFO* FileInfo  /* Pointer to the file information structure */
+);
+
+
+ +
+

Parameters

+
+
DirObject
+
Pointer to the open directory object.
+
FileInfo
+
Pointer to the file information structure to store the read item.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_INVALID_OBJECT
+
The directory object is invalid.
+
+
+ + +
+

Description

+

The f_readdir function reads directory entries in sequence. All items in the directory can be read by calling f_readdir function repeatedly. When all directory entries have been read and no item to read, the function returns a null string into f_name[] member without any error. When a null pointer is given to the FileInfo, the read index of the directory object will be rewinded.

+

When LFN feature is enabled, lfname and lfsize in the file information structure must be initialized with valid value prior to use the f_readdir function. The lfname is a pointer to the string buffer to return the long file name. The lfsize is the size of the string buffer in unit of character. If either the size of read buffer or LFN working buffer is insufficient for the LFN or the object has no LFN, a null string will be returned to the LFN read buffer. If the LFN contains any charactrer that cannot be converted to OEM code, a null string will be returned but this is not the case on Unicode API configuration. When lfname is a NULL, nothing of the LFN is returned. When the object has no LFN, any small capitals can be contained in the SFN.

+

When relative path feature is enabled (_FS_RPATH == 1), "." and ".." entries are not filtered out and it will appear in the read entries.

+
+ + +
+

QuickInfo

+

Available when _FS_MINIMIZE <= 1.

+
+ + +
+

Sample Code

+
+FRESULT scan_files (char* path)
+{
+    FRESULT res;
+    FILINFO fno;
+    DIR dir;
+    int i;
+    char *fn;
+#if _USE_LFN
+    static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1];
+    fno.lfname = lfn;
+    fno.lfsize = sizeof(lfn);
+#endif
+
+
+    res = f_opendir(&dir, path);
+    if (res == FR_OK) {
+        i = strlen(path);
+        for (;;) {
+            res = f_readdir(&dir, &fno);
+            if (res != FR_OK || fno.fname[0] == 0) break;
+            if (fno.fname[0] == '.') continue;
+#if _USE_LFN
+            fn = *fno.lfname ? fno.lfname : fno.fname;
+#else
+            fn = fno.fname;
+#endif
+            if (fno.fattrib & AM_DIR) {
+                sprintf(&path[i], "/%s", fn);
+                res = scan_files(path);
+                if (res != FR_OK) break;
+                path[i] = 0;
+            } else {
+                printf("%s/%s\n", path, fn);
+            }
+        }
+    }
+
+    return res;
+}
+
+
+ + +
+

See Also

+

f_opendir, f_stat, FILINFO, DIR

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/rename.html b/Lib/Fat/doc/en/rename.html new file mode 100644 index 0000000..91c518b --- /dev/null +++ b/Lib/Fat/doc/en/rename.html @@ -0,0 +1,96 @@ + + + + + + + + +FatFs - f_rename + + + + +
+

f_rename

+

Renames an object.

+
+FRESULT f_rename (
+  const TCHAR* OldName, /* Pointer to old object name */
+  const TCHAR* NewName  /* Pointer to new object name */
+);
+
+
+ +
+

Parameters

+
+
OldName
+
Pointer to a null-terminated string specifies the old object name to be renamed.
+
NewName
+
Pointer to a null-terminated string specifies the new object name without drive number.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_FILE
+
Could not find the old name.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The file name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_EXIST
+
The new name is colliding with an existing name.
+
FR_DENIED
+
The new name could not be created due to any reason.
+
FR_WRITE_PROTECTED
+
The medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
FR_LOCKED
+
The function was rejected due to file shareing policy.
+
+
+ + +
+

Description

+

Renames an object and can also move it to other directory. The logical drive number is determined by old name, new name must not contain a logical drive number. Do not rename open objects.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

Example

+
+    /* Rename an object */
+    f_rename("oldname.txt", "newname.txt");
+
+    /* Rename and move an object to other directory */
+    f_rename("oldname.txt", "dir1/newname.txt");
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/sdir.html b/Lib/Fat/doc/en/sdir.html new file mode 100644 index 0000000..06dd74c --- /dev/null +++ b/Lib/Fat/doc/en/sdir.html @@ -0,0 +1,37 @@ + + + + + + + + +FatFs - DIR + + + + +
+

DIR

+

The DIR structure is used for the work area to read a directory by f_oepndir, f_readdir function. There is no member that can be changed by application.

+
+typedef struct {
+    FATFS*  fs;         /* Pointer to the owner file system object */
+    WORD    id;         /* Owner file system mount ID */
+    WORD    index;      /* Directory index number to be read/write next */
+    DWORD   sclust;     /* Table start cluster (0:Root dir) */
+    DWORD   clust;      /* Current cluster */
+    DWORD   sect;       /* Current sector */
+    BYTE*   dir;        /* Pointer to the current SFN entry in the win[] */
+    BYTE*   fn;         /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
+#if _USE_LFN
+    WCHAR*  lfn;        /* Pointer to the LFN working buffer */
+    WORD    lfn_idx;    /* Last matched LFN index (0xFFFF:No LFN) */
+#endif
+} DIR;
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/sfatfs.html b/Lib/Fat/doc/en/sfatfs.html new file mode 100644 index 0000000..bb3b174 --- /dev/null +++ b/Lib/Fat/doc/en/sfatfs.html @@ -0,0 +1,54 @@ + + + + + + + + +FatFs - FATFS + + + + +
+

FATFS

+

The FATFS structure holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with f_mount function. Following members are in standard configuration. There is no member that can be changed from the application program.

+
+typedef struct {
+    BYTE    fs_type;      /* FAT sub-type (0:Not mounted) */
+    BYTE    drv;          /* Physical drive number */
+    BYTE    csize;        /* Sectors per cluster (1,2,4...128) */
+    BYTE    n_fats;       /* Number of FAT copies (1,2) */
+    BYTE    wflag;        /* win[] dirty flag */
+    BYTE    fsi_flag;     /* fsinfo dirty flag */
+    WORD    id;           /* File system mount ID */
+    WORD    n_rootdir;    /* Number of root directory entries (FAT12/16) */
+#if _MAX_SS != 512
+    WORD    ssize;        /* Sector size (512,1024,2048,4096) */
+#endif
+#if _FS_REENTRANT
+    _SYNC_t sobj;         /* Identifier of sync object */
+#endif
+#if !_FS_READONLY
+    DWORD   last_clust;   /* Last allocated cluster */
+    DWORD   free_clust;   /* Number of free clusters */
+    DWORD   fsi_sector;   /* fsinfo sector (FAT32) */
+#endif
+#if _FS_RPATH
+    DWORD   cdir;         /* Current directory cluster (0:root) */
+#endif
+    DWORD   n_fatent;     /* Number of FAT entries (= number of clusters + 2) */
+    DWORD   fsize;        /* Sectors per FAT */
+    DWORD   fatbase;      /* FAT area start sector */
+    DWORD   dirbase;      /* Root directory area start sector (FAT32: cluster#) */
+    DWORD   database;     /* Data area start sector */
+    DWORD   winsect;      /* Current sector appearing in the win[] */
+    BYTE    win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
+} FATFS;
+
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/sfile.html b/Lib/Fat/doc/en/sfile.html new file mode 100644 index 0000000..ff6c5bd --- /dev/null +++ b/Lib/Fat/doc/en/sfile.html @@ -0,0 +1,49 @@ + + + + + + + + +FatFs - FIL + + + + +
+

FIL

+

The FIL structure (file object) holds state of an open file. It is created by f_open function and discarded by f_close function. There is no member that can be changed by the application program except for cltbl. Note that a sector buffer is defined in this structure under non-tiny configuration so that the FIL structures should not be defined as auto variable.

+ +
+typedef struct {
+    FATFS*  fs;           /* Pointer to the owner file system object */
+    WORD    id;           /* Owner file system mount ID */
+    BYTE    flag;         /* File status flags */
+    BYTE    pad1;
+    DWORD   fptr;         /* File read/write pointer (Byte offset origin from top of the file) */
+    DWORD   fsize;        /* File size */
+    DWORD   org_clust;    /* File start cluster */
+    DWORD   curr_clust;   /* Current cluster */
+    DWORD   dsect;        /* Current data sector */
+#if !_FS_READONLY
+    DWORD   dir_sect;     /* Sector containing the directory entry */
+    BYTE*   dir_ptr;      /* Ponter to the directory entry in the window */
+#endif
+#if _USE_FASTSEEK
+    DWORD*  cltbl;        /* Pointer to the cluster link map table */
+#endif
+#if _FS_SHARE
+    UINT    lockid;       /* File lock ID */
+#endif
+#if !_FS_TINY
+    BYTE    buf[_MAX_SS]; /* Data read/write buffer */
+#endif
+} FIL;
+
+ +
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/sfileinfo.html b/Lib/Fat/doc/en/sfileinfo.html new file mode 100644 index 0000000..a4b3d52 --- /dev/null +++ b/Lib/Fat/doc/en/sfileinfo.html @@ -0,0 +1,70 @@ + + + + + + + + +FatFs - FILINFO + + + + +
+

FILINFO

+

The FILINFO structure holds a file information returned by f_stat and f_readdir function.

+
+typedef struct {
+    DWORD fsize;      /* File size */
+    WORD  fdate;      /* Last modified date */
+    WORD  ftime;      /* Last modified time */
+    BYTE  fattrib;    /* Attribute */
+    TCHAR fname[13];  /* Short file name (8.3 format) */
+#if _USE_LFN
+    TCHAR* lfname;    /* Pointer to the LFN buffer */
+    int   lfsize;     /* Size of LFN buffer [characters] */
+#endif
+} FILINFO;
+
+
+ +

Members

+
+
fsize
+
Indicates size of the file in unit of byte. This is always zero when it is a directory.
+
fdate
+
Indicates the date that the file was modified or the directory was created.
+
+
bit15:9
+
Year origin from 1980 (0..127)
+
bit8:5
+
Month (1..12)
+
bit4:0
+
Day (1..31)
+
+
+
ftime
+
Indicates the time that the file was modified or the directory was created.
+
+
bit15:11
+
Hour (0..23)
+
bit10:5
+
Minute (0..59)
+
bit4:0
+
Second / 2 (0..29)
+
+
+
fattrib
+
Indicates the file/directory attribute in combination of AM_DIR, AM_RDO, AM_HID, AM_SYS and AM_ARC.
+
fname[]
+
Indicates the file/directory name in 8.3 format null-terminated string. It is always returnd with upper case on non-LFN configuration but it can be returned with lower case on LFN configuration.
+
lfname
+
Pointer to the LFN buffer to store the read LFN. This member must be initialized by application prior to use this structure. Not available on non-LFN configuration.
+
lfsize
+
Size of the LFN buffer in unit of chars. This member must be initialized by application prior to use this structure. Not available on non-LFN configuration.
+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/stat.html b/Lib/Fat/doc/en/stat.html new file mode 100644 index 0000000..0807990 --- /dev/null +++ b/Lib/Fat/doc/en/stat.html @@ -0,0 +1,76 @@ + + + + + + + + +FatFs - f_stat + + + + +
+

f_stat

+

The f_stat gets the file status.

+
+FRESULT f_stat (
+  const TCHAR* FileName,  /* Pointer to the file or directory name */
+  FILINFO* FileInfo       /* Pointer to the FILINFO structure */
+);
+
+
+ +
+

Parameters

+
+
FileName
+
Pointer to the null-terminated string that specifies the file or directory to get its information.
+
FileInfo
+
Pointer to the blank FILINFO structure to store the information.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_FILE
+
Could not find the file or directory.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The file name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_stat gets the information of a file or directory. For details of the infomation, refer to the FILINFO structure and f_readdir function. This function is not supported in minimization level of >= 1.

+
+ + +
+

References

+

f_opendir, f_readdir, FILINFO

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/sync.html b/Lib/Fat/doc/en/sync.html new file mode 100644 index 0000000..4a42e7b --- /dev/null +++ b/Lib/Fat/doc/en/sync.html @@ -0,0 +1,69 @@ + + + + + + + + +FatFs - f_sync + + + + +
+

f_sync

+

The f_sync function flushes the cached information of a writing file.

+
+FRESULT f_sync (
+  FIL* FileObject     /* Pointer to the file object */
+);
+
+
+ +
+

Parameter

+
+
FileObject
+
Pointer to the open file object to be flushed.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for the applications that open files for a long time in write mode, such as data logger. Performing f_sync of periodic or immediataly after f_write can minimize the risk of data loss due to a sudden blackout or an unintentional disk removal. However f_sync immediataly before f_close has no advantage because f_close performs f_sync in it. In other words, the differnce between those functions is that the file object is invalidated or not.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0.

+
+ + +
+

See Also

+

f_close

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/truncate.html b/Lib/Fat/doc/en/truncate.html new file mode 100644 index 0000000..46b74df --- /dev/null +++ b/Lib/Fat/doc/en/truncate.html @@ -0,0 +1,72 @@ + + + + + + + + +FatFs - f_truncate + + + + +
+

f_truncate

+

The f_truncate function truncates the file size.

+
+FRESULT f_truncate (
+  FIL* FileObject     /* Pointer to the file object */
+);
+
+
+ +
+

Parameter

+
+
FileObject
+
Pointer to the open file object to be truncated.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DENIED
+
The file has been opened in read-only mode.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The f_truncate function truncates the file size to the current file R/W point. When the file R/W pointer is already pointing end of the file, this function has no effect.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

See Also

+

f_open, f_lseek, FIL

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/unlink.html b/Lib/Fat/doc/en/unlink.html new file mode 100644 index 0000000..e53a30e --- /dev/null +++ b/Lib/Fat/doc/en/unlink.html @@ -0,0 +1,81 @@ + + + + + + + + +FatFs - f_unlink + + + + +
+

f_unlink

+

The f_unlink removes an object.

+
+FRESULT f_unlink (
+  const TCHAR* FileName  /* Pointer to the object name */
+);
+
+
+ +
+

Parameter

+
+
FileName
+
Pointer to the null-terminated string that specifies an object to be removed.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_FILE
+
Could not find the file or directory.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The path name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_DENIED
+
The function was denied due to either of following reasons: +
  • The object has read-only attribute
  • The directory is not empty.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_WRITE_PROTECTED
+
The medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
FR_LOCKED
+
The function was rejected due to file shareing policy.
+
+
+ + +
+

Description

+

The f_unlink function removes an object. Do not remove open objects and current directory.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/en/utime.html b/Lib/Fat/doc/en/utime.html new file mode 100644 index 0000000..ac2abd1 --- /dev/null +++ b/Lib/Fat/doc/en/utime.html @@ -0,0 +1,108 @@ + + + + + + + + +FatFs - f_utime + + + + +
+

f_utime

+

The f_utime function changes the timestamp of a file or directory.

+
+FRESULT f_utime (
+  const TCHAR* FileName,   /* Pointer to the file or directory path */
+  const FILINFO* TimeDate  /* Time and data to be set */
+);
+
+
+ +
+

Parameters

+
+
FileName
+
Pointer to the null-terminated string that specifies a file or directory to be changed.
+
TimeDate
+
Pointer to the file information structure that has a timestamp to be set in member fdate and ftime. Do not care any other members.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_NO_FILE
+
Could not find the file.
+
FR_NO_PATH
+
Could not find the path.
+
FR_INVALID_NAME
+
The file name is invalid.
+
FR_INVALID_DRIVE
+
The drive number is invalid.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_WRITE_PROTECTED
+
The medium is write protected.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_ENABLED
+
The logical drive has no work area.
+
FR_NO_FILESYSTEM
+
There is no valid FAT volume on the drive.
+
+
+ + +
+

Description

+

The f_utime function changes the timestamp of a file or directory

+
+ + +
+

Example

+
+FRESULT set_timestamp (
+    char *obj,     /* Pointer to the file name */
+    int year,
+    int month,
+    int mday,
+    int hour,
+    int min,
+    int sec
+)
+{
+    FILINFO fno;
+
+    fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
+    fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
+
+    return f_utime(obj, &fno);
+}
+
+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0 and _FS_MINIMIZE == 0.

+
+ + +
+

See Also

+

f_stat, FILINFO

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/en/write.html b/Lib/Fat/doc/en/write.html new file mode 100644 index 0000000..faba416 --- /dev/null +++ b/Lib/Fat/doc/en/write.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_write + + + + +
+

f_write

+

The f_write writes data to a file.

+
+FRESULT f_write (
+  FIL* FileObject,     /* Pointer to the file object structure */
+  const void* Buffer,  /* Pointer to the data to be written */
+  UINT ByteToWrite,    /* Number of bytes to write */
+  UINT* ByteWritten    /* Pointer to the variable to return number of bytes written */
+);
+
+
+ +
+

Parameters

+
+
FileObject
+
Pointer to the open file object structure.
+
Buffer
+
Pointer to the data to be written.
+
ByteToWrite
+
Specifies number of bytes to write in range of UINT.
+
ByteWritten
+
Pointer to the UINT variable to return the number of bytes written. The value is always valid after the function call regardless of the result.
+
+
+ + +
+

Return Values

+
+
FR_OK (0)
+
The function succeeded.
+
FR_DENIED
+
The function denied due to the file has been opened in non-write mode.
+
FR_DISK_ERR
+
The function failed due to an error in the disk function.
+
FR_INT_ERR
+
The function failed due to a wrong FAT structure or an internal error.
+
FR_NOT_READY
+
The disk drive cannot work due to no medium in the drive or any other reason.
+
FR_INVALID_OBJECT
+
The file object is invalid.
+
+
+ + +
+

Description

+

The read/write pointer in the file object is increased in number of bytes written. After the function succeeded, *ByteWritten should be checked to detect the disk full. In case of *ByteWritten < ByteToWrite, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

+
+ + +
+

QuickInfo

+

Available when _FS_READONLY == 0.

+
+ + +
+

See Also

+

f_open, f_read, fputc, fputs, fprintf, f_close, FIL

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/img/f1.png b/Lib/Fat/doc/img/f1.png new file mode 100644 index 0000000..42cc271 Binary files /dev/null and b/Lib/Fat/doc/img/f1.png differ diff --git a/Lib/Fat/doc/img/f2.png b/Lib/Fat/doc/img/f2.png new file mode 100644 index 0000000..8ef0ec2 Binary files /dev/null and b/Lib/Fat/doc/img/f2.png differ diff --git a/Lib/Fat/doc/img/f3.png b/Lib/Fat/doc/img/f3.png new file mode 100644 index 0000000..9111bfc Binary files /dev/null and b/Lib/Fat/doc/img/f3.png differ diff --git a/Lib/Fat/doc/img/f4.png b/Lib/Fat/doc/img/f4.png new file mode 100644 index 0000000..f9a6b46 Binary files /dev/null and b/Lib/Fat/doc/img/f4.png differ diff --git a/Lib/Fat/doc/img/f5.png b/Lib/Fat/doc/img/f5.png new file mode 100644 index 0000000..b110b29 Binary files /dev/null and b/Lib/Fat/doc/img/f5.png differ diff --git a/Lib/Fat/doc/img/layers.png b/Lib/Fat/doc/img/layers.png new file mode 100644 index 0000000..d485d6b Binary files /dev/null and b/Lib/Fat/doc/img/layers.png differ diff --git a/Lib/Fat/doc/img/rwtest.png b/Lib/Fat/doc/img/rwtest.png new file mode 100644 index 0000000..a34bf06 Binary files /dev/null and b/Lib/Fat/doc/img/rwtest.png differ diff --git a/Lib/Fat/doc/img/rwtest2.png b/Lib/Fat/doc/img/rwtest2.png new file mode 100644 index 0000000..aeb38be Binary files /dev/null and b/Lib/Fat/doc/img/rwtest2.png differ diff --git a/Lib/Fat/doc/ja/appnote.html b/Lib/Fat/doc/ja/appnote.html new file mode 100644 index 0000000..6fb2996 --- /dev/null +++ b/Lib/Fat/doc/ja/appnote.html @@ -0,0 +1,235 @@ + + + + + + + + +FatFsモジュール アプリケーション・ノート + + + +

FatFsモジュール アプリケーション・ノート

+
+ +
+

ãƒãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã®éš›ã«é…æ…®ã™ã¹ãã“ã¨

+

FatFsモジュールã¯ç§»æ¤æ€§ã«é–¢ã—ã¦æ¬¡ã®ç‚¹ã‚’å‰æã¨ã—ã¦ã„ã¾ã™ã€‚

+
    +
  • 処ç†ç³»ã¯ANSI C準拠ã§ã‚ã‚‹ã“ã¨ã€‚
    +FatFsモジュールã¯ANSI C準拠ã§è¨˜è¿°ã•ã‚Œã¦ã„ã‚‹ã®ã§ã€ANSI C準拠ã®ã‚³ãƒ³ãƒ‘イラãªã‚‰ç‰¹ã«å‡¦ç†ç³»ä¾å­˜ãªç‚¹ã¯ã‚ã‚Šã¾ã›ã‚“。
  • +
  • char/short/longã®ã‚µã‚¤ã‚ºã¯ã€ãã‚Œãžã‚Œ8/16/32ビットã§ã€intã¯16ã¾ãŸã¯32ビットã§ã‚ã‚‹ã“ã¨ã€‚
    +サイズを明示ã™ã‚‹æ•´æ•°ã®åž‹ãŒ integer.h 内ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚æ•´æ•°ã®åž‹ã¨ã‚µã‚¤ã‚ºã«é–¢ã—ã¦ã¯ã€ã¾ã£ã¨ã†ãªå‡¦ç†ç³»ãªã‚‰å•é¡Œãªã„ã¯ãšã§ã™ãŒã€æ—¢å­˜ã®å®šç¾©ã¨è¡çªã—ãŸå ´åˆã¯ãƒ¦ãƒ¼ã‚¶ã«ã‚ˆã£ã¦è§£æ±ºã•ã‚Œãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
  • +
+
+ +
+

ãƒãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã®ã—ã‹ãŸ

+

å¿…è¦ãªã®ã¯ FatFsモジュールã®è¦æ±‚ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯é–¢æ•°ã‚’用æ„ã™ã‚‹ã“ã¨ã ã‘ã§ã€ãれ以外ã«ã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。既ã«å‹•ä½œã—ã¦ã„るディスク関数ãŒã‚ã‚‹ãªã‚‰ãã® APIã‚’ FatFsã«åˆã‚ã›ã‚‹ã ã‘ã§æ¸ˆã¿ã¾ã™ãŒã€ç„¡ã„å ´åˆã¯ã»ã‹ã‹ã‚‰ç§»æ¤ã™ã‚‹ã‹ã€æœ€åˆã‹ã‚‰æ›¸ãã‹ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚定義ã•ã‚Œã¦ã„ã‚‹å…¨ã¦ã®é–¢æ•°ãŒå¸¸ã«å¿…è¦ãªã‚ã‘ã§ã¯ã‚ã‚Šã¾ã›ã‚“。例ãˆã°ã€ãƒªãƒ¼ãƒ‰ãƒ»ã‚ªãƒ³ãƒªãƒ¼æ§‹æˆã§ã¯æ›¸ãè¾¼ã¿ç³»é–¢æ•°ã¯å¿…è¦ã‚ã‚Šã¾ã›ã‚“。次ã®è¡¨ã«æ§‹æˆã‚ªãƒ—ションã¨è¦æ±‚ã•ã‚Œã‚‹é–¢æ•°ã®å¯¾å¿œã‚’示ã—ã¾ã™ã€‚

+ + + + + + + + + + + + + + + + + + + +
ユーザ作æˆé–¢æ•°å¿…è¦ã¨ãªã‚‹æ¡ä»¶å‚™è€ƒ
disk_initialize常時ffsample.zip (サンプル)
ãã®ä»–web上ã«å¤šæ•°
disk_status常時
disk_read常時
disk_write_FS_READONLY == 0
disk_ioctl (CTRL_SYNC)_FS_READONLY == 0
disk_ioctl (GET_SECTOR_COUNT)_USE_MKFS == 1
disk_ioctl (GET_SECTOR_SIZE)_MAX_SS >= 1024
disk_ioctl (GET_BLOCK_SIZE)_USE_MKFS == 1
get_fattime_FS_READONLY == 0
ff_convert_USE_LFN >= 1option/cc*.c
ff_wtoupper_USE_LFN >= 1
ff_cre_syncobj_FS_REENTRANT == 1option/syscall.c (サンプル)
ff_del_syncobj_FS_REENTRANT == 1
ff_req_grant_FS_REENTRANT == 1
ff_rel_grant_FS_REENTRANT == 1
ff_mem_alloc_USE_LFN == 3
ff_mem_free_USE_LFN == 3
+
+ +
+

é™ç•Œå€¤

+
    +
  • FATタイプ: FAT12, FAT16, FAT32。
  • +
  • åŒæ™‚オープン・ファイル数: 無制é™ã€‚(利用å¯èƒ½ãƒ¡ãƒ¢ãƒªã«ã‚ˆã‚‹)
  • +
  • ボリューム数: 最大 10。
  • +
  • ファイル・サイズ: FATè¦æ ¼ã«ä¾å­˜ã€‚(最大 4G-1ãƒã‚¤ãƒˆ)
  • +
  • ボリューム・サイズ: FATè¦æ ¼ã«ä¾å­˜ã€‚(最大 2Tãƒã‚¤ãƒˆ(512ãƒã‚¤ãƒˆ/セクタ時))
  • +
  • クラスタ・サイズ: FATè¦æ ¼ã«ä¾å­˜ã€‚(最大 64Kãƒã‚¤ãƒˆ(512ãƒã‚¤ãƒˆ/セクタ時))
  • +
  • セクタ・サイズ: FATè¦æ ¼ã«ä¾å­˜ã€‚(最大 4Kãƒã‚¤ãƒˆ)
  • +
+
+ +
+

ãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ (R0.08)

+

次ã®è¡¨ã«ã„ãã¤ã‹ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã«ãŠã‘るメモリ使用é‡ã®ä¾‹ã‚’示ã—ã¾ã™ã€‚テスト時ã®æ§‹æˆã‚ªãƒ—ションã¯ãã®ä¸‹ã®é€šã‚Šã§ã™ã€‚数値ã®å˜ä½ã¯ãƒã‚¤ãƒˆã§ã€Dã¯è«–ç†ãƒœãƒªãƒ¥ãƒ¼ãƒ æ•°ã€Fã¯åŒæ™‚オープン・ファイル数を示ã—ã¾ã™ã€‚コンパイラã®æœ€é©åŒ–オプションã¯ã‚³ãƒ¼ãƒ‰ãƒ»ã‚µã‚¤ã‚ºã¨ã—ã¦ã„ã¾ã™ã€‚

+ + + + + + + + + + + +
AVRH8/300HPIC24V850ESSH-2AARM7x86
CompilerWinAVR(gcc)CH38C30(gcc)CA850SHCWinARM(gcc)VC6
_WORD_ACCESS1001001
text (Full, R/W)12700106861137677308592105207545
text (Min, R/W)8386698073954930560066364923
text (Full, R/O)6012487452503556384846563450
text (Min, R/O)4384377439392684299634162664
bssD*2 + 2D*4 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
D*560 +
F*544
D*560 +
F*550
D*560 +
F*544
D*560 +
F*550
D*560 +
F*550
D*560 +
F*550
D*560 +
F*550
Work area
(_FS_TINY == 1)
D*560 +
F*32
D*560 +
F*36
D*560 +
F*32
D*560 +
F*36
D*560 +
F*36
D*560 +
F*36
D*560 +
F*36
+
+_FS_READONLY     0 (R/W), 1 (R/O)
+_FS_MINIMIZE     0 (Full function), 3 (Minimized function)
+_USE_STRFUNC     0 (Disable string functions)
+_USE_MKFS        0 (Disable f_mkfs function)
+_USE_FORWARD     0 (Disable f_forward function)
+_USE_FASTSEEK    0 (Disable fast seek feature)
+_CODE_PAGE       932 (Japanese Shift-JIS)
+_USE_LFN         0 (Disable LFN)
+_MAX_SS          512 (Fixed sector size)
+_FS_RPATH        0 (Disable relative path)
+_MULTI_PARTITION 0 (Single partition per drive)
+_FS_REENTRANT    0 (Disable reentrancy)
+_FS_SHARE        0 (Disable shareing control)
+
+
+ +
+

モジュール・サイズã®ç¸®å°

+

次ã®è¡¨ã¯æ§‹æˆã‚ªãƒ—ションã®è¨­å®šå€¤ã«ã‚ˆã‚Šã©ã®æ©Ÿèƒ½ãŒå‰Šé™¤ã•ã‚Œã‚‹ã‹ã‚’示ã—ã¾ã™ã€‚

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Function_FS_MINIMIZE_FS_READONLY_USE_STRFUNC_FS_RPATH_USE_MKFS_USE_FORWARD
12310000
f_mount
f_open
f_close
f_read
f_writex
f_syncx
f_lseekx
f_opendirxx
f_readdirxx
f_statxxx
f_getfreexxxx
f_truncatexxxx
f_unlinkxxxx
f_mkdirxxxx
f_chmodxxxx
f_utimexxxx
f_renamexxxx
f_chdirx
f_chdrivex
f_mkfsxx
f_forwardx
f_putcxx
f_putsxx
f_printfxx
f_getsx
+
+ +
+

é•·ã„ファイルå

+

FatFsモジュールã¯R0.07ã‹ã‚‰é•·ã„ファイルå(LFN)をサãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚ファイルã«ä»˜ã‘られãŸ2ã¤ã®ç•°ãªã‚‹åå‰(短ã„ファルåã¨é•·ã„ファイルå)ã¯ã€f_readdir関数を除ãファイルæ“作関数ã«ãŠã„ã¦é€éŽã§ã™ã€‚LFN機能を有効ã«ã™ã‚‹ã«ã¯ã€_USE_LFNã‚’1,2ã¾ãŸã¯3ã«è¨­å®šã—ã€Unicode変æ›é–¢æ•°ff_convert(), ff_wtoupper()をプロジェクトã«è¿½åŠ ã—ã¾ã™ã€‚ã“れらã®é–¢æ•°ã¯ã€option/cc*.cã«å«ã¾ã‚Œã¦ã„ã¾ã™ã€‚LFN機能ã¯ã€åŠ ãˆã¦ã‚る程度ã®ãƒ¯ãƒ¼ã‚¯ãƒ»ã‚¨ãƒªã‚¢(LFNæ“作ãƒãƒƒãƒ•ã‚¡)ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚ãƒãƒƒãƒ•ã‚¡é•·ã¯ä½¿ç”¨ã§ãるメモリã«å¿œã˜ã¦_MAX_LFNオプションã§æ§‹æˆã•ã‚Œã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚LFNã®é•·ã•ã¯æœ€å¤§255文字ã«é”ã™ã‚‹ã®ã§ã€LFN完全対応ã®ãŸã‚ã«ã¯_MAX_LFNã¯255ã«è¨­å®šã•ã‚Œã‚‹ã¹ãã§ã™ã€‚与ãˆã‚‰ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«åã«å¯¾ã—ã¦ãƒãƒƒãƒ•ã‚¡é•·ãŒä¸è¶³ã—ãŸå ´åˆã€ãƒ•ã‚¡ã‚¤ãƒ«é–¢æ•°ã¯FR_INVALID_NAMEã§å¤±æ•—ã—ã¾ã™ã€‚

+

LFN機能をリエントラント構æˆã§ä½¿ç”¨ã™ã‚‹å ´åˆã¯ã€_USE_LFNã¯2ã¾ãŸã¯3ã«è¨­å®šã•ã‚Œãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。ã“ã®å ´åˆã€ãƒ•ã‚¡ã‚¤ãƒ«é–¢æ•°ã¯ãƒãƒƒãƒ•ã‚¡ã‚’スタックやヒープã«ç¢ºä¿ã—ã¾ã™ã€‚ãƒãƒƒãƒ•ã‚¡ãƒ»ã‚µã‚¤ã‚ºã¯ã€(_MAX_LFN + 1) * 2ãƒã‚¤ãƒˆã«ãªã‚‹ã®ã§ã€ã‚¹ã‚¿ãƒƒã‚¯ç­‰ã®ã‚µã‚¤ã‚ºã¯ãれを考慮ã—ãŸå分ãªã‚µã‚¤ã‚ºã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。

+ + + + + + + + +
LFN cfg on ARM7
コードページコードサイズ[bytes]
SBCS+3721
932(Shift-JIS)+62609
936(GBK)+177797
949(Korean)+139857
950(Big5)+111497
+

LFNを有効ã«ã™ã‚‹ã¨ã€é¸æŠžã•ã‚ŒãŸã‚³ãƒ¼ãƒ‰ãƒ»ãƒšãƒ¼ã‚¸ã«å¿œã˜ã¦ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãƒ»ã‚µã‚¤ã‚ºãŒå¢—大ã•ã‚Œã¾ã™ã€‚å³ã®è¡¨ã«å„コード・ページã«ãŠã‘ã‚‹LFNを有効ã«ã—ãŸã¨ãã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãƒ»ã‚µã‚¤ã‚ºã®é•ã„を示ã—ã¾ã™ã€‚ç§ãŸã¡æ—¥æœ¬äººã€ä¸­å›½äººãŠã‚ˆã³éŸ“国人ã¯æ•°ä¸‡ã®æ–‡å­—ã‚’æŒã¡ã¾ã™ã€‚ä¸å¹¸ãªã“ã¨ã«ã€ãã‚Œã¯å·¨å¤§ãªOEMï¼Unicode相互変æ›ãƒ†ãƒ¼ãƒ–ルをè¦æ±‚ã—ã€ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãƒ»ã‚µã‚¤ã‚ºã¯åŠ‡çš„ã«å¢—大ã•ã‚Œã¾ã™ã€‚ãã®çµæžœã€LFNを有効ã«ã—ãŸFatFsモジュールã¯ã€AVRã‚’å«ã‚€æ®†ã©ã®8ビット・マイコンã«ã‚¤ãƒ³ãƒ—リメントã•ã‚Œã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã‚Œã¯é•·ã„é–“ç§ãŒLFNをインプリメントã™ã‚‹ã“ã¨ã«èˆˆå‘³ã‚’æŒã£ã¦ã“ãªã‹ã£ãŸç†ç”±ã§ã™ã€‚

+

注: FATファイル・システム上ã®LFN機能ã¯ãƒžã‚¤ã‚¯ãƒ­ã‚½ãƒ•ãƒˆç¤¾ã®ç‰¹è¨±ã§ã™ã€‚商用製å“ã§ãれを有効ã«ã™ã‚‹ã¨ãã¯ã€æœ€çµ‚仕å‘地ã«ã‚ˆã£ã¦ã¯ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ãŒå¿…è¦ã‹ã‚‚知れã¾ã›ã‚“。

+
+ +
+

日本語ファイルåã®å¤§æ–‡å­—変æ›

+

CP932(Shift_JIS)ã§ã‹ã¤éžLFN構æˆã®ã¨ãã¯ã€æ‹¡å¼µæ–‡å­—ã®å°æ–‡å­—(2ãƒã‚¤ãƒˆè‹±å­—・キリル文字・ギリシャ文字)ã«å¯¾ã—ã¦å¤§æ–‡å­—変æ›ã‚’è¡Œã‚ãšã€å°æ–‡å­—ã®ã¾ã¾SFNエントリã«è¨˜éŒ²ãƒ»æ¤œç´¢ã•ã‚Œã¾ã™ã€‚ã“ã‚Œã¯æ—¥æœ¬èªžMSDOSã¨åŒã˜ä»•æ§˜ã¨ãªã‚Šã¾ã™ã€‚ã“ã®ãŸã‚ã€éžLFN構æˆã§å…¨è§’å°æ–‡å­—ã‚’å«ã‚€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã™ã‚‹ã¨ã€NTç³»Windowsã§ãã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é–‹ã‘ãªããªã‚Šã¾ã™ã€‚LFN構æˆã§ã¯å¤§æ–‡å­—変æ›ã‚’è¡Œã„ã¾ã™(NTç³»Windows仕様)。

+
+ +
+

Unicode入出力ã¸ã®å¯¾å¿œ

+

ファイル関数ã®ãƒ•ã‚¡ã‚¤ãƒ«å入出力ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯ ANSI/OEMコードã§ã™ãŒã€ã“れをUnicodeã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚Unicodeファイルåã«é–¢ã™ã‚‹è©³ç´°ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«åã‚’å‚ç…§ã—ã¦ãã ã•ã„。

+
+ +
+

リエントランシー

+

互ã„ã«ç•°ãªã‚‹ãƒœãƒªãƒ¥ãƒ¼ãƒ ã«å¯¾ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«æ“作ã¯ã€å¸¸ã«åŒæ™‚平行ã«å‹•ä½œã§ãã¾ã™ã€‚åŒã˜ãƒœãƒªãƒ¥ãƒ¼ãƒ ã«å¯¾ã—ã¦ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯ãƒªã‚¨ãƒ³ãƒˆãƒ©ãƒ³ãƒˆã§ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€_FS_REENTRANTオプションã§ãƒªã‚¨ãƒ³ãƒˆãƒ©ãƒ³ãƒˆã«ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ã“ã®å ´åˆã€OSä¾å­˜ã®åŒæœŸã‚ªãƒ–ジェクトæ“作関数ff_cre_syncobj, ff_del_syncobj, ff_req_grant 㨠ff_rel_grantã‚‚ã¾ãŸãƒ—ロジェクトã«è¿½åŠ ã•ã‚Œãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。サンプル・コードã¨è§£èª¬ã¯option/syncobj.cã«ã‚ã‚Šã¾ã™ã€‚

+

ã‚るタスクãŒãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’使用中ã«ä»–ã®ã‚¿ã‚¹ã‚¯ã‹ã‚‰ãã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã«å¯¾ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«é–¢æ•°ãŒå‘¼ã³å‡ºã•ã‚Œã‚‹ã¨ã€ãã®ã‚¢ã‚¯ã‚»ã‚¹ã¯å…ˆã®ã‚¿ã‚¹ã‚¯ãŒãƒ•ã‚¡ã‚¤ãƒ«é–¢æ•°ã‚’抜ã‘ã‚‹ã¾ã§ãƒ–ロックã•ã‚Œã¾ã™ã€‚ã‚‚ã—ã€å¾…ã¡æ™‚é–“ãŒ_TIMEOUTã§æŒ‡å®šã•ã‚ŒãŸæœŸé–“を越ã™ã¨ã€ãã®é–¢æ•°ã¯FR_TIMEOUTã§ã‚¢ãƒœãƒ¼ãƒˆã—ã¾ã™ã€‚ã„ãã¤ã‹ã®RTOSã§ã¯ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆæ©Ÿèƒ½ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œãªã„ã‹ã‚‚知れã¾ã›ã‚“。

+

ã²ã¨ã¤ã®ä¾‹å¤–ãŒf_mount()ã¨f_mkfs()ã«ã‚ã‚Šã¾ã™ã€‚ã“れらã®é–¢æ•°ã¯åŒã˜ãƒœãƒªãƒ¥ãƒ¼ãƒ ã«å¯¾ã—ã¦ãƒªã‚¨ãƒ³ãƒˆãƒ©ãƒ³ãƒˆã§ã¯ã‚ã‚Šã¾ã›ã‚“。ã“れらã®é–¢æ•°ã‚’使用ã™ã‚‹ã¨ãã¯ã€ã‚¢ãƒ—リケーション・レベルã§æŽ’他制御ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。

+

注: ã“ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã¯FatFsモジュールãれ自体ã®ãƒªã‚¨ãƒ³ãƒˆãƒ©ãƒ³ã‚·ãƒ¼ã«ã¤ã„ã¦èª¬æ˜Žã—ã¦ã„ã¾ã™ã€‚ディスクI/Oモジュールã®ãƒªã‚¨ãƒ³ãƒˆãƒ©ãƒ³ã‚·ãƒ¼ã«é–¢ã—ã¦ã¯ä½•ã®å‰æã‚‚ã‚ã‚Šã¾ã›ã‚“。

+
+ +
+

多é‡ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚¢ã‚¯ã‚»ã‚¹

+

FatFsモジュールã§ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯å¤šé‡ã‚¢ã‚¯ã‚»ã‚¹åˆ¶å¾¡æ©Ÿèƒ½ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。ファイルã«å¯¾ã™ã‚‹å¤šé‡ã‚¢ã‚¯ã‚»ã‚¹ã¯ã€ãã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ»ãƒ¢ãƒ¼ãƒ‰ã«ã‚ˆã£ã¦åˆ¶é™ã•ã‚Œã¾ã™ã€‚一ã¤ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«å¯¾ã™ã‚‹å¤šé‡ã‚ªãƒ¼ãƒ—ンã¯ã€ãれらãŒå…¨ã¦ãƒªãƒ¼ãƒ‰ãƒ»ãƒ¢ãƒ¼ãƒ‰ã®ã¨ãã«é™ã£ã¦è¨±å¯ã•ã‚Œã¾ã™ã€‚書ãè¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ã‚’å«ã‚€å¤šé‡ã‚ªãƒ¼ãƒ—ンã€ã¾ãŸé–‹ã‹ã‚Œã¦ã„るファイルã«å¯¾ã™ã‚‹ãƒªãƒãƒ¼ãƒ ã‚„削除ã€ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®å‰Šé™¤ã‚’è¡Œã£ã¦ã¯ãªã‚Šã¾ã›ã‚“。ã•ã‚‚ãªã„ã¨ã€ãã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã®FAT構造ãŒç ´å£Šã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚

+

_FS_SHAREã«1以上ã®å€¤ã‚’セットã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãƒ•ã‚¡ã‚¤ãƒ«å˜ä½ã®æŽ’他制御を自動ã§è¡Œã†ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ã“ã®å ´åˆã€ä¸Šè¨˜ã®ãƒ«ãƒ¼ãƒ«ã‚’ç ´ã£ãŸã‚ªãƒ¼ãƒ—ン・リãƒãƒ¼ãƒ ãƒ»å‰Šé™¤ã‚’試ã¿ã‚‹ã¨ã€ãã®é–¢æ•°ã¯FR_LOCKEDã§å¤±æ•—ã—ã¾ã™ã€‚

+
+ +
+

効率的ãªãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚¢ã‚¯ã‚»ã‚¹

+

å°è¦æ¨¡ãªçµ„込システムã§ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®èª­ã¿æ›¸ãã«ãŠã‘る効率ã®è‰¯ã„アクセスã®ãŸã‚ã€ã‚¢ãƒ—リケーション・プログラマã¯FatFsモジュールã®ä¸­ã§ã©ã®ã‚ˆã†ãªå‡¦ç†ãŒè¡Œã‚ã‚Œã¦ã„ã‚‹ã‹è€ƒæ…®ã™ã¹ãã§ã™ã€‚ディスク上ã®ãƒ‡ãƒ¼ã‚¿ã¯f_read関数ã«ã‚ˆã‚Šæ¬¡ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§è»¢é€ã•ã‚Œã¾ã™ã€‚

+

図1. セクタ・ミスアラインド・リード (ショート)
+fig.1 +

+

図2. セクタ・ミスアラインド・リード (ロング)
+fig.2 +

+

図3. セクタ・アラインド・リード
+fig.3 +

+

ファイルI/Oãƒãƒƒãƒ•ã‚¡ã¯ã‚»ã‚¯ã‚¿ã®ä¸€éƒ¨ã®ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿æ›¸ãã™ã‚‹ãŸã‚ã®ã‚»ã‚¯ã‚¿ãƒ»ãƒãƒƒãƒ•ã‚¡ã‚’æ„味ã—ã¾ã™ã€‚セクタ・ãƒãƒƒãƒ•ã‚¡ã¯ã€ãã‚Œãžã‚Œã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚ªãƒ–ジェクト内ã®ãƒ—ライベート・セクタ・ãƒãƒƒãƒ•ã‚¡ã¾ãŸã¯ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚·ã‚¹ãƒ†ãƒ ãƒ»ã‚ªãƒ–ジェクト内ã®å…±æœ‰ã‚»ã‚¯ã‚¿ãƒ»ãƒãƒƒãƒ•ã‚¡ã®ã©ã¡ã‚‰ã‹ã§ã™ã€‚ãƒãƒƒãƒ•ã‚¡æ§‹æˆã‚ªãƒ—ションã®_FS_TINYã¯ã€ãƒ‡ãƒ¼ã‚¿è»¢é€ã«ã©ã¡ã‚‰ã‚’使ã†ã‹ã‚’決定ã—ã¾ã™ã€‚タイニー・ãƒãƒƒãƒ•ã‚¡(1)ãŒé¸æŠžã•ã‚Œã‚‹ã¨ãƒ‡ãƒ¼ã‚¿ãƒ»ãƒ¡ãƒ¢ãƒªã®æ¶ˆè²»ã¯ãã‚Œãžã‚Œã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚ªãƒ–ジェクトã§512ãƒã‚¤ãƒˆæ¸›å°‘ã•ã‚Œã¾ã™ã€‚ã“ã®å ´åˆã€FatFsモジュールã¯ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ãƒ‡ãƒ¼ã‚¿ã®è»¢é€ã¨FAT/ディレクトリ・アクセスã«ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ã‚·ã‚¹ãƒ†ãƒ ãƒ»ã‚ªãƒ–ジェクト内ã®ã‚»ã‚¯ã‚¿ãƒ»ãƒãƒƒãƒ•ã‚¡ã ã‘を使用ã—ã¾ã™ã€‚タイニー・ãƒãƒƒãƒ•ã‚¡ã®æ¬ ç‚¹ã¯ã€ã‚»ã‚¯ã‚¿ãƒ»ãƒãƒƒãƒ•ã‚¡ã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã•ã‚ŒãŸFATデータãŒãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ãƒ‡ãƒ¼ã‚¿ã®è»¢é€ã«ã‚ˆã‚Šå¤±ã‚ã‚Œã€ã‚¯ãƒ©ã‚¹ã‚¿å¢ƒç•Œã®æ¯Žã«ãƒªãƒ­ãƒ¼ãƒ‰ã•ã‚Œãªã‘ã‚Œã°ãªã‚‰ãªã„ã“ã¨ã§ã™ã€‚ã§ã‚‚ã€æ‚ªããªã„性能ã¨å°‘ãªã„メモリ消費ã®è¦–点ã‹ã‚‰å¤šãã®ã‚¢ãƒ—リケーションã«é©ã™ã‚‹ã§ã—ょã†ã€‚

+

図1ã¯ã‚»ã‚¯ã‚¿ã®ä¸€éƒ¨ã®ãƒ‡ãƒ¼ã‚¿ãŒãƒ•ã‚¡ã‚¤ãƒ«I/Oãƒãƒƒãƒ•ã‚¡ã‚’経由ã§è»¢é€ã•ã‚Œã‚‹ã“ã¨ã‚’示ã—ã¾ã™ã€‚図2ã«ç¤ºã•ã‚Œã‚‹é•·ã„データã®è»¢é€ã§ã¯ã€è»¢é€ãƒ‡ãƒ¼ã‚¿ã®ä¸­é–“ã®1セクタã¾ãŸã¯ãれ以上ã®ã‚»ã‚¯ã‚¿ã«ã¾ãŸãŒã‚‹è»¢é€ãƒ‡ãƒ¼ã‚¿ãŒã‚¢ãƒ—リケーション・ãƒãƒƒãƒ•ã‚¡ã«ç›´æŽ¥è»¢é€ã•ã‚Œã¦ã„ã¾ã™ã€‚図3ã¯è»¢é€ãƒ‡ãƒ¼ã‚¿å…¨ä½“ãŒã‚»ã‚¯ã‚¿å¢ƒç•Œã«ã‚¢ãƒ©ã‚¤ãƒ¡ãƒ³ãƒˆã•ã‚Œã¦ã„ã‚‹å ´åˆã‚’示ã—ã¦ã„ã¾ã™ã€‚ã“ã®å ´åˆã€ãƒ•ã‚¡ã‚¤ãƒ«I/Oãƒãƒƒãƒ•ã‚¡ã¯ä½¿ç”¨ã•ã‚Œã¾ã›ã‚“。直接転é€ã«ãŠã„ã¦ã¯æœ€å¤§ã®ç¯„囲ã®ã‚»ã‚¯ã‚¿ãŒdisk_read関数ã§ä¸€åº¦ã«èª­ã¿è¾¼ã¾ã‚Œã¾ã™ãŒã€ã‚¯ãƒ©ã‚¹ã‚¿å¢ƒç•Œã‚’越ãˆã‚‹ãƒžãƒ«ãƒãƒ»ã‚»ã‚¯ã‚¿è»¢é€ã¯ãã‚ŒãŒéš£æŽ¥ã§ã‚ã£ã¦ã‚‚è¡Œã‚ã‚Œã¾ã›ã‚“。

+

ã“ã®ã‚ˆã†ã«ã€ã‚»ã‚¯ã‚¿ã«ã‚¢ãƒ©ã‚¤ãƒ¡ãƒ³ãƒˆã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®èª­ã¿æ›¸ãã¸ã®é…æ…®ã¯ãƒãƒƒãƒ•ã‚¡çµŒç”±ã®ãƒ‡ãƒ¼ã‚¿è»¢é€ã‚’é¿ã‘ã€èª­ã¿æ›¸ã性能ã¯æ”¹å–„ã•ã‚Œã‚‹ã§ã—ょã†ã€‚ãã®åŠ¹æžœã«åŠ ãˆã€ã‚¿ã‚¤ãƒ‹ãƒ¼æ§‹æˆã§ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã•ã‚ŒãŸFATデータãŒãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ãƒ‡ãƒ¼ã‚¿ã®è»¢é€ã«ã‚ˆã‚Šãƒ•ãƒ©ãƒƒã‚·ãƒ¥ã•ã‚Œãšã€éžã‚¿ã‚¤ãƒ‹ãƒ¼æ§‹æˆã¨åŒã˜æ€§èƒ½ã‚’å°ã•ãªãƒ¡ãƒ¢ãƒªãƒ»ãƒ•ãƒƒãƒˆãƒ—リントã§é”æˆã§ãã¾ã™ã€‚

+
+ +
+

クリãƒã‚«ãƒ«ãƒ»ã‚»ã‚¯ã‚·ãƒ§ãƒ³

+

ディスク上ã®FAT構造をæ“作ã—ã¦ã„る途中ã§ã€åœé›»ã€ä¸æ­£ãªãƒ¡ãƒ‡ã‚£ã‚¢ã®å–り外ã—ã€å›žå¾©ä¸èƒ½ãªãƒ‡ãƒ¼ã‚¿ãƒ»ã‚¨ãƒ©ãƒ¼ç­‰ã®éšœå®³ãŒç™ºç”Ÿã™ã‚‹ã¨ã€å‡¦ç†ãŒä¸­é€”åŠç«¯ãªçŠ¶æ…‹ã§ä¸­æ–­ã•ã‚Œã€ãã®çµæžœã¨ã—ã¦FAT構造ãŒç ´å£Šã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚次ã«FatFsモジュールã«ãŠã‘るクリãƒã‚«ãƒ«ãƒ»ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã¨ã€ãã®é–“ã®éšœå®³ã«ã‚ˆã‚Šèµ·ãã†ã‚‹ã‚¨ãƒ©ãƒ¼ã®çŠ¶æ…‹ã‚’示ã—ã¾ã™ã€‚

+
+図4. é•·ã„クリãƒã‚«ãƒ«ãƒ»ã‚»ã‚¯ã‚·ãƒ§ãƒ³
+fig.4 +
+
+図5. 最å°åŒ–ã—ãŸã‚¯ãƒªãƒã‚«ãƒ«ãƒ»ã‚»ã‚¯ã‚·ãƒ§ãƒ³
+fig.5 +
+
+

赤ã§ç¤ºã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’実行中ã«éšœå®³ãŒç™ºç”Ÿã—ãŸå ´åˆã€ã‚¯ãƒ­ã‚¹ãƒ»ãƒªãƒ³ã‚¯ãŒç™ºç”Ÿã—ã¦æ“作対象ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå¤±ã‚れるå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚黄色ã§ç¤ºã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’実行中ã«éšœå®³ãŒç™ºç”Ÿã—ãŸå ´åˆã€ã¤ãŽã®ã†ã¡ã„ãšã‚Œã‹ã¾ãŸã¯è¤‡æ•°ã®çµæžœãŒç”Ÿã˜ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚

+
    +
  • 書ãæ›ãˆä¸­ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒ‡ãƒ¼ã‚¿ãŒç ´å£Šã•ã‚Œã‚‹ã€‚
  • +
  • 追記中ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒã‚ªãƒ¼ãƒ—ンå‰ã®çŠ¶æ…‹ã«æˆ»ã‚‹ã€‚
  • +
  • æ–°è¦ã«ä½œæˆã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ãŒæ¶ˆãˆã‚‹ã€‚
  • +
  • æ–°è¦ã¾ãŸã¯ä¸Šæ›¸ãã§ä½œæˆã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã®é•·ã•ãŒã‚¼ãƒ­ã«ãªã£ã¦æ®‹ã‚‹ã€‚
  • +
  • ロストãƒã‚§ãƒ¼ãƒ³ã®ç™ºç”Ÿã«ã‚ˆã‚Šãƒ‡ã‚£ã‚¹ã‚¯ã®åˆ©ç”¨åŠ¹çŽ‡ãŒæ‚ªåŒ–ã™ã‚‹ã€‚
  • +
+

ã„ãšã‚Œã‚‚書ãè¾¼ã¿ä¸­ã‚„æ“作対象ã§ãªã„ファイルã«ã¯å½±éŸ¿ã¯ã‚ã‚Šã¾ã›ã‚“。ã“れらã®ã‚¯ãƒªãƒã‚«ãƒ«ãƒ»ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’書ãè¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ã§é–‹ã„ã¦ã„る時間を最å°é™ã«ã™ã‚‹ã‹ã€f_sync()ã‚’é©å®œä½¿ç”¨ã™ã‚‹ã“ã¨ã§å›³5ã®ã‚ˆã†ã«ãƒªã‚¹ã‚¯ã‚’最å°åŒ–ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚

+
+ +
+

FatFsã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã«ã¤ã„ã¦

+

ソース・ファイルã®ãƒ˜ãƒƒãƒ€ã«ãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ¡ä»¶ãŒè¨˜è¿°ã•ã‚Œã¦ã„ã‚‹ã®ã§ã€åˆ©ç”¨ã®éš›ã¯ãã‚Œã«å¾“ã†ã“ã¨ã€‚英語を読ã‚ãªã„æ–¹ã®ãŸã‚ã«ä»¥ä¸‹ã«æ—¥æœ¬èªžè¨³ã‚’示ã—ã¦ãŠãã¾ã™ã€‚

+
/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.08                    (C)ChaN, 2009
+/-----------------------------------------------------------------------------/
+/ FatFsモジュールã¯ã€å°è¦æ¨¡ãªçµ„ã¿è¾¼ã¿ã‚·ã‚¹ãƒ†ãƒ å‘ã‘ã®æ±Žç”¨FATファイルシステム・
+/ モジュールã§ã™ã€‚ã“ã‚Œã¯ãƒ•ãƒªãƒ¼ãƒ»ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¨ã—ã¦ã€æ•™è‚²ãƒ»ç ”究・開発ã®ãŸã‚ã«
+/ 以下ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ãƒ»ãƒãƒªã‚·ãƒ¼ã®ä¸‹ã§å…¬é–‹ã•ã‚Œã¦ã„ã¾ã™ã€‚
+/
+/  Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * FatFsモジュールã¯ãƒ•ãƒªãƒ¼ãƒ»ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã§ã‚ã‚Šã€ã¾ãŸç„¡ä¿è¨¼ã§ã™ã€‚
+/ * 用途ã«åˆ¶é™ã¯ã‚ã‚Šã¾ã›ã‚“。ã‚ãªãŸã®è²¬ä»»ã®ä¸‹ã«ãŠã„ã¦ã€å€‹äººçš„・éžå–¶åˆ©çš„ãª
+/   ã‚‚ã®ã‹ã‚‰å•†ç”¨è£½å“ã®é–‹ç™ºã«åŠã¶ç›®çš„ã«ä½¿ç”¨ãƒ»æ”¹å¤‰ãƒ»å†é…布ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+/ * ソース・コードをå†é…布ã™ã‚‹ã¨ãã¯ã€ä¸Šè¨˜ã®è‘—作権表示をä¿æŒã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+/
+/-----------------------------------------------------------------------------/
+

è¦ã™ã‚‹ã«FatFsã¯ã‚¿ãƒ€ã§è‡ªç”±ã«ä½¿ãˆã‚‹ã¨ã„ã†ã“ã¨ã§ã™ã€‚ソース・コードをå†é…布ã™ã‚‹ã¨ãã¯ã€ã“ã®ãƒ–ロックをãã®ã¾ã¾ä¿æŒã—ã¦ãŠãã“ã¨ã€‚ã“ã®ã‚ˆã†ã«FatFsã¯BSDライクãªãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã¨ã—ã¦ã„ã¾ã™ãŒã€ä¸€ã¤å¤§ããªé•ã„ãŒã‚ã‚Šã¾ã™ã€‚特ã«çµ„ã¿è¾¼ã¿ç”¨é€”ã§ã®åˆ©ç”¨ä¾¡å€¤ã‚’高ã‚ã‚‹ãŸã‚ã€ãƒã‚¤ãƒŠãƒªå½¢å¼(ソース・コードをå«ã¾ãªã„å½¢å¼å…¨ã¦)ã§ã®å†é…布ã«ã¤ã„ã¦ã¯ã€æ¡ä»¶ã¯è¨­ã‘ã¦ã„ã¾ã›ã‚“。ãã®å ´åˆã¯ã€FatFsãŠã‚ˆã³ãã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ–‡æ›¸ã«ã¤ã„ã¦ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«æ˜Žè¨˜ã—ã¦ã‚‚ã—ãªãã¦ã‚‚ã‹ã¾ã„ã¾ã›ã‚“。もã¡ã‚ã‚“GNU GPLプロジェクトã¨ã‚‚共存å¯èƒ½ã§ã™ã€‚何らã‹ã®å¤‰æ›´ã‚’加ãˆã¦å†é…布ã™ã‚‹éš›ã¯ã€çŸ›ç›¾ã—ãªã„ä»–ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹(GNU GPLã‚„BSDライセンスãªã©)ã«å¤‰æ›´ã™ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚

+
+ +

戻る

+ + diff --git a/Lib/Fat/doc/ja/chdir.html b/Lib/Fat/doc/ja/chdir.html new file mode 100644 index 0000000..fc66f55 --- /dev/null +++ b/Lib/Fat/doc/ja/chdir.html @@ -0,0 +1,92 @@ + + + + + + + + +FatFs - f_chdir + + + + +
+

f_chdir

+

ƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX‚µ‚Ü‚·B

+
+FRESULT f_chdir (
+  const XCHAR* Path /* ƒfƒBƒŒƒNƒgƒŠ–¼‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
Path
+
ˆÚ“®‘Îۂ̃fƒBƒŒƒNƒgƒŠ‚̃pƒX–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

f_chdirŠÖ”‚ÍŠeƒ{ƒŠƒ…[ƒ€‚̃JƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX‚µ‚Ü‚·BƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚̓tƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚̉Šú‰»‚ªs‚í‚ꂽ‚Æ‚«Aƒ‹[ƒgEƒfƒBƒŒƒNƒgƒŠ‚Éݒ肳‚ê‚Ü‚·BƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚ÍAƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚É‹L˜^‚³‚ê‚邽‚ßA‚»‚̃{ƒŠƒ…[ƒ€‚ðŽg—p‚·‚é‘S‚Ẵ^ƒXƒN‚ɑ΂µ‚ĉe‹¿‚ð—^‚¦‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_RPATH == 1‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Æ‚È‚è‚Ü‚·B

+
+ + +
+

Žg—p—á

+
+    // ƒJƒŒƒ“ƒgEƒhƒ‰ƒCƒu‚̃JƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX (ƒ‹[ƒg‰º‚Ìdir1‚Ö)
+    f_chdir("/dir1");
+
+    // ƒhƒ‰ƒCƒu2‚̃JƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX (eƒfƒBƒŒƒNƒgƒŠ‚Ö)
+    f_chdir("2:..");
+
+
+ +
+

ŽQÆ

+

f_chdrive

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/chdrive.html b/Lib/Fat/doc/ja/chdrive.html new file mode 100644 index 0000000..8344a3e --- /dev/null +++ b/Lib/Fat/doc/ja/chdrive.html @@ -0,0 +1,63 @@ + + + + + + + + +FatFs - f_chdrive + + + + +
+

f_chdrive

+

ƒJƒŒƒ“ƒgEƒhƒ‰ƒCƒu‚ð•ÏX‚µ‚Ü‚·B

+
+FRESULT f_chdrive (
+  BYTE Drive /* ˜_—ƒhƒ‰ƒCƒu”Ô† */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
ƒJƒŒƒ“ƒgEƒhƒ‰ƒCƒu‚ÉÝ’è‚·‚é˜_—ƒhƒ‰ƒCƒu”Ô†‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
+
+ + +
+

‰ðà

+

f_chdriveŠÖ”‚̓JƒŒƒ“ƒgEƒhƒ‰ƒCƒu‚ð•ÏX‚µ‚Ü‚·BƒVƒXƒeƒ€‹N“®Žž‚̉Šú’l‚Í0‚Å‚·B‚±‚ÌÝ’è‚ÍFatFsƒ‚ƒWƒ…[ƒ‹‚ÌÓI•Ï”‚É‹L˜^‚³‚ê‚邽‚ßA‘S‚Ẵ^ƒXƒN‚ɑ΂µ‚ĉe‹¿‚ð—^‚¦‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_RPATH == 1‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Æ‚È‚è‚Ü‚·B

+
+ + +
+

ŽQÆ

+

f_chdir

+
+ +

Return

+ + diff --git a/Lib/Fat/doc/ja/chmod.html b/Lib/Fat/doc/ja/chmod.html new file mode 100644 index 0000000..a9b13e0 --- /dev/null +++ b/Lib/Fat/doc/ja/chmod.html @@ -0,0 +1,98 @@ + + + + + + + + +FatFs - f_chmod + + + + +
+

f_chmod

+

ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚Ì‘®«‚ð•ÏX‚µ‚Ü‚·B

+
+FRESULT f_chmod (
+  const TCHAR* FileName, /* ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼‚ւ̃|ƒCƒ“ƒ^ */
+  BYTE Attribute,        /* Ý’è’l */
+  BYTE AttributeMask     /* •ÏXƒ}ƒXƒN */
+);
+
+
+ +
+

ˆø”

+
+
FileName
+
‘®«•ÏX‘Îۂ̃tƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚̃pƒX–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ðŽw’肵‚Ü‚·B
+
Attribute
+
Ý’è‚·‚é‘®«BŽw’è‰Â”\‚È‘®«‚ÍŽŸ‚Ì’Ê‚è‚ÅA‚±‚ê‚ç‚Ì‘g‚݇‚킹‚ÅŽw’肵‚Ü‚·BŽw’肳‚ê‚È‚©‚Á‚½‘®«‚͉𜂳‚ê‚Ü‚·B
+ + + + + + +
’lˆÓ–¡
AM_RDOƒŠ[ƒhEƒIƒ“ƒŠ[
AM_ARCƒA[ƒJƒCƒu
AM_SYSƒVƒXƒeƒ€
AM_HIDƒqƒhƒDƒ“
+
+
AttributeMask
+
•ÏX‚·‚é‘®«‚̃}ƒXƒNBŽw’肵‚½‘®«‚ªÝ’è‚Ü‚½‚͉𜂳‚êAŽw’肳‚ê‚È‚©‚Á‚½‘®«‚Íó‘Ô‚ª•ÛŽ‚³‚ê‚Ü‚·BAttribute‚Æ“¯‚¶’l‚ðŽg‚¢‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚Ì‘®«‚ð•ÏX‚µ‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+    /* ƒŠ[ƒhƒIƒ“ƒŠ[‚ðƒZƒbƒgAƒA[ƒJƒCƒu‚ðƒNƒŠƒAA‚»‚Ì‘¼‚Í•ÏX‚µ‚È‚¢ */
+    f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/close.html b/Lib/Fat/doc/ja/close.html new file mode 100644 index 0000000..30de321 --- /dev/null +++ b/Lib/Fat/doc/ja/close.html @@ -0,0 +1,69 @@ + + + + + + + + +FatFs - f_close + + + + +
+

f_close

+

ƒtƒ@ƒCƒ‹‚ð•Â‚¶‚Ü‚·B

+
+FRESULT f_close (
+  FIL* FileObject     /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
•Â‚¶‚悤‚Æ‚·‚éƒtƒ@ƒCƒ‹‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚ð•Â‚¶‚Ü‚·B‰½‚ç‚©‚Ì‘‚«ž‚Ý‚Ìs‚í‚ꂽƒtƒ@ƒCƒ‹‚Ìê‡AƒLƒƒƒbƒVƒ…‚³‚ꂽó‘Ô(ƒŠ[ƒh/ƒ‰ƒCƒgEƒoƒbƒtƒ@ã‚̃f[ƒ^A•ÏX‚³‚ꂽFAT‚âƒfƒBƒŒƒNƒgƒŠ€–Ú)‚̓fƒBƒXƒN‚É‘‚«–ß‚³‚ê‚Ü‚·BŠÖ”‚ª³íI—¹‚·‚é‚ÆA‚»‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚Í–³Œø‚É‚È‚èA‚»‚̃ƒ‚ƒŠ‚à‰ð•ú‚Å‚«‚Ü‚·B“Ç‚Ýž‚Ýê—pƒ‚[ƒh‚ÅŠJ‚©‚ꂽƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ÍA‚±‚ÌŠÖ”‚É‚æ‚éƒNƒ[ƒYˆ—‚ðŒo‚¸‚É”jŠü‚·‚邱‚Æ‚à‚Å‚«‚Ü‚·‚ªA„§‚Í‚³‚ê‚Ü‚¹‚ñB

+
+ + +
+

‘Ήžî•ñ

+

‘S‚Ä‚Ì\¬‚ÅŽg—p‰Â”\‚Å‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/dinit.html b/Lib/Fat/doc/ja/dinit.html new file mode 100644 index 0000000..93fae2a --- /dev/null +++ b/Lib/Fat/doc/ja/dinit.html @@ -0,0 +1,46 @@ + + + + + + + + +FatFs - disk_initialize + + + + +
+

disk_initialize

+

ƒfƒBƒXƒNEƒhƒ‰ƒCƒu‚ð‰Šú‰»‚µ‚Ü‚·B

+
+DSTATUS disk_initialize (
+  BYTE Drive      /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
‰Šú‰»‚·‚镨—ƒhƒ‰ƒCƒu”Ô†(0-9)‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+

‚±‚ÌŠÖ”‚Í–ß‚è’l‚Æ‚µ‚ăfƒBƒXƒNEƒXƒe[ƒ^ƒX‚ð•Ô‚µ‚Ü‚·BƒfƒBƒXƒNEƒXƒe[ƒ^ƒX‚ÌÚׂɊւµ‚Ä‚Ídisk_status()‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B

+
+ +
+

‰ðà

+

ƒfƒBƒXƒNEƒhƒ‰ƒCƒu‚ð‰Šú‰»‚µ‚Ü‚·BŠÖ”‚ª¬Œ÷‚·‚é‚ÆA–ß‚è’l‚ÌSTA_NOINITƒtƒ‰ƒO‚ªƒNƒŠƒA‚³‚ê‚Ü‚·B

+

FatFsƒ‚ƒWƒ…[ƒ‹‚ÍAŽ©“®ƒ}ƒEƒ“ƒg“®ì‚É‚æ‚è•K—v‚ɉž‚¶‚Ä‚±‚ÌŠÖ”‚ðŒÄ‚Ño‚µ‚Ü‚·BƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚©‚炱‚ÌŠÖ”‚ðŒÄ‚Ño‚µ‚Ä‚Í‚È‚è‚Ü‚¹‚ñB‚³‚à‚È‚¢‚ÆFAT\‘¢‚ª”j‰ó‚³‚ê‚é‰Â”\«‚ª‚ ‚è‚Ü‚·BƒGƒ‰[“™‚É‚æ‚èĉŠú‰»‚ª•K—v‚È‚Æ‚«‚ÍAf_mount()‚ðŽg—p‚µ‚Ü‚·B

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/dioctl.html b/Lib/Fat/doc/ja/dioctl.html new file mode 100644 index 0000000..9ad5542 --- /dev/null +++ b/Lib/Fat/doc/ja/dioctl.html @@ -0,0 +1,68 @@ + + + + + + + + +FatFs - disk_ioctl + + + + +
+

disk_ioctl

+

ƒZƒNƒ^‚Ì“Ç‚Ý‘‚«ˆÈŠO‚̃fƒBƒXƒNEƒhƒ‰ƒCƒuŽ©‘̂ɑ΂·‚é—lX‚ȧŒä‚ð‚µ‚Ü‚·B

+
+DRESULT disk_ioctl (
+  BYTE Drive,      /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+  BYTE Command,    /* §ŒäƒRƒ}ƒ“ƒh */
+  void* Buffer     /* ƒf[ƒ^Žó‚¯“n‚µƒoƒbƒtƒ@ */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
•¨—ƒhƒ‰ƒCƒu”Ô†(0-9)‚ðŽw’肵‚Ü‚·B
+
Command
+
§ŒäƒRƒ}ƒ“ƒhEƒR[ƒh‚ðŽw’肵‚Ü‚·B
+
Buffer
+
§ŒäƒRƒ}ƒ“ƒh‚Ɉˑ¶‚µ‚½ƒpƒ‰ƒ[ƒ^‚ðŽöŽó‚·‚éƒoƒbƒtƒ@‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·Bƒoƒbƒtƒ@‚ðŽg—p‚µ‚È‚¢ƒRƒ}ƒ“ƒh‚ÌꇂÍANULL‚ðŽw’肵‚Ü‚·B
+
+
+ +
+

–ß‚è’l

+
+
RES_OK (0)
+
³íI—¹B
+
RES_ERROR
+
‰½‚ç‚©‚̃Gƒ‰[‚ª”­¶‚µ‚½B
+
RES_PARERR
+
ƒRƒ}ƒ“ƒh‚ª•s³B
+
RES_NOTRDY
+
ƒhƒ‰ƒCƒu‚ª“®ì‰Â”\ó‘Ô‚Å‚Í‚È‚¢A‚Ü‚½‚͉Šú‰»‚³‚ê‚Ä‚¢‚È‚¢B
+
+
+ +
+

‰ðà

+

•¨—ƒhƒ‰ƒCƒu‚ÌŽí—Þ‚É‚æ‚èƒTƒ|[ƒg‚³‚ê‚éƒRƒ}ƒ“ƒh‚͈قȂè‚Ü‚·‚ªAFatFsƒ‚ƒWƒ…[ƒ‹‚Å‚ÍAŽŸ‚̔ėpƒRƒ}ƒ“ƒh‚Ì‚ÝŽg—p‚µAƒhƒ‰ƒCƒu‚ÌŽí—ނɈˑ¶‚µ‚½§Œä‚Ís‚¢‚Ü‚¹‚ñB

+

‚±‚ÌŠÖ”‚̓Š[ƒhEƒIƒ“ƒŠ[\¬‚Å‚Í•K—v‚Æ‚³‚ê‚Ü‚¹‚ñB

+ + + + + + +
ƒRƒ}ƒ“ƒh‰ðà
CTRL_SYNCƒhƒ‰ƒCƒu‚ªƒf[ƒ^‚Ì‘‚«ž‚݈—‚ðŠ®—¹‚·‚é‚Ì‚ð‘Ò‚¿‚Ü‚·B‚Ü‚½Aƒ‰ƒCƒgEƒoƒbƒNEƒLƒƒƒbƒVƒ…‚ª‘¶Ý‚·‚éꇂÍA‘‚«ž‚Ü‚ê‚Ä‚¢‚È‚¢ƒf[ƒ^‚𑦎ž‘‚«–ß‚µ‚Ü‚·B
GET_SECTOR_SIZEBuffer‚ÌŽw‚·WORD•Ï”‚Ƀhƒ‰ƒCƒu‚̃ZƒNƒ^EƒTƒCƒY‚ð•Ô‚µ‚Ü‚·BƒZƒNƒ^ƒTƒCƒY‚ªŒÅ’è(_MAX_SS‚ª512)‚Ì‚Æ‚«‚Í‚±‚̃Rƒ}ƒ“ƒh‚Í•K—v‚ ‚è‚Ü‚¹‚ñB
GET_SECTOR_COUNTBuffer‚ÌŽw‚·DWORD•Ï”‚Ƀhƒ‰ƒCƒuã‚Ì‘ƒZƒNƒ^”‚ð•Ô‚µ‚Ü‚·Bf_mkfsŠÖ”“à‚Å쬂·‚éƒ{ƒŠƒ…[ƒ€‚̃TƒCƒY‚ðŒˆ’è‚·‚邽‚ß‚ÉŽg—p‚³‚ê‚Ü‚·B
GET_BLOCK_SIZEƒtƒ‰ƒbƒVƒ…Eƒƒ‚ƒŠEƒAƒŒ[‚ÌÁ‹ŽƒuƒƒbƒNEƒTƒCƒY‚ª•ª‚©‚éꇂÍABuffer‚ÌŽw‚·DWORD•Ï”‚É‚»‚ê‚ðƒZƒNƒ^’PˆÊ‚Å•Ô‚µ‚Ü‚·B1‚©‚ç32768‚Å‚©‚Â2‚Ì—Ýæ‚Ì’l‚Å‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñBf_mkfsŠÖ”“à‚Å‚Ì‚ÝŽg—p‚³‚êAƒf[ƒ^—̈æ‚Í‚±‚Ì‹«ŠE‚ɃAƒ‰ƒCƒƒ“ƒg‚³‚ê‚Ü‚·B•s–¾‚Èꇂ܂½‚̓fƒBƒXƒNEƒhƒ‰ƒCƒu‚Å‚Í1‚ð•Ô‚µ‚Ü‚·B
+
+ + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/dread.html b/Lib/Fat/doc/ja/dread.html new file mode 100644 index 0000000..25cd0c1 --- /dev/null +++ b/Lib/Fat/doc/ja/dread.html @@ -0,0 +1,59 @@ + + + + + + + + +FatFs - disk_read + + + + +
+

disk_read

+

ƒfƒBƒXƒN‚©‚çƒZƒNƒ^‚ð“Ç‚Ýo‚µ‚Ü‚·B

+
+DRESULT disk_read (
+  BYTE Drive,          /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+  BYTE* Buffer,        /* “Ç‚Ýo‚µƒoƒbƒtƒ@‚ւ̃|ƒCƒ“ƒ^ */
+  DWORD SectorNumber,  /* “Ç‚Ýo‚µŠJŽnƒZƒNƒ^”Ô† */
+  BYTE SectorCount     /* “Ç‚Ýo‚µƒZƒNƒ^” */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
•¨—ƒhƒ‰ƒCƒu”Ô†(0-9)‚ðŽw’肵‚Ü‚·B
+
Buffer
+
ƒfƒBƒXƒN‚©‚ç“Ç‚Ýo‚µ‚½ƒf[ƒ^‚ðŠi”[‚·‚éƒoƒCƒg”z—ñ‚ÅA“Ç‚Ýo‚³‚ê‚éƒoƒCƒg”•ª‚̃TƒCƒY‚ª•K—v‚Å‚·BƒAƒhƒŒƒX‚̓Aƒ‰ƒCƒƒ“ƒg‚³‚ê‚Ä‚¢‚é‚Æ‚ÍŒÀ‚è‚Ü‚¹‚ñB
+
SectorNumber
+
“Ç‚Ýo‚µ‚ðŠJŽn‚·‚éƒZƒNƒ^”Ô†BLBA‚ÅŽw’肵‚Ü‚·B
+
SectorCount
+
“Ç‚Ýo‚·ƒZƒNƒ^”B 1`255‚͈̔͂Åݒ肵‚Ü‚·
+
+
+ + +
+

–ß‚è’l

+
+
RES_OK (0)
+
³íI—¹B
+
RES_ERROR
+
“Ç‚Ýž‚Ý’†‚ɃGƒ‰[‚ª”­¶‚µA‚»‚̉ñ•œ‚É‚àŽ¸”s‚µ‚½B
+
RES_PARERR
+
ƒpƒ‰ƒ[ƒ^‚ª•s³B
+
RES_NOTRDY
+
ƒhƒ‰ƒCƒu‚ª“®ì‰Â”\ó‘Ô‚Å‚Í‚È‚¢i‰Šú‰»‚³‚ê‚Ä‚¢‚È‚¢jB
+
+
+ + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/dstat.html b/Lib/Fat/doc/ja/dstat.html new file mode 100644 index 0000000..bd3f323 --- /dev/null +++ b/Lib/Fat/doc/ja/dstat.html @@ -0,0 +1,48 @@ + + + + + + + + +FatFs - disk_status + + + + +
+

disk_status

+

ƒfƒBƒXƒNEƒhƒ‰ƒCƒu‚Ìó‘Ô‚ðŽæ“¾‚µ‚Ü‚·B

+
+DSTATUS disk_status (
+  BYTE Drive           /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
ƒXƒe[ƒ^ƒX‚ðŽæ“¾‚·‚镨—ƒhƒ‰ƒCƒu”Ô†‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+

•¨—ƒhƒ‰ƒCƒu‚Ìó‘Ô‚ªŽŸ‚̃tƒ‰ƒO‚Ì‘g‚݇‚킹‚Ì’l‚Å•Ô‚³‚ê‚Ü‚·B

+
+
STA_NOINIT
+
ƒhƒ‰ƒCƒu‚ª‰Šú‰»‚³‚ê‚Ä‚¢‚È‚¢‚±‚Æ‚ðŽ¦‚·ƒtƒ‰ƒOBƒVƒXƒeƒ€EƒŠƒZƒbƒg‚⃃fƒBƒA‚ÌŽæ‚èŠO‚µ“™‚ŃZƒbƒg‚³‚êAdisk_initialize() ‚̳íI—¹‚ŃNƒŠƒAAŽ¸”s‚ŃZƒbƒg‚³‚ê‚Ü‚·B
+
STA_NODISK
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚±‚Æ‚ðŽ¦‚·ƒtƒ‰ƒOBƒƒfƒBƒA‚ªŽæ‚èŠO‚³‚ê‚Ä‚¢‚éŠÔ‚̓Zƒbƒg‚³‚êAƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚éŠÔ‚̓NƒŠƒA‚³‚ê‚Ü‚·BŒÅ’èƒfƒBƒXƒN‚Å‚Íí‚ɃNƒŠƒA‚³‚ê‚Ä‚¢‚Ü‚·B
+
STA_PROTECTED
+
ƒƒfƒBƒA‚ªƒ‰ƒCƒgEƒvƒƒeƒNƒg‚³‚ê‚Ä‚¢‚邱‚Æ‚ðŽ¦‚·ƒtƒ‰ƒOBƒ‰ƒCƒgEƒvƒƒeƒNƒg‹@”\‚ðƒTƒ|[ƒg‚µ‚È‚¢ƒƒfƒBƒA‚Å‚Íí‚ɃNƒŠƒA‚³‚ê‚Ä‚¢‚Ü‚·B
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/dwrite.html b/Lib/Fat/doc/ja/dwrite.html new file mode 100644 index 0000000..527f604 --- /dev/null +++ b/Lib/Fat/doc/ja/dwrite.html @@ -0,0 +1,67 @@ + + + + + + + + +FatFs - disk_write + + + + +
+

disk_write

+

ƒfƒBƒXƒN‚Ƀf[ƒ^‚ð‘‚«ž‚Ý‚Ü‚·B

+
+DRESULT disk_write (
+  BYTE Drive,          /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+  const BYTE* Buffer,  /* ‘‚«ž‚Þƒf[ƒ^‚ւ̃|ƒCƒ“ƒ^ */
+  DWORD SectorNumber,  /* ‘‚«ž‚ÝŠJŽnƒZƒNƒ^”Ô† */
+  BYTE SectorCount     /* ‘‚«ž‚݃ZƒNƒ^” */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
•¨—ƒhƒ‰ƒCƒu”Ô†(0-9)‚ðŽw’肵‚Ü‚·B
+
Buffer
+
ƒfƒBƒXƒN‚É‘‚«ž‚ÞƒoƒCƒg”z—ñ‚ðŽw’肵‚Ü‚·BƒAƒhƒŒƒX‚̓Aƒ‰ƒCƒƒ“ƒg‚³‚ê‚Ä‚¢‚é‚Æ‚ÍŒÀ‚è‚Ü‚¹‚ñB
+
SectorNumber
+
‘‚«ž‚Ý‚ðŠJŽn‚·‚éƒZƒNƒ^”Ô†BLBA‚ÅŽw’肵‚Ü‚·B
+
SectorCount
+
‘‚«ž‚ÞƒZƒNƒ^”B 1`255‚Åݒ肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
RES_OK (0)
+
³íI—¹B
+
RES_ERROR
+
‘‚«ž‚Ý’†‚ɃGƒ‰[‚ª”­¶‚µA‚»‚̉ñ•œ‚É‚àŽ¸”s‚µ‚½B
+
RES_WRPRT
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
RES_PARERR
+
ƒpƒ‰ƒ[ƒ^‚ª•s³B
+
RES_NOTRDY
+
ƒhƒ‰ƒCƒu‚ª“®ì‰Â”\ó‘Ô‚Å‚Í‚È‚¢i‰Šú‰»‚³‚ê‚Ä‚¢‚È‚¢jB
+
+
+ + +
+

‰ðà

+

ƒŠ[ƒhEƒIƒ“ƒŠ[\¬‚Å‚Í‚±‚ÌŠÖ”‚Í•K—v‚Æ‚³‚ê‚Ü‚¹‚ñB

+
+ + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/fattime.html b/Lib/Fat/doc/ja/fattime.html new file mode 100644 index 0000000..f9a1f94 --- /dev/null +++ b/Lib/Fat/doc/ja/fattime.html @@ -0,0 +1,51 @@ + + + + + + + + +FatFs - get_fattime + + + + +
+

get_fattime

+

Œ»ÝŽž‚ðŽæ“¾‚µ‚Ü‚·B

+
+DWORD get_fattime (void);
+
+
+ + +
+

–ß‚è’l

+

Œ»Ý‚̃[ƒJƒ‹Eƒ^ƒCƒ€‚ªDWORD’l‚ɃpƒbƒN‚³‚ê‚Ä•Ô‚³‚ê‚Ü‚·BƒrƒbƒgEƒtƒB[ƒ‹ƒh‚ÍŽŸ‚ÉŽ¦‚·‚悤‚É‚È‚è‚Ü‚·B

+
+
bit31:25
+
1980”N‚ð‹N“_‚Æ‚µ‚½”N‚ª 0..127 ‚Å“ü‚è‚Ü‚·B
+
bit24:21
+
ŒŽ‚ª 1..12 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit20:16
+
“ú‚ª 1..31 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit15:11
+
Žž‚ª 0..23 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit10:5
+
•ª‚ª 0..59 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit4:0
+
•b/2‚ª 0..29 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
+
+ + +
+

‰ðà

+

RTC‚ðƒTƒ|[ƒg‚µ‚È‚¢ƒVƒXƒeƒ€‚Å‚àA‰½‚ç‚©‚Ì“ú•t‚Æ‚µ‚Ä—LŒø‚È’l‚ð•Ô‚³‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB0‚ð•Ô‚µ‚½ê‡A‚»‚̃tƒ@ƒCƒ‹‚Í“ú•t‚ðŽ‚¿‚Ü‚¹‚ñBƒŠ[ƒhEƒIƒ“ƒŠ[\¬‚Å‚Í‚±‚ÌŠÖ”‚Í•K—v‚Æ‚³‚ê‚Ü‚¹‚ñB

+
+ + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/filename.html b/Lib/Fat/doc/ja/filename.html new file mode 100644 index 0000000..3226ecc --- /dev/null +++ b/Lib/Fat/doc/ja/filename.html @@ -0,0 +1,72 @@ + + + + + + + + +FatFs - ファイル・ディレクトリã®æŒ‡å®šæ–¹æ³• + + + +
+

ファイル・ディレクトリã®æŒ‡å®šæ–¹æ³•

+

FatFsモジュールã§ã®ãƒ•ã‚¡ã‚¤ãƒ«ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ãƒ‰ãƒ©ã‚¤ãƒ–ã®æŒ‡å®šæ–¹æ³•ã¯DOS/Windowsã¨ã»ã¼åŒã˜ã§ã™ã€‚パスåã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã¯æ¬¡ã®é€šã‚Šã§ã™ã€‚

+

"[è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–番å·:][/]ディレクトリå/ファイルå"

+

FatFsモジュールã¯é•·ã„ファイルå(LFN)ãŠã‚ˆã³8.3å½¢å¼ãƒ•ã‚¡ã‚¤ãƒ«å(SFN)ã«å¯¾å¿œã—ã¦ã„ã¾ã™ã€‚LFNã¯ã€(_USE_LFN > 0)ã®ã¨ã使用å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚DOS/Windowsã¨ã®é•ã„ã¯ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ»ã‚»ãƒ‘レータã¨è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–番å·ã®æŒ‡å®šã§ã™ã€‚ディレクトリ・セパレータã«ã¯ / ã¾ãŸã¯ \ を使用ã—ã¾ã™ã€‚è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–番å·ã¯ã€'0'~'9'ã®ä¸€æ–‡å­—ã®æ•°å­—ã¨ã‚³ãƒ­ãƒ³ã§æŒ‡å®šã—ã€çœç•¥ã—ãŸå ´åˆã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ»ãƒ‰ãƒ©ã‚¤ãƒ–(0ã¾ãŸã¯ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‰ãƒ©ã‚¤ãƒ–)ãŒé¸æŠžã•ã‚Œã¾ã™ã€‚

+

Nul文字ã¨åˆ¶å¾¡æ–‡å­—(\0~\x1F)ã¯ã€ãƒ‘スåã®çµ‚端ã¨ã—ã¦èªè­˜ã•ã‚Œã¾ã™ã€‚パスåã«å…ˆè¡Œã‚ã‚‹ã„ã¯ä¸­ã«å«ã¾ã‚Œã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã¯ã€LFN構æˆã§ã¯åå‰ã®ä¸€éƒ¨ã¨ã—ã¦æœ‰åŠ¹ã§ã™ãŒã€éžLFN構æˆã§ã¯ãƒ‘スåã®çµ‚端ã¨ã—ã¦èªè­˜ã•ã‚Œã¾ã™ã€‚

+

標準構æˆ(_FS_RPATH == 0)ã®ã¨ãã¯ã€å…¨ã¦ã®ã‚ªãƒ–ジェクトãŒãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰è¾¿ã‚‹çµ¶å¯¾ãƒ‘スã§æŒ‡å®šã•ã‚Œã¾ã™ã€‚OS指å‘ãªã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ã„ã†æ¦‚念ã¯ç„¡ãã€ã¾ãŸãƒ‰ãƒƒãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª("."ã‚„"..")ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。パスå先頭ã®ã‚»ãƒ‘レータã¯ç„¡è¦–ã•ã‚Œã¾ã™ã€‚デフォルト・ドライブ番å·ã¯å¸¸ã«0ã«ãªã‚Šã¾ã™ã€‚

+

相対パスを有効(_FS_RPATH == 1)ã«ã—ãŸã¨ãã¯ã€å…ˆè¡Œã™ã‚‹ã‚»ãƒ‘レータã®æœ‰ç„¡ã«ã‚ˆã£ã¦æ¤œç´¢é–‹å§‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå¤‰ã‚ã‚Šã€ã‚»ãƒ‘レータãŒã‚ã‚‹å ´åˆã¯ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰ã€ç„¡ã„å ´åˆã¯f_chdir関数ã§è¨­å®šã•ã‚Œã‚‹ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰ã«ãªã‚Šã¾ã™ã€‚ã¾ãŸãƒ‘スåã«ãƒ‰ãƒƒãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒä½¿ç”¨ã§ãã¾ã™ã€‚デフォルト・ドライブ番å·ã¯f_chdrive関数ã§è¨­å®šã•ã‚ŒãŸå€¤ã¨ãªã‚Šã¾ã™ã€‚

+ + + + + + + + + + + + + +
パスå_FS_RPATH == 0_FS_RPATH == 1
file.txtドライブ0ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‰ãƒ©ã‚¤ãƒ–ã®ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«
/file.txtドライブ0ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‰ãƒ©ã‚¤ãƒ–ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«
ドライブ0ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‰ãƒ©ã‚¤ãƒ–ã®ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
2:ドライブ2ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ‰ãƒ©ã‚¤ãƒ–2ã®ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
2:file1.txtドライブ2ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‰ãƒ©ã‚¤ãƒ–2ã®ã‚«ãƒ¬ãƒ³ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«
2:/ドライブ2ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ‰ãƒ©ã‚¤ãƒ–2ã®ãƒ«ãƒ¼ãƒˆãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
../file.txt無効親ディレクトリ下ã®ãƒ•ã‚¡ã‚¤ãƒ«
.無効ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
..無効カレント・ディレクトリã®è¦ªãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
dir1/..無効カレント・ディレクトリ
/..無効ルート・ディレクトリ(ãã®ä¸Šã¯è¾¿ã‚Œãªã„)
+
+ +


+
+

Unicode API

+

ファイル関数ã®å…¥å‡ºåŠ›ã®ã†ã¡ãƒ•ã‚¡ã‚¤ãƒ«åやパスåを指定ã™ã‚‹å¼•æ•°ã®åž‹ã¯ã€TCHARã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ãŒã€ã“ã‚Œã¯charã®ã‚¨ãƒªã‚¢ã‚¹ã«ãªã£ã¦ã„ã¾ã™ã€‚ãã—ã¦ã€_CODE_PAGEã§æŒ‡å®šã•ã‚Œã‚‹ ANSI/OEMコード(SBCSã¾ãŸã¯DBCS)ã®æ–‡å­—列ã¨ã—ã¦æ‰±ã‚ã‚Œã¾ã™ã€‚ファイルå入出力をUnicodeã¨ã™ã‚‹æ§‹æˆ(LFN構æˆã§ã€ã‹ã¤_LFN_UNICODEã‚’ 1)ã«ã—ãŸã¨ãã¯ã€TCHARã¯ãƒ¯ã‚¤ãƒ‰æ–‡å­—(unsigned short)ã«åˆ‡ã‚Šæ›¿ã‚ã‚Šã€ãƒ‘スåã«Unicodeを使用ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚Š LFNフル対応ã¨ãªã‚Šã€ANSI/OEMコードã«ãªã„文字(ãŸã¨ãˆã° âœâ˜ªâœ¡â˜¸â˜­ãªã©)も使用ã§ãã¾ã™ã€‚ã“ã®è¨­å®šã¯æ–‡å­—列入出力関数ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¨ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã«ã‚‚影響を与ãˆã¾ã™ã€‚リテラル文字列を定義ã™ã‚‹ã¨ãã€æ¬¡ã«ç¤ºã™ã‚ˆã†ã«_T(s)ãŠã‚ˆã³_TEXT(s)マクロを使ã£ã¦ANSI/OEMã¨Unicodeを自動切り替ãˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚

+
+ f_open(fp, "filename.txt", FA_READ);      /* ANSI/OEM専用コード */
+ f_open(fp, L"filename.txt", FA_READ);     /* Unicode専用コード */
+ f_open(fp, _T("filename.txt"), FA_READ);  /* 両用コード */
+
+
+ +


+
+

è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–(ボリューム)ã¨ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–(ディスク装置)ã®å¯¾å¿œ

+

デフォルトã®æ§‹æˆã§ã¯ã€ãã‚Œãžã‚Œã®è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã¯åŒã˜ç•ªå·ã®ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã«1:1ã§çµã³ã¤ã‘られã¦ã„ã¦ã€ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã®å…ˆé ­ã®åŒºç”»ã«ã‚るボリュームãŒãƒžã‚¦ãƒ³ãƒˆã•ã‚Œã¾ã™ã€‚_MULTI_PARTITIONã« 1を指定ã™ã‚‹ã¨ã€å€‹ã€…ã®è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã«å¯¾ã—ã¦å€‹åˆ¥ã«ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–番å·ãƒ»åŒºç”»ã‚’指定ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ã“ã®æ§‹æˆã§ã¯ã€è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã¨åŒºç”»ã®å¯¾å¿œã‚’解決ã™ã‚‹ãŸã‚ã®ãƒ†ãƒ¼ãƒ–ルを次ã«ç¤ºã™ã‚ˆã†ã«å®šç¾©ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚

+
+例:è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–0~2を物ç†ãƒ‰ãƒ©ã‚¤ãƒ–0(固定ディスク)ã®3ã¤ã®åŸºæœ¬åŒºç”»ã«å‰²ã‚Šå½“ã¦ã€
+   è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–3を物ç†ãƒ‰ãƒ©ã‚¤ãƒ–1(リムーãƒãƒ–ル・ディスク)ã«å‰²ã‚Šå½“ã¦ã‚‹å ´åˆã€‚
+
+const PARTITION Drives[] = {
+    {0, 0},     /* Logical drive 0 ==> Physical drive 0, 1st partition */
+    {0, 1},     /* Logical drive 1 ==> Physical drive 0, 2nd partition */
+    {0, 2},     /* Logical drive 2 ==> Physical drive 0, 3rd partition */
+    {1, 0}      /* Logical drive 3 ==> Physical drive 1 */
+};
+
+

複数区画指定を使用ã™ã‚‹å ´åˆã€æ¬¡ã®ç‚¹ã«æ³¨æ„ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。 +

    +
  • 指定å¯èƒ½ãªåŒºç”»ã¯åŸºæœ¬åŒºç”»(0~3)ã®ã¿ã€‚
  • +
  • 物ç†ãƒ‰ãƒ©ã‚¤ãƒ–ãŒSFDå½¢å¼(区画テーブル無ã—)ã®å ´åˆã€åŒºç”»æŒ‡å®šã¯ç„¡è¦–ã•ã‚Œã‚‹ã€‚
  • +
  • 複数ã®è«–ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã‚’æŒã¤ç‰©ç†ãƒ‰ãƒ©ã‚¤ãƒ–ã¯ã€å›ºå®šãƒ‡ã‚£ã‚¹ã‚¯ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。
  • +
+
+ + + diff --git a/Lib/Fat/doc/ja/forward.html b/Lib/Fat/doc/ja/forward.html new file mode 100644 index 0000000..fc50f5f --- /dev/null +++ b/Lib/Fat/doc/ja/forward.html @@ -0,0 +1,145 @@ + + + + + + + + +FatFs - f_forward + + + + +
+

f_forward

+

ƒtƒ@ƒCƒ‹‚©‚çƒf[ƒ^‚ð“Ç‚Ýo‚µA‘—MƒXƒgƒŠ[ƒ€‚É’¼Ú“]‘—‚µ‚Ü‚·B

+
+FRESULT f_forward (
+  FIL* FileObject,                 /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘Ì */
+  UINT (*Func)(const BYTE*,UINT),  /* ƒf[ƒ^“]‘—ŠÖ” */
+  UINT ByteToFwd,                  /* “]‘—‚·‚éƒoƒCƒg” */
+  UINT* ByteFwd                    /* “]‘—‚³‚ꂽƒoƒCƒg” */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Func
+
ƒf[ƒ^‚ð“n‚·ƒ†[ƒU’è‹`ŠÖ”‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B‚±‚ÌŠÖ”‚ÌŽd—l‚̓Tƒ“ƒvƒ‹‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B
+
ByteToRead
+
“]‘—‚·‚éƒoƒCƒg”(0`UINT‚ÌÅ‘å’l)‚ðŽw’肵‚Ü‚·B
+
ByteRead
+
ŽÀÛ‚É“]‘—‚³‚ꂽƒoƒCƒg”‚ðŠi”[‚·‚é•Ï”‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DENIED
+
”ñ“Ç‚Ýž‚݃‚[ƒh‚ÅŠJ‚¢‚½ƒtƒ@ƒCƒ‹‚©‚ç“Ç‚Ýž‚à‚¤‚Æ‚µ‚½B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚̃f[ƒ^‚ðƒoƒbƒtƒ@‚É“Ç‚Ýo‚³‚¸‚É‘—MƒXƒgƒŠ[ƒ€‚É’¼Ú“]‘—‚µ‚Ü‚·BƒAƒvƒŠƒP[ƒVƒ‡ƒ“‘¤‚Ńf[ƒ^Eƒoƒbƒtƒ@‚ð•K—v‚Æ‚µ‚È‚¢‚Ì‚ÅAƒƒ‚ƒŠ‚ÌŒÀ‚ç‚ꂽŠÂ‹«‚Å—LŒø‚Å‚·B“]‘—ŠJŽnˆÊ’u‚ÍAŒ»Ý‚̃tƒ@ƒCƒ‹R/Wƒ|ƒCƒ“ƒ^‚©‚ç‚É‚È‚è‚Ü‚·Bƒtƒ@ƒCƒ‹R/Wƒ|ƒCƒ“ƒ^‚Í“]‘—‚³‚ꂽƒoƒCƒg”‚¾‚¯i‚Ý‚Ü‚·BŽw’肳‚ꂽƒoƒCƒg”‚Ì“]‘—’†‚Ƀtƒ@ƒCƒ‹‚ÌI’[‚É’B‚µ‚½ê‡‚â‘—MƒXƒgƒŠ[ƒ€‚ªƒrƒW[‚É‚È‚Á‚½ê‡A*ByteFwd‚ÍByteToFwd‚æ‚è‚ଂ³‚­‚È‚è‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_USE_FORWARD == 1‚ÅAŠŽ‚Â_FS_TINY == 1‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—áiƒI[ƒfƒBƒIĶj

+
+/*-----------------------------------------------------------------------*/
+/* f_forwardŠÖ”‚©‚çŒÄ‚΂ê‚éƒf[ƒ^‘—MŠÖ”‚Ì—á                           */
+/*-----------------------------------------------------------------------*/
+
+UINT out_stream (   /* –ß‚è’l: “]‘—‚³‚ꂽƒoƒCƒg”‚Ü‚½‚̓XƒgƒŠ[ƒ€‚Ìó‘Ô */
+    const BYTE *p,  /* “]‘—‚·‚éƒf[ƒ^‚ðŽw‚·ƒ|ƒCƒ“ƒ^ */
+    UINT btf        /* >0: “]‘—‚ðs‚¤(ƒoƒCƒg”). 0: ƒXƒgƒŠ[ƒ€‚Ìó‘Ԃ𒲂ׂé */
+)
+{
+    UINT cnt = 0;
+
+
+    if (btf == 0) {     /* ƒZƒ“ƒX—v‹ */
+        /* ƒXƒgƒŠ[ƒ€‚Ìó‘Ô‚ð•Ô‚· (0: ƒrƒW[, 1: ƒŒƒfƒB) */
+        /* ˆê’UAƒŒƒfƒB‚ð•Ô‚µ‚½‚çA‘±‚­“]‘——v‹‚Å­‚È‚­‚Æ‚à1ƒoƒCƒg‚Í */
+        /* “]‘—‚³‚ê‚È‚¢‚Æ f_forwardŠÖ”‚Í FR_RW_ERROR ‚Æ‚È‚éB */
+        if (FIFO_READY) cnt = 1;
+    }
+    else {              /* “]‘——v‹ */
+        do {    /* ‘S‚ẴoƒCƒg‚ð“]‘—‚·‚é‚©AƒXƒgƒŠ[ƒ€‚ªƒrƒW[‚É‚È‚é‚Ü‚ÅŒJ‚è•Ô‚· */
+            FIFO_PORT = *p++;
+            cnt++;
+        } while (cnt < btf && FIFO_READY);
+    }
+
+    return cnt;
+}
+
+
+/*-----------------------------------------------------------------------*/
+/* f_forwardŠÖ”‚ÌŽg—p—á                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT play_file (
+    char *fn        /* Ķ‚·‚éƒI[ƒfƒBƒIEƒtƒ@ƒCƒ‹–¼‚ðŽw‚·ƒ|ƒCƒ“ƒ^ */
+)
+{
+    FRESULT rc;
+    FIL fil;
+    UINT dmy;
+
+    /* ƒtƒ@ƒCƒ‹‚ð“Ç‚Ýo‚µƒ‚[ƒh‚ÅŠJ‚­ */
+    rc = f_open(&fil, fn, FA_READ);
+    if (rc) return rc;
+
+    /* ‘S‚Ẵf[ƒ^‚ª“]‘—‚³‚ê‚é‚©ƒGƒ‰[‚ª”­¶‚·‚é‚Ü‚Å‘±‚¯‚é */
+    while (rc == FR_OK && fil.fptr < fil.fsize) {
+
+        /* ‚Ù‚©‚̈—... */
+
+        /* ’èŠú“I‚Ü‚½‚Í—v‹‚ɉž‚¶‚ăf[ƒ^‚ðƒXƒgƒŠ[ƒ€‚É‘—o‚·‚é */
+        rc = f_forward(&fil, out_stream, 1000, &dmy);
+    }
+
+    /* ƒtƒ@ƒCƒ‹‚ð•Â‚¶‚Ä–ß‚é */
+    f_close(&fil);
+    return rc;	
+}
+
+
+ + +
+

ŽQÆ

+

f_open, fgets, f_write, f_close, FIL

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/getfree.html b/Lib/Fat/doc/ja/getfree.html new file mode 100644 index 0000000..4b9d99e --- /dev/null +++ b/Lib/Fat/doc/ja/getfree.html @@ -0,0 +1,102 @@ + + + + + + + + +FatFs - f_getfree + + + + +
+

f_getfree

+

˜_—ƒhƒ‰ƒCƒuã‚Ì–¢Žg—pƒNƒ‰ƒXƒ^”‚𓾂܂·B

+
+FRESULT f_getfree (
+  const TCHAR* Path,       /* ‘ÎÛƒhƒ‰ƒCƒu‚ðŽw’肵‚Ü‚· */
+  DWORD* Clusters,         /* ‹ó‚«ƒNƒ‰ƒXƒ^”‚ðŠi”[‚·‚é•Ï”‚ւ̃|ƒCƒ“ƒ^ */
+  FATFS** FileSystemObject /* ƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
Path
+
’²‚ׂé‘Îۂ̘_—ƒhƒ‰ƒCƒu‚ðŽ¦‚·ƒpƒX–¼‚ª“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Clusters
+
‹ó‚«ƒNƒ‰ƒXƒ^”‚ðŠi”[‚·‚éDWORD•Ï”‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
FileSystemObject
+
‘ÎÛƒhƒ‰ƒCƒu‚̃tƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ª•Ô‚³‚ê‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B*Clusters‚ɋ󂫃Nƒ‰ƒXƒ^”‚ª•Ô‚³‚ê‚Ü‚·B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

˜_—ƒhƒ‰ƒCƒuã‚̋󂫃Nƒ‰ƒXƒ^”‚ðŽæ“¾‚µ‚Ü‚·B•Ô‚³‚ꂽƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚Ìcsizeƒƒ“ƒo‚ªƒNƒ‰ƒXƒ^‚ ‚½‚è‚̃ZƒNƒ^”‚ðŽ¦‚µ‚Ä‚¢‚é‚Ì‚ÅA‚±‚ê‚ðŒ³‚ÉŽÀۂ̋󂫃TƒCƒY‚ªŒvŽZ‚Å‚«‚Ü‚·BFAT32ƒ{ƒŠƒ…[ƒ€‚É‚¨‚¢‚Ä‚ÍAFSINFOƒZƒNƒ^‚Ìó‘Ô‚É‚æ‚Á‚Ä‚Í•s³Šm‚È’l‚ð•Ô‚µ‚½‚èAˆ—‚ÉŽžŠÔ‚ª‚©‚©‚Á‚½‚è‚·‚é‰Â”\«‚ª‚ ‚è‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+    FATFS *fs;
+    DWORD fre_clust, fre_sect, tot_sect;
+
+
+    /* ƒhƒ‰ƒCƒu1‚̃{ƒŠƒ…[ƒ€î•ñ‚Ƌ󂫃Nƒ‰ƒXƒ^”‚𓾂é */
+    res = f_getfree("1:", &fre_clust, &fs);
+    if (res) die(res);
+
+    /* ‘SƒZƒNƒ^”‚Ƌ󂫃ZƒNƒ^”‚ðŒvŽZ */
+    tot_sect = (fs->max_clust - 2) * fs->csize;
+    fre_sect = fre_clust * fs->csize;
+
+    /* ƒhƒ‰ƒCƒuƒTƒCƒY‚Ƌ󂫃TƒCƒY‚Ì•\Ž¦ (512ƒoƒCƒg/ƒZƒNƒ^‚Ɖ¼’è) */
+    printf("%lu KB total drive space.\n"
+           "%lu KB available.\n",
+           fre_sect / 2, tot_sect / 2);
+
+
+ + +
+

ŽQÆ

+FATFS +
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/gets.html b/Lib/Fat/doc/ja/gets.html new file mode 100644 index 0000000..2dfcdf6 --- /dev/null +++ b/Lib/Fat/doc/ja/gets.html @@ -0,0 +1,65 @@ + + + + + + + + +FatFs - f_gets + + + + +
+

f_gets

+

ƒtƒ@ƒCƒ‹‚©‚當Žš—ñ‚ð“Ç‚Ýo‚µ‚Ü‚·B

+
+TCHAR* f_gets (
+  TCHAR* Str,       /* ƒoƒbƒtƒ@ */
+  int Size,         /* ƒoƒbƒtƒ@‚̃TƒCƒY */
+  FIL* FileObject   /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+);
+
+
+ +
+

ˆø”

+
+
Str
+
•¶Žš—ñ‚ð“Ç‚Ýo‚·ƒoƒbƒtƒ@‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Size
+
ƒoƒbƒtƒ@‚̃TƒCƒY‚ð—v‘f”‚ÅŽw’肵‚Ü‚·B
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+

ŠÖ”‚ª¬Œ÷‚·‚é‚ÆStr‚ª•Ô‚³‚ê‚Ü‚·B

+
+ + +
+

‰ðà

+

‚±‚ÌŠÖ”‚Íf_read()‚̃‰ƒbƒp[ŠÖ”‚Å‚·B“Ç‚Ýo‚µ“®ì‚ÍAʼn‚Ì'\n'‚ð“Ç‚Ýž‚Þ‚©Aƒtƒ@ƒCƒ‹I’[‚É’B‚·‚é‚©ASize - 1•¶Žš‚ð“Ç‚Ýo‚·‚Ü‚Å‘±‚«‚Ü‚·B“Ç‚Ýž‚܂ꂽ•¶Žš—ñ‚ÌI’[‚É‚Í'\0'‚ª•t‰Á‚³‚ê‚Ü‚·BŠù‚Ƀtƒ@ƒCƒ‹I’[‚Å1•¶Žš‚à“Ç‚Ýž‚Ü‚ê‚È‚©‚Á‚½‚Æ‚«A‚Ü‚½‚͉½‚ç‚©‚̃Gƒ‰[‚ª”­¶‚µ‚½‚Æ‚«‚ÍŠÖ”‚ÍŽ¸”s‚µƒkƒ‹Eƒ|ƒCƒ“ƒ^‚ð•Ô‚µ‚Ü‚·Bƒtƒ@ƒCƒ‹I’[‚©ƒGƒ‰[‚©‚Íf_eof(),f_error()ƒ}ƒNƒ‚Å’²‚ׂç‚ê‚Ü‚·B

+

API‚ÉUnicode‚ª‘I‘ð‚³‚ê‚Ä‚¢‚é(_LFN_UNICODE‚ª1)‚Æ‚«‚ÍAUTF-8ƒGƒ“ƒR[ƒh‚̃eƒLƒXƒgEƒtƒ@ƒCƒ‹‚Æ‚µ‚ÄUCS-2‚É•ÏŠ·‚µ‚ăoƒbƒtƒ@‚É“Ç‚Ýž‚Ý‚Ü‚·B‚»‚êˆÈŠO‚ÌŽž‚Í–³•ÏŠ·(1•¶Žš1ƒoƒCƒg)‚Å“Ç‚Ýž‚Ý‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_USE_STRFUNC‚ª 1‚Ü‚½‚Í 2‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B2‚Ì‚Æ‚«‚ÍAƒtƒ@ƒCƒ‹‚ÉŠÜ‚Ü‚ê‚é'\r'‚ªŽæ‚蜂©‚ê‚ăoƒbƒtƒ@‚É“Ç‚Ýž‚Ü‚ê‚Ü‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/lseek.html b/Lib/Fat/doc/ja/lseek.html new file mode 100644 index 0000000..fe5c88b --- /dev/null +++ b/Lib/Fat/doc/ja/lseek.html @@ -0,0 +1,127 @@ + + + + + + + + +FatFs - f_lseek + + + + +
+

f_lseek

+

ƒtƒ@ƒCƒ‹‚̃Š[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚ðˆÚ“®‚µ‚Ü‚·B

+
+FRESULT f_lseek (
+  FIL* FileObject,    /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+  DWORD Offset        /* ˆÚ“®æƒIƒtƒZƒbƒg */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
‘ÎÛ‚Æ‚È‚éƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Offset
+
ˆÚ“®æ‚̃IƒtƒZƒbƒgiƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^j’lBƒtƒ@ƒCƒ‹æ“ª‚©‚ç‚̃IƒtƒZƒbƒg‚ðƒoƒCƒg’PˆÊ‚ÅŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒgB
+
FR_NOT_ENOUGH_CORE
+
ƒŠƒ“ƒNEƒ}ƒbƒvEƒe[ƒuƒ‹‚̃TƒCƒY‚ª•s‘«B
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚̃Š[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^(ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg“à‚Ìfptrƒƒ“ƒo‚ÅAŽŸ‚É“Ç‚Ýo‚µE‘‚«ž‚Ý‚³‚ê‚éƒoƒCƒg‚̃IƒtƒZƒbƒg‚ðŽ¦‚·)‚ðˆÚ“®‚µ‚Ü‚·BƒIƒtƒZƒbƒg‚ÌŒ´“_‚̓tƒ@ƒCƒ‹æ“ª‚Å‚·B‘‚«ž‚݃‚[ƒh‚Ńtƒ@ƒCƒ‹EƒTƒCƒY‚æ‚è‘å‚«‚È’l‚ðŽw’è‚·‚é‚ÆA‚»‚±‚܂Ńtƒ@ƒCƒ‹EƒTƒCƒY‚ªŠg’£‚³‚êAŠg’£‚³‚ꂽ•”•ª‚̃f[ƒ^‚Í–¢’è‹`‚Æ‚È‚è‚Ü‚·Bƒf[ƒ^‚ð’x‰„–³‚­‚‘¬‚É‘‚«ž‚Ý‚½‚¢‚Æ‚«‚ÍA—\‚ß‚±‚ÌŠÖ”‚Å•K—v‚ȃTƒCƒY‚܂Ńtƒ@ƒCƒ‹EƒTƒCƒY‚ðŠg’£‚µ‚Ä‚¨‚­‚Æ—Ç‚¢‚Å‚µ‚傤Bf_lseekŠÖ”‚ª³íI—¹‚µ‚½‚ ‚Æ‚ÍAƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚ª³‚µ‚­ˆÚ“®‚µ‚½‚©fptr‚ðƒ`ƒFƒbƒN‚·‚é‚ׂ«‚Å‚·BƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚ªŽw’è‚æ‚謂³‚¢‚Æ‚«‚ÍAŽŸ‚ÌŒ´ˆö‚ªl‚¦‚ç‚ê‚Ü‚·B

+
    +
  • ”ñ‘‚«ž‚݃‚[ƒh‚Ü‚½‚Í‚‘¬ƒV[ƒNEƒ‚[ƒh‚Ì‚½‚ßAƒtƒ@ƒCƒ‹EƒTƒCƒY‚ŃNƒŠƒbƒv‚³‚ꂽB
  • +
  • ƒtƒ@ƒCƒ‹Šg’£’†‚ɃfƒBƒXƒN‚ª–ž”t‚É‚È‚Á‚½B
  • +
+

_USE_FASTSEEK‚É1‚ªŽw’肳‚ê‚Ä‚¢‚ÄAŠŽ‚ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚Ìcltblƒƒ“ƒo‚ªNULLˆÈŠO‚Ì‚Æ‚«A‚‘¬ƒV[ƒNEƒ‚[ƒh‚É‚È‚è‚Ü‚·B‚±‚ê‚̓tƒ@ƒCƒ‹‚̃Nƒ‰ƒXƒ^î•ñ‚ðƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚ÌŽw’肵‚½”z—ñ‚É•ÛŽ‚µ‚Ä‚¨‚­‚±‚Æ‚É‚æ‚èAFAT‚ɃAƒNƒZƒX‚·‚邱‚Æ‚È‚­Œã•ûƒV[ƒN‚⃃“ƒOEƒV[ƒN‚ð‚‘¬‚És‚¤‹@”\‚Å‚·B‚‘¬ƒV[ƒN“®ì‚ðs‚¤‘O‚É‚ÍA”z—ñ‚ð‰Šú‰»‚µ‚Ä‚¨‚­•K—v‚ª‚ ‚è‚Ü‚·B•K—v‚È”z—ñƒTƒCƒY(—v‘f”)‚ÍA(ƒtƒ@ƒCƒ‹‚Ì•ªŠ„” + 1) * 2 ‚Å‚·B‚½‚Æ‚¦‚ÎAƒtƒ@ƒCƒ‹‚ª5‚‚ɕª’f‚³‚ê‚Ä‚¢‚é‚Æ‚«‚É•K—v‚È”z—ñƒTƒCƒY‚ÍA12—v‘f‚Æ‚È‚è‚Ü‚·B‚‘¬ƒV[ƒNŽg—pŽž‚̓tƒ@ƒCƒ‹EƒTƒCƒY‚ÌŠg’£‚Í‚Å‚«‚Ü‚¹‚ñB

+
+ + +
+

‘Ήžî•ñ

+

_FS_MINIMIZE < 3‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+    /* ƒtƒ@ƒCƒ‹EƒIƒtƒZƒbƒg5000‚ÖˆÚ“® */
+    res = f_lseek(&file, 5000, 0);
+
+    /* ƒtƒ@ƒCƒ‹’Ç‹L‚Ì€”õ (ƒtƒ@ƒCƒ‹I’[‚ÖˆÚ“®) */
+    res = f_lseek(&file, file.fsize, 0);
+
+    /* 3000ƒoƒCƒgi‚ß‚é */
+    res = f_lseek(&file, file.fptr + 3000, 0);
+
+    /* 2000ƒoƒCƒg–ß‚· (ƒI[ƒo[ƒtƒ[‚É’ˆÓ) */
+    res = f_lseek(&file, file.fptr - 2000, 0);
+
+
+    /* ƒNƒ‰ƒXƒ^æsŠ„‚è“–‚Ä (ƒXƒgƒŠ[ƒ~ƒ“ƒOEƒ‰ƒCƒgŽž‚̃oƒbƒtƒ@EƒI[ƒo[ƒ‰ƒ“–hŽ~) */
+
+    res = f_open(&file, "record.wav", FA_CREATE_NEW | FA_WRITE); /* ƒtƒ@ƒCƒ‹ì¬ */
+
+    res = f_lseek(&file, MAX_SIZE, 0);     /* \•ª‚ȃNƒ‰ƒXƒ^‚ÌæsŠ„‚è“–‚Ä */
+    if (res || file.fptr != PRE_SIZE) .... /* ³‚µ‚­ƒtƒ@ƒCƒ‹‚ªŠg’£‚³‚ꂽ‚©ƒ`ƒFƒbƒN */
+
+    res = f_lseek(&file, DATA_START, 0);   /* ƒf[ƒ^EƒXƒgƒŠ[ƒ€‚Ì‹L˜^(ƒAƒƒP[ƒVƒ‡ƒ“ƒfƒBƒŒƒC–³‚µ) */
+    ...
+
+    res = f_truncate(&file);               /* •s—v—̈æ‚ÌØ‚èŽÌ‚Ä */
+    res = f_lseek(&file, 0, 0);            /* ƒwƒbƒ_‚Ì‹L˜^ */
+    ...
+
+    res = f_close(&file);
+
+
+    /* ‚‘¬ƒV[ƒN‹@”\‚ðŽg‚¤ */
+
+    DWORD lktbl[SZ_TBL];                   /* ƒŠƒ“ƒNEƒ}ƒbƒvEƒe[ƒuƒ‹Ši”[ƒoƒbƒtƒ@ */
+
+    res = f_lseek(&file, ofs1);            /* ’ÊíƒV[ƒN (ƒI[ƒvƒ“Žž‚Í file.cltbl == NULL) */
+
+    file.cltbl = lktbl;                    /* ‚‘¬ƒV[ƒN‹@”\‚Ì—LŒø‰» */
+    lktbl[0] = SZ_TBL;                     /* 擪—v‘f‚É”z—ñ—v‘f”‚ðƒZƒbƒg */
+    res = f_lseek(&file, CREATE_LINKMAP);  /* ƒŠƒ“ƒNEƒ}ƒbƒvEƒe[ƒuƒ‹‚Ìì¬ */
+
+    res = f_lseek(&file, ofs2);            /* ‚‘¬ƒV[ƒN (file.cltbl != NULL) */
+
+
+ + +
+

ŽQÆ

+

f_open, FIL

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/mkdir.html b/Lib/Fat/doc/ja/mkdir.html new file mode 100644 index 0000000..831b094 --- /dev/null +++ b/Lib/Fat/doc/ja/mkdir.html @@ -0,0 +1,90 @@ + + + + + + + + +FatFs - f_mkdir + + + + +
+

f_mkdir

+

ƒfƒBƒŒƒNƒgƒŠ‚ð쬂µ‚Ü‚·B

+
+FRESULT f_mkdir (
+  const TCHAR* DirName /* 쬂·‚éƒfƒBƒŒƒNƒgƒŠ–¼‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
DirName
+
쬂·‚éƒfƒBƒŒƒNƒgƒŠ‚̃pƒX–¼‚ª“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_DENIED
+
ƒfƒBƒXƒN‚âƒfƒBƒŒƒNƒgƒŠEƒGƒ“ƒgƒŠ‚ª–ž”t‚ÌꇂȂÇB
+
FR_EXIST
+
“¯–¼‚̃fƒBƒŒƒNƒgƒŠ‚âƒtƒ@ƒCƒ‹‚ª‘¶Ý‚·‚éB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

‹ó‚̃fƒBƒŒƒNƒgƒŠ‚ð쬂µ‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+    res = f_mkdir("sub1");
+    if (res) die(res);
+    res = f_mkdir("sub1/sub2");
+    if (res) die(res);
+    res = f_mkdir("sub1/sub2/sub3");
+    if (res) die(res);
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/mkfs.html b/Lib/Fat/doc/ja/mkfs.html new file mode 100644 index 0000000..3421356 --- /dev/null +++ b/Lib/Fat/doc/ja/mkfs.html @@ -0,0 +1,79 @@ + + + + + + + + +FatFs - f_mkfs + + + + +
+

f_mkfs

+

ƒhƒ‰ƒCƒuã‚ÉFATƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€‚ðì¬(ƒtƒH[ƒ}ƒbƒg)‚µ‚Ü‚·B

+
+FRESULT f_mkfs (
+  BYTE  Drive,              /* ˜_—ƒhƒ‰ƒCƒu”Ô† */
+  BYTE  PartitioningRule,   /* ‹æ‰æ쬕û–@ */
+  UINT  AllocSize           /* ƒNƒ‰ƒXEƒ^ƒTƒCƒY */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
ƒtƒH[ƒ}ƒbƒg‚·‚é˜_—ƒhƒ‰ƒCƒu(0-9)B
+
PartitioningRule
+
0‚ðŽw’è‚·‚é‚ÆAƒhƒ‰ƒCƒu‚Ì‘S—̈æ‚ðè‚ß‚éŠî–{DOS‹æ‰æ‚ð쬂µ‚½‚ ‚ÆA‚»‚Ì‹æ‰æ‚Ƀtƒ@ƒCƒ‹EƒVƒXƒeƒ€‚ð쬂µ‚Ü‚·(FDISKƒtƒH[ƒ}ƒbƒg)B1‚ðŽw’è‚·‚é‚ÆA‹æ‰æƒe[ƒuƒ‹‚ð쬂¹‚¸•¨—ƒhƒ‰ƒCƒu‚Ì擪ƒZƒNƒ^‚©‚ç’¼Úƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€‚ð쬂µ‚Ü‚·(super floppy (SFD) ƒtƒH[ƒ}ƒbƒg)B
+
AllocSize
+
ƒNƒ‰ƒXƒ^EƒTƒCƒY‚ðƒoƒCƒg’PˆÊ‚ÅŽw’肵‚Ü‚·B2‚Ì—ÝæAŠŽ‚ƒZƒNƒ^EƒTƒCƒYˆÈãAŠŽ‚ƒZƒNƒ^EƒTƒCƒY‚Ì128”{ˆÈ‰º‚Å‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB–³Œø‚È’l‚ðŽw’肵‚½ê‡Aƒhƒ‰ƒCƒuEƒTƒCƒY‚ɉž‚¶‚½ƒfƒtƒHƒ‹ƒg‚̃Nƒ‰ƒXƒ^EƒTƒCƒY‚ª‘I‘ð‚³‚ê‚Ü‚·B“Á‚ÉŽw’肵‚È‚¢ê‡‚ÍA0‚ðŽw’肵‚ÄŽ©“®‘I‘ð‚Æ‚µ‚Ü‚·B
+
+
+ +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª–³ŒøB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ªŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_MKFS_ABORTED
+
ŽŸ‚Ì——R‚ÅŠJŽn‘O‚Ɉ—‚ª’†’f‚³‚ꂽB +
    +
  • ƒfƒBƒXƒNEƒTƒCƒY‚ª¬‚³‚·‚¬‚éB
  • +
  • ‰½‚ç‚©‚̈ø”‚ª•s³B
  • +
  • ‚»‚̃Nƒ‰ƒXƒ^EƒTƒCƒY‚ªŽg‚¦‚È‚¢BƒNƒ‰ƒXƒ^”‚ª0xFF7‚Æ0xFFF7‹ß•Ó‚É‚È‚é‚Æ‚«”­¶‚·‚é‰Â”\«‚ª‚ ‚éB
  • +
+
+
+
+ +
+

à–¾

+

f_mkfsŠÖ”‚ÍFATƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€‚ðƒhƒ‰ƒCƒuã‚É쬂µ‚Ü‚·BƒŠƒ€[ƒoƒuƒ‹EƒƒfƒBƒA‚̃p[ƒe[ƒVƒ‡ƒjƒ“ƒOEƒ‹[ƒ‹‚Æ‚µ‚Ä‚ÍFDISKŒ`Ž®‚ÆSFDŒ`Ž®‚ª‚ ‚èAƒƒ‚ƒŠEƒJ[ƒh‚Å‚ÍFDISKŒ`Ž®‚ª•’Ê‚Å‚·B‚±‚ÌŠÖ”‚Í•¡”‹æ‰æ‚ɂ͑Ήž‚µ‚Ä‚¢‚È‚¢‚Ì‚ÅA‚»‚Ì•¨—ƒhƒ‰ƒCƒu‚ÌŠù‘¶‚Ì‹æ‰æ‚Í‘S‚Ä휂³‚êA‘S‘Ì‚ªˆê‚‚̋æ‰æ‚É‚È‚è‚Ü‚·B

+

FATƒ^ƒCƒv(FAT12/FAT16/FAT32)‚ÍA‚»‚̘_—ƒhƒ‰ƒCƒuã‚̃Nƒ‰ƒXƒ^”‚É‚æ‚Á‚Ä‚Ì‚ÝŒˆ’肳‚ê‚錈‚Ü‚è[FATŽd—l‘‚æ‚è]‚É‚È‚Á‚Ä‚¢‚ÄA‚»‚êˆÈŠO‚Ì—vˆö‚Í‚ ‚è‚Ü‚¹‚ñB‚µ‚½‚ª‚Á‚ÄA‚Ç‚ÌFATƒ^ƒCƒv‚É‚È‚é‚©‚̓hƒ‰ƒCƒuEƒTƒCƒY‚ƃNƒ‰ƒXƒ^EƒTƒCƒY‚Ɉˑ¶‚µ‚Ü‚·BƒNƒ‰ƒXƒ^EƒTƒCƒY‚Í‘å‚«‚­‚·‚é‚Ù‚Ç«”\‚ªã‚ª‚èA‹t‚ɃfƒBƒXƒN—˜—pŒø—¦‚Í—Ž‚¿‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_USE_MKFS == 1‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/ja/mount.html b/Lib/Fat/doc/ja/mount.html new file mode 100644 index 0000000..d9309a9 --- /dev/null +++ b/Lib/Fat/doc/ja/mount.html @@ -0,0 +1,66 @@ + + + + + + + + +FatFs - f_mount + + + + +
+

f_mount

+

˜_—ƒhƒ‰ƒCƒu‚̃[ƒNEƒGƒŠƒA‚ð“o˜^E–•Á‚µ‚Ü‚·B

+
+FRESULT f_mount (
+  BYTE  Drive,               /* ˜_—ƒhƒ‰ƒCƒu”Ô† */
+  FATFS*  FileSystemObject   /* ƒ[ƒNEƒGƒŠƒA‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
Drive
+
˜_—ƒhƒ‰ƒCƒu”Ô†(0-9)B
+
FileSystemObject
+
“o˜^‚·‚éƒ[ƒNEƒGƒŠƒA(ƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg)‚ւ̃|ƒCƒ“ƒ^B
+
+
+ +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_INVALID_DRIVE
+
˜_—ƒhƒ‰ƒCƒu”Ô†‚ª–³ŒøB
+
+
+ + +
+

‰ðà

+

FatFsƒ‚ƒWƒ…[ƒ‹‚Å‚Í‚»‚ꂼ‚ê‚̘_—ƒhƒ‰ƒCƒu‚Ƀtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚Æ‚¢‚¤ƒ[ƒNEƒGƒŠƒA‚ª•K—v‚Å‚·B‚±‚ÌŠÖ”‚͘_—ƒhƒ‰ƒCƒu‚É‚»‚̃[ƒNEƒGƒŠƒA‚ð“o˜^‚µ‚½‚è–•Á‚µ‚½‚肵‚Ü‚·B‰½‚ç‚©‚̃tƒ@ƒCƒ‹ŠÖ”‚ðŽg—p‚·‚é‘O‚É‚±‚ÌŠÖ”‚Å‚»‚̘_—ƒhƒ‰ƒCƒu‚̃[ƒNEƒGƒŠƒA‚ð—^‚¦‚Ä‚¨‚©‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñBFileSystemObject‚Ƀkƒ‹Eƒ|ƒCƒ“ƒ^‚ðŽw’è‚·‚é‚Æ‚»‚̘_—ƒhƒ‰ƒCƒu‚̃[ƒNEƒGƒŠƒA‚Ì“o˜^‚Í–•Á‚³‚êA“o˜^‚³‚ê‚Ä‚¢‚½ƒ[ƒNEƒGƒŠƒA‚Í”jŠü‚Å‚«‚Ü‚·B‘€ì‘Îۂ̃hƒ‰ƒCƒu‚ɑ΂µ‚ÄŠJ‚©‚ê‚Ä‚¢‚éƒtƒ@ƒCƒ‹‚âƒfƒBƒŒƒNƒgƒŠ‚ª‚ ‚Á‚½ê‡A‚»‚ê‚ç‚Í‘S‚Ä–³Œø‚É‚È‚è‚Ü‚·B

+

‚±‚ÌŠÖ”“à‚ł͉ºˆÊƒŒƒCƒ„(•¨—ƒhƒ‰ƒCƒu)‚ւ̃AƒNƒZƒX‚Í”­¶‚¹‚¸Aƒ[ƒNEƒGƒŠƒA‚ð‰Šú‰»‚µ‚Ä“à•””z—ñ‚É‚»‚̃AƒhƒŒƒX‚ð“o˜^‚·‚邾‚¯‚Å‚·BŽÀۂ̃}ƒEƒ“ƒg“®ì‚ÍAf_mount()‚Ü‚½‚̓ƒfƒBƒAŒðŠ·ŒãAʼn‚̃tƒ@ƒCƒ‹EƒAƒNƒZƒX‚Ì‚Æ‚«‚És‚í‚ê‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

‘S‚Ä‚Ì\¬‚ÅŽg—p‰Â”\‚Å‚·B

+
+ + +
+

ŽQÆ

+

FATFS

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/open.html b/Lib/Fat/doc/ja/open.html new file mode 100644 index 0000000..c2a16cf --- /dev/null +++ b/Lib/Fat/doc/ja/open.html @@ -0,0 +1,147 @@ + + + + + + + + +FatFs - f_open + + + + +
+

f_open

+

ƒtƒ@ƒCƒ‹‚ðƒI[ƒvƒ“‚Ü‚½‚Í쬂µ‚Ü‚·B

+
+FRESULT f_open (
+  FIL* FileObject,       /* ‹ó‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+  const TCHAR* FileName, /* ƒtƒ@ƒCƒ‹‚̃tƒ‹ƒpƒX–¼‚ւ̃|ƒCƒ“ƒ^ */
+  BYTE ModeFlags         /* ƒ‚[ƒhƒtƒ‰ƒO */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
V‚µ‚­ì¬‚·‚éƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·BˆÈ~A‚»‚̃tƒ@ƒCƒ‹‚ð•Â‚¶‚é‚Ü‚Å‚±‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ðŽg—p‚µ‚ătƒ@ƒCƒ‹‘€ì‚ð‚µ‚Ü‚·B
+
FileName
+
ŠJ‚­(‚Ü‚½‚Í쬂·‚é)ƒtƒ@ƒCƒ‹‚Ì ƒtƒ@ƒCƒ‹–¼‚ª“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
ModeFlags
+
ƒtƒ@ƒCƒ‹‚̃AƒNƒZƒX•û–@‚âƒI[ƒvƒ“•û–@‚ðŒˆ‚ß‚éƒtƒ‰ƒO‚Å‚·B‚±‚̃pƒ‰ƒ[ƒ^‚É‚ÍŽŸ‚Ì‘g‚݇‚킹‚ðŽw’肵‚Ü‚·B
+ + + + + + + + +
’lˆÓ–¡
FA_READ“Ç‚Ýo‚µƒ‚[ƒh‚ÅŠJ‚«‚Ü‚·B“Ç‚Ý‘‚«‚·‚éꇂÍFA_WRITE‚Æ‹¤‚ÉŽw’肵‚Ü‚·B
FA_WRITE‘‚«ž‚݃‚[ƒh‚ÅŠJ‚«‚Ü‚·B“Ç‚Ý‘‚«‚·‚éꇂÍFA_READ‚Æ‹¤‚ÉŽw’肵‚Ü‚·B
FA_OPEN_EXISTINGŠù‘¶‚̃tƒ@ƒCƒ‹‚ðŠJ‚«‚Ü‚·Bƒtƒ@ƒCƒ‹‚ª–³‚¢‚Æ‚«‚̓Gƒ‰[‚É‚È‚è‚Ü‚·B(ƒfƒtƒHƒ‹ƒg)
FA_OPEN_ALWAYSŠù‘¶‚̃tƒ@ƒCƒ‹‚ðŠJ‚«‚Ü‚·Bƒtƒ@ƒCƒ‹‚ª–³‚¢‚Æ‚«‚̓tƒ@ƒCƒ‹‚ð쬂µ‚Ü‚·B’Ç‹L‚·‚éꇂÍA‚±‚Ì•û–@‚ŃI[ƒvƒ“‚µ‚½ŒãAf_lseek()‚Ńtƒ@ƒCƒ‹‚ÌÅŒã”ö‚Ɉړ®‚µ‚Ä‚­‚¾‚³‚¢B
FA_CREATE_NEWƒtƒ@ƒCƒ‹‚ð쬂µ‚Ü‚·B“¯–¼‚̃tƒ@ƒCƒ‹‚ª‚ ‚éꇂÍAƒGƒ‰[‚É‚È‚è‚Ü‚·B
FA_CREATE_ALWAYSƒtƒ@ƒCƒ‹‚ð쬂µ‚Ü‚·B“¯–¼‚̃tƒ@ƒCƒ‹‚ª‚ ‚éꇂÍAƒTƒCƒY‚ð0‚É‚µ‚Ä‚©‚çŠJ‚«‚Ü‚·B
+
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹BˆÈ~AFileObject\‘¢‘Ì‚ðŽg‚Á‚Ä‚±‚̃tƒ@ƒCƒ‹‚ð‘€ì‚Å‚«‚Ü‚·B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒtƒ@ƒCƒ‹–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_EXIST
+
“¯–¼‚̃tƒ@ƒCƒ‹‚ªŠù‚É‚ ‚éB
+
FR_DENIED
+
ƒAƒNƒZƒX‚ª‹‘”Û‚³‚ꂽBƒŠ[ƒhEƒIƒ“ƒŠ[Eƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚݃‚[ƒhEƒI[ƒvƒ“A“¯–¼‚̃fƒBƒŒƒNƒgƒŠ‚Ü‚½‚̓Š[ƒhEƒIƒ“ƒŠ[Eƒtƒ@ƒCƒ‹‚ª‚ ‚éó‘Ԃł̃tƒ@ƒCƒ‹ì¬AƒfƒBƒXƒN‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠEƒe[ƒuƒ‹‚ª–ž”t‚Ńtƒ@ƒCƒ‹‚ð쬂ł«‚È‚¢‚È‚ÇB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘Ô‚Å‘‚«ž‚ÝŒnƒI[ƒvƒ“‚ð‚µ‚½B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ªŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_LOCKED
+
ƒtƒ@ƒCƒ‹‹¤—L‹@”\‚É‚æ‚éƒAƒNƒZƒX‹‘”ÛB
+
+
+ + +
+

‰ðà

+

Šù‘¶‚̃tƒ@ƒCƒ‹‚ðŠJ‚¢‚½‚èAV‚µ‚¢ƒtƒ@ƒCƒ‹‚ð쬂µ‚Ü‚·BŠÖ”‚ª¬Œ÷‚·‚é‚ƃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ªì¬‚³‚êAˆÈ~‚»‚̃tƒ@ƒCƒ‹‚ɑ΂·‚éƒAƒNƒZƒX‚ÉŽg—p‚µ‚Ü‚·Bƒtƒ@ƒCƒ‹‚ð•Â‚¶‚é‚Æ‚«‚ÍAf_close()‚ðŽg—p‚µ‚Ü‚·B‰½‚ç‚©‚Ì•ÏX‚ªs‚í‚ꂽƒtƒ@ƒCƒ‹‚ª‚»‚̌㳂µ‚­•Â‚¶‚ç‚ê‚È‚©‚Á‚½ê‡A‚»‚̃tƒ@ƒCƒ‹‚ª”j‘¹‚·‚éꇂª‚ ‚è‚Ü‚·B

+

ƒtƒ@ƒCƒ‹EƒAƒNƒZƒX‚ðŠJŽn‚·‚é‘O‚ÉAf_mount()‚ðŽg‚Á‚Ä‚»‚ꂼ‚ê‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA(ƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg)‚ð—^‚¦‚é•K—v‚ª‚ ‚è‚Ü‚·B‚±‚̉Šú‰»‚ÌŒãA‚»‚̘_—ƒhƒ‰ƒCƒu‚ɑ΂µ‚Ä‘S‚Ẵtƒ@ƒCƒ‹ŠÖ”‚ªŽg‚¦‚é‚悤‚É‚È‚è‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

‘S‚Ä‚Ì\¬‚ÅŽg—p‰Â”\‚Å‚·B_FS_READONLY == 1‚Ì‚Æ‚«‚ÍAFA_WRITE, FA_CREATE_ALWAYS, FA_CREATE_NEW, FA_OPEN_ALWAYS‚ÌŠeƒtƒ‰ƒO‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñB

+
+ + +
+

Žg—p—áiƒtƒ@ƒCƒ‹EƒRƒs[j

+
+void main (void)
+{
+    FATFS fs[2];         /* ˜_—ƒhƒ‰ƒCƒu‚̃[ƒNEƒGƒŠƒA(ƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg) */
+    FIL fsrc, fdst;      /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+    BYTE buffer[4096];   /* file copy buffer */
+    FRESULT res;         /* FatFs function common result code */
+    UINT br, bw;         /* File R/W count */
+
+    /* ƒhƒ‰ƒCƒu0,1‚Ƀ[ƒNEƒGƒŠƒA‚ð—^‚¦‚é */
+    f_mount(0, &fs[0]);
+    f_mount(1, &fs[1]);
+
+    /* ƒhƒ‰ƒCƒu1‚̃\[ƒXEƒtƒ@ƒCƒ‹‚ðŠJ‚­ */
+    res = f_open(&fsrc, "1:srcfile.dat", FA_OPEN_EXISTING | FA_READ);
+    if (res) die(res);
+
+    /* ƒhƒ‰ƒCƒu0‚ɃfƒXƒeƒBƒl[ƒVƒ‡ƒ“Eƒtƒ@ƒCƒ‹‚ð쬂·‚é */
+    res = f_open(&fdst, "0:dstfile.dat", FA_CREATE_ALWAYS | FA_WRITE);
+    if (res) die(res);
+
+    /* ƒ\[ƒX‚©‚çƒfƒXƒeƒBƒl[ƒVƒ‡ƒ“‚ɃRƒs[‚·‚é */
+    for (;;) {
+        res = f_read(&fsrc, buffer, sizeof(buffer), &br);
+        if (res || br == 0) break;   /* ƒGƒ‰[‚©ƒtƒ@ƒCƒ‹I’[ */
+        res = f_write(&fdst, buffer, br, &bw);
+        if (res || bw < br) break;   /* ƒGƒ‰[‚©ƒfƒBƒXƒN–ž”t */
+    }
+
+    /* ‘S‚Ẵtƒ@ƒCƒ‹‚ð•Â‚¶‚é */
+    f_close(&fsrc);
+    f_close(&fdst);
+
+    /* ƒ[ƒNEƒGƒŠƒA‚ðŠJ•ú‚·‚é */
+    f_mount(0, NULL);
+    f_mount(1, NULL);
+}
+
+
+ + +
+

ŽQÆ

+

f_read, f_write, f_close, FIL, FATFS

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/opendir.html b/Lib/Fat/doc/ja/opendir.html new file mode 100644 index 0000000..fffe569 --- /dev/null +++ b/Lib/Fat/doc/ja/opendir.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_opendir + + + + +
+

f_opendir

+

ƒfƒBƒŒƒNƒgƒŠ‚ðŠJ‚«‚Ü‚·B

+
+FRESULT f_opendir (
+  DIR* DirObject,       /* ƒfƒBƒŒƒNƒgƒŠEƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+  const TCHAR* DirName  /* ƒfƒBƒŒƒNƒgƒŠ–¼‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
DirObject
+
‰Šú‰»‚·‚éƒfƒBƒŒƒNƒgƒŠEƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
DirName
+
ƒI[ƒvƒ“‚·‚éƒfƒBƒŒƒNƒgƒŠ‚ւ̃pƒX–¼‚ª“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
˜_—ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
˜_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

ƒfƒBƒŒƒNƒgƒŠ‚ðŠJ‚«‚Ü‚·B³íI—¹‚µ‚½‚çADirObject\‘¢‘Ì‚ðŽg‚Á‚Ä‚±‚̃fƒBƒŒƒNƒgƒŠ‚Ì€–Ú‚ð‡ŽŸ“Ç‚Ýo‚¹‚Ü‚·BDirObject\‘¢‘Ì‚ÍŽg—pŒã‚Í”CˆÓ‚ÌŽž“_‚Å”jŠü‚Å‚«‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_MINIMIZE <= 1‚Ì‚Æ‚«Žg—p‰Â”\‚É‚È‚è‚Ü‚·B

+
+ + +
+

ŽQÆ

+

f_readdir, DIR

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/printf.html b/Lib/Fat/doc/ja/printf.html new file mode 100644 index 0000000..2df2628 --- /dev/null +++ b/Lib/Fat/doc/ja/printf.html @@ -0,0 +1,84 @@ + + + + + + + + +FatFs - f_printf + + + + +
+

f_printf

+

ƒtƒ@ƒCƒ‹‚É‘Ž®‰»•¶Žš—ñ‚ð‘‚«ž‚Ý‚Ü‚·B

+
+int f_printf (
+  FIL* FileObject,      /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+  const TCHAR* Foramt,  /* ‘Ž®§Œä•¶Žš—ñ */
+  ...
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Format
+
'\0'‚ÅI‚í‚é‘Ž®§Œä•¶Žš—ñ‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B'\0'‚Í‘‚«ž‚Ü‚ê‚Ü‚¹‚ñB
+
...
+
ƒIƒvƒVƒ‡ƒ“‚̈ø”B
+ +
+
+ + +
+

–ß‚è’l

+

•¶Žš—ñ‚ª³í‚É‘‚«ž‚Ü‚ê‚é‚Æ‘‚«ž‚܂ꂽ•¶Žš”‚ª•Ô‚³‚ê‚Ü‚·BƒfƒBƒXƒN‚ª–ž”t‚Ü‚½‚Í‚»‚Ì‘¼ƒGƒ‰[‚É‚æ‚è³í‚É‘‚«ž‚Ü‚ê‚È‚©‚Á‚½‚Æ‚«‚ÍŠÖ”‚ÍŽ¸”s‚µEOF (-1)‚ª•Ô‚³‚ê‚Ü‚·B

+
+ + +
+

‰ðà

+

‚±‚ÌŠÖ”‚Íf_putc()‚¨‚æ‚Ñf_puts()‚̃‰ƒbƒp[ŠÖ”‚Å‚·B‘Ž®§Œä‹@”\‚̓TƒuƒZƒbƒg‚Æ‚È‚Á‚Ä‚¢‚ÄA‘Ž®§Œä•¶Žš‚ÍŽŸ‚ÉŽ¦‚·‚à‚Ì‚ªŽg—p‰Â”\‚Å‚·B

+
    +
  • ƒ^ƒCƒv: c C s S d D u U x X b B
  • +
  • ¸“xŽw’è: l L
  • +
  • ƒtƒ‰ƒO: 0
  • +
+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_USE_STRFUNC‚ª 1‚Ü‚½‚Í 2‚Ì‚Æ‚«Žg—p‰Â”\‚É‚È‚è‚Ü‚·B2‚ÌŽž‚ÍAo—Í‚ÉŠÜ‚Ü‚ê‚é'\n'‚ª"\r\n"‚É“WŠJ‚³‚ê‚ătƒ@ƒCƒ‹‚É‘‚«ž‚Ü‚ê‚Ü‚·B

+

API‚ÉUnicode‚ª‘I‘ð‚³‚ê‚Ä‚¢‚é(_LFN_UNICODE‚ª1)‚Æ‚«‚ÍAUTF-8ƒGƒ“ƒR[ƒh‚Ńtƒ@ƒCƒ‹‚É‘‚«ž‚Ý‚Ü‚·B‚»‚êˆÈŠO‚ÌŽž‚Í–³•ÏŠ·(1•¶Žš1ƒoƒCƒg)‚Å‘‚«ž‚Ý‚Ü‚·B

+
+ + +
+

Žg—p—á

+
+    f_printf(&fil, "%6d", -200);         /* "  -200" */
+    f_printf(&fil, "%02u", 5);           /* "05" */
+    f_printf(&fil, "%ld", 12345678L);    /* "12345678" */
+    f_printf(&fil, "%08lX", 1194684UL);  /* "00123ABC" */
+    f_printf(&fil, "%s", "String");      /* "String" */
+    f_printf(&fil, "%c", 'a');           /* "a" */
+
+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/putc.html b/Lib/Fat/doc/ja/putc.html new file mode 100644 index 0000000..956723e --- /dev/null +++ b/Lib/Fat/doc/ja/putc.html @@ -0,0 +1,62 @@ + + + + + + + + +FatFs - f_putc + + + + +
+

f_putc

+

ƒtƒ@ƒCƒ‹‚É•¶Žš‚ð‘‚«ž‚Ý‚Ü‚·B

+
+int f_putc (
+  TCHAR Chr,        /* ‘‚«ž‚Þ•¶Žš */
+  FIL* FileObject   /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+);
+
+
+ +
+

ˆø”

+
+
Chr
+
‘‚«ž‚Þ•¶Žš‚ðŽw’肵‚Ü‚·B
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+

•¶Žš‚ª³í‚É‘‚«ž‚Ü‚ê‚é‚Æ‘‚«ž‚ñ‚¾•¶Žš‚ª•Ô‚³‚ê‚Ü‚·BƒfƒBƒXƒN‚ª–ž”t‚Ü‚½‚̓Gƒ‰[‚É‚æ‚è‘‚«ž‚Ü‚ê‚È‚©‚Á‚½‚Æ‚«‚ÍEOF (-1)‚ª•Ô‚³‚ê‚Ü‚·B

+

API‚ÉUnicode‚ª‘I‘ð‚³‚ê‚Ä‚¢‚é(_LFN_UNICODE‚ª1)‚Æ‚«‚ÍAUTF-8ƒGƒ“ƒR[ƒh‚Ńtƒ@ƒCƒ‹‚É‘‚«ž‚Ý‚Ü‚·B‚»‚êˆÈŠO‚ÌŽž‚Í–³•ÏŠ·(1•¶Žš1ƒoƒCƒg)‚Å‘‚«ž‚Ý‚Ü‚·B

+
+ + +
+

‰ðà

+

1•¶Žš‚ðƒtƒ@ƒCƒ‹‚É‘‚«ž‚Ý‚Ü‚·B‚±‚ÌŠÖ”‚Íf_write()‚̃‰ƒbƒp[ŠÖ”‚Å‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_USE_STRFUNC‚ª 1‚Ü‚½‚Í 2‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B2‚ðŽw’è‚·‚é‚ÆA'\n'‚Í"\r\n"‚É“WŠJ‚³‚ê‚ătƒ@ƒCƒ‹‚É‘‚«ž‚Ü‚ê‚Ü‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/puts.html b/Lib/Fat/doc/ja/puts.html new file mode 100644 index 0000000..b2fe474 --- /dev/null +++ b/Lib/Fat/doc/ja/puts.html @@ -0,0 +1,62 @@ + + + + + + + + +FatFs - f_puts + + + + +
+

f_puts

+

ƒtƒ@ƒCƒ‹‚É•¶Žš—ñ‚ð‘‚«ž‚Ý‚Ü‚·B

+
+int f_puts (
+  const TCHAR* Str,  /* •¶Žš—ñ */
+  FIL* FileObject    /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+);
+
+
+ +
+

ˆø”

+
+
Str
+
‘‚«ž‚Þ'\0'‚ÅI‚í‚镶Žš—ñ‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B'\0'‚Í‘‚«ž‚Ü‚ê‚Ü‚¹‚ñB
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+

•¶Žš—ñ‚ª³í‚É‘‚«ž‚Ü‚ê‚é‚ÆA‘‚«ž‚܂ꂽ•¶Žš”‚ª•Ô‚³‚ê‚Ü‚·BƒfƒBƒXƒN‚ª–ž”t‚Ü‚½‚̓Gƒ‰[‚É‚æ‚è³í‚É‘‚«ž‚Ü‚ê‚È‚©‚Á‚½‚Æ‚«‚ÍEOF (-1)‚ª•Ô‚³‚ê‚Ü‚·B

+

API‚ÉUnicode‚ª‘I‘ð‚³‚ê‚Ä‚¢‚é(_LFN_UNICODE‚ª1)‚Æ‚«‚ÍAUTF-8ƒGƒ“ƒR[ƒh‚Ńtƒ@ƒCƒ‹‚É‘‚«ž‚Ý‚Ü‚·B‚»‚êˆÈŠO‚ÌŽž‚Í–³•ÏŠ·(1•¶Žš1ƒoƒCƒg)‚Å‘‚«ž‚Ý‚Ü‚·B

+
+ + +
+

‰ðà

+

•¶Žš—ñ‚ðƒtƒ@ƒCƒ‹‚É‘‚«ž‚Ý‚Ü‚·B‚±‚ÌŠÖ”‚Íf_putc()‚̃‰ƒbƒp[ŠÖ”‚Å‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_USE_STRFUNC‚ª 1‚Ü‚½‚Í 2‚Ì‚Æ‚«Žg—p‰Â”\‚Å‚·B2‚ðŽw’è‚·‚é‚ÆA•¶Žš—ñ‚ÉŠÜ‚Ü‚ê‚é'\n'‚Í"\r\n"‚É“WŠJ‚³‚ê‚ătƒ@ƒCƒ‹‚É‘‚«ž‚Ü‚ê‚Ü‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/read.html b/Lib/Fat/doc/ja/read.html new file mode 100644 index 0000000..fb344cc --- /dev/null +++ b/Lib/Fat/doc/ja/read.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_read + + + + +
+

f_read

+

ƒtƒ@ƒCƒ‹‚©‚çƒf[ƒ^‚ð“Ç‚Ýo‚µ‚Ü‚·B

+
+FRESULT f_read (
+  FIL* FileObject,    /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘Ì */
+  void* Buffer,       /* “Ç‚Ýo‚µ‚½ƒf[ƒ^‚ðŠi”[‚·‚éƒoƒbƒtƒ@ */
+  UINT ByteToRead,    /* “Ç‚Ýo‚·ƒoƒCƒg” */
+  UINT* ByteRead      /* “Ç‚Ýo‚³‚ꂽƒoƒCƒg” */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Buffer
+
“Ç‚Ýo‚µ‚½ƒf[ƒ^‚ðŠi”[‚·‚éƒoƒbƒtƒ@‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
ByteToRead
+
“Ç‚Ýo‚·ƒoƒCƒg”(0`UINT‚ÌÅ‘å’l)‚ðŽw’肵‚Ü‚·B
+
ByteRead
+
ŽÀÛ‚É“Ç‚Ýo‚³‚ꂽƒoƒCƒg”‚ðŠi”[‚·‚é•Ï”‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B–ß‚è’l‚ÍŠÖ”‚̬”Û‚É‚©‚©‚í‚炸í‚É—LŒø‚Å‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DENIED
+
”ñ“Ç‚Ýž‚݃‚[ƒh‚ÅŠJ‚¢‚½ƒtƒ@ƒCƒ‹‚©‚ç“Ç‚Ýž‚à‚¤‚Æ‚µ‚½B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

“Ç‚Ýž‚ÝŠJŽnˆÊ’u‚ÍAŒ»Ý‚̃Š[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚©‚ç‚É‚È‚è‚Ü‚·BƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚Í“Ç‚Ýž‚܂ꂽƒoƒCƒg”‚¾‚¯i‚Ý‚Ü‚·BŠÖ”‚ª³íI—¹‚µ‚½Œã‚ÍA*ByteRead‚Ì’l‚ðƒ`ƒFƒbƒN‚·‚ׂ«‚Å‚·B*ByteRead‚ªByteToRead‚æ‚è‚ଂ³‚¢‚Æ‚«‚ÍA“Ç‚Ýž‚Ý’†‚Ƀtƒ@ƒCƒ‹‚ÌI’[‚É’B‚µ‚½‚±‚Æ‚ðŽ¦‚µ‚Ä‚¢‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

‘S‚Ä‚Ì\¬‚ÅŽg—p‰Â”\‚Å‚·B

+
+ + +
+

ŽQÆ

+

f_open, fgets, f_write, f_close, FIL

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/readdir.html b/Lib/Fat/doc/ja/readdir.html new file mode 100644 index 0000000..339b40f --- /dev/null +++ b/Lib/Fat/doc/ja/readdir.html @@ -0,0 +1,125 @@ + + + + + + + + +FatFs - f_readdir + + + + +
+

f_readdir

+

ƒfƒBƒŒƒNƒgƒŠ€–Ú‚ð“Ç‚Ýo‚µ‚Ü‚·

+
+FRESULT f_readdir (
+  DIR* DirObject,    /* ƒfƒBƒŒƒNƒgƒŠEƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+  FILINFO* FileInfo  /* ƒtƒ@ƒCƒ‹î•ñ\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
DirObject
+
ƒfƒBƒŒƒNƒgƒŠEƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
FileInfo
+
“Ç‚Ýo‚µ‚½ƒfƒBƒŒƒNƒgƒŠ€–Ú‚ðŠi”[‚·‚éƒtƒ@ƒCƒ‹î•ñ\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃfƒBƒŒƒNƒgƒŠEƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

ƒfƒBƒŒƒNƒgƒŠ€–Ú‚ð‡ŽŸ“Ç‚Ýo‚µ‚Ü‚·B‚±‚ÌŠÖ”‚ðŒJ‚è•Ô‚µŽÀs‚·‚邱‚Æ‚É‚æ‚èƒfƒBƒŒƒNƒgƒŠ‚Ì‘S‚Ä‚Ì€–Ú‚ð“Ç‚Ýo‚·‚±‚Æ‚ª‚Å‚«‚Ü‚·B‘S‚Ä‚Ì€–Ú‚ð“Ç‚Ýo‚µA“Ç‚Ýo‚·€–Ú‚ª‚à‚¤–³‚¢‚Æ‚«‚ÍAf_name[]ƒƒ“ƒo‚Ƀkƒ‹•¶Žš—ñ‚ª•Ô‚³‚ê‚Ü‚·Bƒ{ƒŠƒ…[ƒ€Eƒ‰ƒxƒ‹‚Í“Ç‚Ýo‚·‚Æ‚«‚ÉŠü‚Ä‚ç‚êAŒ»‚ê‚邱‚Æ‚Í‚ ‚è‚Ü‚¹‚ñB"."A".."‚ÍA‘Š‘΃pƒX‚ª—LŒø‚È‚Æ‚«(_FS_RPATH == 1)‚É‚Ì‚ÝŒ»‚ê‚Ü‚·B“¾‚ç‚ê‚éƒtƒ@ƒCƒ‹î•ñ‚ÌÚׂɂ‚¢‚Ä‚Í FILINFO\‘¢‘Ì‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢BFileInfo‚Ƀkƒ‹Eƒ|ƒCƒ“ƒ^‚ðŽw’è‚·‚é‚ÆA‚»‚̃fƒBƒŒƒNƒgƒŠ‚̃Š[ƒhEƒCƒ“ƒfƒbƒNƒX‚ðŠª‚«–ß‚µ‚Ü‚·B

+

LFN‹@”\‚ª—LŒø‚ÈŽž‚ÍAf_readdirŠÖ”‚̌ĂÑo‚µ‚Éæ—§‚Á‚ÄFILINFO\‘¢‘Ì‚Ìlfname‚Ælfsize‚ª—LŒø‚È’l‚ʼnŠú‰»‚³‚ê‚Ä‚¢‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñBlfname‚ÍLFN‚ðŠi”[‚·‚éƒoƒbƒtƒ@‚ÅAlfsize‚Í‚»‚̃oƒbƒtƒ@EƒTƒCƒY(•¶Žš”)‚Å‚·BŽŸ‚ÌðŒ‚Ɉê‚‚łàŠY“–‚·‚éꇂÍALFNŠi”[ƒoƒbƒtƒ@‚Ƀkƒ‹•¶Žš—ñ‚ª•Ô‚³‚ê‚Ü‚·B

+
    +
  • ‚»‚̃fƒBƒŒƒNƒgƒŠ€–Ú‚ÉLFN‚ª‘¶Ý‚µ‚È‚¢B
  • +
  • LFN‚Ì’·‚³‚ɑ΂µ‚ÄLFNŠi”[ƒoƒbƒtƒ@‚Ü‚½‚ÍLFN‘€ìƒoƒbƒtƒ@‚̃TƒCƒY‚ª•s\•ªB
  • +
  • LFN‚ÉOEMƒR[ƒh‚É‘¶Ý‚µ‚È‚¢•¶Žš‚ªŠÜ‚Ü‚ê‚Ä‚¢‚éB(Unicode API‚Å‚Í‚È‚¢‚Æ‚«)
  • +
+

‚Ü‚½Alfname‚Ƀkƒ‹Eƒ|ƒCƒ“ƒ^‚ðŽw’肵‚½ê‡‚ÍALFN‚ÉŠÖ‚µ‚ĉ½‚à•Ô‚³‚ê‚Ü‚¹‚ñBLFN‚ª‘¶Ý‚µ‚È‚¢‚Æ‚«‚ÍAf_name[]ƒƒ“ƒo‚ÌSFN‚ÉASCII‰p¬•¶Žš‚ªŠÜ‚Ü‚ê‚éꇂª‚ ‚è‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_MINIMIZE <= 1‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+FRESULT scan_files (char* path)
+{
+    FRESULT res;
+    FILINFO fno;
+    DIR dir;
+    int i;
+    char *fn;
+#if _USE_LFN
+    static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1];
+    fno.lfname = lfn;
+    fno.lfsize = sizeof(lfn);
+#endif
+
+
+    res = f_opendir(&dir, path);
+    if (res == FR_OK) {
+        i = strlen(path);
+        for (;;) {
+            res = f_readdir(&dir, &fno);
+            if (res != FR_OK || fno.fname[0] == 0) break;
+            if (fno.fname[0] == '.') continue;
+#if _USE_LFN
+            fn = *fno.lfname ? fno.lfname : fno.fname;
+#else
+            fn = fno.fname;
+#endif
+            if (fno.fattrib & AM_DIR) {
+                sprintf(&path[i], "/%s", fn);
+                res = scan_files(path);
+                if (res != FR_OK) break;
+                path[i] = 0;
+            } else {
+                printf("%s/%s\n", path, fn);
+            }
+        }
+    }
+
+    return res;
+}
+
+
+ + +
+

ŽQÆ

+

f_opendir, f_stat, FILINFO, DIR

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/rename.html b/Lib/Fat/doc/ja/rename.html new file mode 100644 index 0000000..a98bafb --- /dev/null +++ b/Lib/Fat/doc/ja/rename.html @@ -0,0 +1,94 @@ + + + + + + + + +FatFs - f_rename + + + + +
+

f_rename

+

ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚Ì–¼‘O‚Ì•ÏX‚Ü‚½‚͈ړ®B

+
+FRESULT f_rename (
+  const TCHAR* OldName, /* ŒÃ‚¢ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼ */
+  const TCHAR* NewName  /* V‚µ‚¢ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼ */
+);
+
+
+ +
+

ˆø”

+
+
OldName
+
•ÏX‘Îۂ̃IƒuƒWƒFƒNƒg(ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ)‚ւ̃pƒX–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
NewName
+
V‚µ‚¢ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚̃tƒ‹ƒpƒX–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·BŠù‚É‘¶Ý‚·‚é–¼‘O‚ÍŽg‚¦‚Ü‚¹‚ñB‚Ü‚½Aƒhƒ‰ƒCƒu”Ô†‚ÍŽw’è‚Å‚«‚¸AOldName‚ÅŽw’肳‚ꂽ˜_—ƒhƒ‰ƒCƒuã‚̃IƒuƒWƒFƒNƒg‚Æ‚µ‚Ĉµ‚í‚ê‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
OldName‚̃IƒuƒWƒFƒNƒg‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_DENIED
+
ƒhƒ‰ƒCƒu—e—Ê‚Ì•s‘«“™‚Ì——R‚ÅV‚µ‚¢–¼‘O‚̃IƒuƒWƒFƒNƒg‚ªì‚ê‚È‚¢B
+
FR_EXIST
+
NewName‚Æ“¯‚¶–¼‘O‚ªŠù‚É‘¶Ý‚·‚éB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
˜_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNƒGƒŠƒA‚ªŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

ƒIƒuƒWƒFƒNƒg‚Ì–¼‘O‚ð•ÏX‚µ‚Ü‚·B‚Ü‚½A•Ê‚̃fƒBƒŒƒNƒgƒŠ‚ւ̈ړ®(“¯‚¶ƒhƒ‰ƒCƒu“à‚Ì‚Ý)‚à‰Â”\‚Å‚·BŠJ‚©‚ê‚Ä‚¢‚éƒIƒuƒWƒFƒNƒg‚ɑ΂µ‚ÄŽg—p‚µ‚Ä‚Í‚È‚è‚Ü‚¹‚ñB

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

Žg—p—á

+
+    /* ƒtƒ@ƒCƒ‹‚Ü‚½‚̓TƒuƒfƒBƒŒƒNƒgƒŠ‚Ì–¼‘O‚ð•ÏX‚·‚é */
+    f_rename("oldname.txt", "newname.txt");
+
+    /* ƒtƒ@ƒCƒ‹‚Ü‚½‚̓TƒuƒfƒBƒŒƒNƒgƒŠ‚Ì–¼‘O‚Ì•ÏX‚ƕʂ̃fƒBƒŒƒNƒgƒŠ‚ւ̈ړ® */
+    f_rename("oldname.txt", "dir1/newname.txt");
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/sdir.html b/Lib/Fat/doc/ja/sdir.html new file mode 100644 index 0000000..86c5430 --- /dev/null +++ b/Lib/Fat/doc/ja/sdir.html @@ -0,0 +1,37 @@ + + + + + + + + +FatFs - DIR + + + + +
+

DIR

+

DIR\‘¢‘Ì‚ÍAf_opendir(), f_readdir()‚̃[ƒNEƒGƒŠƒA‚Æ‚µ‚ÄŽg—p‚³‚ê‚Ü‚·BƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚©‚ç•ÏX‰Â”\‚ȃƒ“ƒo‚Í‚ ‚è‚Ü‚¹‚ñB

+
+typedef struct {
+    FATFS*  fs;        /* eƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚ւ̃|ƒCƒ“ƒ^ */
+    WORD    id;        /* eƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚̃}ƒEƒ“ƒgID */
+    WORD    index;     /* ŽŸ‚É“Ç‚Ýo‚·ƒfƒBƒŒƒNƒgƒŠEƒCƒ“ƒfƒbƒNƒX”Ô† */
+    DWORD   sclust;    /* ƒfƒBƒŒƒNƒgƒŠŠJŽnƒNƒ‰ƒXƒ^ (0:ƒ‹[ƒg) */
+    DWORD   clust;     /* Œ»Ý‚̃Nƒ‰ƒXƒ^”Ô† */
+    DWORD   sect;      /* Œ»Ý‚̃ZƒNƒ^”Ô† */
+    BYTE*   dir;       /* Œ»Ý‚ÌSFNƒGƒ“ƒgƒŠ‚ւ̃|ƒCƒ“ƒ^ */
+    BYTE*   fn;        /* SFNƒoƒbƒtƒ@‚ւ̃|ƒCƒ“ƒ^ (in/out) {file[8],ext[3],status[1]} */
+#if _USE_LFN
+    WCHAR*  lfn;       /* LFNƒoƒbƒtƒ@‚ւ̃|ƒCƒ“ƒ^ */
+    WORD    lfn_idx;   /* ÅŒã‚Ƀ}ƒbƒ`‚µ‚½LFNƒGƒ“ƒgƒŠ‚̃Cƒ“ƒfƒbƒNƒX (0xFFFF:–³Œø) */
+#endif
+} DIR;
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/sfatfs.html b/Lib/Fat/doc/ja/sfatfs.html new file mode 100644 index 0000000..6a17d82 --- /dev/null +++ b/Lib/Fat/doc/ja/sfatfs.html @@ -0,0 +1,55 @@ + + + + + + + + +FatFs - FATFS + + + + +
+

FATFS

+

FATFS\‘¢‘Ì‚ÍAŒÂX‚̘_—ƒhƒ‰ƒCƒu‚̃_ƒCƒiƒ~ƒbƒNEƒ[ƒNEƒGƒŠƒA‚ð•ÛŽ‚µAf_mount()‚ÅFatFsƒ‚ƒWƒ…[ƒ‹‚É“o˜^‚³‚ê‚Ü‚·B•W€ó‘Ô‚Å‚ÍŽŸ‚̂悤‚ȃƒ“ƒo‚É‚È‚Á‚Ä‚¢‚Ü‚·BƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚©‚ç‘‚«Š·‚¦‰Â”\‚ȃƒ“ƒo‚Í‚ ‚è‚Ü‚¹‚ñB

+ +
+typedef struct {
+    BYTE    fs_type;      /* FATƒ^ƒCƒv */
+    BYTE    drv;          /* •¨—ƒhƒ‰ƒCƒu”Ô† */
+    BYTE    csize;        /* ƒNƒ‰ƒXƒ^“–‚½‚è‚̃ZƒNƒ^” */
+    BYTE    n_fats;       /* FAT‚Ì‘½d‰»” */
+    BYTE    wflag;        /* win[]ƒ_[ƒeƒBEƒtƒ‰ƒO */
+    BYTE    fsi_flag;     /* fsinfoƒ_[ƒeƒBEƒtƒ‰ƒO */
+    WORD    id;           /* ƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€Eƒ}ƒEƒ“ƒgID */
+    WORD    n_rootdir;    /* ƒ‹[ƒgEƒfƒBƒŒƒNƒgƒŠ‚̃Gƒ“ƒgƒŠ” (FAT12/16) */
+#if _MAX_SS != 512
+    WORD    ssize;        /* ƒZƒNƒ^EƒTƒCƒY (‰Â•ÏƒZƒNƒ^’·‚Ì‚Ý) */
+#endif
+#if _FS_REENTRANT
+    HANDLE  h_mutex;      /* “¯ŠúƒIƒuƒWƒFƒNƒgID */
+#endif
+#if !_FS_READONLY
+    DWORD   last_clust;   /* ÅŒã‚ÉŠ„‚è“–‚Ä‚ç‚ꂽƒNƒ‰ƒXƒ^”Ô† */
+    DWORD   free_clust;   /* ‹ó‚«ƒNƒ‰ƒXƒ^” */
+    DWORD   fsi_sector;   /* fsinfoƒZƒNƒ^ (FAT32) */
+#endif
+#if _FS_RPATH
+    DWORD   cdir;         /* ƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚̃Nƒ‰ƒXƒ^ (0:ƒ‹[ƒg) */
+#endif
+    DWORD   n_fatent;     /* FAT‚̃Gƒ“ƒgƒŠ” (= ƒNƒ‰ƒXƒ^” + 2) */
+    DWORD   fsize;        /* FAT 1ŒÂ“–‚½‚è‚̃ZƒNƒ^” */
+    DWORD   fatbase;      /* FAT—̈æŠJŽnƒZƒNƒ^ */
+    DWORD   dirbase;      /* ƒ‹[ƒgEƒfƒBƒŒƒNƒgƒŠŠJŽnƒZƒNƒ^ (FAT32: ƒNƒ‰ƒXƒ^”Ô†) */
+    DWORD   database;     /* ƒf[ƒ^—̈æŠJŽn‹æƒZƒNƒ^ */
+    DWORD   winsect;      /* win[]‚ÉŒ»‚ê‚Ä‚¢‚éƒZƒNƒ^”Ô† */
+    BYTE    win[_MAX_SS]; /* ƒfƒBƒXƒNEƒAƒNƒZƒXEƒEƒBƒ“ƒhƒE */
+} FATFS;
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/sfile.html b/Lib/Fat/doc/ja/sfile.html new file mode 100644 index 0000000..792ba41 --- /dev/null +++ b/Lib/Fat/doc/ja/sfile.html @@ -0,0 +1,48 @@ + + + + + + + + +FatFs - FIL + + + + +
+

FIL

+

FIL\‘¢‘Ì‚ÍAf_openŠÖ”‚Å쬂³‚êA‚»‚̃tƒ@ƒCƒ‹‚Ìó‘Ô‚ð•ÛŽ‚µ‚Ü‚·B‚Ü‚½Af_closeŠÖ”‚Ńtƒ@ƒCƒ‹‚ª•Â‚¶‚ç‚ê‚é‚Æ–³Œø‰»‚³‚ê‚Ü‚·BƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚©‚ç‚Ì‘‚«Š·‚¦‚ª‰Â”\‚ȃƒ“ƒo‚Ícltbl‚Ì‚Ý‚Å‚·B”ñƒ^ƒCƒj[\¬‚Å‚Í“à•”‚ɃZƒNƒ^Eƒoƒbƒtƒ@‚ªŠm•Û‚³‚ê‚é‚Ì‚ÅAƒTƒCƒY‚É’ˆÓ‚ª•K—v‚Å‚·B

+ +
+typedef struct {
+    FATFS*  fs;           /* eƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚ւ̃|ƒCƒ“ƒ^ */
+    WORD    id;           /* eƒtƒ@ƒCƒ‹EƒVƒXƒeƒ€EƒIƒuƒWƒFƒNƒg‚̃}ƒEƒ“ƒgID */
+    BYTE    flag;         /* ƒtƒ@ƒCƒ‹EƒXƒe[ƒ^ƒXEƒtƒ‰ƒO */
+    BYTE    pad1;
+    DWORD   fptr;         /* ƒtƒ@ƒCƒ‹“Ç‚Ý‘‚«ƒ|ƒCƒ“ƒ^(ƒtƒ@ƒCƒ‹æ“ª‚©‚ç‚̃oƒCƒgEƒIƒtƒZƒbƒg) */
+    DWORD   fsize;        /* ƒtƒ@ƒCƒ‹EƒTƒCƒY(ƒoƒCƒg’PˆÊ) */
+    DWORD   org_clust;    /* ƒtƒ@ƒCƒ‹ŠJŽnƒNƒ‰ƒXƒ^”Ô† (0: fsize==0) */
+    DWORD   curr_clust;   /* Œ»Ý‚̃Nƒ‰ƒXƒ^ */
+    DWORD   dsect;        /* Œ»Ý‚̃f[ƒ^EƒZƒNƒ^ */
+#if _FS_READONLY == 0
+    DWORD   dir_sect;     /* ‚±‚̃tƒ@ƒCƒ‹‚̃fƒBƒŒƒNƒgƒŠEƒGƒ“ƒgƒŠ‚Ì‚ ‚éƒZƒNƒ^ */
+    BYTE*   dir_ptr;      /* ‚±‚̃tƒ@ƒCƒ‹‚̃fƒBƒŒƒNƒgƒŠ‚ւ̃|ƒCƒ“ƒ^ */
+#endif
+#if _USE_FASTSEEK
+    DWORD*  cltbl;        /* ƒtƒ@ƒCƒ‹‚̃Nƒ‰ƒXƒ^EƒŠƒ“ƒNî•ñ‚ւ̃|ƒCƒ“ƒ^ */
+#endif
+#if _FS_SHARE
+    UINT    lockid;       /* ƒtƒ@ƒCƒ‹EƒƒbƒNID */
+#endif
+#if !_FS_TINY
+    BYTE    buf[_MAX_SS]; /* ƒf[ƒ^“]‘—ƒoƒbƒtƒ@ */
+#endif
+} FIL;
+
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/sfileinfo.html b/Lib/Fat/doc/ja/sfileinfo.html new file mode 100644 index 0000000..b0c2c08 --- /dev/null +++ b/Lib/Fat/doc/ja/sfileinfo.html @@ -0,0 +1,70 @@ + + + + + + + + +FatFs - FILINFO + + + + +
+

FILINFO

+

FILINFO\‘¢‘Ì‚ÍAf_stat(), f_readdir()‚Å•Ô‚³‚ê‚éƒtƒ@ƒCƒ‹î•ñ‚ð•ÛŽ‚µ‚Ü‚·B

+
+typedef struct {
+    DWORD fsize;     /* ƒtƒ@ƒCƒ‹EƒTƒCƒY */
+    WORD fdate;      /* ÅŒã‚ÉXV‚³‚ꂽ“ú•t */
+    WORD ftime;      /* ÅŒã‚ÉXV‚³‚ꂽŽž  */
+    BYTE fattrib;    /* ƒAƒgƒŠƒrƒ…[ƒg */
+    TCHAR fname[13]; /* ’Z‚¢ƒtƒ@ƒCƒ‹–¼ (8.3ƒtƒH[ƒ}ƒbƒg) */
+#if _USE_LFN
+    TCHAR* lfname;   /* ’·‚¢ƒtƒ@ƒCƒ‹–¼‚̃oƒbƒtƒ@‚ւ̃|ƒCƒ“ƒ^ */
+    int lfsize;      /* ’·‚¢ƒtƒ@ƒCƒ‹–¼‚̃oƒbƒtƒ@‚̃TƒCƒY [•¶Žš”] */
+#endif
+} FILINFO;
+
+
+ +

ƒƒ“ƒo

+
+
fsize
+
ƒtƒ@ƒCƒ‹‚̃oƒCƒg’PˆÊ‚̃TƒCƒY‚ªŠi”[‚³‚ê‚Ü‚·BƒfƒBƒŒƒNƒgƒŠ‚ÌꇂÍí‚É0‚Å‚·B
+
fdate
+
ƒtƒ@ƒCƒ‹‚Ì•ÏX‚³‚ꂽ“ú•tA‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚Ì쬂³‚ꂽ“ú•t‚ªŠi”[‚³‚ê‚Ü‚·B
+
+
bit15:9
+
1980”N‚ð‹N“_‚Æ‚µ‚½”N‚ª 0..127 ‚Å“ü‚è‚Ü‚·B
+
bit8:5
+
ŒŽ‚ª 1..12 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit4:0
+
“ú‚ª 1..31 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
+
+
ftime
+
ƒtƒ@ƒCƒ‹‚Ì•ÏX‚³‚ꂽŽžA‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚Ì쬂³‚ꂽŽž‚ªŠi”[‚³‚ê‚Ü‚·B
+
+
bit15:11
+
Žž‚ª 0..23 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit10:5
+
•ª‚ª 0..59 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
bit4:0
+
•b/2‚ª 0..29 ‚Ì’l‚Å“ü‚è‚Ü‚·B
+
+
+
fattrib
+
‘®«ƒtƒ‰ƒO‚ªŠi”[‚³‚ê‚Ü‚·Bƒtƒ‰ƒO‚ÍAM_DIR, AM_RDO, AM_HID, AM_SYS, AM_ARC‚Ì‘g‚݇‚킹‚Æ‚È‚è‚Ü‚·B
+
fname[]
+
8.3Œ`Ž®‚Ì–¼‘O‚ª'\0'‚ÅI‚í‚镶Žš—ñ‚Æ‚µ‚ÄŠi”[‚³‚ê‚Ü‚·B”ñLFN\¬‚Ì‚Æ‚«‚ÍAí‚ɑ啶Žš‚Å•Ô‚³‚ê‚Ü‚·BLFN\¬‚Ì‚Æ‚«‚Í’Z‚¢–¼‘O‚ª•Ô‚³‚ê‚Ü‚·‚ªAASCII‰pŽš‚ª¬•¶Žš‚É‚È‚éꇂª‚ ‚è‚Ü‚·B
+
lfname
+
•Ô‚³‚ê‚é’·‚¢ƒtƒ@ƒCƒ‹–¼‚ðŠi”[‚·‚éƒoƒbƒtƒ@‚ւ̃|ƒCƒ“ƒ^B‚±‚Ì\‘¢‘Ì‚ðŽg—p‚·‚é‘O‚ɃAƒvƒŠƒP[ƒVƒ‡ƒ“‚É‚æ‚艊ú‰»‚³‚ê‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB‚±‚̃ƒ“ƒo‚ÉNULL‚ªÝ’肳‚ê‚é‚ÆLFN‚Í•Ô‚³‚ê‚Ü‚¹‚ñB”ñLFN\¬‚Ì‚Æ‚«‚Í‚±‚̃ƒ“ƒo‚Í‘¶Ý‚µ‚Ü‚¹‚ñB
+
lfsize
+
’·‚¢ƒtƒ@ƒCƒ‹–¼‚ðŠi”[‚·‚éƒoƒbƒtƒ@‚̃TƒCƒY(•¶Žš”)B‚±‚Ì\‘¢‘Ì‚ðŽg—p‚·‚é‘O‚ɃAƒvƒŠƒP[ƒVƒ‡ƒ“‚É‚æ‚艊ú‰»‚³‚ê‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB”ñLFN\¬‚Ì‚Æ‚«‚Í‚±‚̃ƒ“ƒo‚Í‘¶Ý‚µ‚Ü‚¹‚ñB
+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/stat.html b/Lib/Fat/doc/ja/stat.html new file mode 100644 index 0000000..4bafcf9 --- /dev/null +++ b/Lib/Fat/doc/ja/stat.html @@ -0,0 +1,81 @@ + + + + + + + + +FatFs - f_stat + + + + +
+

f_stat

+
+FRESULT f_stat (
+  const TCHAR* FileName,  /* ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼‚ւ̃|ƒCƒ“ƒ^ */
+  FILINFO* FileInfo       /* ƒtƒ@ƒCƒ‹î•ñ\‘¢‘̂ւ̃|ƒCƒ“ƒ^ *
+);
+
+
+ +
+

ˆø”

+
+
FileName
+
î•ñ‚𓾂éƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼‚Ì'\0'‚ÅI‚í‚镶Žš—ñ‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
FileInfo
+
“Ç‚Ýo‚µ‚½ƒtƒ@ƒCƒ‹î•ñ‚ðŠi”[‚·‚éƒtƒ@ƒCƒ‹î•ñ\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
˜_—ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
˜_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNƒGƒŠƒA‚ªŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚ÉŠÖ‚·‚éî•ñ‚𓾂܂·B“¾‚ç‚ê‚éƒtƒ@ƒCƒ‹î•ñ‚ÌÚׂɂ‚¢‚Ä‚Í FILINFO\‘¢‘Ì‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B

+
+ + +
+

‘Ήžî•ñ

+

_FS_MINIMIZE == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/sync.html b/Lib/Fat/doc/ja/sync.html new file mode 100644 index 0000000..0b9852b --- /dev/null +++ b/Lib/Fat/doc/ja/sync.html @@ -0,0 +1,69 @@ + + + + + + + + +FatFs - f_sync + + + + +
+

f_sync

+

‘‚«ž‚Ý’†‚̃tƒ@ƒCƒ‹‚̃LƒƒƒbƒVƒ…‚³‚ꂽî•ñ‚ðƒtƒ‰ƒbƒVƒ…‚µ‚Ü‚·B

+
+FRESULT f_sync (
+  FIL* FileObject     /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
sync‚·‚éƒtƒ@ƒCƒ‹‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ª–³ŒøB
+
+
+ + +
+

‰ðà

+

‚±‚ÌŠÖ”‚Íf_close()‚Æ“¯‚¶ˆ—‚ðŽÀs‚µ‚Ü‚·‚ªAƒtƒ@ƒCƒ‹‚͈ø‚«‘±‚«ŠJ‚©‚ꂽ‚Ü‚Ü‚É‚È‚èA“Ç‚Ý‘‚«‚ð‘±s‚Å‚«‚Ü‚·BƒƒMƒ“ƒO‚È‚ÇA‘‚«ž‚݃‚[ƒh‚Å’·ŽžŠÔƒtƒ@ƒCƒ‹‚ªŠJ‚©‚ê‚Ä‚¢‚éƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚É‚¨‚¢‚ÄA’èŠú“I‚Ü‚½‚Í‹æØ‚è‚Ì—Ç‚¢‚Æ‚±‚ë‚Å‚±‚ÌŠÖ”‚ðŽg—p‚·‚邱‚Æ‚É‚æ‚èA•sˆÓ‚Ì“dŒ¹’f‚⃃fƒBƒA‚ÌŽæ‚èŠO‚µ‚É‚æ‚莸‚í‚ê‚éƒf[ƒ^‚ðŬ‚É‚·‚邱‚Æ‚ª‚Å‚«‚Ü‚·BŽÀÛ‚Ì‚Æ‚±‚ëAf_close()“à‚Å‚Í‚±‚ÌŠÖ”‚ðŒÄ‚Ño‚µ‚½Œãƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚𖳌ø‰»‚µ‚Ä‚¢‚邾‚¯‚È‚Ì‚ÅAf_close()’¼‘O‚Ìf_sync()‚͈Ӗ¡‚ª‚ ‚è‚Ü‚¹‚ñB

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

ŽQÆ

+

f_close

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/truncate.html b/Lib/Fat/doc/ja/truncate.html new file mode 100644 index 0000000..0487c7f --- /dev/null +++ b/Lib/Fat/doc/ja/truncate.html @@ -0,0 +1,72 @@ + + + + + + + + +FatFs - f_truncate + + + + +
+

f_truncate

+

ƒtƒ@ƒCƒ‹’·‚ðØ‚è‹l‚ß‚Ü‚·B

+
+FRESULT f_truncate (
+  FIL* FileObject     /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
Ø‚è‹l‚ß‘ÎÛƒtƒ@ƒCƒ‹‚̃tƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg‚ւ̃|ƒCƒ“ƒ^
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DENIED
+
ƒtƒ@ƒCƒ‹‚ª”ñ‘‚«ž‚݃‚[ƒh‚ÅŠJ‚©‚ê‚Ä‚¢‚éB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

ƒtƒ@ƒCƒ‹‚Ì’·‚³‚ªŒ»Ý‚̃tƒ@ƒCƒ‹R/Wƒ|ƒCƒ“ƒ^‚ÉØ‚è‹l‚ß‚ç‚ê‚Ü‚·Bƒtƒ@ƒCƒ‹R/Wƒ|ƒCƒ“ƒ^‚ªƒtƒ@ƒCƒ‹‚ÌI’[‚ðŽw‚µ‚Ä‚¢‚é‚Æ‚«‚ÍA‚±‚ÌŠÖ”‚͉½‚ÌŒø‰Ê‚àŽ‚¿‚Ü‚¹‚ñB

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

ŽQÆ

+

f_open, f_lseek, FIL

+
+ + +

Return

+ + diff --git a/Lib/Fat/doc/ja/unlink.html b/Lib/Fat/doc/ja/unlink.html new file mode 100644 index 0000000..1cbfa65 --- /dev/null +++ b/Lib/Fat/doc/ja/unlink.html @@ -0,0 +1,79 @@ + + + + + + + + +FatFs - f_unlink + + + + +
+

f_unlink

+

ƒIƒuƒWƒFƒNƒg‚ð휂µ‚Ü‚·B

+
+FRESULT f_unlink (
+  const TCHAR* FileName  /* ƒIƒuƒWƒFƒNƒg–¼‚ւ̃|ƒCƒ“ƒ^ */
+);
+
+
+ +
+

ˆø”

+
+
FileName
+
휑Îۂ̃tƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_DRIVE
+
ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_DENIED
+
‘ÎÛƒIƒuƒWƒFƒNƒg‚ªƒŠ[ƒhEƒIƒ“ƒŠ[‘®«AƒfƒBƒŒƒNƒgƒŠ‚Ìꇂ͋ó‚Å‚È‚¢ê‡‚È‚ÇB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
˜_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ªŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_LOCKED
+
ƒtƒ@ƒCƒ‹‹¤—L‹@”\‚É‚æ‚éƒAƒNƒZƒX‹‘”ÛB
+
+
+ + +
+

‰ðà

+

ƒIƒuƒWƒFƒNƒg‚ð휂µ‚Ü‚·BŠJ‚©‚ê‚Ä‚¢‚éƒIƒuƒWƒFƒNƒg‚âƒJƒŒƒ“ƒgEƒfƒBƒŒƒNƒgƒŠ‚Í휂µ‚Ä‚Í‚È‚è‚Ü‚¹‚ñB

+
+ +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/utime.html b/Lib/Fat/doc/ja/utime.html new file mode 100644 index 0000000..e143c0d --- /dev/null +++ b/Lib/Fat/doc/ja/utime.html @@ -0,0 +1,108 @@ + + + + + + + + +FatFs - f_utime + + + + +
+

f_utime

+

ƒIƒuƒWƒFƒNƒg‚̃^ƒCƒ€ƒXƒ^ƒ“ƒv‚ð•ÏX‚µ‚Ü‚·B

+
+FRESULT f_utime (
+  const TCHAR* FileName,   /* ƒIƒuƒWƒFƒNƒg–¼‚ւ̃|ƒCƒ“ƒ^ */
+  const FILINFO* TimeDate  /* Ý’è‚·‚é“ú•t */
+);
+
+
+ +
+

ˆø”

+
+
FileName
+
•ÏX‘Îۂ̃tƒ@ƒCƒ‹‚Ü‚½‚̓fƒBƒŒƒNƒgƒŠ‚ւ̃pƒX–¼‚Ì“ü‚Á‚½'\0'‚ÅI‚í‚镶Žš—ñ‚ðŽw’肵‚Ü‚·B
+
TimeDate
+
Ý’è‚·‚é“ú•t‚ÆŽžŠÔ‚ðfdate‚Æftimeƒƒ“ƒo‚Éݒ肳‚ꂽFILINFO\‘¢‘̂ւ̃|ƒCƒ“ƒ^B‘¼‚̃ƒ“ƒo‚ÍDon't care‚Å‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_NO_FILE
+
ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_NO_PATH
+
ƒpƒX‚ªŒ©‚‚©‚ç‚È‚¢B
+
FR_INVALID_NAME
+
ƒpƒX–¼‚ª•s³B
+
FR_INVALID_NAME
+
˜_—ƒhƒ‰ƒCƒu”Ô†‚ª•s³B
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_WRITE_PROTECTED
+
ƒƒfƒBƒA‚ª‘‚«ž‚Ý‹ÖŽ~ó‘ÔB
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_ENABLED
+
‚»‚̘_—ƒhƒ‰ƒCƒu‚Ƀ[ƒNEƒGƒŠƒA‚ª—^‚¦‚ç‚ê‚Ä‚¢‚È‚¢B
+
FR_NO_FILESYSTEM
+
—LŒø‚ÈFATƒ{ƒŠƒ…[ƒ€‚ªŒ©‚‚©‚ç‚È‚¢B
+
+
+ + +
+

‰ðà

+

ƒIƒuƒWƒFƒNƒg‚̃^ƒCƒ€ƒXƒ^ƒ“ƒv‚ð•ÏX‚µ‚Ü‚·B

+
+ + +
+

Žg—p—á

+
+FRESULT set_timestamp (
+    char *obj,     /* ƒtƒ@ƒCƒ‹–¼‚ւ̃|ƒCƒ“ƒ^ */
+    int year,
+    int month,
+    int mday,
+    int hour,
+    int min,
+    int sec
+)
+{
+    FILINFO fno;
+
+    fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
+    fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
+
+    return f_utime(obj, &fno);
+}
+
+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚ÅAŠŽ‚Â_FS_MINIMIZE == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + +
+

ŽQÆ

+

f_stat, FILINFO

+
+ +

–ß‚é

+ + diff --git a/Lib/Fat/doc/ja/write.html b/Lib/Fat/doc/ja/write.html new file mode 100644 index 0000000..4f82bf4 --- /dev/null +++ b/Lib/Fat/doc/ja/write.html @@ -0,0 +1,80 @@ + + + + + + + + +FatFs - f_write + + + + +
+

f_write

+

ƒtƒ@ƒCƒ‹‚Ƀf[ƒ^‚ð‘‚«ž‚Ý‚Ü‚·B

+
+FRESULT f_write (
+  FIL* FileObject,     /* ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg */
+  const void* Buffer,  /* ‘‚«ž‚݃f[ƒ^ */
+  UINT ByteToWrite,    /* ‘‚«ž‚ÞƒoƒCƒg” */
+  UINT* ByteWritten    /* ‘‚«ž‚܂ꂽƒoƒCƒg” */
+);
+
+
+ +
+

ˆø”

+
+
FileObject
+
ƒtƒ@ƒCƒ‹EƒIƒuƒWƒFƒNƒg\‘¢‘̂ւ̃|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
Buffer
+
‘‚«ž‚Þƒf[ƒ^‚ðŠi”[‚µ‚½ƒoƒbƒtƒ@‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B
+
ByteToWrite
+
‘‚«ž‚ÞƒoƒCƒg”(0`UINT‚ÌÅ‘å’l)‚ðŽw’肵‚Ü‚·B
+
ByteWritten
+
‘‚«ž‚܂ꂽƒoƒCƒg”‚ðŠi”[‚·‚é•Ï”‚ðŽw‚·ƒ|ƒCƒ“ƒ^‚ðŽw’肵‚Ü‚·B–ß‚è’l‚ÍŠÖ”‚̬”Û‚É‚©‚©‚í‚炸í‚É—LŒø‚Å‚·B
+
+
+ + +
+

–ß‚è’l

+
+
FR_OK (0)
+
³íI—¹B
+
FR_DENIED
+
”ñ‘‚«ž‚݃‚[ƒh‚ÅŠJ‚©‚ꂽƒtƒ@ƒCƒ‹‚É‘‚«ž‚à‚¤‚Æ‚µ‚½B
+
FR_DISK_ERR
+
ƒfƒBƒXƒNEƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_INT_ERR
+
•s³‚ÈFAT\‘¢‚Ü‚½‚Í“à•”ƒGƒ‰[‚É‚æ‚鎸”sB
+
FR_NOT_READY
+
ƒƒfƒBƒA‚ªƒZƒbƒg‚³‚ê‚Ä‚¢‚È‚¢‚È‚ÇA•¨—ƒhƒ‰ƒCƒu‚ª“®ì•s”\ó‘ÔB
+
FR_INVALID_OBJECT
+
–³Œø‚ȃtƒ@ƒCƒ‹ƒIƒuƒWƒFƒNƒgB
+
+
+ + +
+

‰ðà

+

‘‚«ž‚ÝŠJŽnˆÊ’u‚ÍAƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚̈ʒu‚©‚ç‚É‚È‚è‚Ü‚·BƒŠ[ƒh/ƒ‰ƒCƒgEƒ|ƒCƒ“ƒ^‚ÍŽÀÛ‚É‘‚«ž‚܂ꂽƒoƒCƒg”‚¾‚¯i‚Ý‚Ü‚·BŠÖ”‚ª³íI—¹‚µ‚½ŒãA—v‹‚µ‚½ƒoƒCƒg”‚ª‘‚«ž‚܂ꂽ‚©‚Ç‚¤‚©*ByteWritten‚ðƒ`ƒFƒbƒN‚·‚ׂ«‚Å‚·B*ByteWritten < ByteToWrite‚Ì‚Æ‚«‚ÍAƒfƒBƒXƒNEƒtƒ‹‚ðˆÓ–¡‚µ‚Ü‚·BƒfƒBƒXƒNEƒtƒ‹‚ª”­¶‚µ‚Ä‚¢‚é‚Æ‚«‚Ü‚½‚Í‚»‚ê‚É‹ß‚¢‚Æ‚«‚ÍA§Œä‚ª‹A‚é‚Ü‚ÅŽžŠÔ‚ª‚©‚©‚éꇂª‚ ‚è‚Ü‚·B

+
+ + +
+

‘Ήžî•ñ

+

_FS_READONLY == 0‚Ì‚Æ‚«‚ÉŽg—p‰Â”\‚Å‚·B

+
+ + + + +

–ß‚é

+ + diff --git a/Lib/Fat/doc/updates.txt b/Lib/Fat/doc/updates.txt new file mode 100644 index 0000000..95070dd --- /dev/null +++ b/Lib/Fat/doc/updates.txt @@ -0,0 +1,97 @@ +R0.08, May 15, 2010 + Added a memory configuration option. (_USE_LFN) + Added file lock feature. (_FS_SHARE) + Added fast seek feature. (_USE_FASTSEEK) + Changed some types on the API, XCHAR->TCHAR. + Changed fname member in the FILINFO structure on Unicode cfg. + String functions support UTF-8 encoding files on Unicode cfg. + +R0.07e, Nov 3, 2009 + Separated out configuration options from ff.h to ffconf.h. + Added a configuration option, _LFN_UNICODE. + Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. + Fixed name matching error on the 13 char boundary. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. + +R0.07c, Jun 21, 2009 + Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion to extended characters. + +R0.07a, Apr 14, 2009 + Separated out OS dependent code on re-entrant configuration. + Added multiple sector size support. + +R0.07, Apr 01, 2009 + Merged Tiny-FatFs into FatFs as a buffer configuration option. + Added long file name support. + Added multiple code page support. + Added re-entrancy for multitask operation. + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + +R0.06, Apr 01, 2008 + Added f_forward. (Tiny-FatFs) + Added string functions: fgets, fputc, fputs and fprintf. + Improved performance of f_lseek on moving to the same or following cluster. + +R0.05a, Feb 03, 2008 + Added f_truncate. + Added f_utime. + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read can be mistruncated. + Fixed cached sector is left not flushed when create and close without write. + +R0.05, Aug 26, 2007 + Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + +R0.04b, May 05, 2007 + Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (<= csize) collapses the file object. + +R0.04a, Apr 01, 2007 + Supported multiple partitions on a plysical drive. (FatFs) + Added minimization level 3. + Added a capability of extending file size to f_lseek. + Fixed an endian sensitive code in f_mkfs. (FatFs) + Fixed a problem corresponds to FAT32 support. (Tiny-FatFs) + +R0.04, Feb 04, 2007 + Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + +R0.03a, Dec 11, 2006 + Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + +R0.03, Sep 22, 2006 + Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + +R0.02a, Jun 10, 2006 + Added a configuration option _FS_MINIMUM. + +R0.02, Jun 01, 2006 + Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + +R0.01, Apr 29, 2006 + First release + +R0.00, Feb 26, 2006 + Prototype (not released) + diff --git a/Lib/Fat/src/00readme.txt b/Lib/Fat/src/00readme.txt new file mode 100644 index 0000000..b63874a --- /dev/null +++ b/Lib/Fat/src/00readme.txt @@ -0,0 +1,117 @@ +FatFs Module Source Files R0.08 (C)ChaN, 2010 + + +FILES + + ffconf.h Configuration file for FatFs module. + ff.h Common include file for FatFs and application module. + ff.c FatFs module. + diskio.h Common include file for FatFs and disk I/O module. + diskio.c Skeleton of low level disk I/O module. + integer.h Alternative type definitions for integer variables. + option Optional external functions. + + Low level disk I/O module is not included in this archive because the FatFs + module is only a generic file system layer and not depend on any specific + storage device. You have to provide a low level disk I/O module that written + to control your storage device. + + + +AGREEMENTS + + FatFs module is an open source software to implement FAT file system to + small embedded systems. This is a free software and is opened for education, + research and commercial developments under license policy of following trems. + + Copyright (C) 2010, ChaN, all right reserved. + + * The FatFs module is a free software and there is NO WARRANTY. + * No restriction on use. You can use, modify and redistribute it for + personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * Redistributions of source code must retain the above copyright notice. + + + +REVISION HISTORY + + Feb 26, 2006 R0.00 Prototype + + Apr 29, 2006 R0.01 First release. + + Jun 01, 2006 R0.02 Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + + Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. + + Sep 22, 2006 R0.03 Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + + Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + + Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + + Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) + Fixed an endian sensitive code in f_mkfs. (FatFs) + Added a capability of extending the file size to f_lseek. + Added minimization level 3. + Fixed a problem that can collapse a sector when recreate an + existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) + + May 05, 2007 R0.04b Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (0 < ofs <= csize) collapses the file object. + + Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + + Feb 03, 2008 R0.05a Added f_truncate(). + Added f_utime(). + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read() can be mistruncated. + Fixed cached sector is not flushed when create and close without write. + + Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) + Added string functions: fputc(), fputs(), fprintf() and fgets(). + Improved performance of f_lseek() on move to the same or following cluster. + + Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. + Added long file name support. + Added multiple code page support. + Added re-entrancy for multitask operation. + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + + Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. + Added multiple sector size support. + + Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion for extended characters. + + Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h. + Added a configuration option, _LFN_UNICODE. + Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. + Fixed name matching error on the 13 char boundary. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. + + May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN) + Added file lock feature. (_FS_SHARE) + Added fast seek feature. (_USE_FASTSEEK) + Changed some types on the API, XCHAR->TCHAR. + Changed fname member in the FILINFO structure on Unicode cfg. + String functions support UTF-8 encoding files on Unicode cfg. diff --git a/Lib/Fat/src/diskio.c b/Lib/Fat/src/diskio.c new file mode 100644 index 0000000..9c7f80e --- /dev/null +++ b/Lib/Fat/src/diskio.c @@ -0,0 +1,213 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* This is a stub disk I/O module that acts as front end of the existing */ +/* disk I/O modules and attach it to FatFs module with common interface. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" + +/*-----------------------------------------------------------------------*/ +/* Correspondence between physical drive number and physical drive. */ +/*-----------------------------------------------------------------------*/ + +#define ATA 0 +#define MMC 1 +#define USB 2 + + + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_initialize(); + // translate the reslut code here + + return stat; + + case MMC : + result = MMC_disk_initialize(); + // translate the reslut code here + + return stat; + + case USB : + result = USB_disk_initialize(); + // translate the reslut code here + + return stat; + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Return Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_status(); + // translate the reslut code here + + return stat; + + case MMC : + result = MMC_disk_status(); + // translate the reslut code here + + return stat; + + case USB : + result = USB_disk_status(); + // translate the reslut code here + + return stat; + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address (LBA) */ + BYTE count /* Number of sectors to read (1..255) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + + case MMC : + result = MMC_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + + case USB : + result = USB_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + } + return RES_PARERR; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ +/* The FatFs module will issue multiple sector transfer request +/ (count > 1) to the disk I/O layer. The disk function should process +/ the multiple sector transfer properly Do. not translate it into +/ multiple single sector transfers to the media, or the data read/write +/ performance may be drasticaly decreased. */ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0..) */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address (LBA) */ + BYTE count /* Number of sectors to write (1..255) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + + case MMC : + result = MMC_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + + case USB : + result = USB_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + } + return RES_PARERR; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + // pre-process here + + result = ATA_disk_ioctl(ctrl, buff); + // post-process here + + return res; + + case MMC : + // pre-process here + + result = MMC_disk_ioctl(ctrl, buff); + // post-process here + + return res; + + case USB : + // pre-process here + + result = USB_disk_ioctl(ctrl, buff); + // post-process here + + return res; + } + return RES_PARERR; +} + diff --git a/Lib/Fat/src/diskio.h b/Lib/Fat/src/diskio.h new file mode 100644 index 0000000..bbbe0d9 --- /dev/null +++ b/Lib/Fat/src/diskio.h @@ -0,0 +1,69 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +DSTATUS disk_initialize (BYTE); +DSTATUS disk_status (BYTE); +DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); +#if _READONLY == 0 +DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); +#endif +DRESULT disk_ioctl (BYTE, BYTE, void*); + + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */ +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + + +#define _DISKIO +#endif diff --git a/Lib/Fat/src/ff.c b/Lib/Fat/src/ff.c new file mode 100644 index 0000000..ff34b19 --- /dev/null +++ b/Lib/Fat/src/ff.c @@ -0,0 +1,3553 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.08 (C)ChaN, 2010 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed fname member in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 8085 +#error Wrong include file (ff.h). +#endif + + +/* FAT sub-type boundaries */ +/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */ +#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */ + + +/* Definitions corresponds to multiple sector size */ +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->ssize) +#else +#error Wrong sector size. +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + +/*------------------------------------------------------------*/ +/* Work area */ + +#if !_DRIVES +#error Number of drives must not be 0. +#endif +static +WORD Fsid; /* File system mount ID */ +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 0 /* No LFN */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN with static LFN working buffer */ +static WCHAR LfnBuf[_MAX_LFN + 1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof(int)) { + *(int*)d = *(int*)s; + d += sizeof(int); s += sizeof(int); + cnt -= sizeof(int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +int lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* File shareing control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_SHARE + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dj, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_SHARE; i++) { + if (dj->fs->flsem[i].ctr) { /* Existing entry */ + if (dj->fs->flsem[i].clu == dj->sclust && /* The file is found (identified with its location) */ + dj->fs->flsem[i].idx == dj->index) break; + } else { /* Blank entry */ + be++; + } + } + if (i == _FS_SHARE) /* The file has not been opened */ + return (be || acc != 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ + + /* The file has been opened. Reject any open against writing file and all write mode open */ + return (acc || dj->fs->flsem[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock ( /* Check if an entry is available for a new file */ + FATFS* fs /* File system object */ +) +{ + UINT i; + + for (i = 0; i < _FS_SHARE && fs->flsem[i].ctr; i++) ; + return (i == _FS_SHARE) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */ + DIR* dj, /* Directory object pointing the file to register or increment */ + int acc /* Desired access mode (0:Read, !0:Write) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_SHARE; i++) { /* Find the file */ + if (dj->fs->flsem[i].ctr && + dj->fs->flsem[i].clu == dj->sclust && + dj->fs->flsem[i].idx == dj->index) break; + } + + if (i == _FS_SHARE) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_SHARE && dj->fs->flsem[i].ctr; i++) ; + if (i == _FS_SHARE) return 0; /* No space to register (int err) */ + dj->fs->flsem[i].clu = dj->sclust; + dj->fs->flsem[i].idx = dj->index; + } + + if (acc && dj->fs->flsem[i].ctr) return 0; /* Access violation (int err) */ + + dj->fs->flsem[i].ctr = acc ? 0x100 : dj->fs->flsem[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement file open counter */ + FATFS* fs, /* File system object */ + UINT i /* Semaphore index */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_SHARE) { + n = fs->flsem[i].ctr; + if (n >= 0x100) n = 0; + if (n) n--; + fs->flsem[i].ctr = n; + res = FR_OK; + } else { + res = FR_INT_ERR; + } + return res; +} + +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drv, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, (void*)0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Chack range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "last link" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ + DIR *dj, /* Pointer to directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to generated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + int i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_sdi(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contiguous entry */ + if (++n == ne) break; /* A contiguous entry that required count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_sdi(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ +#if _USE_LFN + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const TCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */ +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = excvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if extended char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE nt, *dir; + TCHAR *p, c; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = (TCHAR)0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + TCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (TCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const TCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading separator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ + res = dir_sdi(dj, 0); + dj->dir = 0; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + ns = *(dj->fn+NS); + if (res != FR_OK) { /* Failed to find the object */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occured */ + /* Object not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ + dj->sclust = 0; dj->dir = 0; /* It is the root dir */ + res = FR_OK; + if (!(ns & NS_LAST)) continue; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; + } + break; + } + if (ns & NS_LAST) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ + const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, b, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + const TCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume (initialize the file system object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive (Supports only generic partitionings, FDISK and SFD) */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */ + if (fmt == 1) { /* Not an FAT-VBR, the disk may be partitioned */ + /* Check the partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= b; /* Number of sectors for FAT area */ + + fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be 1,2,4...128) */ + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / 32)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */ + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / 32); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->database = bsect + sysect; /* Data start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (FAT size must not be less than FAT sectors */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->last_clust = 0; + + /* Get fsinfo if available */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ + fs->winsect = 0; /* Invalidate sector cache */ + fs->wflag = 0; +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_SHARE /* Clear file lock semaphores */ + for (vol = 0; vol < _FS_SHARE; vol++) + fs->flsem[vol].ctr = 0; +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const TCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + fp->fs = 0; /* Clear file object */ + +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + INIT_BUF(dj); + if (res == FR_OK) + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; + +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_SHARE + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_SHARE + res = enq_lock(dj.fs) ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) { /* Cannot create new */ + res = FR_EXIST; + } else { + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) + mode |= FA__WRITTEN; /* Set file changed flag */ + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_SHARE + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* No cluster link map table */ +#endif + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = buff; + + + *br = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + BYTE csect; + + + *bw = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or stretch cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + +#if _FS_READONLY + FATFS *fs = fp->fs; + res = validate(fs, fp->id); + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + +#else + res = f_sync(fp); /* Flush cached data */ +#if _FS_SHARE + if (res == FR_OK) { /* Decrement open counter */ +#if _FS_REENTRANT + res = validate(fp->fs, fp->id); + if (res == FR_OK) { + res = dec_lock(fp->fs, fp->lockid); + unlock_fs(fp->fs, FR_OK); + } +#else + res = dec_lock(fp->fs, fp->lockid); +#endif + } +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, *tbl = fp->cltbl; + BYTE csc; + + tlen = *tbl++; + if (ofs == CREATE_LINKMAP) { /* Create link map table */ + cl = fp->org_clust; + if (cl) { + do { + if (tlen < 4) { /* Not enough table items */ + res = FR_NOT_ENOUGH_CORE; break; + } + tcl = cl; ncl = 0; + do { /* Get a fragment and store the top and length */ + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + *tbl++ = ncl; *tbl++ = tcl; + tlen -= 2; + } while (cl < fp->fs->n_fatent); + } + *tbl = 0; /* Terminate table */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + dsc = (ofs - 1) / SS(fp->fs); + cl = dsc / fp->fs->csize; + for (;;) { + ncl = *tbl++; + if (!ncl) ABORT(fp->fs, FR_INT_ERR); + if (cl < ncl) break; + cl -= ncl; tbl++; + } + fp->curr_clust = cl + *tbl; + csc = (BYTE)(dsc & (fp->fs->csize - 1)); + dsc = clust2sect(fp->fs, fp->curr_clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += csc; + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INIT_BUF(*dj); + res = follow_path(dj, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the current dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_sdi(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dj, 0); + } else { + INIT_BUF(*dj); + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) { + *nclst = (*fatfs)->free_clust; + } else { + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < (*fatfs)->n_fatent); + } else { + clst = (*fatfs)->n_fatent; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) break; + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + } + } + LEAVE_FF(*fatfs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__ERROR) { /* Check abort flag */ + res = FR_INT_ERR; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj); + if (res == FR_OK /* Not empty dir */ +#if _FS_RPATH + || dclst == sdj.fs->cdir /* Current dir */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync(dj.fs); + } + } + } + FREE_BUF(); + } + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tim = get_fattime(); + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = move_window(dj.fs, 0); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dcl); + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + ST_WORD(dir+32+DIR_FstClusLO, pcl); + ST_WORD(dir+32+DIR_FstClusHI, pcl >> 16); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */ + ST_WORD(dir+DIR_FstClusLO, dcl); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR *path_old, /* Pointer to the old name */ + const TCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + res = chk_mounted(&path_old, &djo.fs, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption or error can cause cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djn.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djn.fs, dw); + dir = djn.fs->win+32; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + djn.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 */ +#define N_FATS 1 /* 1 or 2 */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit size [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + BYTE fmt, md, *tbl; + DWORD n_clst, vs, n; + UINT as, i; + DWORD b_vol, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Area size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd == 1) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; + if (au & (au - 1)) au = 0; /* Check validity of the allocation unit size */ + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + if (_MAX_SS != 512 && au < SS(fs)) au = SS(fs); + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT syb-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = N_ROOTDIR * 32UL / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_DISK_ERR; + if (!n || n > 32768) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest boundary from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT start */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Create partition table if required */ + if (sfd == 1) { + md = 0xF0; + } else { + DWORD n_disk = b_vol + n_vol; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_vol < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + md = 0xF8; + } + + /* Create VBR */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + as = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, as); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + as = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */ + ST_WORD(tbl+BPB_RootEntCnt, as); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Original (VBR) */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Backup (VBR+6) */ + disk_write(drv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + for (i = 0; i < N_FATS; i++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0x0FFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0x0FFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector write */ + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + n = (fmt == FS_FAT32) ? as : n_dir; + while (n--) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_vol + 1, 1); /* Original (VBR+1) */ + disk_write(drv, tbl, b_vol + 7, 1); /* Backup (VBR+7) */ + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fil /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; /* Break on EOF or error */ + c = s[0]; +#if _LFN_UNICODE /* Read a character in UTF-8 encoding */ + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequense */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; + c = ((c & 0x1F) << 6) | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequense */ + f_read(fil, s, 2, &rc); + if (rc != 2) break; + c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequense */ + c = '?'; + } + } + } +#endif +#if _USE_STRFUNC >= 2 + if (c == '\r') continue; /* Strip '\r' */ +#endif + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + UINT bw, btw; + BYTE s[3]; + + +#if _USE_STRFUNC >= 2 + if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + +#if _LFN_UNICODE /* Write the character in UTF-8 encoding */ + if (c < 0x80) { /* 7-bit */ + s[0] = (BYTE)c; + btw = 1; + } else { + if (c < 0x800) { /* 11-bit */ + s[0] = (BYTE)(0xC0 | (c >> 6)); + s[1] = (BYTE)(0x80 | (c & 0x3F)); + btw = 2; + } else { /* 16-bit */ + s[0] = (BYTE)(0xE0 | (c >> 12)); + s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F)); + s[2] = (BYTE)(0x80 | (c & 0x3F)); + btw = 3; + } + } +#else /* Write the character without conversion */ + s[0] = (BYTE)c; + btw = 1; +#endif + f_write(fil, s, btw, &bw); /* Write the char to the file */ + return (bw == btw) ? 1 : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const TCHAR* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT i, w; + ULONG val; + TCHAR c, d, s[16]; + int res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *str++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + cc = f_puts(va_arg(arp, TCHAR*), fil); continue; + case 'C' : /* Character */ + cc = f_putc((TCHAR)va_arg(arp, int), fil); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown */ + cc = f_putc(c, fil); continue; + } + + /* Get an argument */ + val = (f & 2) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : va_arg(arp, unsigned int)); + if (d == 'D' && (val & 0x80000000)) { + val = 0 - val; + f |= 4; + } + /* Put it in numeral string */ + i = 0; + do { + d = (TCHAR)(val % r); val /= r; + if (d > 9) { + d += 7; + if (c == 'x') d += 0x20; + } + s[i++] = d + '0'; + } while (val && i < sizeof(s) / sizeof(s[0])); + if (f & 4) s[i++] = '-'; + cc = 0; + while (i < w-- && cc != EOF) { + cc = f_putc((TCHAR)((f & 1) ? '0' : ' '), fil); + res++; + } + do { + cc = f_putc(s[--i], fil); + res++; + } while (i && cc != EOF); + if (cc != EOF) cc = 0; + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/Lib/Fat/src/ff.h b/Lib/Fat/src/ff.h new file mode 100644 index 0000000..f4dc90c --- /dev/null +++ b/Lib/Fat/src/ff.h @@ -0,0 +1,613 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 8085 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Definitions corresponds to volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ +typedef struct { + BYTE pd; /* Physical drive# */ + BYTE pt; /* Partition # (0-3) */ +} PARTITION; +extern const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ + +#else /* Single partition configuration */ +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* Definitions corresponds to file shareing feature */ + +#if _FS_SHARE +#if _FS_READONLY +#error _FS_SHARE must be 0 on R/O cfg. +#endif +typedef struct { + DWORD clu; /* File ID 1, directory */ + WORD idx; /* File ID 2, index in the directory */ + WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:in write open */ +} FILESEM; +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1,2) */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /* Bytes per sector (512,1024,2048,4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector (FAT32) */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /* Sectors per FAT */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ +#if _FS_SHARE + FILESEM flsem[_FS_SHARE]; /* File lock semaphores */ +#endif +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE flag; /* File status flags */ + BYTE pad1; + DWORD fptr; /* File read/write pointer */ + DWORD fsize; /* File size */ + DWORD org_clust; /* File start cluster (0 when fsize==0) */ + DWORD curr_clust; /* Current cluster */ + DWORD dsect; /* Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Ponter to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table */ +#endif +#if _FS_SHARE + UINT lockid; /* File lock ID */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + int lfsize; /* Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Acces denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ +FRESULT f_close (FIL*); /* Close an open file object */ +FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ +FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ +#if !_FS_READONLY +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ +FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL*); /* Truncate file */ +FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ +FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ +FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ +FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ +FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ +#endif +#if _USE_FORWARD +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ +#endif +#if _USE_MKFS +FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */ +#endif +#if _FS_RPATH +FRESULT f_chdir (const TCHAR*); /* Change current directory */ +FRESULT f_chdrive (BYTE); /* Change current drive */ +#endif +#if _USE_STRFUNC +int f_putc (TCHAR, FIL*); /* Put a character to the file */ +int f_puts (const TCHAR*, FIL*); /* Put a string to the file */ +int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */ +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#ifndef EOF +#define EOF (-1) +#endif +#endif + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT); /* Allocate memory block */ +void ff_memfree (void*); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */ +int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ +int ff_req_grant (_SYNC_t); /* Lock sync object */ +void ff_rel_grant (_SYNC_t); /* Unlock sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#define FA__ERROR 0x80 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek function */ +#define CREATE_LINKMAP 0xFFFFFFFF + + +/* FatFs refers the members in the FAT structures with byte offset instead of +/ structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/Lib/Fat/src/ffconf.h b/Lib/Fat/src/ffconf.h new file mode 100644 index 0000000..dba0e68 --- /dev/null +++ b/Lib/Fat/src/ffconf.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 932 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. */ + + +#define _FS_RPATH 0 /* 0:Disable or 1:Enable */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0:Single parition or 1:Multiple partition */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* Include a header file here to define O/S system calls */ +/* #include , , or ohters. */ + +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONFIG */ diff --git a/Lib/Fat/src/integer.h b/Lib/Fat/src/integer.h new file mode 100644 index 0000000..137b988 --- /dev/null +++ b/Lib/Fat/src/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/Lib/Fat/src/option/cc932.c b/Lib/Fat/src/option/cc932.c new file mode 100644 index 0000000..a5bb707 --- /dev/null +++ b/Lib/Fat/src/option/cc932.c @@ -0,0 +1,3798 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ +/* */ +/* CP932 (Japanese Shift-JIS) */ +/*------------------------------------------------------------------------*/ + +#include "../ff.h" + +#define _TINY_TABLE 0 + +#if !_USE_LFN || _CODE_PAGE != 932 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2sjis[] = { +/* Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, */ + 0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D, + 0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180, + 0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2, + 0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6, + 0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA, + 0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE, + 0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2, + 0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6, + 0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2, + 0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6, + 0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA, + 0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE, + 0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2, + 0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6, + 0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442, + 0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447, + 0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B, + 0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F, + 0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453, + 0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457, + 0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B, + 0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F, + 0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472, + 0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477, + 0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B, + 0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480, + 0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484, + 0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488, + 0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C, + 0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490, + 0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C, + 0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168, + 0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163, + 0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6, + 0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0, + 0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757, + 0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B, + 0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41, + 0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45, + 0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49, + 0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB, + 0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD, + 0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9, + 0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187, + 0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8, + 0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7, + 0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6, + 0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF, + 0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2, + 0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB, + 0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740, + 0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744, + 0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748, + 0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C, + 0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750, + 0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F, + 0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1, + 0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4, + 0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5, + 0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7, + 0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6, + 0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8, + 0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9, + 0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1, + 0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5, + 0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B, + 0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A, + 0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4, + 0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141, + 0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159, + 0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173, + 0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177, + 0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7, + 0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780, + 0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1, + 0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5, + 0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9, + 0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD, + 0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1, + 0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5, + 0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9, + 0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD, + 0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1, + 0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5, + 0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9, + 0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD, + 0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1, + 0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5, + 0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9, + 0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD, + 0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1, + 0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5, + 0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9, + 0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED, + 0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1, + 0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154, + 0x309E, 0x8155, 0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342, + 0x30A4, 0x8343, 0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346, + 0x30A8, 0x8347, 0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A, + 0x30AC, 0x834B, 0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E, + 0x30B0, 0x834F, 0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352, + 0x30B4, 0x8353, 0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356, + 0x30B8, 0x8357, 0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A, + 0x30BC, 0x835B, 0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E, + 0x30C0, 0x835F, 0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362, + 0x30C4, 0x8363, 0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366, + 0x30C8, 0x8367, 0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A, + 0x30CC, 0x836B, 0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E, + 0x30D0, 0x836F, 0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372, + 0x30D4, 0x8373, 0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376, + 0x30D8, 0x8377, 0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A, + 0x30DC, 0x837B, 0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E, + 0x30E0, 0x8380, 0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383, + 0x30E4, 0x8384, 0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387, + 0x30E8, 0x8388, 0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B, + 0x30EC, 0x838C, 0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F, + 0x30F0, 0x8390, 0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393, + 0x30F4, 0x8394, 0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145, + 0x30FC, 0x815B, 0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A, + 0x3232, 0x878B, 0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786, + 0x32A6, 0x8787, 0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765, + 0x330D, 0x8769, 0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761, + 0x3323, 0x876B, 0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C, + 0x3336, 0x8766, 0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D, + 0x334D, 0x8762, 0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E, + 0x337C, 0x878F, 0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772, + 0x338F, 0x8773, 0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771, + 0x33A1, 0x8775, 0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA, + 0x4E01, 0x929A, 0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4, + 0x4E09, 0x8E4F, 0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573, + 0x4E0E, 0x975E, 0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E, + 0x4E15, 0x98A1, 0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75, + 0x4E19, 0x95B8, 0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0, + 0x4E28, 0xFA68, 0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3, + 0x4E32, 0x8BF8, 0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F, + 0x4E3B, 0x8EE5, 0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7, + 0x4E43, 0x9454, 0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1, + 0x4E4E, 0x8CC1, 0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8, + 0x4E57, 0x8FE6, 0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3, + 0x4E5E, 0x8CEE, 0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790, + 0x4E73, 0x93FB, 0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA, + 0x4E85, 0x98AB, 0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188, + 0x4E8A, 0x98AD, 0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0, + 0x4E91, 0x895D, 0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4, + 0x4E98, 0x986A, 0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F, + 0x4E9E, 0x98B1, 0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653, + 0x4EA2, 0x98B4, 0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692, + 0x4EA8, 0x8B9C, 0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0, + 0x4EAE, 0x97BA, 0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7, + 0x4EBA, 0x906C, 0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC, + 0x4EC4, 0x98BA, 0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1, + 0x4ECB, 0x89EE, 0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7, + 0x4ED4, 0x8E65, 0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD, + 0x4ED8, 0x9574, 0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE, + 0x4EDF, 0x98C0, 0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF, + 0x4EE5, 0x88C8, 0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2, + 0x4EF2, 0x9287, 0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443, + 0x4EFC, 0xFA6A, 0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C, + 0x4F09, 0x98C2, 0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA, + 0x4F0F, 0x959A, 0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF, + 0x4F1C, 0x98E5, 0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4, + 0x4F34, 0x94BA, 0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D, + 0x4F3A, 0x8E66, 0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF, + 0x4F46, 0x9241, 0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1, + 0x4F4F, 0x8F5A, 0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC, + 0x4F55, 0x89BD, 0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D, + 0x4F5A, 0x98C3, 0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6, + 0x4F5E, 0x9B43, 0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF, + 0x4F73, 0x89C0, 0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD, + 0x4F7C, 0x8CF1, 0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2, + 0x4F88, 0x98CA, 0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98, + 0x4F8F, 0x98CB, 0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72, + 0x4F96, 0x98D3, 0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F, + 0x4F9D, 0x88CB, 0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44, + 0x4FAD, 0x9699, 0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E, + 0x4FB6, 0x97B5, 0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3, + 0x4FC4, 0x89E2, 0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73, + 0x4FCE, 0x98D7, 0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5, + 0x4FD7, 0x91AD, 0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9, + 0x4FDD, 0x95DB, 0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693, + 0x4FE4, 0x98DD, 0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB, + 0x4FF3, 0x946F, 0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE, + 0x4FFA, 0x89B4, 0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4, + 0x5006, 0x98ED, 0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B, + 0x500F, 0xE0C5, 0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1, + 0x5016, 0x8CF4, 0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77, + 0x501F, 0x8ED8, 0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED, + 0x5024, 0x926C, 0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0, + 0x5029, 0x98E8, 0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9, + 0x502D, 0x9860, 0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74, + 0x5042, 0xFA7A, 0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF, + 0x5048, 0x98F3, 0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2, + 0x5055, 0x98F1, 0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2, + 0x5065, 0x8C92, 0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3, + 0x5074, 0x91A4, 0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7, + 0x507D, 0x8B55, 0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654, + 0x5091, 0x8C86, 0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5, + 0x509A, 0x98F9, 0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC, + 0x50B3, 0x9942, 0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D, + 0x50BE, 0x8C58, 0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940, + 0x50CA, 0x9941, 0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1, + 0x50D5, 0x966C, 0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB, + 0x50DE, 0x9945, 0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D, + 0x50ED, 0x9947, 0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B, + 0x50F9, 0x994A, 0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D, + 0x5102, 0x994E, 0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2, + 0x5114, 0x9951, 0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4, + 0x511A, 0x9952, 0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744, + 0x5132, 0x96D7, 0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957, + 0x513C, 0x9956, 0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2, + 0x5143, 0x8CB3, 0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B, + 0x5147, 0x8BA2, 0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E, + 0x514B, 0x8D8E, 0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365, + 0x5150, 0x8E99, 0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D, + 0x515C, 0x8A95, 0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC, + 0x5168, 0x9153, 0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA, + 0x516C, 0x8CF6, 0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4, + 0x5175, 0x95BA, 0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354, + 0x517C, 0x8C93, 0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0, + 0x5186, 0x897E, 0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965, + 0x518D, 0x8DC4, 0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968, + 0x5192, 0x9660, 0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B, + 0x5197, 0x8FE7, 0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5, + 0x51A2, 0x996E, 0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D, + 0x51A8, 0x9579, 0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971, + 0x51AC, 0x937E, 0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974, + 0x51B3, 0x9972, 0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8, + 0x51B7, 0x97E2, 0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6, + 0x51C5, 0x9978, 0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C, + 0x51CC, 0x97BD, 0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A, + 0x51DC, 0xEAA3, 0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D, + 0x51E6, 0x8F88, 0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2, + 0x51EC, 0xFA83, 0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D, + 0x51F5, 0x9981, 0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A, + 0x51FA, 0x8F6F, 0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381, + 0x5203, 0x906E, 0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8, + 0x5208, 0x8AA0, 0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986, + 0x5211, 0x8C59, 0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1, + 0x521D, 0x8F89, 0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987, + 0x5229, 0x9798, 0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E, + 0x5233, 0x998A, 0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94, + 0x5239, 0x998B, 0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4, + 0x5244, 0x998D, 0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E, + 0x524C, 0x998F, 0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991, + 0x5256, 0x9655, 0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95, + 0x5264, 0x8DDC, 0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992, + 0x526F, 0x959B, 0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84, + 0x5273, 0x9995, 0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997, + 0x527F, 0x9996, 0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C, + 0x5289, 0x97AB, 0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A, + 0x5294, 0x9999, 0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7, + 0x52A0, 0x89C1, 0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95, + 0x52AA, 0x9377, 0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1, + 0x52AF, 0xFB77, 0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3, + 0x52B9, 0x8CF8, 0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87, + 0x52C1, 0x99A4, 0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745, + 0x52C9, 0x95D7, 0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE, + 0x52D7, 0x99A6, 0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88, + 0x52DD, 0x8F9F, 0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB, + 0x52E2, 0x90A8, 0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9, + 0x52E7, 0x8AA9, 0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD, + 0x52F8, 0x99AE, 0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9, + 0x52FF, 0x96DC, 0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5, + 0x5305, 0x95EF, 0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1, + 0x530D, 0x99B3, 0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6, + 0x5316, 0x89BB, 0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7, + 0x531D, 0x9178, 0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8, + 0x5324, 0xFA8B, 0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA, + 0x5333, 0x99BB, 0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6, + 0x533B, 0x88E3, 0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C, + 0x5343, 0x90E7, 0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1, + 0x5348, 0x8CDF, 0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2, + 0x5351, 0x94DA, 0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6, + 0x5357, 0x93EC, 0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D, + 0x535E, 0x99C4, 0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5, + 0x536E, 0x99C6, 0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB, + 0x5372, 0xFA8C, 0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791, + 0x5377, 0x99C9, 0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8, + 0x5382, 0x99CA, 0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB, + 0x5398, 0x97D0, 0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC, + 0x53A5, 0x99CE, 0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958, + 0x53AD, 0x897D, 0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E, + 0x53B3, 0x8CB5, 0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51, + 0x53C3, 0x99D2, 0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79, + 0x53CB, 0x9746, 0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB, + 0x53D4, 0x8F66, 0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96, + 0x53DB, 0x94BE, 0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962, + 0x53E2, 0x9170, 0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5, + 0x53E8, 0x99D9, 0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9, + 0x53EC, 0x8FA2, 0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2, + 0x53F0, 0x91E4, 0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945, + 0x53F6, 0x8A90, 0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB, + 0x5401, 0x99DC, 0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87, + 0x5409, 0x8B67, 0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF, + 0x540D, 0x96BC, 0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366, + 0x5411, 0x8CFC, 0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1, + 0x5420, 0x9669, 0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC, + 0x542C, 0x99DF, 0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3, + 0x5438, 0x8B7A, 0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1, + 0x543D, 0x99DD, 0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843, + 0x5446, 0x95F0, 0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90, + 0x544E, 0x99E6, 0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC, + 0x546A, 0x8EF4, 0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1, + 0x5475, 0x99E8, 0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF, + 0x547C, 0x8CC4, 0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2, + 0x5486, 0x99F4, 0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861, + 0x548E, 0x99E9, 0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE, + 0x549C, 0xFA91, 0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8, + 0x54A8, 0x99FC, 0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9, + 0x54AF, 0x9A5D, 0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7, + 0x54BC, 0x9A44, 0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3, + 0x54C1, 0x9569, 0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5, + 0x54C8, 0x99FB, 0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5, + 0x54E2, 0x9A4E, 0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3, + 0x54E9, 0x9689, 0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E, + 0x54FA, 0x9A4D, 0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953, + 0x5506, 0x8DB4, 0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382, + 0x5514, 0x9A49, 0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742, + 0x5531, 0x8FA5, 0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F, + 0x553E, 0x91C1, 0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55, + 0x5546, 0x8FA4, 0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B, + 0x5556, 0x9A56, 0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A, + 0x5563, 0x9A51, 0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61, + 0x5580, 0x9A5C, 0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95, + 0x5587, 0x9A68, 0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D, + 0x5598, 0x9A62, 0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC, + 0x559D, 0x8A85, 0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96, + 0x55A8, 0x9A69, 0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69, + 0x55AC, 0x8BAA, 0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963, + 0x55C4, 0x9A6D, 0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70, + 0x55DA, 0x9A6A, 0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B, + 0x55E4, 0x9A6F, 0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75, + 0x55FE, 0x9A74, 0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71, + 0x5616, 0x9A73, 0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76, + 0x5629, 0x89DC, 0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D, + 0x5634, 0x9A7B, 0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C, + 0x564C, 0x9158, 0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A, + 0x5664, 0x9A81, 0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80, + 0x566C, 0x9A83, 0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6, + 0x5680, 0x9A86, 0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87, + 0x568F, 0x9A8A, 0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458, + 0x56A5, 0x9A8B, 0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D, + 0x56BC, 0x9A90, 0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F, + 0x56C3, 0x9A92, 0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96, + 0x56D3, 0x9A97, 0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA, + 0x56DB, 0x8E6C, 0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263, + 0x56EE, 0x9A99, 0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D, + 0x56F9, 0x9A9A, 0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C, + 0x5700, 0x9A9B, 0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F, + 0x5709, 0x9A9E, 0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97, + 0x5712, 0x8980, 0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3, + 0x571C, 0x9AA6, 0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3, + 0x5728, 0x8DDD, 0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8, + 0x5738, 0x9AA9, 0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2, + 0x5747, 0x8BCF, 0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD, + 0x5750, 0x8DBF, 0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1, + 0x5764, 0x8DA3, 0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE, + 0x576A, 0x92D8, 0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0, + 0x5789, 0x9AB3, 0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5, + 0x57A2, 0x8D43, 0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8, + 0x57AC, 0xFA98, 0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF, + 0x57C3, 0x9ABA, 0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99, + 0x57CB, 0x9684, 0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE, + 0x57D4, 0x9ABC, 0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6, + 0x57E0, 0x9575, 0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7, + 0x57F9, 0x947C, 0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678, + 0x5802, 0x93B0, 0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF, + 0x580B, 0x9AC2, 0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4, + 0x5821, 0x9AC6, 0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F, + 0x5830, 0x8981, 0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367, + 0x583A, 0x8DE4, 0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB, + 0x584A, 0x89F2, 0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB, + 0x5854, 0x9383, 0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7, + 0x585A, 0x92CB, 0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996, + 0x586B, 0x9355, 0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F, + 0x5879, 0x9ACD, 0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE, + 0x5893, 0x95E6, 0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D, + 0x589F, 0x9AD0, 0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6, + 0x58B2, 0xFA9E, 0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF, + 0x58BA, 0x9AD2, 0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7, + 0x58C5, 0x9AD7, 0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB, + 0x58D1, 0x9AD9, 0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA, + 0x58D8, 0x9ADC, 0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3, + 0x58DF, 0x9AE0, 0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D, + 0x58EC, 0x9070, 0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA, + 0x58F1, 0x88EB, 0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3, + 0x58FA, 0x9AE2, 0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6, + 0x5902, 0x9AE7, 0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F, + 0x590F, 0x89C4, 0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F, + 0x5918, 0x99C7, 0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA, + 0x591C, 0x96E9, 0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5, + 0x5929, 0x9356, 0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED, + 0x592D, 0x9AEE, 0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF, + 0x5937, 0x88CE, 0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982, + 0x5947, 0x8AEF, 0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5, + 0x594F, 0x9174, 0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0, + 0x5954, 0x967A, 0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7, + 0x595A, 0x9AF6, 0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9, + 0x5962, 0x9AF8, 0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA, + 0x5968, 0x8FA7, 0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB, + 0x596E, 0x95B1, 0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40, + 0x597D, 0x8D44, 0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC, + 0x5984, 0x96CF, 0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57, + 0x5996, 0x9764, 0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42, + 0x59A3, 0x9B45, 0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657, + 0x59AC, 0x9369, 0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5, + 0x59BB, 0x8DC8, 0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F, + 0x59CB, 0x8E6E, 0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9, + 0x59D4, 0x88CF, 0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49, + 0x59E5, 0x8957, 0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3, + 0x59EB, 0x9550, 0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70, + 0x5A01, 0x88D0, 0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F, + 0x5A18, 0x96BA, 0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E, + 0x5A20, 0x9050, 0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2, + 0x5A35, 0x9B56, 0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53, + 0x5A41, 0x984B, 0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5, + 0x5A62, 0x9B58, 0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54, + 0x5A7F, 0x96B9, 0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551, + 0x5ABC, 0x9B5B, 0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5, + 0x5AC2, 0x9B5E, 0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99, + 0x5AD0, 0x9B6B, 0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284, + 0x5AE3, 0x9B60, 0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65, + 0x5AFB, 0x9B66, 0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67, + 0x5B16, 0x9B69, 0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA, + 0x5B30, 0x8964, 0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E, + 0x5B40, 0x9B71, 0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71, + 0x5B51, 0x9B72, 0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6, + 0x5B57, 0x8E9A, 0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75, + 0x5B5C, 0x8E79, 0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47, + 0x5B64, 0x8CC7, 0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77, + 0x5B6B, 0x91B7, 0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79, + 0x5B75, 0x9B7A, 0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E, + 0x5B83, 0x9B80, 0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7, + 0x5B89, 0x88C0, 0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3, + 0x5B8F, 0x8D47, 0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF, + 0x5B99, 0x9288, 0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58, + 0x5B9D, 0x95F3, 0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9, + 0x5BA4, 0x8EBA, 0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B, + 0x5BB0, 0x8DC9, 0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA, + 0x5BB6, 0x89C6, 0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68, + 0x5BC0, 0xFAA7, 0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1, + 0x5BC5, 0x93D0, 0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85, + 0x5BCC, 0x9578, 0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5, + 0x5BD4, 0x9B86, 0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051, + 0x5BDE, 0x9B8B, 0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A, + 0x5BE4, 0x9B88, 0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A, + 0x5BE8, 0x9ECB, 0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA, + 0x5BEE, 0x97BE, 0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E, + 0x5BF6, 0x9B8F, 0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE, + 0x5BFF, 0x8EF5, 0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB, + 0x5C05, 0x9B91, 0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93, + 0x5C09, 0x88D1, 0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94, + 0x5C0E, 0x93B1, 0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95, + 0x5C16, 0x90EB, 0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96, + 0x5C22, 0x9B97, 0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4, + 0x5C31, 0x8F41, 0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA, + 0x5C3B, 0x904B, 0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6, + 0x5C3F, 0x9441, 0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F, + 0x5C46, 0x9B9C, 0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE, + 0x5C4D, 0x8E72, 0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F, + 0x5C51, 0x8BFB, 0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE, + 0x5C60, 0x936A, 0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A, + 0x5C6C, 0x9BA2, 0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52, + 0x5C76, 0x9BA5, 0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2, + 0x5C91, 0x9BA8, 0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC, + 0x5CA8, 0x915A, 0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6, + 0x5CB1, 0x91D0, 0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF, + 0x5CB8, 0x8ADD, 0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE, + 0x5CBE, 0x9BB1, 0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3, + 0x5CE0, 0x93BB, 0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4, + 0x5CEA, 0x9BB9, 0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4, + 0x5CF5, 0xFAAE, 0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73, + 0x5CFD, 0x9BB5, 0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8, + 0x5D11, 0x9BC0, 0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52, + 0x5D17, 0x9BBC, 0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3, + 0x5D1B, 0x9BBF, 0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF, + 0x5D29, 0x95F6, 0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6, + 0x5D4E, 0x9BC8, 0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0, + 0x5D5C, 0x9BBD, 0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3, + 0x5D6F, 0x8DB5, 0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF, + 0x5D84, 0x9BCE, 0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8, + 0x5D90, 0x9BD5, 0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2, + 0x5DAE, 0x9BD3, 0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5, + 0x5DBA, 0x97E4, 0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8, + 0x5DCC, 0x8ADE, 0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB, + 0x5DD3, 0x9BDA, 0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC, + 0x5DDE, 0x8F42, 0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48, + 0x5DE6, 0x8DB6, 0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE, + 0x5DEE, 0x8DB7, 0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4, + 0x5DF4, 0x9462, 0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA, + 0x5DFD, 0x9246, 0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A, + 0x5E06, 0x94BF, 0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4, + 0x5E16, 0x929F, 0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5, + 0x5E1D, 0x92E9, 0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8, + 0x5E2F, 0x91D1, 0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6, + 0x5E37, 0x9BE7, 0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA, + 0x5E43, 0x9BE9, 0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1, + 0x5E4C, 0x9679, 0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B, + 0x5E57, 0x9BEC, 0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF, + 0x5E63, 0x95BC, 0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD, + 0x5E74, 0x944E, 0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B, + 0x5E79, 0x8AB2, 0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763, + 0x5E7D, 0x9748, 0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1, + 0x5E83, 0x8D4C, 0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0, + 0x5E8F, 0x8F98, 0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358, + 0x5E9A, 0x8D4D, 0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378, + 0x5EA7, 0x8DC0, 0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1, + 0x5EB6, 0x8F8E, 0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8, + 0x5EC2, 0x9BF9, 0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5, + 0x5ECA, 0x984C, 0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66, + 0x5ED6, 0x9C40, 0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42, + 0x5EDF, 0x955F, 0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45, + 0x5EE3, 0x9C41, 0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49, + 0x5EF0, 0x9C4C, 0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D, + 0x5EF6, 0x8984, 0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A, + 0x5EFB, 0x89F4, 0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9, + 0x5F01, 0x95D9, 0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51, + 0x5F0A, 0x95BE, 0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF, + 0x5F0F, 0x8EAE, 0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C, + 0x5F14, 0x92A2, 0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4, + 0x5F18, 0x8D4F, 0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7, + 0x5F25, 0x96ED, 0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57, + 0x5F2D, 0x9C58, 0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8, + 0x5F35, 0x92A3, 0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A, + 0x5F3E, 0x9265, 0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B, + 0x5F4A, 0x8BAE, 0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F, + 0x5F53, 0x9396, 0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62, + 0x5F5C, 0x9C53, 0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60, + 0x5F66, 0x9546, 0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556, + 0x5F6B, 0x92A4, 0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2, + 0x5F71, 0x8965, 0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0, + 0x5F7C, 0x94DE, 0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA, + 0x5F82, 0x9C68, 0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2, + 0x5F87, 0x9C6D, 0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5, + 0x5F8C, 0x8CE3, 0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B, + 0x5F93, 0x8F5D, 0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F, + 0x5F9E, 0x9C6E, 0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72, + 0x5FA9, 0x959C, 0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7, + 0x5FB3, 0x93BF, 0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F, + 0x5FBC, 0x9C74, 0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B, + 0x5FCC, 0x8AF5, 0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75, + 0x5FD8, 0x9659, 0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A, + 0x5FDE, 0xFABB, 0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5, + 0x5FF0, 0x9CAB, 0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78, + 0x5FFB, 0x9C76, 0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83, + 0x600F, 0x9C89, 0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86, + 0x6016, 0x957C, 0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5, + 0x601D, 0x8E76, 0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D, + 0x6026, 0x9C88, 0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82, + 0x602A, 0x89F6, 0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84, + 0x603A, 0x9C8A, 0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94, + 0x6046, 0x9C91, 0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92, + 0x6050, 0x8BB0, 0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99, + 0x605A, 0x9C8B, 0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E, + 0x6062, 0x89F8, 0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270, + 0x6068, 0x8DA6, 0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98, + 0x606C, 0x9C97, 0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86, + 0x6075, 0x8C62, 0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D, + 0x6084, 0x9C9F, 0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE, + 0x608B, 0x9CA5, 0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3, + 0x6094, 0x89F7, 0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E, + 0x609B, 0x9CA0, 0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3, + 0x60A6, 0x8978, 0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB, + 0x60B2, 0x94DF, 0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE, + 0x60B6, 0x96E3, 0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC, + 0x60C5, 0x8FEE, 0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866, + 0x60D3, 0x9CA9, 0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B, + 0x60DC, 0x90C9, 0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8, + 0x60E1, 0x9CA6, 0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53, + 0x60F0, 0x91C4, 0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A, + 0x60F4, 0x9CB6, 0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4, + 0x60FA, 0x9CB7, 0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44, + 0x6103, 0x9CB8, 0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9, + 0x610D, 0x9CBC, 0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3, + 0x6115, 0x9CB1, 0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4, + 0x6120, 0xFAC1, 0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0, + 0x612C, 0x9CC5, 0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4, + 0x613C, 0x9CC4, 0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3, + 0x6142, 0x9CC8, 0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C, + 0x614A, 0x9CC2, 0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0, + 0x614E, 0x9054, 0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC, + 0x6159, 0x9CCD, 0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4, + 0x6162, 0x969D, 0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64, + 0x6168, 0x8A53, 0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1, + 0x6170, 0x88D4, 0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0, + 0x6175, 0x9CD7, 0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C, + 0x6182, 0x974A, 0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E, + 0x6190, 0x97F7, 0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9, + 0x6198, 0xFAC6, 0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE, + 0x61A7, 0x93B2, 0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB, + 0x61AE, 0x9CE1, 0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9, + 0x61BE, 0x8AB6, 0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7, + 0x61C8, 0x9CE6, 0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA, + 0x61CC, 0x9CE2, 0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE, + 0x61E6, 0x9CED, 0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF, + 0x61F7, 0x9CE5, 0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4, + 0x61FD, 0x9CF3, 0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6, + 0x6208, 0x9CF7, 0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA, + 0x620D, 0x9CF9, 0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4, + 0x6212, 0x89FA, 0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD, + 0x621A, 0x90CA, 0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40, + 0x621F, 0x8C81, 0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42, + 0x622E, 0x9D43, 0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45, + 0x6233, 0x9D46, 0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF, + 0x623F, 0x965B, 0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE, + 0x6248, 0xE7BB, 0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB, + 0x624E, 0x9D48, 0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF, + 0x625B, 0x9D4B, 0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A, + 0x6268, 0x9D4D, 0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D, + 0x6279, 0x94E1, 0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3, + 0x6280, 0x8B5A, 0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4, + 0x6289, 0x9D50, 0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52, + 0x6293, 0x9D53, 0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54, + 0x6297, 0x8D52, 0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2, + 0x629E, 0x91F0, 0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB, + 0x62B1, 0x95F8, 0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A, + 0x62BC, 0x899F, 0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253, + 0x62C6, 0x9D5D, 0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66, + 0x62CA, 0x9D62, 0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B, + 0x62D0, 0x89FB, 0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1, + 0x62D4, 0x9D55, 0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9, + 0x62DB, 0x8FB5, 0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92, + 0x62E1, 0x8A67, 0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68, + 0x62EF, 0x9D6D, 0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E, + 0x62F6, 0x8E41, 0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C, + 0x6301, 0x8E9D, 0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C, + 0x6309, 0x88C2, 0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93, + 0x631F, 0x8BB2, 0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1, + 0x632F, 0x9055, 0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70, + 0x633F, 0x917D, 0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71, + 0x634F, 0x9D73, 0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB, + 0x635C, 0x917B, 0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80, + 0x636B, 0x9D7E, 0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78, + 0x6377, 0x8FB7, 0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76, + 0x6383, 0x917C, 0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6, + 0x638E, 0x9D75, 0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74, + 0x6398, 0x8C40, 0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9, + 0x63A1, 0x8DCC, 0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA, + 0x63A7, 0x8D54, 0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B, + 0x63AB, 0x9D77, 0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD, + 0x63B5, 0x9D7D, 0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83, + 0x63C3, 0x91B5, 0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86, + 0x63CF, 0x9560, 0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B, + 0x63DA, 0x9767, 0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85, + 0x63E9, 0x9D82, 0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9, + 0x63F6, 0x9D88, 0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9, + 0x640F, 0x9D93, 0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91, + 0x641C, 0x9D72, 0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0, + 0x642D, 0x938B, 0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67, + 0x643E, 0x8DEF, 0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345, + 0x6460, 0xFACA, 0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95, + 0x6476, 0x9D96, 0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82, + 0x6488, 0x9D9D, 0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99, + 0x649A, 0x9451, 0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350, + 0x64A5, 0x9D9B, 0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464, + 0x64AE, 0x8E42, 0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68, + 0x64BB, 0x9DA3, 0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5, + 0x64C5, 0x9DA1, 0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC, + 0x64D2, 0x9DA0, 0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F, + 0x64E0, 0x9DA9, 0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC, + 0x64E6, 0x8E43, 0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD, + 0x64F1, 0x9DA6, 0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF, + 0x64FA, 0x9DB2, 0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3, + 0x6505, 0x9DB7, 0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90, + 0x6523, 0x9DB9, 0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA, + 0x652C, 0x9DAE, 0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC, + 0x6536, 0x9DBE, 0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC, + 0x653B, 0x8D55, 0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC, + 0x6548, 0x9DC1, 0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571, + 0x6551, 0x8B7E, 0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473, + 0x6558, 0x9DC5, 0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6, + 0x6562, 0x8AB8, 0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68, + 0x6570, 0x9094, 0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347, + 0x6577, 0x957E, 0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB, + 0x6587, 0x95B6, 0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B, + 0x658E, 0x8DD6, 0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C, + 0x6599, 0x97BF, 0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE, + 0x65A1, 0x88B4, 0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580, + 0x65AB, 0x9DCF, 0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A, + 0x65B0, 0x9056, 0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997, + 0x65BD, 0x8E7B, 0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4, + 0x65C5, 0x97B7, 0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5, + 0x65CF, 0x91B0, 0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8, + 0x65DB, 0x9DD7, 0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9, + 0x65E5, 0x93FA, 0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C, + 0x65E9, 0x9181, 0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB, + 0x65FA, 0x89A0, 0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56, + 0x6603, 0x9DDE, 0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1, + 0x660A, 0x9DDD, 0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8, + 0x6613, 0x88D5, 0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4, + 0x661E, 0xFAD3, 0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4, + 0x6625, 0x8F74, 0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA, + 0x662E, 0xFAD2, 0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3, + 0x6635, 0x9DE1, 0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B, + 0x663F, 0x9E45, 0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57, + 0x6644, 0x9DE6, 0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5, + 0x6652, 0x8E4E, 0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA, + 0x665E, 0x9DE9, 0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB, + 0x6665, 0xFAD5, 0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED, + 0x6669, 0x94D3, 0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0, + 0x6673, 0xFAD9, 0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271, + 0x6681, 0x8BC5, 0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9, + 0x6688, 0x9DF2, 0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B, + 0x6696, 0x9267, 0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA, + 0x669D, 0x9DF7, 0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF, + 0x66AB, 0x8E62, 0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C, + 0x66B8, 0x9E41, 0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB, + 0x66BF, 0xFADD, 0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC, + 0x66C9, 0x9DFA, 0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43, + 0x66DC, 0x976A, 0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46, + 0x66E9, 0x9E47, 0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967, + 0x66F4, 0x8D58, 0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91, + 0x66F9, 0x9182, 0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6, + 0x66FD, 0x915D, 0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5, + 0x6703, 0x98F0, 0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC, + 0x670D, 0x959E, 0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1, + 0x6715, 0x92BD, 0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D, + 0x671D, 0x92A9, 0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E, + 0x6727, 0x9E4F, 0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696, + 0x672C, 0x967B, 0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9, + 0x6734, 0x9670, 0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55, + 0x673A, 0x8AF7, 0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54, + 0x6746, 0x9E57, 0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7, + 0x6750, 0x8DDE, 0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1, + 0x6759, 0x9E5A, 0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9, + 0x6760, 0x9E59, 0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B, + 0x6764, 0x9E5C, 0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61, + 0x676D, 0x8D59, 0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C, + 0x6772, 0x9DDC, 0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466, + 0x677C, 0x9E60, 0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66, + 0x6787, 0x94F8, 0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62, + 0x6790, 0x90CD, 0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687, + 0x679C, 0x89CA, 0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65, + 0x67A2, 0x9095, 0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD, + 0x67B3, 0x9E6B, 0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67, + 0x67B8, 0x9E6D, 0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4, + 0x67C1, 0x91C6, 0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541, + 0x67CE, 0x9E74, 0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9, + 0x67D3, 0x90F5, 0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D, + 0x67DD, 0x9E70, 0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E, + 0x67E7, 0x9E76, 0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72, + 0x67EF, 0x9E68, 0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4, + 0x67F5, 0x8DF2, 0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60, + 0x6801, 0xFAE5, 0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968, + 0x6813, 0x90F0, 0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78, + 0x6821, 0x8D5A, 0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94, + 0x682B, 0x9E81, 0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A, + 0x6839, 0x8DAA, 0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B, + 0x6841, 0x8C85, 0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6, + 0x6846, 0x9E79, 0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E, + 0x6850, 0x8BCB, 0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA, + 0x6854, 0x8B6A, 0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691, + 0x685F, 0x8E56, 0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F, + 0x6876, 0x89B1, 0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85, + 0x6881, 0x97C0, 0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94, + 0x688F, 0x9E87, 0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B, + 0x689B, 0x9E8B, 0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91, + 0x68A2, 0x8FBD, 0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C, + 0x68AD, 0x9E88, 0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB, + 0x68B3, 0x9E80, 0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E, + 0x68BA, 0x9E92, 0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0, + 0x68C8, 0xFA64, 0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB, + 0x68CD, 0x9E9E, 0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F, + 0x68D5, 0x9EA1, 0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249, + 0x68DF, 0x938F, 0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6, + 0x68E7, 0x9EA0, 0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1, + 0x68F9, 0x9EA8, 0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96, + 0x6904, 0x9EA4, 0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8, + 0x690C, 0x9E9D, 0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93, + 0x6912, 0x9EA3, 0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91, + 0x691C, 0x8C9F, 0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE, + 0x6925, 0x9EA7, 0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC, + 0x6930, 0x9EBD, 0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9, + 0x693D, 0x9EBB, 0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596, + 0x6954, 0x9EB6, 0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E, + 0x695C, 0x9EB3, 0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED, + 0x6961, 0x9EBE, 0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2, + 0x696B, 0x9EB5, 0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C, + 0x6973, 0x9480, 0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2, + 0x6978, 0x9EB4, 0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79, + 0x697E, 0x9EB7, 0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5, + 0x698E, 0x897C, 0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5, + 0x6998, 0xFAEB, 0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3, + 0x69A7, 0x9ED0, 0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3, + 0x69B4, 0x9ED6, 0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6, + 0x69C1, 0x9EC7, 0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC, + 0x69CB, 0x8D5C, 0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA, + 0x69D0, 0x9EC5, 0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A, + 0x69DD, 0x9ECD, 0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF, + 0x69E8, 0x9ED8, 0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE, + 0x69F9, 0x9EDD, 0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB, + 0x6A02, 0x9ED9, 0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3, + 0x6A0C, 0x9EEC, 0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4, + 0x6A17, 0x9294, 0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2, + 0x6A1F, 0x8FBE, 0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9, + 0x6A29, 0x8CA0, 0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1, + 0x6A30, 0xFAED, 0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5, + 0x6A39, 0x8EF7, 0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB, + 0x6A46, 0xFAEF, 0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4, + 0x6A58, 0x8B6B, 0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9, + 0x6A62, 0x9EF1, 0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED, + 0x6A73, 0xFAF0, 0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80, + 0x6A80, 0x9268, 0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7, + 0x6A90, 0x9EF7, 0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9, + 0x6AA2, 0x9EFB, 0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47, + 0x6AAE, 0x9E8D, 0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42, + 0x6AC1, 0x9EE8, 0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49, + 0x6AD3, 0x9845, 0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48, + 0x6ADF, 0x9F4A, 0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5, + 0x6AEA, 0x9F4D, 0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793, + 0x6B05, 0x9F4F, 0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53, + 0x6B1D, 0x8954, 0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F, + 0x6B23, 0x8BD3, 0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57, + 0x6B38, 0x9F56, 0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4, + 0x6B3E, 0x8ABC, 0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D, + 0x6B4C, 0x89CC, 0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD, + 0x6B54, 0x9F60, 0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62, + 0x6B61, 0x9F63, 0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F, + 0x6B66, 0x9590, 0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95, + 0x6B73, 0x8DCE, 0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65, + 0x6B7B, 0x8E80, 0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69, + 0x6B84, 0x9F68, 0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA, + 0x6B8B, 0x8E63, 0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042, + 0x6B98, 0x9F6B, 0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F, + 0x6BAB, 0x9F70, 0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72, + 0x6BB3, 0x9F74, 0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75, + 0x6BBA, 0x8E45, 0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361, + 0x6BC0, 0x9ACA, 0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78, + 0x6BCD, 0x95EA, 0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79, + 0x6BD4, 0x94E4, 0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1, + 0x6BDF, 0x9F7A, 0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E, + 0x6BF3, 0x9F7D, 0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF, + 0x6C13, 0x9F82, 0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84, + 0x6C23, 0x9F86, 0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558, + 0x6C38, 0x8969, 0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3, + 0x6C41, 0x8F60, 0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC, + 0x6C55, 0x9F88, 0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6, + 0x6C5D, 0x93F0, 0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272, + 0x6C62, 0x9F89, 0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8, + 0x6C70, 0x91BF, 0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88, + 0x6C7D, 0x8B44, 0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B, + 0x6C83, 0x9780, 0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7, + 0x6C8D, 0x9F8C, 0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42, + 0x6C96, 0x89AB, 0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F, + 0x6CA1, 0x9676, 0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C, + 0x6CB1, 0x9F9D, 0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB, + 0x6CBA, 0x9F9F, 0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98, + 0x6CBE, 0x9F9E, 0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95, + 0x6CC5, 0x9F9A, 0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5, + 0x6CD3, 0x9F97, 0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2, + 0x6CDA, 0xFAF9, 0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641, + 0x6CE2, 0x9467, 0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D, + 0x6CEA, 0x9FA3, 0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96, + 0x6CF3, 0x896A, 0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE, + 0x6D12, 0x9FAD, 0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C, + 0x6D1E, 0x93B4, 0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B, + 0x6D2A, 0x8D5E, 0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC, + 0x6D35, 0x9FAB, 0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88, + 0x6D3D, 0x9FA8, 0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2, + 0x6D45, 0x90F3, 0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C, + 0x6D63, 0x9FAF, 0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F, + 0x6D6A, 0x9851, 0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC, + 0x6D74, 0x9781, 0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3, + 0x6D85, 0x9FB8, 0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F, + 0x6D8E, 0x9FB5, 0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40, + 0x6D99, 0x97DC, 0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41, + 0x6DAF, 0x8A55, 0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF, + 0x6DBC, 0x97C1, 0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0, + 0x6DC7, 0x9FBD, 0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42, + 0x6DD1, 0x8F69, 0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391, + 0x6DD9, 0x9FC8, 0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9, + 0x6DE6, 0x9FBE, 0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA, + 0x6DEC, 0x9FC1, 0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44, + 0x6DF3, 0x8F7E, 0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43, + 0x6DF9, 0x9FB9, 0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45, + 0x6E05, 0x90B4, 0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2, + 0x6E0A, 0x9FBB, 0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA, + 0x6E19, 0x9FD0, 0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF, + 0x6E1F, 0x9FD9, 0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4, + 0x6E24, 0x9FDD, 0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48, + 0x6E29, 0x89B7, 0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD, + 0x6E2E, 0x9FCF, 0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46, + 0x6E3A, 0x9FDB, 0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA, + 0x6E4A, 0x96A9, 0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE, + 0x6E58, 0x8FC3, 0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2, + 0x6E67, 0x974E, 0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392, + 0x6E72, 0x9FD1, 0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC, + 0x6E80, 0x969E, 0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED, + 0x6E90, 0x8CB9, 0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD, + 0x6E9D, 0x8D61, 0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE, + 0x6EAA, 0x9FE2, 0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E, + 0x6EB7, 0x9FE5, 0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A, + 0x6EC2, 0x9FEF, 0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4, + 0x6ECB, 0x8EA0, 0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6, + 0x6ED4, 0x9FEB, 0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8, + 0x6EEC, 0x9FF4, 0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348, + 0x6EF7, 0xE042, 0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE, + 0x6F01, 0x8B99, 0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97, + 0x6F0F, 0x9852, 0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989, + 0x6F15, 0x9186, 0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8, + 0x6F2B, 0x969F, 0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB, + 0x6F38, 0x9151, 0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1, + 0x6F45, 0x8AC1, 0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049, + 0x6F5C, 0x90F6, 0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052, + 0x6F6D, 0xE04B, 0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7, + 0x6F74, 0xE06B, 0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D, + 0x6F80, 0xE047, 0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F, + 0x6F86, 0xE043, 0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050, + 0x6F97, 0x8AC0, 0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056, + 0x6FAA, 0xE059, 0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C, + 0x6FB9, 0xE057, 0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051, + 0x6FC3, 0x945A, 0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B, + 0x6FD8, 0xE05E, 0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A, + 0x6FE1, 0x9447, 0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C, + 0x6FEE, 0xE060, 0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A, + 0x6FF5, 0xFB4D, 0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068, + 0x7001, 0xE066, 0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062, + 0x700B, 0xE063, 0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D, + 0x7018, 0xE06D, 0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C, + 0x701E, 0x93D2, 0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB, + 0x7028, 0xFB50, 0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071, + 0x703E, 0xE070, 0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5, + 0x7063, 0xE073, 0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44, + 0x7078, 0x8B84, 0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51, + 0x7089, 0x9846, 0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075, + 0x7099, 0xE074, 0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259, + 0x70AE, 0xE07B, 0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079, + 0x70B9, 0x935F, 0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3, + 0x70CB, 0xE07D, 0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E, + 0x70DF, 0xE07C, 0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082, + 0x7104, 0xFB54, 0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B, + 0x7119, 0xE084, 0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3, + 0x7126, 0x8FC5, 0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56, + 0x7147, 0xFB57, 0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7, + 0x7155, 0xE086, 0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55, + 0x7162, 0xE089, 0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088, + 0x7167, 0x8FC6, 0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF, + 0x717D, 0x90F8, 0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46, + 0x718F, 0xE08D, 0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4, + 0x719F, 0x8F6E, 0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D, + 0x71B9, 0xE094, 0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452, + 0x71C8, 0x9395, 0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3, + 0x71D2, 0xE096, 0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093, + 0x71DF, 0x9A7A, 0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57, + 0x71E7, 0xE09C, 0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7, + 0x71F5, 0xE09D, 0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E, + 0x71FE, 0xFB5A, 0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1, + 0x7210, 0xE0A2, 0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC, + 0x722C, 0xE0A6, 0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8, + 0x7235, 0x8EDD, 0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9, + 0x723C, 0xE0AA, 0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB, + 0x7240, 0xE0AC, 0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5, + 0x724B, 0xE0AE, 0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF, + 0x7259, 0x89E5, 0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4, + 0x7261, 0x89B2, 0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8, + 0x7272, 0x90B5, 0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1, + 0x727E, 0xE0B1, 0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2, + 0x7287, 0xE0B4, 0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D, + 0x72A2, 0xE0B7, 0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6, + 0x72B1, 0xFB5B, 0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9, + 0x72BE, 0xFB5C, 0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD, + 0x72C6, 0xE0BC, 0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF, + 0x72D7, 0x8BE7, 0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1, + 0x72E1, 0xE0C2, 0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6, + 0x72ED, 0x8BB7, 0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3, + 0x72FC, 0x9854, 0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9, + 0x7317, 0xE0C6, 0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA, + 0x731F, 0x97C2, 0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD, + 0x732A, 0x9296, 0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC, + 0x7334, 0xE0CB, 0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF, + 0x733F, 0x898E, 0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0, + 0x734F, 0xE0D1, 0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5, + 0x736A, 0xE0D4, 0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8, + 0x7377, 0xFB5F, 0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9, + 0x7384, 0x8CBA, 0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4, + 0x7396, 0x8BE8, 0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC, + 0x73BB, 0xE0DE, 0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF, + 0x73C8, 0xE0DB, 0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF, + 0x73CE, 0xE0DD, 0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2, + 0x73E0, 0x8EEC, 0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D, + 0x73ED, 0x94C7, 0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66, + 0x73F8, 0xE0E7, 0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4, + 0x7406, 0x979D, 0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4, + 0x7425, 0xE0E6, 0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68, + 0x742E, 0xFB6A, 0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5, + 0x7435, 0x94FA, 0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB, + 0x7441, 0xE0EE, 0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8, + 0x745B, 0x896C, 0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC, + 0x7460, 0x97DA, 0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2, + 0x7469, 0xE0F0, 0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1, + 0x7473, 0x8DBA, 0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E, + 0x7489, 0xFB6C, 0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D, + 0x74A2, 0xE0E3, 0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3, + 0x74CA, 0xE0F9, 0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A, + 0x74E0, 0xE140, 0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2, + 0x74E7, 0xE142, 0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146, + 0x74F1, 0xE147, 0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149, + 0x74F8, 0xE148, 0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A, + 0x7505, 0xE14C, 0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E, + 0x7511, 0x8D99, 0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3, + 0x751A, 0x9072, 0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6, + 0x7523, 0x8E59, 0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770, + 0x752B, 0x95E1, 0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363, + 0x7531, 0x9752, 0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A, + 0x7538, 0x99B2, 0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155, + 0x7544, 0xE156, 0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158, + 0x754B, 0x9DC0, 0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8, + 0x7551, 0x94A8, 0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C, + 0x755B, 0xE15A, 0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9, + 0x7562, 0x954C, 0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C, + 0x7567, 0xE15F, 0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160, + 0x756D, 0xE161, 0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4, + 0x7574, 0xE166, 0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162, + 0x757F, 0x8B45, 0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165, + 0x7589, 0xE168, 0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161, + 0x758F, 0x9160, 0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B, + 0x759D, 0xE16C, 0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975, + 0x75B1, 0xE176, 0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172, + 0x75B8, 0xE174, 0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173, + 0x75BE, 0x8EBE, 0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561, + 0x75C7, 0x8FC7, 0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179, + 0x75D4, 0x8EA4, 0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A, + 0x75DB, 0x92C9, 0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B, + 0x75E9, 0x9189, 0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185, + 0x75F4, 0x9273, 0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D, + 0x75FF, 0xE17E, 0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186, + 0x760D, 0xE187, 0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C, + 0x7622, 0xE18D, 0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190, + 0x7634, 0xE18F, 0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194, + 0x7647, 0xE192, 0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC, + 0x7656, 0x95C8, 0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197, + 0x7662, 0xE198, 0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A, + 0x766A, 0xE19B, 0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F, + 0x7676, 0xE1A0, 0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F, + 0x767C, 0xE1A2, 0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3, + 0x7682, 0xFB70, 0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46, + 0x7687, 0x8D63, 0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7, + 0x7690, 0x8E48, 0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA, + 0x769A, 0xE1AB, 0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72, + 0x76A6, 0xFB74, 0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD, + 0x76B7, 0xEA89, 0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0, + 0x76BF, 0x8E4D, 0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E, + 0x76C8, 0x896D, 0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4, + 0x76D6, 0xE1B3, 0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58, + 0x76DE, 0xE1B5, 0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4, + 0x76E4, 0x94D5, 0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9, + 0x76EE, 0x96DA, 0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A, + 0x76FB, 0xE1BB, 0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE, + 0x7707, 0xE1BD, 0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5, + 0x770C, 0x8CA7, 0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E, + 0x7720, 0x96B0, 0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3, + 0x7729, 0xE1BF, 0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD, + 0x773C, 0x8AE1, 0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7, + 0x775A, 0xE1C8, 0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2, + 0x7765, 0xE1CC, 0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA, + 0x7779, 0xE1CF, 0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1, + 0x778E, 0xE1D0, 0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3, + 0x77A5, 0x95CB, 0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5, + 0x77B3, 0x93B5, 0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB, + 0x77BC, 0xE1D9, 0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC, + 0x77CD, 0xE1DD, 0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5, + 0x77DC, 0xE1E0, 0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D, + 0x77E7, 0x948A, 0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2, + 0x77EF, 0x8BB8, 0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB, + 0x780C, 0xE1E4, 0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3, + 0x7820, 0xE1E7, 0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4, + 0x7827, 0x8B6D, 0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376, + 0x783F, 0x8D7B, 0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9, + 0x7864, 0xFB7A, 0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5, + 0x7872, 0x94A1, 0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED, + 0x7881, 0x8CE9, 0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF, + 0x788D, 0x8A56, 0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F, + 0x7895, 0x8DEA, 0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0, + 0x78A7, 0x95C9, 0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3, + 0x78B5, 0xE1F1, 0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8, + 0x78C1, 0x8EA5, 0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB, + 0x78CB, 0xE1F6, 0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7, + 0x78DA, 0xE241, 0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC, + 0x78EF, 0x88E9, 0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA, + 0x7907, 0xE244, 0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245, + 0x7919, 0xE247, 0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249, + 0x792C, 0xE248, 0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7, + 0x793E, 0x8ED0, 0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F, + 0x7948, 0x8B46, 0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250, + 0x7955, 0xE24F, 0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E, + 0x795D, 0x8F6A, 0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B, + 0x7962, 0x9449, 0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5, + 0x7977, 0x9398, 0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268, + 0x7981, 0x8BD6, 0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253, + 0x798D, 0x89D0, 0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81, + 0x799B, 0xFB83, 0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255, + 0x79AA, 0xE257, 0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259, + 0x79B9, 0xE25A, 0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1, + 0x79BF, 0x93C3, 0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C, + 0x79CB, 0x8F48, 0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D, + 0x79D8, 0x94E9, 0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261, + 0x79E4, 0x9489, 0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281, + 0x79EC, 0xE25F, 0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48, + 0x7A08, 0xE262, 0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5, + 0x7A14, 0x96AB, 0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265, + 0x7A1A, 0x9274, 0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266, + 0x7A2E, 0x8EED, 0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C, + 0x7A3B, 0xE26A, 0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B, + 0x7A3F, 0x8D65, 0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D, + 0x7A46, 0x9673, 0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E, + 0x7A4F, 0x89B8, 0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270, + 0x7A62, 0xE271, 0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E, + 0x7A70, 0xE274, 0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275, + 0x7A7A, 0x8BF3, 0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB, + 0x7A83, 0x90DE, 0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282, + 0x7A93, 0x918B, 0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278, + 0x7A98, 0xE27A, 0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45, + 0x7AAE, 0x8B87, 0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280, + 0x7ABA, 0x894D, 0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282, + 0x7AC5, 0xE281, 0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286, + 0x7ACB, 0x97A7, 0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84, + 0x7AD2, 0x9AF2, 0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B, + 0x7ADA, 0xE28C, 0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED, + 0x7AE0, 0x8FCD, 0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76, + 0x7AE5, 0x93B6, 0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247, + 0x7AEB, 0xFB87, 0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292, + 0x7AF6, 0x8BA3, 0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1, + 0x7AFF, 0x8AC6, 0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296, + 0x7B08, 0x8B88, 0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294, + 0x7B11, 0x8FCE, 0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A, + 0x7B1E, 0xE29A, 0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584, + 0x7B28, 0xE29C, 0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B, + 0x7B36, 0xE29D, 0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D, + 0x7B48, 0x94A4, 0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3, + 0x7B4D, 0xE2A1, 0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D, + 0x7B52, 0x939B, 0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6, + 0x7B65, 0xE2A6, 0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC, + 0x7B70, 0xE2A9, 0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5, + 0x7B7A, 0xE29F, 0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3, + 0x7B8D, 0xE2B0, 0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493, + 0x7B95, 0x96A5, 0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7, + 0x7B9A, 0xE2B2, 0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88, + 0x7B9F, 0xE2AF, 0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB, + 0x7BB1, 0x94A0, 0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF, + 0x7BC1, 0xE2B9, 0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1, + 0x7BC9, 0x927A, 0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB, + 0x7BDD, 0xE2BE, 0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3, + 0x7BE6, 0xE2C2, 0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8, + 0x7BF6, 0xE2CC, 0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6, + 0x7C0D, 0xE2CB, 0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7, + 0x7C14, 0xE2C1, 0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8, + 0x7C23, 0xE2CD, 0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2, + 0x7C37, 0xE2D1, 0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA, + 0x7C3F, 0x95EB, 0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4, + 0x7C4D, 0x90D0, 0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6, + 0x7C56, 0xE2DD, 0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4, + 0x7C64, 0xE2DC, 0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4, + 0x7C75, 0xE2E0, 0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48, + 0x7C83, 0xE2E1, 0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE, + 0x7C90, 0xE2E2, 0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165, + 0x7C98, 0x9453, 0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7, + 0x7CA2, 0xE2E5, 0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF, + 0x7CA8, 0xE2E8, 0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, + 0x7CB1, 0xE2EB, 0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, + 0x7CBD, 0xE2EE, 0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, + 0x7CC5, 0xE2F0, 0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3, + 0x7CD6, 0x939C, 0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3, + 0x7CDF, 0x918C, 0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6, + 0x7CEF, 0xE2F7, 0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA, + 0x7CF8, 0x8E85, 0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A, + 0x7D00, 0x8B49, 0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67, + 0x7D06, 0xE2FC, 0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B, + 0x7D10, 0x9552, 0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1, + 0x7D18, 0x8D68, 0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4, + 0x7D1C, 0xE341, 0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5, + 0x7D2B, 0x8E87, 0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD, + 0x7D30, 0x8DD7, 0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349, + 0x7D39, 0x8FD0, 0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49, + 0x7D43, 0x8CBC, 0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A, + 0x7D48, 0xFB8A, 0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D, + 0x7D4F, 0xE351, 0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355, + 0x7D5C, 0xFB8B, 0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA, + 0x7D63, 0xE352, 0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350, + 0x7D71, 0x939D, 0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47, + 0x7D76, 0x90E2, 0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354, + 0x7D8F, 0xE356, 0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1, + 0x7D9B, 0xE358, 0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D, + 0x7DA2, 0xE361, 0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8, + 0x7DAD, 0x88DB, 0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366, + 0x7DB1, 0x8D6A, 0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C, + 0x7DB7, 0xFB8C, 0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D, + 0x7DBD, 0xE35E, 0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D, + 0x7DCA, 0x8BD9, 0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE, + 0x7DD2, 0x8F8F, 0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367, + 0x7DDA, 0x90FC, 0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A, + 0x7DE0, 0x92F7, 0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2, + 0x7DE9, 0x8AC9, 0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C, + 0x7DF4, 0x97FB, 0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA, + 0x7E05, 0xE36E, 0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376, + 0x7E12, 0xE372, 0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374, + 0x7E21, 0xE371, 0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63, + 0x7E2B, 0x9644, 0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380, + 0x7E35, 0xE37B, 0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381, + 0x7E3B, 0xE37A, 0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9, + 0x7E43, 0xE37D, 0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71, + 0x7E4D, 0x8F4A, 0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155, + 0x7E56, 0xE384, 0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383, + 0x7E5E, 0xE385, 0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A, + 0x7E6A, 0xE389, 0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388, + 0x7E7B, 0xE38C, 0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391, + 0x7E82, 0x8E5B, 0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393, + 0x7E8A, 0xFA5C, 0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A, + 0x7E90, 0xE396, 0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398, + 0x7E96, 0xE399, 0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA, + 0x7F38, 0xE39D, 0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90, + 0x7F4C, 0xE3A0, 0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3, + 0x7F51, 0xE3A4, 0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7, + 0x7F5F, 0xE3A8, 0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA, + 0x7F69, 0xE3AB, 0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275, + 0x7F70, 0x94B1, 0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB, + 0x7F78, 0xE3AD, 0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0, + 0x7F85, 0x9785, 0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1, + 0x7F8A, 0x9772, 0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4, + 0x7F9A, 0xE3B7, 0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91, + 0x7FA3, 0xE3B8, 0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60, + 0x7FAE, 0xE3BC, 0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD, + 0x7FB8, 0xE3BE, 0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5, + 0x7FC5, 0xE3C0, 0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782, + 0x7FD2, 0x8F4B, 0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089, + 0x7FE1, 0xE3C5, 0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3, + 0x7FF0, 0x8ACB, 0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C, + 0x7FFC, 0x9783, 0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C, + 0x8004, 0xE3CC, 0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD, + 0x800C, 0x8EA7, 0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B, + 0x8017, 0x96D5, 0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1, + 0x8021, 0xE3D2, 0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB, + 0x803B, 0xE3D5, 0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7, + 0x804A, 0xE3D6, 0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9, + 0x805A, 0xE3DA, 0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F, + 0x8062, 0xE3DC, 0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0, + 0x8072, 0xE3DF, 0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1, + 0x8077, 0x9045, 0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857, + 0x807F, 0xE3E4, 0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6, + 0x8087, 0x94A3, 0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7, + 0x8093, 0xE3E9, 0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA, + 0x809B, 0xE3E8, 0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88, + 0x80A5, 0x94EC, 0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED, + 0x80AD, 0xE3EB, 0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7, + 0x80B4, 0x8DE6, 0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2, + 0x80C6, 0x925F, 0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4, + 0x80D9, 0xE3F0, 0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1, + 0x80DE, 0x9645, 0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF, + 0x80EF, 0xE3F6, 0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9, + 0x80FC, 0xE445, 0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA, + 0x8106, 0x90C6, 0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5, + 0x810A, 0x90D2, 0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA, + 0x8129, 0xE3F9, 0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D, + 0x8139, 0x92AF, 0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC, + 0x814E, 0x9074, 0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443, + 0x8154, 0x8D6F, 0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448, + 0x8166, 0xE449, 0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98, + 0x8171, 0xE446, 0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0, + 0x817A, 0x9142, 0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F, + 0x8183, 0xE44B, 0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70, + 0x8193, 0xE455, 0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C, + 0x819D, 0x9547, 0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452, + 0x81A8, 0x9663, 0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156, + 0x81B5, 0xE458, 0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B, + 0x81BE, 0xE459, 0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D, + 0x81C6, 0x89B0, 0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460, + 0x81D1, 0xE461, 0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462, + 0x81DA, 0xE465, 0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062, + 0x81E5, 0x89E7, 0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9, + 0x81ED, 0x8F4C, 0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469, + 0x81FB, 0xE46A, 0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C, + 0x8202, 0xE46D, 0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB, + 0x8209, 0x9DA8, 0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471, + 0x820E, 0x8EC9, 0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473, + 0x8217, 0x95DC, 0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77, + 0x821E, 0x9591, 0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71, + 0x822B, 0xE475, 0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477, + 0x8235, 0x91C7, 0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476, + 0x8239, 0x9144, 0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A, + 0x8259, 0xE479, 0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D, + 0x8262, 0xE480, 0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481, + 0x826A, 0xE482, 0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7, + 0x8271, 0xE485, 0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486, + 0x8278, 0xE487, 0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489, + 0x8292, 0xE48A, 0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C, + 0x82A5, 0x8A48, 0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E, + 0x82AD, 0x946D, 0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646, + 0x82B8, 0x8C7C, 0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8, + 0x82C5, 0x8AA1, 0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8, + 0x82D4, 0x91DB, 0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5, + 0x82DC, 0xE49C, 0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F, + 0x82E3, 0xE490, 0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297, + 0x82EB, 0x93CF, 0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493, + 0x82F9, 0xE499, 0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93, + 0x8302, 0x96CE, 0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D, + 0x8306, 0xE49B, 0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1, + 0x8317, 0xE4AA, 0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2, + 0x8328, 0x88EF, 0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3, + 0x8332, 0xE4A2, 0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283, + 0x8338, 0x91F9, 0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7, + 0x8349, 0x9190, 0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6, + 0x8352, 0x8D72, 0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8, + 0x8375, 0xE4B9, 0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6, + 0x837F, 0xFB95, 0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB, + 0x838A, 0xE4B5, 0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1, + 0x839A, 0xE4AD, 0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA, + 0x83A2, 0xE4B0, 0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C, + 0x83B1, 0x9789, 0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5, + 0x83C5, 0x909B, 0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB, + 0x83CE, 0xE4C0, 0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3, + 0x83DC, 0x8DD8, 0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC, + 0x83EB, 0xE4BF, 0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548, + 0x83F2, 0xE4C9, 0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6, + 0x83FB, 0xE4D0, 0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8, + 0x8407, 0xE4C7, 0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA, + 0x840E, 0x88DE, 0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB, + 0x8429, 0x948B, 0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E, + 0x8435, 0xE4E0, 0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E, + 0x8446, 0xE4DC, 0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8, + 0x8457, 0x9298, 0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2, + 0x8463, 0x939F, 0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7, + 0x846C, 0x9192, 0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE, + 0x8471, 0x944B, 0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF, + 0x847A, 0x9598, 0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3, + 0x8490, 0x8F4E, 0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566, + 0x849F, 0xE4E5, 0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97, + 0x84B4, 0xFB99, 0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8, + 0x84BC, 0x9193, 0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E, + 0x84C6, 0xE4EC, 0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57, + 0x84CD, 0xE4E7, 0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED, + 0x84D9, 0xE4E6, 0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648, + 0x84EE, 0x9840, 0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0, + 0x8500, 0x8EC1, 0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0, + 0x8514, 0xE4F7, 0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3, + 0x851A, 0x8955, 0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3, + 0x852C, 0xE4F4, 0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1, + 0x8540, 0xE4F9, 0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC, + 0x8549, 0x8FD4, 0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC, + 0x8553, 0xFB9A, 0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB, + 0x8559, 0xFB9B, 0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E, + 0x8569, 0x93A0, 0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A, + 0x8577, 0xE550, 0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496, + 0x8587, 0xE54E, 0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552, + 0x8591, 0xE547, 0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3, + 0x859B, 0xE54C, 0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145, + 0x85A8, 0xE549, 0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F, + 0x85AC, 0x96F2, 0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E, + 0x85B9, 0xE556, 0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553, + 0x85CD, 0x9795, 0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558, + 0x85DC, 0xE55B, 0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A, + 0x85E9, 0x94CB, 0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C, + 0x85FA, 0xE561, 0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541, + 0x8606, 0xE562, 0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F, + 0x8613, 0xE55E, 0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564, + 0x8622, 0xE563, 0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565, + 0x863F, 0xE566, 0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73, + 0x8654, 0xE569, 0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8, + 0x865E, 0x8BF1, 0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E, + 0x8671, 0xE56C, 0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1, + 0x868B, 0xE571, 0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C, + 0x86A3, 0xE56E, 0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570, + 0x86AB, 0xE57A, 0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573, + 0x86C4, 0xE575, 0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578, + 0x86CB, 0x9260, 0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B, + 0x86D9, 0x8A5E, 0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580, + 0x86E4, 0x94B8, 0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567, + 0x86EE, 0x94D8, 0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C, + 0x86FB, 0xE588, 0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649, + 0x8703, 0xE587, 0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A, + 0x870A, 0xE58D, 0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583, + 0x8718, 0x9277, 0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592, + 0x8729, 0xE593, 0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591, + 0x873F, 0xE58F, 0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598, + 0x874E, 0xE599, 0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B, + 0x8759, 0xE59E, 0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0, + 0x8766, 0x89DA, 0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D, + 0x8774, 0xE59A, 0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488, + 0x8782, 0xE5A5, 0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3, + 0x87AB, 0xE5AC, 0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786, + 0x87BB, 0xE5B1, 0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD, + 0x87C6, 0xE5B0, 0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA, + 0x87D2, 0xE5BB, 0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3, + 0x87F6, 0xE5B8, 0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61, + 0x87FE, 0xE5B7, 0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6, + 0x880E, 0xE5BA, 0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE, + 0x8816, 0xE5BD, 0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579, + 0x8827, 0xE5C4, 0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3, + 0x883B, 0xE5C5, 0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6, + 0x8846, 0x8F4F, 0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8, + 0x8853, 0x8F70, 0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971, + 0x885D, 0x8FD5, 0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB, + 0x8863, 0x88DF, 0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A, + 0x8872, 0xE5D3, 0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1, + 0x887E, 0xE5CE, 0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4, + 0x8888, 0x8C55, 0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6, + 0x8896, 0x91B3, 0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, + 0x88A2, 0xE5D9, 0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, + 0x88B0, 0xE5DC, 0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2, + 0x88B7, 0x88BF, 0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4, + 0x88C3, 0xE5DF, 0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0, + 0x88D4, 0xE5E1, 0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3, + 0x88DC, 0x95E2, 0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1, + 0x88E8, 0xE5E9, 0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8, + 0x88F5, 0xFBA2, 0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7, + 0x88FD, 0x90BB, 0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB, + 0x8907, 0x95A1, 0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C, + 0x8912, 0x964A, 0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA, + 0x891E, 0xE5F0, 0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3, + 0x8936, 0xE5F7, 0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4, + 0x8943, 0xE5EF, 0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5, + 0x8956, 0x89A6, 0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB, + 0x8964, 0xE641, 0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642, + 0x896F, 0xE644, 0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646, + 0x897E, 0xE647, 0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648, + 0x8986, 0x95A2, 0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A, + 0x898B, 0x8CA9, 0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B, + 0x8997, 0x9460, 0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D, + 0x89A6, 0xE64F, 0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065, + 0x89AC, 0xE650, 0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF, + 0x89BA, 0xE653, 0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656, + 0x89D2, 0x8A70, 0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659, + 0x89E3, 0x89F0, 0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B, + 0x89F8, 0xE65C, 0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D, + 0x8A08, 0x8C76, 0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2, + 0x8A10, 0xE65F, 0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E, + 0x8A17, 0x91F5, 0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662, + 0x8A1F, 0x8FD7, 0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B, + 0x8A2D, 0x90DD, 0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169, + 0x8A36, 0xE664, 0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290, + 0x8A3C, 0x8FD8, 0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669, + 0x8A50, 0x8DBC, 0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9, + 0x8A55, 0x955D, 0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972, + 0x8A62, 0xE66D, 0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D, + 0x8A6B, 0x986C, 0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146, + 0x8A70, 0x8B6C, 0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA, + 0x8A79, 0xFBA5, 0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670, + 0x8A85, 0xE66E, 0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F, + 0x8A8D, 0x9446, 0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261, + 0x8A98, 0x9755, 0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD, + 0x8AA1, 0xE672, 0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674, + 0x8AA6, 0xE675, 0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0, + 0x8AAD, 0x93C7, 0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE, + 0x8ABC, 0x8B62, 0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A, + 0x8AC4, 0xE678, 0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0, + 0x8ACD, 0xE679, 0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F, + 0x8ADA, 0xE67B, 0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686, + 0x8ADF, 0xFBA8, 0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684, + 0x8AE4, 0xE680, 0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C, + 0x8AED, 0x9740, 0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D, + 0x8AF6, 0xFBAA, 0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF, + 0x8AFE, 0x91F8, 0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0, + 0x8B04, 0x93A3, 0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4, + 0x8B10, 0xE68D, 0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E, + 0x8B19, 0x8CAA, 0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3, + 0x8B20, 0xE68F, 0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695, + 0x8B2B, 0xE693, 0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE, + 0x8B3E, 0xE694, 0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697, + 0x8B4E, 0xE699, 0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B, + 0x8B58, 0x8EAF, 0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588, + 0x8B5F, 0xE69F, 0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0, + 0x8B6F, 0xE6A1, 0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7, + 0x8B74, 0xE6A2, 0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC, + 0x8B80, 0xE6A4, 0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5, + 0x8B8E, 0xE6A6, 0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8, + 0x8B96, 0xE6A9, 0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A, + 0x8C3A, 0xE6AC, 0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4, + 0x8C48, 0xE6AF, 0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1, + 0x8C50, 0xE6B2, 0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB, + 0x8C62, 0xE6B4, 0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5, + 0x8C78, 0xE6B6, 0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF, + 0x8C82, 0xE6B8, 0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB, + 0x8C8C, 0x9665, 0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE, + 0x8C98, 0xE6C0, 0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589, + 0x8CA1, 0x8DE0, 0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD, + 0x8CA9, 0x94CC, 0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3, + 0x8CAD, 0xE6C2, 0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1, + 0x8CB2, 0xE6C5, 0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8, + 0x8CB7, 0x9483, 0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C, + 0x8CBD, 0xE6C4, 0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA, + 0x8CC2, 0x9847, 0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91, + 0x8CC8, 0xE6C9, 0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147, + 0x8CD1, 0x93F6, 0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E, + 0x8CDC, 0x8E92, 0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB, + 0x8CE3, 0xE6CC, 0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF, + 0x8CED, 0x9371, 0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF, + 0x8CFB, 0xE6D0, 0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1, + 0x8D05, 0xE6D2, 0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3, + 0x8D0B, 0x8AE4, 0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7, + 0x8D12, 0xFBAF, 0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC, + 0x8D64, 0x90D4, 0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71, + 0x8D6D, 0xE6DE, 0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0, + 0x8D74, 0x958B, 0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1, + 0x8D85, 0x92B4, 0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF, + 0x8DA8, 0x9096, 0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4, + 0x8DC2, 0xE6E3, 0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6, + 0x8DD6, 0xE6E8, 0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97, + 0x8DDF, 0xE6EE, 0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7, + 0x8DEA, 0xE6EC, 0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5, + 0x8DF5, 0x9148, 0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1, + 0x8E09, 0xE6F2, 0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6, + 0x8E1D, 0xE6F4, 0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748, + 0x8E30, 0xE6FA, 0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8, + 0x8E44, 0x92FB, 0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741, + 0x8E4A, 0xE6FC, 0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A, + 0x8E59, 0xE745, 0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749, + 0x8E64, 0xE746, 0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B, + 0x8E7C, 0xE74D, 0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750, + 0x8E87, 0xE74F, 0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4, + 0x8E91, 0xE755, 0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757, + 0x8EA1, 0xE759, 0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A, + 0x8EAF, 0x8BEB, 0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E, + 0x8EC5, 0xE75F, 0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4, + 0x8ECB, 0xE761, 0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2, + 0x8ED2, 0x8CAC, 0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D, + 0x8EE3, 0xE763, 0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765, + 0x8EFC, 0xE764, 0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72, + 0x8F05, 0xE769, 0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771, + 0x8F12, 0xE76B, 0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A, + 0x8F19, 0xE76C, 0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50, + 0x8F1F, 0xE76F, 0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6, + 0x8F2F, 0x8F53, 0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775, + 0x8F3B, 0xE774, 0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777, + 0x8F44, 0x8A8D, 0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A, + 0x8F4C, 0xE779, 0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D, + 0x8F5C, 0xE77E, 0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780, + 0x8F63, 0xE781, 0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783, + 0x8F9E, 0x8EAB, 0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F, + 0x8FA8, 0x999E, 0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787, + 0x8FB0, 0x9243, 0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788, + 0x8FBA, 0x95D3, 0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248, + 0x8FC2, 0x8949, 0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D, + 0x8FD1, 0x8BDF, 0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B, + 0x8FE5, 0xE78A, 0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C, + 0x8FEB, 0x9497, 0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71, + 0x8FF4, 0xE78F, 0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791, + 0x8FFA, 0xE792, 0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197, + 0x9003, 0x93A6, 0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799, + 0x900D, 0xE796, 0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280, + 0x9011, 0xE793, 0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794, + 0x9016, 0xE798, 0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA, + 0x901D, 0x90C0, 0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2, + 0x9021, 0xE795, 0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A, + 0x902E, 0x91DF, 0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C, + 0x9036, 0xE79B, 0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E, + 0x903E, 0xE7A5, 0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278, + 0x9047, 0x8BF6, 0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E, + 0x904D, 0x95D5, 0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0, + 0x9051, 0xE7A1, 0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242, + 0x9055, 0x88E1, 0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1, + 0x905C, 0x91BB, 0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B, + 0x9063, 0x8CAD, 0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9, + 0x9069, 0x934B, 0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA, + 0x9072, 0xE7AD, 0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A, + 0x9078, 0x9149, 0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF, + 0x907F, 0x94F0, 0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE, + 0x9083, 0xE284, 0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3, + 0x908A, 0xE7B2, 0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF, + 0x90A6, 0x964D, 0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6, + 0x90B1, 0xE7B7, 0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8, + 0x90CA, 0x8D78, 0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6, + 0x90E1, 0x8C53, 0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594, + 0x90ED, 0x8A73, 0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373, + 0x9102, 0xE7BD, 0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF, + 0x9127, 0xFBB9, 0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0, + 0x9149, 0x93D1, 0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE, + 0x914D, 0x947A, 0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C, + 0x9156, 0xE7C3, 0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5, + 0x9165, 0xE7C6, 0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56, + 0x9172, 0xE7C9, 0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93, + 0x9178, 0x8E5F, 0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB, + 0x918B, 0xE7CA, 0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1, + 0x9197, 0x94AE, 0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD, + 0x91AA, 0xE7D0, 0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2, + 0x91B5, 0xE7D1, 0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4, + 0x91C1, 0xE7D5, 0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF, + 0x91C9, 0xE7D6, 0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64, + 0x91CE, 0x96EC, 0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0, + 0x91D6, 0xE7D9, 0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA, + 0x91DB, 0xE7DC, 0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC, + 0x91DF, 0xE7DA, 0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF, + 0x91E5, 0xFBC0, 0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD, + 0x91EE, 0xFBBE, 0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD, + 0x91FF, 0xE7E1, 0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD, + 0x920E, 0x8A62, 0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2, + 0x9215, 0xE7E4, 0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3, + 0x9234, 0x97E9, 0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4, + 0x923C, 0xFBC6, 0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353, + 0x9245, 0xE7E8, 0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE, + 0x924E, 0xFBC7, 0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7, + 0x9259, 0xFBC8, 0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6, + 0x9262, 0x94AB, 0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB, + 0x9271, 0x8D7A, 0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667, + 0x9280, 0x8BE2, 0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F, + 0x9291, 0x914C, 0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1, + 0x9298, 0x96C1, 0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0, + 0x92A7, 0xFBCC, 0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6, + 0x92CF, 0xE7F5, 0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6, + 0x92D5, 0xFBD4, 0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5, + 0x92E4, 0x8F9B, 0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD, + 0x92ED, 0x8973, 0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98, + 0x92F9, 0xFA65, 0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C, + 0x92FF, 0xFBDC, 0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9, + 0x9310, 0x908D, 0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842, + 0x931D, 0xFBDD, 0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8, + 0x9322, 0xE841, 0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1, + 0x9328, 0x9564, 0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC, + 0x932F, 0x8DF6, 0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844, + 0x933B, 0xE846, 0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7, + 0x934D, 0x9374, 0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0, + 0x935B, 0x9262, 0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C, + 0x936E, 0xE84A, 0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849, + 0x937E, 0x8FDF, 0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD, + 0x9397, 0x9199, 0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A, + 0x93AC, 0xE84D, 0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C, + 0x93B9, 0xE850, 0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859, + 0x93D0, 0xE858, 0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852, + 0x93D8, 0xE855, 0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE, + 0x93E4, 0xE85A, 0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4, + 0x9403, 0xE85E, 0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D, + 0x9414, 0xE85C, 0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B, + 0x9421, 0xE864, 0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863, + 0x9436, 0xE861, 0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866, + 0x9444, 0xE868, 0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3, + 0x9452, 0xE867, 0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869, + 0x945E, 0xE86C, 0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D, + 0x9470, 0xE86F, 0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874, + 0x947D, 0xE872, 0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876, + 0x9577, 0x92B7, 0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D, + 0x9587, 0xE879, 0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A, + 0x958F, 0x895B, 0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4, + 0x9594, 0xE87B, 0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E, + 0x95A0, 0xE880, 0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D, + 0x95A5, 0x94B4, 0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883, + 0x95B2, 0x897B, 0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884, + 0x95BE, 0xE887, 0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888, + 0x95CC, 0xE88C, 0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D, + 0x95D6, 0xE88F, 0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891, + 0x95E2, 0xE893, 0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894, + 0x9628, 0xE895, 0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897, + 0x9632, 0x9668, 0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9, + 0x9642, 0xE898, 0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899, + 0x964D, 0x8D7E, 0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3, + 0x965C, 0xE89D, 0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0, + 0x9662, 0x8940, 0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7, + 0x9666, 0xE8A1, 0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941, + 0x9672, 0xE8A2, 0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9, + 0x9677, 0xE89C, 0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A, + 0x9685, 0x8BF7, 0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0, + 0x968B, 0xE440, 0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F, + 0x9694, 0x8A75, 0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5, + 0x9699, 0x8C84, 0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB, + 0x96A0, 0x8942, 0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC, + 0x96AA, 0xE8A8, 0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA, + 0x96B2, 0xE8AB, 0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA, + 0x96B8, 0xE8AF, 0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9, + 0x96C0, 0x909D, 0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB, + 0x96C6, 0x8F57, 0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2, + 0x96CC, 0x8E93, 0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47, + 0x96D5, 0xE8B8, 0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097, + 0x96DC, 0xE8B6, 0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A, + 0x96EA, 0x90E1, 0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F, + 0x96F6, 0x97EB, 0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364, + 0x9700, 0x8EF9, 0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B, + 0x9708, 0xE8BC, 0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE, + 0x970F, 0xE8C0, 0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1, + 0x9719, 0xE8C2, 0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3, + 0x9727, 0x96B6, 0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849, + 0x9733, 0xFBED, 0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE, + 0x973D, 0xE8C7, 0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF, + 0x9744, 0xE8C9, 0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD, + 0x974D, 0xFBF0, 0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2, + 0x9755, 0xFBF3, 0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE, + 0x975E, 0x94F1, 0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA, + 0x9764, 0xE8D0, 0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76, + 0x976B, 0xE8D4, 0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43, + 0x9779, 0xE8D6, 0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9, + 0x9784, 0x8A93, 0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC, + 0x978D, 0x88C6, 0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2, + 0x979C, 0xE8DF, 0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1, + 0x97A8, 0xE8E0, 0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3, + 0x97B4, 0xE8E4, 0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7, + 0x97CB, 0xE8E8, 0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA, + 0x97EE, 0x9442, 0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF, + 0x97F6, 0xE8EE, 0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5, + 0x9802, 0x92B8, 0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87, + 0x9808, 0x907B, 0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761, + 0x9811, 0x8AE6, 0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C, + 0x9818, 0x97CC, 0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3, + 0x982C, 0x966A, 0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5, + 0x9838, 0xE8F2, 0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6, + 0x9846, 0xE8F7, 0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A, + 0x984E, 0x8A7B, 0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0, + 0x9857, 0xFBF4, 0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE, + 0x9865, 0xFBF5, 0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB, + 0x9870, 0xE8FC, 0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941, + 0x98A8, 0x9597, 0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945, + 0x98B6, 0xE946, 0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949, + 0x98DB, 0x94F2, 0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51, + 0x98E9, 0xE94A, 0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A, + 0x98EF, 0x94D1, 0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94, + 0x98FD, 0x964F, 0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD, + 0x9909, 0xE94D, 0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60, + 0x9912, 0xE94E, 0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950, + 0x991D, 0xE952, 0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951, + 0x9924, 0xE954, 0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956, + 0x992E, 0xE957, 0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A, + 0x9945, 0xE95C, 0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961, + 0x9950, 0xE95D, 0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962, + 0x9957, 0x8BC0, 0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964, + 0x9999, 0x8D81, 0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D, + 0x99AC, 0x946E, 0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279, + 0x99B4, 0x93E9, 0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA, + 0x99C5, 0x8977, 0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293, + 0x99D1, 0xE96D, 0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C, + 0x99DB, 0xE96A, 0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977, + 0x99ED, 0xE96E, 0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971, + 0x99F8, 0xE973, 0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974, + 0x9A05, 0xE976, 0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B, + 0x9A13, 0x8CB1, 0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979, + 0x9A30, 0x93AB, 0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D, + 0x9A42, 0xE97C, 0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982, + 0x9A4E, 0xFBFB, 0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1, + 0x9A5B, 0xE983, 0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988, + 0x9A65, 0xE987, 0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A, + 0x9AA8, 0x8D9C, 0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B, + 0x9ABC, 0xE98E, 0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990, + 0x9AD1, 0xE991, 0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82, + 0x9AD9, 0xFBFC, 0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995, + 0x9AE2, 0xE996, 0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF, + 0x9AEB, 0xE99A, 0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999, + 0x9AF1, 0xE99D, 0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F, + 0x9B06, 0xE9A0, 0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3, + 0x9B22, 0xE9A4, 0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7, + 0x9B28, 0xE9A8, 0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB, + 0x9B2F, 0xE9AC, 0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6, + 0x9B3C, 0x8B53, 0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF, + 0x9B44, 0xE9AE, 0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2, + 0x9B4F, 0xE9B0, 0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4, + 0x9B5A, 0x8B9B, 0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5, + 0x9B75, 0xFC41, 0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43, + 0x9B91, 0xE9B8, 0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9, + 0x9B97, 0xE9BA, 0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD, + 0x9BAA, 0x968E, 0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E, + 0x9BB1, 0xFC44, 0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45, + 0x9BC0, 0xE9BF, 0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0, + 0x9BCF, 0xE9C3, 0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9, + 0x9BD6, 0x8E49, 0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7, + 0x9BE3, 0xE9C6, 0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE, + 0x9BF1, 0xE9CD, 0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46, + 0x9C04, 0xE9D8, 0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1, + 0x9C0A, 0xE9D7, 0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B, + 0x9C12, 0xE9D6, 0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF, + 0x9C1B, 0xE9DA, 0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB, + 0x9C2D, 0x9568, 0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE, + 0x9C32, 0xE9E0, 0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956, + 0x9C3E, 0xE9E2, 0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C, + 0x9C52, 0x9690, 0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4, + 0x9C67, 0xE9E5, 0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9, + 0x9CE7, 0xE9E8, 0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9, + 0x9CF0, 0xE9EA, 0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE, + 0x9D03, 0xE9EE, 0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC, + 0x9D09, 0xE9EB, 0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6, + 0x9D1B, 0x8995, 0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1, + 0x9D28, 0x8A9B, 0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7, + 0x9D3B, 0x8D83, 0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8, + 0x9D44, 0xE9F5, 0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44, + 0x9D51, 0xEA43, 0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40, + 0x9D5E, 0xEA41, 0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42, + 0x9D6B, 0xFC48, 0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47, + 0x9D72, 0xEA46, 0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47, + 0x9D8F, 0x8C7B, 0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E, + 0x9DAB, 0xEA49, 0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF, + 0x9DB8, 0xEA53, 0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51, + 0x9DC2, 0xEA57, 0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56, + 0x9DD3, 0xEA59, 0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C, + 0x9DEF, 0xEA5D, 0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9, + 0x9DFA, 0x8DEB, 0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F, + 0x9E1B, 0xEA60, 0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2, + 0x9E79, 0xEA63, 0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65, + 0x9E88, 0xEA66, 0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B, + 0x9E92, 0xEA69, 0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED, + 0x9E9D, 0xEA6C, 0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E, + 0x9EA9, 0xEA6E, 0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F, + 0x9EB9, 0x8D8D, 0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5, + 0x9EBE, 0x9F80, 0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73, + 0x9ECD, 0x8B6F, 0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76, + 0x9ED1, 0xFC4B, 0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2, + 0x9ED9, 0x96D9, 0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A, + 0x9EDE, 0xEA79, 0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D, + 0x9EEF, 0xEA7E, 0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82, + 0x9EF9, 0xEA83, 0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86, + 0x9F07, 0xEA87, 0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB, + 0x9F15, 0xEA8A, 0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C, + 0x9F3B, 0x9540, 0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256, + 0x9F4E, 0xE6D8, 0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90, + 0x9F5F, 0xEA92, 0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE, + 0x9F63, 0xEA91, 0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98, + 0x9F6C, 0xEA97, 0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99, + 0x9F8D, 0x97B4, 0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273, + 0x9FA0, 0xEA9E, 0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90, + 0xFA0F, 0xFA9B, 0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8, + 0xFA13, 0xFAE8, 0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E, + 0xFA17, 0xFB75, 0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80, + 0xFA1B, 0xFB82, 0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92, + 0xFA1F, 0xFB9D, 0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9, + 0xFA23, 0xFBB1, 0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7, + 0xFA27, 0xFBD3, 0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6, + 0xFA2B, 0xFBF7, 0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149, + 0xFF02, 0xFA57, 0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193, + 0xFF06, 0x8195, 0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A, + 0xFF0A, 0x8196, 0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C, + 0xFF0E, 0x8144, 0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250, + 0xFF12, 0x8251, 0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254, + 0xFF16, 0x8255, 0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258, + 0xFF1A, 0x8146, 0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181, + 0xFF1E, 0x8184, 0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260, + 0xFF22, 0x8261, 0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264, + 0xFF26, 0x8265, 0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268, + 0xFF2A, 0x8269, 0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C, + 0xFF2E, 0x826D, 0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270, + 0xFF32, 0x8271, 0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274, + 0xFF36, 0x8275, 0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278, + 0xFF3A, 0x8279, 0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E, + 0xFF3E, 0x814F, 0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281, + 0xFF42, 0x8282, 0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285, + 0xFF46, 0x8286, 0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289, + 0xFF4A, 0x828A, 0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D, + 0xFF4E, 0x828E, 0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291, + 0xFF52, 0x8292, 0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295, + 0xFF56, 0x8296, 0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299, + 0xFF5A, 0x829A, 0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170, + 0xFF5E, 0x8160, 0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3, + 0xFF64, 0x00A4, 0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7, + 0xFF68, 0x00A8, 0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB, + 0xFF6C, 0x00AC, 0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF, + 0xFF70, 0x00B0, 0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3, + 0xFF74, 0x00B4, 0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7, + 0xFF78, 0x00B8, 0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB, + 0xFF7C, 0x00BC, 0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF, + 0xFF80, 0x00C0, 0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3, + 0xFF84, 0x00C4, 0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7, + 0xFF88, 0x00C8, 0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB, + 0xFF8C, 0x00CC, 0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF, + 0xFF90, 0x00D0, 0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3, + 0xFF94, 0x00D4, 0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7, + 0xFF98, 0x00D8, 0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB, + 0xFF9C, 0x00DC, 0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF, + 0xFFE0, 0x8191, 0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, + 0xFFE4, 0xFA55, 0xFFE5, 0x818F, 0, 0 +}; + +#if !_TINY_TABLE +static +const WCHAR sjis2uni[] = { +/* SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, */ + 0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64, + 0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68, + 0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C, + 0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70, + 0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74, + 0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78, + 0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C, + 0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80, + 0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84, + 0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88, + 0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C, + 0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90, + 0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94, + 0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98, + 0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C, + 0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000, + 0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E, + 0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F, + 0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4, + 0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3, + 0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D, + 0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005, + 0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015, + 0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E, + 0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025, + 0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D, + 0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015, + 0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D, + 0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B, + 0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F, + 0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D, + 0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D, + 0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266, + 0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642, + 0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033, + 0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0, + 0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06, + 0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606, + 0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE, + 0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0, + 0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC, + 0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190, + 0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208, + 0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282, + 0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227, + 0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4, + 0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5, + 0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261, + 0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A, + 0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B, + 0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F, + 0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021, + 0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11, + 0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15, + 0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19, + 0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24, + 0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28, + 0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C, + 0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30, + 0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34, + 0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38, + 0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42, + 0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46, + 0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A, + 0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E, + 0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52, + 0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56, + 0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A, + 0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044, + 0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048, + 0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C, + 0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050, + 0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054, + 0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058, + 0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C, + 0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060, + 0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064, + 0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068, + 0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C, + 0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070, + 0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074, + 0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078, + 0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C, + 0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080, + 0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084, + 0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088, + 0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C, + 0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090, + 0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1, + 0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5, + 0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9, + 0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD, + 0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1, + 0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5, + 0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9, + 0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD, + 0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1, + 0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5, + 0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9, + 0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD, + 0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1, + 0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5, + 0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9, + 0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD, + 0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1, + 0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5, + 0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9, + 0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED, + 0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1, + 0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x30F4, + 0x8395, 0x30F5, 0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392, + 0x83A1, 0x0393, 0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396, + 0x83A5, 0x0397, 0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A, + 0x83A9, 0x039B, 0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E, + 0x83AD, 0x039F, 0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3, + 0x83B1, 0x03A4, 0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7, + 0x83B5, 0x03A8, 0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2, + 0x83C1, 0x03B3, 0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6, + 0x83C5, 0x03B7, 0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA, + 0x83C9, 0x03BB, 0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE, + 0x83CD, 0x03BF, 0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3, + 0x83D1, 0x03C4, 0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7, + 0x83D5, 0x03C8, 0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411, + 0x8442, 0x0412, 0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415, + 0x8446, 0x0401, 0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418, + 0x844A, 0x0419, 0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C, + 0x844E, 0x041D, 0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420, + 0x8452, 0x0421, 0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424, + 0x8456, 0x0425, 0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428, + 0x845A, 0x0429, 0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C, + 0x845E, 0x042D, 0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430, + 0x8471, 0x0431, 0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434, + 0x8475, 0x0435, 0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437, + 0x8479, 0x0438, 0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B, + 0x847D, 0x043C, 0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F, + 0x8482, 0x0440, 0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443, + 0x8486, 0x0444, 0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447, + 0x848A, 0x0448, 0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B, + 0x848E, 0x044C, 0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F, + 0x849F, 0x2500, 0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510, + 0x84A3, 0x2518, 0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C, + 0x84A7, 0x2524, 0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501, + 0x84AB, 0x2503, 0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B, + 0x84AF, 0x2517, 0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B, + 0x84B3, 0x253B, 0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F, + 0x84B7, 0x2528, 0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D, + 0x84BB, 0x2530, 0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542, + 0x8740, 0x2460, 0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463, + 0x8744, 0x2464, 0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467, + 0x8748, 0x2468, 0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B, + 0x874C, 0x246C, 0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F, + 0x8750, 0x2470, 0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473, + 0x8754, 0x2160, 0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163, + 0x8758, 0x2164, 0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167, + 0x875C, 0x2168, 0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314, + 0x8761, 0x3322, 0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327, + 0x8765, 0x3303, 0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357, + 0x8769, 0x330D, 0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B, + 0x876D, 0x334A, 0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D, + 0x8771, 0x339E, 0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4, + 0x8775, 0x33A1, 0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F, + 0x8782, 0x2116, 0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4, + 0x8786, 0x32A5, 0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8, + 0x878A, 0x3231, 0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E, + 0x878E, 0x337D, 0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211, + 0x8798, 0x221F, 0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516, + 0x88A1, 0x5A03, 0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B, + 0x88A5, 0x6328, 0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475, + 0x88A9, 0x831C, 0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1, + 0x88AD, 0x6E25, 0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6, + 0x88B1, 0x9BF5, 0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1, + 0x88B5, 0x6271, 0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B, + 0x88B9, 0x98F4, 0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E, + 0x88BD, 0x6216, 0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89, + 0x88C1, 0x5EB5, 0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848, + 0x88C5, 0x95C7, 0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5, + 0x88C9, 0x4F0A, 0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049, + 0x88CD, 0x56F2, 0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01, + 0x88D1, 0x5C09, 0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170, + 0x88D5, 0x6613, 0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F, + 0x88D9, 0x7570, 0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF, + 0x88DD, 0x80C3, 0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02, + 0x88E1, 0x9055, 0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95, + 0x88E5, 0x4EA5, 0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1, + 0x88E9, 0x78EF, 0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2, + 0x88ED, 0x9038, 0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B, + 0x88F1, 0x9C2F, 0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD, + 0x88F5, 0x54E1, 0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15, + 0x88F9, 0x98F2, 0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D, + 0x8940, 0x9662, 0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB, + 0x8944, 0x540B, 0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF, + 0x8948, 0x7FBD, 0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F, + 0x894C, 0x9D5C, 0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893, + 0x8950, 0x81FC, 0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504, + 0x8954, 0x6B1D, 0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5, + 0x8958, 0x53A9, 0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F, + 0x895C, 0x5642, 0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2, + 0x8960, 0x834F, 0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6, + 0x8964, 0x5B30, 0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3, + 0x8968, 0x6804, 0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29, + 0x896C, 0x745B, 0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834, + 0x8970, 0x82F1, 0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED, + 0x8974, 0x6DB2, 0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5, + 0x8978, 0x60A6, 0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2, + 0x897C, 0x698E, 0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712, + 0x8981, 0x5830, 0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6, + 0x8985, 0x6028, 0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF, + 0x8989, 0x6F14, 0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159, + 0x898D, 0x71D5, 0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276, + 0x8991, 0x82D1, 0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B, + 0x8995, 0x9D1B, 0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A, + 0x8999, 0x7525, 0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965, + 0x899D, 0x5F80, 0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA, + 0x89A1, 0x6A2A, 0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B, + 0x89A5, 0x7FC1, 0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E, + 0x89A9, 0x9EC4, 0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B, + 0x89AD, 0x5104, 0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6, + 0x89B1, 0x6876, 0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA, + 0x89B5, 0x5378, 0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F, + 0x89B9, 0x97F3, 0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE, + 0x89BD, 0x4F55, 0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73, + 0x89C1, 0x52A0, 0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F, + 0x89C5, 0x5AC1, 0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1, + 0x89C9, 0x6687, 0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C, + 0x89CD, 0x6CB3, 0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D, + 0x89D1, 0x79BE, 0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1, + 0x89D5, 0x82DB, 0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF, + 0x89D9, 0x83D3, 0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629, + 0x89DD, 0x8CA8, 0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E, + 0x89E1, 0x868A, 0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211, + 0x89E5, 0x7259, 0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD, + 0x89E9, 0x86FE, 0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913, + 0x89ED, 0x99D5, 0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3, + 0x89F1, 0x56DE, 0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB, + 0x89F5, 0x5FEB, 0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062, + 0x89F9, 0x61D0, 0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539, + 0x8A40, 0x9B41, 0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77, + 0x8A44, 0x7070, 0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75, + 0x8A48, 0x82A5, 0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E, + 0x8A4C, 0x8C9D, 0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916, + 0x8A50, 0x54B3, 0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168, + 0x8A54, 0x6982, 0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB, + 0x8A58, 0x8857, 0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8, + 0x8A5C, 0x6D6C, 0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3, + 0x8A60, 0x67FF, 0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283, + 0x8A64, 0x5687, 0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1, + 0x8A68, 0x64B9, 0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB, + 0x8A6C, 0x7372, 0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A, + 0x8A70, 0x89D2, 0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED, + 0x8A74, 0x95A3, 0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66, + 0x8A78, 0x5CB3, 0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E, + 0x8A7C, 0x639B, 0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F, + 0x8A81, 0x68B6, 0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272, + 0x8A85, 0x559D, 0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B, + 0x8A89, 0x6E07, 0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910, + 0x8A8D, 0x8F44, 0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6, + 0x8A91, 0x691B, 0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A, + 0x8A95, 0x515C, 0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC, + 0x8A99, 0x938C, 0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822, + 0x8A9D, 0x8305, 0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208, + 0x8AA1, 0x82C5, 0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83, + 0x8AA5, 0x51A0, 0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8, + 0x8AA9, 0x52E7, 0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A, + 0x8AAD, 0x59E6, 0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB, + 0x8AB1, 0x5E72, 0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F, + 0x8AB5, 0x6163, 0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562, + 0x8AB9, 0x67D1, 0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E, + 0x8ABD, 0x6B53, 0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97, + 0x8AC1, 0x6F45, 0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3, + 0x8AC5, 0x770B, 0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21, + 0x8AC9, 0x7DE9, 0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D, + 0x8ACD, 0x8266, 0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC, + 0x8AD1, 0x8CAB, 0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593, + 0x8AD5, 0x9591, 0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3, + 0x8AD9, 0x9928, 0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B, + 0x8ADD, 0x5CB8, 0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C, + 0x8AE1, 0x773C, 0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B, + 0x8AE5, 0x96C1, 0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858, + 0x8AE9, 0x4F01, 0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C, + 0x8AED, 0x5668, 0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09, + 0x8AF1, 0x5BC4, 0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E, + 0x8AF5, 0x5FCC, 0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7, + 0x8AF9, 0x65E2, 0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4, + 0x8B40, 0x6A5F, 0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17, + 0x8B44, 0x6C7D, 0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63, + 0x8B48, 0x7A00, 0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F, + 0x8B4C, 0x8A18, 0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC, + 0x8B50, 0x8F1D, 0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C, + 0x8B54, 0x4E80, 0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993, + 0x8B58, 0x5B9C, 0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC, + 0x8B5C, 0x6B3A, 0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947, + 0x8B60, 0x7FA9, 0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70, + 0x8B64, 0x63AC, 0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409, + 0x8B68, 0x5403, 0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58, + 0x8B6C, 0x8A70, 0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD, + 0x8B70, 0x5374, 0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650, + 0x8B74, 0x9006, 0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7, + 0x8B78, 0x4F11, 0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE, + 0x8B7C, 0x5F13, 0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D, + 0x8B81, 0x6C42, 0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078, + 0x8B85, 0x7403, 0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08, + 0x8B89, 0x7D1A, 0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7, + 0x8B8D, 0x725B, 0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8, + 0x8B91, 0x62D2, 0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20, + 0x8B95, 0x865A, 0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8, + 0x8B99, 0x6F01, 0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8, + 0x8B9D, 0x4EAB, 0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0, + 0x8BA1, 0x50D1, 0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171, + 0x8BA5, 0x51F6, 0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F, + 0x8BA9, 0x53EB, 0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1, + 0x8BAD, 0x5F37, 0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050, + 0x8BB1, 0x606D, 0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B, + 0x8BB5, 0x6CC1, 0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF, + 0x8BB9, 0x80F8, 0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E, + 0x8BBD, 0x90F7, 0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957, + 0x8BC1, 0x9A5A, 0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D, + 0x8BC5, 0x6681, 0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2, + 0x8BC9, 0x6975, 0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81, + 0x8BCD, 0x50C5, 0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE, + 0x8BD1, 0x9326, 0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D, + 0x8BD5, 0x7434, 0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B, + 0x8BD9, 0x7DCA, 0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F, + 0x8BDD, 0x895F, 0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1, + 0x8BE1, 0x541F, 0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036, + 0x8BE5, 0x53E5, 0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396, + 0x8BE9, 0x77E9, 0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6, + 0x8BED, 0x99C8, 0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A, + 0x8BF1, 0x865E, 0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076, + 0x8BF5, 0x5BD3, 0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32, + 0x8BF9, 0x6ADB, 0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48, + 0x8C40, 0x6398, 0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774, + 0x8C44, 0x8F61, 0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688, + 0x8C48, 0x7C82, 0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851, + 0x8C4C, 0x936C, 0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB, + 0x8C50, 0x8A13, 0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1, + 0x8C54, 0x5366, 0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2, + 0x8C58, 0x50BE, 0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553, + 0x8C5C, 0x572D, 0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951, + 0x8C60, 0x5F62, 0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176, + 0x8C64, 0x6167, 0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A, + 0x8C68, 0x656C, 0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13, + 0x8C6C, 0x7566, 0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C, + 0x8C70, 0x7D99, 0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E, + 0x8C74, 0x834A, 0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63, + 0x8C78, 0x8B66, 0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F, + 0x8C7C, 0x82B8, 0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287, + 0x8C81, 0x621F, 0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699, + 0x8C85, 0x6841, 0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A, + 0x8C89, 0x6F54, 0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840, + 0x8C8D, 0x8A23, 0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039, + 0x8C91, 0x5026, 0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238, + 0x8C95, 0x5263, 0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805, + 0x8C99, 0x5ACC, 0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8, + 0x8C9D, 0x62F3, 0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29, + 0x8CA1, 0x727D, 0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814, + 0x8CA5, 0x786F, 0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9, + 0x8CA9, 0x898B, 0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2, + 0x8CAD, 0x9063, 0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855, + 0x8CB1, 0x9A13, 0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F, + 0x8CB5, 0x53B3, 0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B, + 0x8CB9, 0x6E90, 0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43, + 0x8CBD, 0x8237, 0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650, + 0x8CC1, 0x4E4E, 0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C, + 0x8CC5, 0x56FA, 0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1, + 0x8CC9, 0x5EAB, 0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545, + 0x8CCD, 0x67AF, 0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA, + 0x8CD1, 0x88B4, 0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0, + 0x8CD5, 0x864E, 0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237, + 0x8CD9, 0x96C7, 0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94, + 0x8CDD, 0x4E92, 0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449, + 0x8CE1, 0x543E, 0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1, + 0x8CE5, 0x609F, 0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A, + 0x8CE9, 0x7881, 0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77, + 0x8CED, 0x9190, 0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4, + 0x8CF1, 0x4F7C, 0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016, + 0x8CF5, 0x5149, 0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9, + 0x8CF9, 0x52FE, 0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411, + 0x8D40, 0x540E, 0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2, + 0x8D44, 0x597D, 0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F, + 0x8D48, 0x5DE5, 0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78, + 0x8D4C, 0x5E83, 0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18, + 0x8D50, 0x6052, 0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8, + 0x8D54, 0x63A7, 0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643, + 0x8D58, 0x66F4, 0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897, + 0x8D5C, 0x69CB, 0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69, + 0x8D60, 0x6E2F, 0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687, + 0x8D64, 0x786C, 0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05, + 0x8D68, 0x7D18, 0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015, + 0x8D6C, 0x8003, 0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154, + 0x8D70, 0x818F, 0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C, + 0x8D74, 0x8861, 0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC, + 0x8D78, 0x90CA, 0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F, + 0x8D7C, 0x92FC, 0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805, + 0x8D81, 0x9999, 0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B, + 0x8D85, 0x52AB, 0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5, + 0x8D89, 0x62F7, 0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F, + 0x8D8D, 0x9EB9, 0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A, + 0x8D91, 0x56FD, 0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60, + 0x8D95, 0x9ED2, 0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170, + 0x8D99, 0x7511, 0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8, + 0x8D9D, 0x72DB, 0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803, + 0x8DA1, 0x4ECA, 0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE, + 0x8DA5, 0x5A5A, 0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F, + 0x8DA9, 0x6606, 0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7, + 0x8DAD, 0x75D5, 0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42, + 0x8DB1, 0x4E9B, 0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506, + 0x8DB5, 0x5D6F, 0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB, + 0x8DB9, 0x6C99, 0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50, + 0x8DBD, 0x9396, 0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7, + 0x8DC1, 0x632B, 0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D, + 0x8DC5, 0x6700, 0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB, + 0x8DC9, 0x5BB0, 0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1, + 0x8DCD, 0x683D, 0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D, + 0x8DD1, 0x91C7, 0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826, + 0x8DD5, 0x796D, 0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC, + 0x8DD9, 0x88C1, 0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264, + 0x8DDD, 0x5728, 0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1, + 0x8DE1, 0x51B4, 0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A, + 0x8DE5, 0x698A, 0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E, + 0x8DE9, 0x57FC, 0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C, + 0x8DED, 0x524A, 0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628, + 0x8DF1, 0x6714, 0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56, + 0x8DF5, 0x7D22, 0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD, + 0x8DF9, 0x7B39, 0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237, + 0x8E40, 0x5BDF, 0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6, + 0x8E44, 0x672D, 0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1, + 0x8E48, 0x7690, 0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306, + 0x8E4C, 0x9BAB, 0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09, + 0x8E50, 0x5098, 0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8, + 0x8E54, 0x6492, 0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6, + 0x8E58, 0x73CA, 0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82, + 0x8E5C, 0x8695, 0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178, + 0x8E60, 0x9910, 0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B, + 0x8E64, 0x4ED5, 0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F, + 0x8E68, 0x523A, 0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3, + 0x8E6C, 0x56DB, 0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9, + 0x8E70, 0x59FF, 0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02, + 0x8E74, 0x5E2B, 0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307, + 0x8E78, 0x652F, 0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD, + 0x8E7C, 0x65E8, 0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B, + 0x8E81, 0x6C0F, 0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1, + 0x8E85, 0x7CF8, 0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2, + 0x8E89, 0x8102, 0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E, + 0x8E8D, 0x8A69, 0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE, + 0x8E91, 0x8CC7, 0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC, + 0x8E95, 0x6B6F, 0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D, + 0x8E99, 0x5150, 0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148, + 0x8E9D, 0x6301, 0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB, + 0x8EA1, 0x6CBB, 0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4, + 0x8EA5, 0x78C1, 0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033, + 0x8EA9, 0x81EA, 0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50, + 0x8EAD, 0x9E7F, 0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B, + 0x8EB1, 0x7AFA, 0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB, + 0x8EB5, 0x4E03, 0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931, + 0x8EB9, 0x5AC9, 0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F, + 0x8EBD, 0x6F06, 0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F, + 0x8EC1, 0x8500, 0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4, + 0x8EC5, 0x829D, 0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E, + 0x8EC9, 0x820E, 0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368, + 0x8ECD, 0x8D66, 0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E, + 0x8ED1, 0x7D17, 0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA, + 0x8ED5, 0x906E, 0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F, + 0x8ED9, 0x52FA, 0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C, + 0x8EDD, 0x7235, 0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B, + 0x8EE1, 0x82E5, 0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9, + 0x8EE5, 0x4E3B, 0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B, + 0x8EE9, 0x6731, 0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0, + 0x8EED, 0x7A2E, 0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152, + 0x8EF1, 0x9996, 0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A, + 0x8EF5, 0x5BFF, 0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC, + 0x8EF9, 0x9700, 0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468, + 0x8F40, 0x5B97, 0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE, + 0x8F44, 0x6101, 0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0, + 0x8F48, 0x79CB, 0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2, + 0x8F4C, 0x81ED, 0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846, + 0x8F50, 0x8972, 0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F, + 0x8F54, 0x9031, 0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6, + 0x8F58, 0x919C, 0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145, + 0x8F5C, 0x5341, 0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4, + 0x8F60, 0x6C41, 0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26, + 0x8F64, 0x91CD, 0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919, + 0x8F68, 0x5BBF, 0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E, + 0x8F6C, 0x7C9B, 0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA, + 0x8F70, 0x8853, 0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB, + 0x8F74, 0x6625, 0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C, + 0x8F78, 0x99FF, 0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC, + 0x8F7C, 0x696F, 0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96, + 0x8F81, 0x6F64, 0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1, + 0x8F85, 0x9075, 0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6, + 0x8F89, 0x521D, 0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9, + 0x8F8D, 0x6E1A, 0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72, + 0x8F91, 0x66F8, 0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8, + 0x8F95, 0x52A9, 0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F, + 0x8F99, 0x5F90, 0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664, + 0x8F9D, 0x50B7, 0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320, + 0x8FA1, 0x5347, 0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546, + 0x8FA5, 0x5531, 0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE, + 0x8FA9, 0x5A3C, 0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F, + 0x8FAD, 0x5C11, 0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A, + 0x8FB1, 0x5EE0, 0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284, + 0x8FB5, 0x62DB, 0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607, + 0x8FB9, 0x660C, 0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E, + 0x8FBD, 0x68A2, 0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC, + 0x8FC1, 0x6D88, 0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C, + 0x8FC5, 0x7126, 0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701, + 0x8FC9, 0x785D, 0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0, + 0x8FCD, 0x7AE0, 0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39, + 0x8FD1, 0x8096, 0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549, + 0x8FD5, 0x885D, 0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C, + 0x8FD9, 0x8A54, 0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE, + 0x8FDD, 0x91A4, 0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418, + 0x8FE1, 0x969C, 0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08, + 0x8FE5, 0x4E1E, 0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270, + 0x8FE9, 0x57CE, 0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22, + 0x8FED, 0x5E38, 0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761, + 0x8FF1, 0x6756, 0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573, + 0x8FF5, 0x7A63, 0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8, + 0x8FF9, 0x9320, 0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE, + 0x9040, 0x62ED, 0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED, + 0x9044, 0x7E54, 0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6, + 0x9048, 0x98DF, 0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B, + 0x904C, 0x4F38, 0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507, + 0x9050, 0x5A20, 0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3, + 0x9054, 0x614E, 0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B, + 0x9058, 0x68EE, 0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1, + 0x905C, 0x7533, 0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E, + 0x9060, 0x79E6, 0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF, + 0x9064, 0x85AA, 0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB, + 0x9068, 0x8F9B, 0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707, + 0x906C, 0x4EBA, 0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875, + 0x9070, 0x58EC, 0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D, + 0x9074, 0x814E, 0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663, + 0x9078, 0x976D, 0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808, + 0x907C, 0x9162, 0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017, + 0x9081, 0x5439, 0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8, + 0x9085, 0x6C34, 0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B, + 0x9089, 0x7FE0, 0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154, + 0x908D, 0x9310, 0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E, + 0x9091, 0x9AC4, 0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570, + 0x9095, 0x67A2, 0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E, + 0x9099, 0x6749, 0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817, + 0x909D, 0x96C0, 0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A, + 0x90A1, 0x5BF8, 0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D, + 0x90A5, 0x662F, 0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2, + 0x90A9, 0x59D3, 0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210, + 0x90AD, 0x653F, 0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674, + 0x90B1, 0x68F2, 0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05, + 0x90B5, 0x7272, 0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE, + 0x90B9, 0x8056, 0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F, + 0x90BD, 0x8AA0, 0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D, + 0x90C1, 0x9192, 0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589, + 0x90C5, 0x7A0E, 0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D, + 0x90C9, 0x60DC, 0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614, + 0x90CD, 0x6790, 0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D, + 0x90D1, 0x7E3E, 0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64, + 0x90D5, 0x8DE1, 0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207, + 0x90D9, 0x62D9, 0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298, + 0x90DD, 0x8A2D, 0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC, + 0x90E1, 0x96EA, 0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749, + 0x90E5, 0x4ED9, 0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360, + 0x90E9, 0x5BA3, 0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD, + 0x90ED, 0x6226, 0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813, + 0x90F1, 0x6834, 0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17, + 0x90F5, 0x67D3, 0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D, + 0x90F9, 0x65CB, 0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA, + 0x9140, 0x7E4A, 0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B, + 0x9144, 0x8239, 0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE, + 0x9148, 0x8DF5, 0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD, + 0x914C, 0x9291, 0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D, + 0x9150, 0x5584, 0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168, + 0x9154, 0x7985, 0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE, + 0x9158, 0x564C, 0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA, + 0x915C, 0x66FE, 0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9, + 0x9160, 0x758F, 0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956, + 0x9164, 0x79DF, 0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44, + 0x9168, 0x8607, 0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061, + 0x916C, 0x9F20, 0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC, + 0x9170, 0x53E2, 0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE, + 0x9174, 0x594F, 0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64, + 0x9178, 0x531D, 0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C, + 0x917C, 0x6383, 0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD, + 0x9181, 0x65E9, 0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD, + 0x9185, 0x69FD, 0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89, + 0x9189, 0x75E9, 0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF, + 0x918D, 0x7DCF, 0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349, + 0x9191, 0x8358, 0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB, + 0x9195, 0x88C5, 0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D, + 0x9199, 0x9397, 0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF, + 0x919D, 0x5897, 0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535, + 0x91A1, 0x8D08, 0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074, + 0x91A5, 0x5247, 0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349, + 0x91A9, 0x675F, 0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F, + 0x91AD, 0x4FD7, 0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF, + 0x91B1, 0x7D9A, 0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176, + 0x91B5, 0x63C3, 0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A, + 0x91B9, 0x640D, 0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6, + 0x91BD, 0x591A, 0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51, + 0x91C1, 0x553E, 0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0, + 0x91C5, 0x6253, 0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955, + 0x91C9, 0x9640, 0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53, + 0x91CD, 0x5806, 0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1, + 0x91D1, 0x5E2F, 0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B, + 0x91D5, 0x6234, 0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE, + 0x91D9, 0x80CE, 0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B, + 0x91DD, 0x8CB8, 0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A, + 0x91E1, 0x9EDB, 0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0, + 0x91E5, 0x5927, 0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C, + 0x91E9, 0x9DF9, 0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353, + 0x91ED, 0x5544, 0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E, + 0x91F1, 0x62D3, 0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422, + 0x91F5, 0x8A17, 0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE, + 0x91F9, 0x8338, 0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA, + 0x9240, 0x53E9, 0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0, + 0x9244, 0x596A, 0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA, + 0x9248, 0x8FBF, 0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8, + 0x924C, 0x9C48, 0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39, + 0x9250, 0x5358, 0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5, + 0x9254, 0x63A2, 0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1, + 0x9258, 0x6E5B, 0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF, + 0x925C, 0x7BAA, 0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6, + 0x9260, 0x86CB, 0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3, + 0x9264, 0x58C7, 0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696, + 0x9268, 0x6A80, 0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7, + 0x926C, 0x5024, 0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B, + 0x9270, 0x6065, 0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4, + 0x9274, 0x7A1A, 0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718, + 0x9278, 0x9045, 0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C, + 0x927C, 0x7AF9, 0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010, + 0x9281, 0x79E9, 0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1, + 0x9285, 0x7740, 0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99, + 0x9289, 0x5FE0, 0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1, + 0x928D, 0x6CE8, 0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B, + 0x9291, 0x914E, 0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17, + 0x9295, 0x7026, 0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457, + 0x9299, 0x8CAF, 0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB, + 0x929D, 0x558B, 0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33, + 0x92A1, 0x5E81, 0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B, + 0x92A5, 0x5FB4, 0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2, + 0x92A9, 0x671D, 0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A, + 0x92AD, 0x773A, 0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178, + 0x92B1, 0x8776, 0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85, + 0x92B5, 0x8DF3, 0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802, + 0x92B9, 0x9CE5, 0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4, + 0x92BD, 0x6715, 0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3, + 0x92C1, 0x93AE, 0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C, + 0x92C5, 0x690E, 0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A, + 0x92C9, 0x75DB, 0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802, + 0x92CD, 0x63B4, 0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C, + 0x92D1, 0x67D8, 0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4, + 0x92D5, 0x9354, 0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A, + 0x92D9, 0x58F7, 0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A, + 0x92DD, 0x540A, 0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD, + 0x92E1, 0x4F4E, 0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243, + 0x92E5, 0x8C9E, 0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A, + 0x92E9, 0x5E1D, 0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7, + 0x92ED, 0x5F1F, 0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A, + 0x92F1, 0x63D0, 0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887, + 0x92F5, 0x798E, 0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247, + 0x92F9, 0x8A02, 0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013, + 0x9340, 0x90B8, 0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E, + 0x9344, 0x6CE5, 0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575, + 0x9348, 0x6EF4, 0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069, + 0x934C, 0x93D1, 0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9, + 0x9350, 0x64A4, 0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244, + 0x9354, 0x5178, 0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55, + 0x9358, 0x5E97, 0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C, + 0x935C, 0x8CBC, 0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9, + 0x9360, 0x4F1D, 0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530, + 0x9364, 0x96FB, 0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835, + 0x9368, 0x5857, 0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92, + 0x936C, 0x6597, 0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B, + 0x9370, 0x83DF, 0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD, + 0x9374, 0x934D, 0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA, + 0x9378, 0x5EA6, 0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012, + 0x937C, 0x5012, 0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD, + 0x9381, 0x5200, 0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858, + 0x9385, 0x5957, 0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B, + 0x9389, 0x60BC, 0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771, + 0x938D, 0x6843, 0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7, + 0x9391, 0x6DD8, 0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F, + 0x9395, 0x71C8, 0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977, + 0x9399, 0x7B49, 0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6, + 0x939D, 0x7D71, 0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569, + 0x93A1, 0x85E4, 0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46, + 0x93A5, 0x8E0F, 0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419, + 0x93A9, 0x9676, 0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8, + 0x93AD, 0x50CD, 0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802, + 0x93B1, 0x5C0E, 0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E, + 0x93B5, 0x77B3, 0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404, + 0x93B9, 0x9053, 0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07, + 0x93BD, 0x533F, 0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C, + 0x93C1, 0x7279, 0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4, + 0x93C5, 0x6BD2, 0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803, + 0x93C9, 0x6A61, 0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934, + 0x93CD, 0x5C4A, 0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5, + 0x93D1, 0x9149, 0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F, + 0x93D5, 0x60C7, 0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A, + 0x93D9, 0x9041, 0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7, + 0x93DD, 0x920D, 0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185, + 0x93E1, 0x4E4D, 0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E, + 0x93E5, 0x7058, 0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962, + 0x93E9, 0x99B4, 0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357, + 0x93ED, 0x6960, 0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D, + 0x93F1, 0x4E8C, 0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9, + 0x93F5, 0x5302, 0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679, + 0x93F9, 0x5EFF, 0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165, + 0x9440, 0x5982, 0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB, + 0x9444, 0x598A, 0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1, + 0x9448, 0x79B0, 0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471, + 0x944C, 0x732B, 0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5, + 0x9450, 0x637B, 0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98, + 0x9454, 0x4E43, 0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC, + 0x9458, 0x56A2, 0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D, + 0x945C, 0x80FD, 0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2, + 0x9460, 0x8997, 0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A, + 0x9464, 0x64AD, 0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2, + 0x9468, 0x6D3E, 0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46, + 0x946C, 0x7F75, 0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3, + 0x9470, 0x5EC3, 0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557, + 0x9474, 0x676F, 0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC, + 0x9478, 0x80BA, 0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D, + 0x947C, 0x57F9, 0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973, + 0x9481, 0x7164, 0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2, + 0x9485, 0x8CE0, 0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F, + 0x9489, 0x79E4, 0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F, + 0x948D, 0x5265, 0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF, + 0x9491, 0x6CCA, 0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95, + 0x9495, 0x8236, 0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD, + 0x9499, 0x6F20, 0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB, + 0x949D, 0x99C1, 0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1, + 0x94A1, 0x7872, 0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48, + 0x94A5, 0x6AE8, 0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551, + 0x94A9, 0x7560, 0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C, + 0x94AD, 0x767A, 0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10, + 0x94B1, 0x7F70, 0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5, + 0x94B5, 0x9CE9, 0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4, + 0x94B9, 0x96BC, 0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A, + 0x94BD, 0x53CD, 0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C, + 0x94C1, 0x6591, 0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E, + 0x94C5, 0x7248, 0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554, + 0x94C9, 0x7E41, 0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9, + 0x94CD, 0x7BC4, 0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812, + 0x94D1, 0x98EF, 0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A, + 0x94D5, 0x76E4, 0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE, + 0x94D9, 0x532A, 0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983, + 0x94DD, 0x5E87, 0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249, + 0x94E1, 0x6279, 0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4, + 0x94E5, 0x6CCC, 0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891, + 0x94E9, 0x79D8, 0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5, + 0x94ED, 0x88AB, 0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F, + 0x94F1, 0x975E, 0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38, + 0x94F5, 0x5099, 0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787, + 0x94F9, 0x6BD8, 0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E, + 0x9540, 0x9F3B, 0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339, + 0x9544, 0x758B, 0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D, + 0x9548, 0x83F1, 0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5, + 0x954C, 0x7562, 0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867, + 0x9550, 0x59EB, 0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E, + 0x9554, 0x8B2C, 0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19, + 0x9558, 0x6C37, 0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968, + 0x955C, 0x8868, 0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF, + 0x9560, 0x63CF, 0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7, + 0x9564, 0x9328, 0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED, + 0x9568, 0x9C2D, 0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C, + 0x956C, 0x6D5C, 0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3, + 0x9570, 0x983B, 0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D, + 0x9574, 0x4ED8, 0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66, + 0x9578, 0x5BCC, 0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C, + 0x957C, 0x6016, 0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7, + 0x9581, 0x666E, 0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26, + 0x9585, 0x8150, 0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C, + 0x9589, 0x8CA0, 0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C, + 0x958D, 0x9644, 0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66, + 0x9591, 0x821E, 0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8, + 0x9595, 0x5C01, 0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A, + 0x9599, 0x8557, 0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9, + 0x959D, 0x5E45, 0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179, + 0x95A1, 0x8907, 0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17, + 0x95A5, 0x6255, 0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269, + 0x95A9, 0x9B92, 0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674, + 0x95AD, 0x58B3, 0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A, + 0x95B1, 0x596E, 0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B, + 0x95B5, 0x96F0, 0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19, + 0x95B9, 0x4F75, 0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63, + 0x95BD, 0x5E73, 0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26, + 0x95C1, 0x853D, 0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73, + 0x95C5, 0x9801, 0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656, + 0x95C9, 0x78A7, 0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511, + 0x95CD, 0x7B86, 0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247, + 0x95D1, 0x7BC7, 0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4, + 0x95D5, 0x904D, 0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29, + 0x95D9, 0x5F01, 0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217, + 0x95DD, 0x92EA, 0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69, + 0x95E1, 0x752B, 0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42, + 0x95E5, 0x52DF, 0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A, + 0x95E9, 0x66AE, 0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9, + 0x95ED, 0x5023, 0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446, + 0x95F1, 0x5831, 0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0, + 0x95F5, 0x5CEF, 0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1, + 0x95F9, 0x6367, 0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B, + 0x9640, 0x6CD5, 0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832, + 0x9644, 0x7E2B, 0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C, + 0x9648, 0x84EC, 0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A, + 0x964C, 0x8C4A, 0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD, + 0x9650, 0x9CF3, 0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1, + 0x9654, 0x508D, 0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8, + 0x9658, 0x5E3D, 0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F, + 0x965C, 0x66B4, 0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2, + 0x9660, 0x5192, 0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8, + 0x9664, 0x8B00, 0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E, + 0x9668, 0x9632, 0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317, + 0x966C, 0x50D5, 0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2, + 0x9670, 0x6734, 0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46, + 0x9674, 0x91E6, 0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86, + 0x9678, 0x5800, 0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C, + 0x967C, 0x7FFB, 0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469, + 0x9681, 0x78E8, 0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB, + 0x9685, 0x59B9, 0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE, + 0x9689, 0x54E9, 0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C, + 0x968D, 0x6795, 0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52, + 0x9691, 0x685D, 0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8, + 0x9695, 0x62B9, 0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4, + 0x9699, 0x4FAD, 0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07, + 0x969D, 0x6162, 0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513, + 0x96A1, 0x5473, 0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3, + 0x96A5, 0x7B95, 0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C, + 0x96A9, 0x6E4A, 0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108, + 0x96AD, 0x5999, 0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720, + 0x96B1, 0x52D9, 0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F, + 0x96B5, 0x77DB, 0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B, + 0x96B9, 0x5A7F, 0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D, + 0x96BD, 0x547D, 0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7, + 0x96C1, 0x9298, 0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D, + 0x96C5, 0x6EC5, 0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF, + 0x96C9, 0x7DEC, 0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478, + 0x96CD, 0x6A21, 0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F, + 0x96D1, 0x6BDB, 0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2, + 0x96D5, 0x8017, 0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728, + 0x96D9, 0x9ED9, 0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF, + 0x96DD, 0x9905, 0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E, + 0x96E1, 0x8CB0, 0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B, + 0x96E5, 0x9580, 0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6, + 0x96E9, 0x591C, 0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE, + 0x96ED, 0x5F25, 0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79, + 0x96F1, 0x7D04, 0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D, + 0x96F5, 0x9756, 0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453, + 0x96F9, 0x6109, 0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652, + 0x9740, 0x8AED, 0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51, + 0x9744, 0x512A, 0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5, + 0x9748, 0x5E7D, 0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6, + 0x974C, 0x6709, 0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C, + 0x9750, 0x7336, 0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950, + 0x9754, 0x88D5, 0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091, + 0x9758, 0x90F5, 0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915, + 0x975C, 0x4E88, 0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89, + 0x9760, 0x8F3F, 0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C, + 0x9764, 0x5996, 0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA, + 0x9768, 0x63FA, 0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A, + 0x976C, 0x69D8, 0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194, + 0x9770, 0x7528, 0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000, + 0x9774, 0x8449, 0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21, + 0x9778, 0x8E0A, 0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A, + 0x977C, 0x617E, 0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83, + 0x9781, 0x6D74, 0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0, + 0x9785, 0x7F85, 0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765, + 0x9789, 0x83B1, 0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B, + 0x978D, 0x7D61, 0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71, + 0x9791, 0x5375, 0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB, + 0x9795, 0x85CD, 0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229, + 0x9799, 0x540F, 0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8, + 0x979D, 0x7406, 0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF, + 0x97A1, 0x88E1, 0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678, + 0x97A5, 0x5F8B, 0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E, + 0x97A9, 0x63A0, 0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41, + 0x97AD, 0x6E9C, 0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B, + 0x97B1, 0x7C92, 0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D, + 0x97B5, 0x4FB6, 0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C, + 0x97B9, 0x4E86, 0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21, + 0x97BD, 0x51CC, 0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881, + 0x97C1, 0x6DBC, 0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD, + 0x97C5, 0x7A1C, 0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2, + 0x97C9, 0x907C, 0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818, + 0x97CD, 0x529B, 0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398, + 0x97D1, 0x6797, 0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433, + 0x97D5, 0x81E8, 0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57, + 0x97D9, 0x9E9F, 0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99, + 0x97DD, 0x7D2F, 0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36, + 0x97E1, 0x4F8B, 0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA, + 0x97E5, 0x601C, 0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3, + 0x97E9, 0x9234, 0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A, + 0x97ED, 0x9E97, 0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74, + 0x97F1, 0x5217, 0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2, + 0x97F5, 0x5EC9, 0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23, + 0x97F9, 0x7149, 0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F, + 0x9840, 0x84EE, 0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442, + 0x9844, 0x9B6F, 0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2, + 0x9848, 0x8DEF, 0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41, + 0x984C, 0x5ECA, 0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C, + 0x9850, 0x6994, 0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262, + 0x9854, 0x72FC, 0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E, + 0x9858, 0x874B, 0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93, + 0x985C, 0x7984, 0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6, + 0x9860, 0x502D, 0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A, + 0x9864, 0x8CC4, 0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0, + 0x9868, 0x9DF2, 0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10, + 0x986C, 0x8A6B, 0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900, + 0x9870, 0x6E7E, 0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C, + 0x98A0, 0x4E10, 0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31, + 0x98A4, 0x4E36, 0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42, + 0x98A8, 0x4E56, 0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85, + 0x98AC, 0x8C6B, 0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D, + 0x98B0, 0x4E8E, 0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0, + 0x98B4, 0x4EA2, 0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6, + 0x98B8, 0x4ECE, 0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6, + 0x98BC, 0x4EC2, 0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED, + 0x98C0, 0x4EDF, 0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A, + 0x98C4, 0x4F30, 0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57, + 0x98C8, 0x4F47, 0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F, + 0x98CC, 0x4F98, 0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70, + 0x98D0, 0x4F91, 0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96, + 0x98D4, 0x5118, 0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE, + 0x98D8, 0x4FD8, 0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA, + 0x98DC, 0x4FD0, 0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A, + 0x98E0, 0x5028, 0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025, + 0x98E4, 0x5005, 0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021, + 0x98E8, 0x5029, 0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF, + 0x98EC, 0x5011, 0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047, + 0x98F0, 0x6703, 0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048, + 0x98F4, 0x505A, 0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078, + 0x98F8, 0x5080, 0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4, + 0x98FC, 0x50B2, 0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3, + 0x9943, 0x50C2, 0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5, + 0x9947, 0x50ED, 0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9, + 0x994B, 0x50F5, 0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102, + 0x994F, 0x5116, 0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A, + 0x9953, 0x5121, 0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C, + 0x9957, 0x513B, 0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152, + 0x995B, 0x514C, 0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8, + 0x995F, 0x5169, 0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180, + 0x9963, 0x5182, 0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189, + 0x9967, 0x518F, 0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195, + 0x996B, 0x5196, 0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2, + 0x996F, 0x51A9, 0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3, + 0x9973, 0x51B1, 0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5, + 0x9977, 0x51BD, 0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB, + 0x997B, 0x51E0, 0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED, + 0x9980, 0x51F0, 0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204, + 0x9984, 0x520B, 0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227, + 0x9988, 0x522A, 0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239, + 0x998C, 0x524F, 0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C, + 0x9990, 0x525E, 0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274, + 0x9994, 0x5269, 0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D, + 0x9998, 0x528D, 0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271, + 0x999C, 0x5288, 0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7, + 0x99A0, 0x52AC, 0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5, + 0x99A4, 0x52C1, 0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE, + 0x99A8, 0x52E3, 0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0, + 0x99AC, 0x52F3, 0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9, + 0x99B0, 0x5306, 0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D, + 0x99B4, 0x5310, 0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A, + 0x99B8, 0x5323, 0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333, + 0x99BC, 0x5338, 0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345, + 0x99C0, 0x4E17, 0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6, + 0x99C4, 0x535E, 0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918, + 0x99C8, 0x537B, 0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396, + 0x99CC, 0x53A0, 0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE, + 0x99D0, 0x53B0, 0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12, + 0x99D4, 0x96D9, 0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE, + 0x99D8, 0x53EE, 0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA, + 0x99DC, 0x5401, 0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C, + 0x99E0, 0x542D, 0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436, + 0x99E4, 0x5429, 0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F, + 0x99E8, 0x5475, 0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471, + 0x99EC, 0x5477, 0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B, + 0x99F0, 0x5480, 0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490, + 0x99F4, 0x5486, 0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8, + 0x99F8, 0x54A5, 0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8, + 0x99FC, 0x54A8, 0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4, + 0x9A43, 0x54BE, 0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5, + 0x9A47, 0x54E6, 0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD, + 0x9A4B, 0x54EE, 0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2, + 0x9A4F, 0x5539, 0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C, + 0x9A53, 0x552E, 0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556, + 0x9A57, 0x5557, 0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D, + 0x9A5B, 0x5599, 0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A, + 0x9A5F, 0x559F, 0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598, + 0x9A63, 0x559E, 0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583, + 0x9A67, 0x55A9, 0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA, + 0x9A6B, 0x55C5, 0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC, + 0x9A6F, 0x55E4, 0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7, + 0x9A73, 0x5616, 0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B, + 0x9A77, 0x55F9, 0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF, + 0x9A7B, 0x5634, 0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638, + 0x9A80, 0x566B, 0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C, + 0x9A84, 0x566A, 0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A, + 0x9A88, 0x56A0, 0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5, + 0x9A8C, 0x56AE, 0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2, + 0x9A90, 0x56BC, 0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0, + 0x9A94, 0x56C8, 0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3, + 0x9A98, 0x56D7, 0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700, + 0x9A9C, 0x56FF, 0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708, + 0x9AA0, 0x570B, 0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718, + 0x9AA4, 0x5716, 0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726, + 0x9AA8, 0x5737, 0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B, + 0x9AAC, 0x5740, 0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0, + 0x9AB0, 0x5788, 0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789, + 0x9AB4, 0x5793, 0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4, + 0x9AB8, 0x57AA, 0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6, + 0x9ABC, 0x57D4, 0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A, + 0x9AC0, 0x57D6, 0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819, + 0x9AC4, 0x581D, 0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862, + 0x9AC8, 0x584B, 0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852, + 0x9ACC, 0x583D, 0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9, + 0x9AD0, 0x589F, 0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE, + 0x9AD4, 0x58BB, 0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5, + 0x9AD8, 0x58D3, 0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9, + 0x9ADC, 0x58D8, 0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4, + 0x9AE0, 0x58DF, 0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9, + 0x9AE4, 0x58FB, 0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902, + 0x9AE8, 0x590A, 0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6, + 0x9AEC, 0x5925, 0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932, + 0x9AF0, 0x5938, 0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955, + 0x9AF4, 0x5950, 0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958, + 0x9AF8, 0x5962, 0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C, + 0x9AFC, 0x5969, 0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D, + 0x9B43, 0x4F5E, 0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2, + 0x9B47, 0x59C6, 0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D, + 0x9B4B, 0x59D9, 0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F, + 0x9B4F, 0x5A11, 0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A, + 0x9B53, 0x5A40, 0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35, + 0x9B57, 0x5A36, 0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A, + 0x9B5B, 0x5ABC, 0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2, + 0x9B5F, 0x5ABD, 0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6, + 0x9B63, 0x5AE9, 0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB, + 0x9B67, 0x5B0C, 0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32, + 0x9B6B, 0x5AD0, 0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E, + 0x9B6F, 0x5B43, 0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51, + 0x9B73, 0x5B55, 0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65, + 0x9B77, 0x5B69, 0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75, + 0x9B7B, 0x5B78, 0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80, + 0x9B80, 0x5B83, 0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3, + 0x9B84, 0x5BC7, 0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0, + 0x9B88, 0x5BE4, 0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE, + 0x9B8C, 0x5BE5, 0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6, + 0x9B90, 0x5BF3, 0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08, + 0x9B94, 0x5C0D, 0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22, + 0x9B98, 0x5C28, 0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41, + 0x9B9C, 0x5C46, 0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50, + 0x9BA0, 0x5C4F, 0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E, + 0x9BA4, 0x4E62, 0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C, + 0x9BA8, 0x5C91, 0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB, + 0x9BAC, 0x5CBB, 0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7, + 0x9BB0, 0x5CC5, 0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9, + 0x9BB4, 0x5CE9, 0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED, + 0x9BB8, 0x5D8C, 0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15, + 0x9BBC, 0x5D17, 0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B, + 0x9BC0, 0x5D11, 0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A, + 0x9BC4, 0x5D19, 0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52, + 0x9BC8, 0x5D4E, 0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73, + 0x9BCC, 0x5D76, 0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82, + 0x9BD0, 0x5DA2, 0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE, + 0x9BD4, 0x5DBD, 0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC, + 0x9BD8, 0x5DC9, 0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2, + 0x9BDC, 0x5DD6, 0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2, + 0x9BE0, 0x5DF5, 0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19, + 0x9BE4, 0x5E11, 0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37, + 0x9BE8, 0x5E44, 0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E, + 0x9BEC, 0x5E57, 0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62, + 0x9BF0, 0x5E64, 0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76, + 0x9BF4, 0x5E7A, 0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0, + 0x9BF8, 0x5EC1, 0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0, + 0x9BFC, 0x5ECF, 0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD, + 0x9C43, 0x5EDA, 0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1, + 0x9C47, 0x5EE8, 0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1, + 0x9C4B, 0x5EF3, 0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8, + 0x9C4F, 0x5EFE, 0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D, + 0x9C53, 0x5F5C, 0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16, + 0x9C57, 0x5F29, 0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41, + 0x9C5B, 0x5F48, 0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F, + 0x9C5F, 0x5F51, 0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59, + 0x9C63, 0x5F61, 0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77, + 0x9C67, 0x5F83, 0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A, + 0x9C6B, 0x5F88, 0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E, + 0x9C6F, 0x5F99, 0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8, + 0x9C73, 0x5FAD, 0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB, + 0x9C77, 0x5FE4, 0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD, + 0x9C7B, 0x60B3, 0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060, + 0x9C80, 0x6019, 0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E, + 0x9C84, 0x6031, 0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B, + 0x9C88, 0x6026, 0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A, + 0x9C8C, 0x6041, 0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F, + 0x9C90, 0x604A, 0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063, + 0x9C94, 0x6043, 0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C, + 0x9C98, 0x606B, 0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D, + 0x9C9C, 0x60E7, 0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084, + 0x9CA0, 0x609B, 0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092, + 0x9CA4, 0x60A7, 0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8, + 0x9CA8, 0x60E0, 0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0, + 0x9CAC, 0x60BD, 0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8, + 0x9CB0, 0x614D, 0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6, + 0x9CB4, 0x60F7, 0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA, + 0x9CB8, 0x6103, 0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1, + 0x9CBC, 0x610D, 0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E, + 0x9CC0, 0x6128, 0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F, + 0x9CC4, 0x613C, 0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D, + 0x9CC8, 0x6142, 0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177, + 0x9CCC, 0x6158, 0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B, + 0x9CD0, 0x6174, 0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171, + 0x9CD4, 0x615F, 0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175, + 0x9CD8, 0x6199, 0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC, + 0x9CDC, 0x6194, 0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191, + 0x9CE0, 0x61AB, 0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA, + 0x9CE4, 0x61C9, 0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3, + 0x9CE8, 0x61C6, 0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79, + 0x9CEC, 0x61CD, 0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6, + 0x9CF0, 0x61FA, 0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD, + 0x9CF4, 0x61FC, 0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208, + 0x9CF8, 0x6209, 0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214, + 0x9CFC, 0x621B, 0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A, + 0x9D43, 0x622E, 0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233, + 0x9D47, 0x6241, 0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263, + 0x9D4B, 0x625B, 0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C, + 0x9D4F, 0x6282, 0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292, + 0x9D53, 0x6293, 0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283, + 0x9D57, 0x6294, 0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB, + 0x9D5B, 0x62CF, 0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4, + 0x9D5F, 0x62C8, 0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA, + 0x9D63, 0x62C2, 0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9, + 0x9D67, 0x630C, 0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327, + 0x9D6B, 0x6302, 0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5, + 0x9D6F, 0x6350, 0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C, + 0x9D73, 0x634F, 0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380, + 0x9D77, 0x63AB, 0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F, + 0x9D7B, 0x6389, 0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B, + 0x9D80, 0x6369, 0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0, + 0x9D84, 0x63C6, 0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2, + 0x9D88, 0x63F6, 0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434, + 0x9D8C, 0x6406, 0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436, + 0x9D90, 0x651D, 0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F, + 0x9D94, 0x6467, 0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E, + 0x9D98, 0x652A, 0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5, + 0x9D9C, 0x64A9, 0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA, + 0x9DA0, 0x64D2, 0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB, + 0x9DA4, 0x64D8, 0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7, + 0x9DA8, 0x8209, 0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC, + 0x9DAC, 0x64E3, 0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6, + 0x9DB0, 0x64F4, 0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500, + 0x9DB4, 0x64FD, 0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505, + 0x9DB8, 0x6524, 0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534, + 0x9DBC, 0x6535, 0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538, + 0x9DC0, 0x754B, 0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555, + 0x9DC4, 0x654D, 0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D, + 0x9DC8, 0x6572, 0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583, + 0x9DCC, 0x8B8A, 0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB, + 0x9DD0, 0x65B7, 0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1, + 0x9DD4, 0x65C4, 0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB, + 0x9DD8, 0x65D9, 0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1, + 0x9DDC, 0x6772, 0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB, + 0x9DE0, 0x6773, 0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634, + 0x9DE4, 0x661C, 0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649, + 0x9DE8, 0x6641, 0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664, + 0x9DEC, 0x6667, 0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662, + 0x9DF0, 0x6670, 0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E, + 0x9DF4, 0x6689, 0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D, + 0x9DF8, 0x66C1, 0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE, + 0x9DFC, 0x66BC, 0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6, + 0x9E43, 0x66DA, 0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6, + 0x9E47, 0x66E9, 0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7, + 0x9E4B, 0x670F, 0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726, + 0x9E4F, 0x6727, 0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F, + 0x9E53, 0x6736, 0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737, + 0x9E57, 0x6746, 0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759, + 0x9E5B, 0x6763, 0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770, + 0x9E5F, 0x67A9, 0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C, + 0x9E63, 0x678B, 0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785, + 0x9E67, 0x67B7, 0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC, + 0x9E6B, 0x67B3, 0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4, + 0x9E6F, 0x67DE, 0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE, + 0x9E73, 0x67B9, 0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7, + 0x9E77, 0x6A9C, 0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829, + 0x9E7B, 0x6840, 0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E, + 0x9E80, 0x68B3, 0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863, + 0x9E84, 0x6877, 0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F, + 0x9E88, 0x68AD, 0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B, + 0x9E8C, 0x6883, 0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874, + 0x9E90, 0x68B5, 0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F, + 0x9E94, 0x688D, 0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA, + 0x9E98, 0x6908, 0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926, + 0x9E9C, 0x68E1, 0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4, + 0x9EA0, 0x68E7, 0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912, + 0x9EA4, 0x6904, 0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925, + 0x9EA8, 0x68F9, 0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928, + 0x9EAC, 0x692A, 0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921, + 0x9EB0, 0x68C6, 0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C, + 0x9EB4, 0x6978, 0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E, + 0x9EB8, 0x696E, 0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D, + 0x9EBC, 0x6959, 0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E, + 0x9EC0, 0x695D, 0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2, + 0x9EC4, 0x69AE, 0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1, + 0x9EC8, 0x69D3, 0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8, + 0x9ECC, 0x69CA, 0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3, + 0x9ED0, 0x69A7, 0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0, + 0x9ED4, 0x699C, 0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE, + 0x9ED8, 0x69E8, 0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF, + 0x9EDC, 0x6B0A, 0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7, + 0x9EE0, 0x6A05, 0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED, + 0x9EE4, 0x6A14, 0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12, + 0x9EE8, 0x6AC1, 0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44, + 0x9EEC, 0x6A0C, 0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78, + 0x9EF0, 0x6A47, 0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66, + 0x9EF4, 0x6A48, 0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90, + 0x9EF8, 0x6A8D, 0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2, + 0x9EFC, 0x6AA3, 0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB, + 0x9F43, 0x6AC3, 0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3, + 0x9F47, 0x6AAC, 0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF, + 0x9F4B, 0x6AAA, 0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB, + 0x9F4F, 0x6B05, 0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12, + 0x9F53, 0x6B16, 0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38, + 0x9F57, 0x6B37, 0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE, + 0x9F5B, 0x6B47, 0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50, + 0x9F5F, 0x6B59, 0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F, + 0x9F63, 0x6B61, 0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F, + 0x9F67, 0x6B80, 0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D, + 0x9F6B, 0x6B98, 0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4, + 0x9F6F, 0x6BAA, 0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2, + 0x9F73, 0x6BB1, 0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC, + 0x9F77, 0x6BC6, 0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF, + 0x9F7B, 0x6BEC, 0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF, + 0x9F80, 0x9EBE, 0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14, + 0x9F84, 0x6C1B, 0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E, + 0x9F88, 0x6C55, 0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82, + 0x9F8C, 0x6C8D, 0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B, + 0x9F90, 0x6C7E, 0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92, + 0x9F94, 0x6C90, 0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3, + 0x9F98, 0x6CBD, 0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD, + 0x9F9C, 0x6CAE, 0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA, + 0x9FA0, 0x6CDB, 0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA, + 0x9FA4, 0x6D1F, 0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B, + 0x9FA8, 0x6D3D, 0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35, + 0x9FAC, 0x6D33, 0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63, + 0x9FB0, 0x6D93, 0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79, + 0x9FB4, 0x6D59, 0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4, + 0x9FB8, 0x6D85, 0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A, + 0x9FBC, 0x6DB5, 0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8, + 0x9FC0, 0x6DC6, 0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC, + 0x9FC4, 0x6DE8, 0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA, + 0x9FC8, 0x6DD9, 0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA, + 0x9FCC, 0x6DEE, 0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E, + 0x9FD0, 0x6E19, 0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E, + 0x9FD4, 0x6E23, 0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76, + 0x9FD8, 0x6E4D, 0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A, + 0x9FDC, 0x6E4E, 0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D, + 0x9FE0, 0x6E38, 0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98, + 0x9FE4, 0x6EC9, 0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD, + 0x9FE8, 0x6EAF, 0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4, + 0x9FEC, 0x6ED5, 0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2, + 0x9FF0, 0x6E9F, 0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C, + 0x9FF4, 0x6EEC, 0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F, + 0x9FF8, 0x6EF2, 0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32, + 0x9FFC, 0x6ECC, 0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7, + 0xE043, 0x6F86, 0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81, + 0xE047, 0x6F80, 0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3, + 0xE04B, 0x6F6D, 0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58, + 0xE04F, 0x6F8E, 0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66, + 0xE053, 0x6FB3, 0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4, + 0xE057, 0x6FB9, 0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF, + 0xE05B, 0x6FD5, 0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8, + 0xE05F, 0x6FF1, 0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009, + 0xE063, 0x700B, 0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001, + 0xE067, 0x700F, 0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A, + 0xE06B, 0x6F74, 0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F, + 0xE06F, 0x7030, 0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051, + 0xE073, 0x7063, 0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF, + 0xE077, 0x70F1, 0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3, + 0xE07B, 0x70AE, 0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD, + 0xE080, 0x70D9, 0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C, + 0xE084, 0x7119, 0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188, + 0xE088, 0x7166, 0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156, + 0xE08C, 0x716C, 0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184, + 0xE090, 0x7195, 0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7, + 0xE094, 0x71B9, 0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9, + 0xE098, 0x71D4, 0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC, + 0xE09C, 0x71E7, 0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9, + 0xE0A0, 0x71FF, 0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B, + 0xE0A4, 0x7228, 0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230, + 0xE0A8, 0x7232, 0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F, + 0xE0AC, 0x7240, 0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258, + 0xE0B0, 0x7274, 0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281, + 0xE0B4, 0x7287, 0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2, + 0xE0B8, 0x72A7, 0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3, + 0xE0BC, 0x72C6, 0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2, + 0xE0C0, 0x72E2, 0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9, + 0xE0C4, 0x72F7, 0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A, + 0xE0C8, 0x731C, 0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334, + 0xE0CC, 0x732F, 0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E, + 0xE0D0, 0x734E, 0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357, + 0xE0D4, 0x736A, 0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378, + 0xE0D8, 0x7375, 0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8, + 0xE0DC, 0x73B3, 0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0, + 0xE0E0, 0x73E5, 0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2, + 0xE0E4, 0x7405, 0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8, + 0xE0E8, 0x7432, 0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F, + 0xE0EC, 0x745F, 0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C, + 0xE0F0, 0x7469, 0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A, + 0xE0F4, 0x7476, 0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E, + 0xE0F8, 0x74A7, 0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4, + 0xE0FC, 0x73F1, 0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7, + 0xE143, 0x74E9, 0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0, + 0xE147, 0x74F1, 0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504, + 0xE14B, 0x7503, 0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E, + 0xE14F, 0x750D, 0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E, + 0xE153, 0x7526, 0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544, + 0xE157, 0x754D, 0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B, + 0xE15B, 0x7546, 0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564, + 0xE15F, 0x7567, 0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578, + 0xE163, 0x7576, 0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574, + 0xE167, 0x758A, 0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594, + 0xE16B, 0x759A, 0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3, + 0xE16F, 0x75C2, 0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5, + 0xE173, 0x75BD, 0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1, + 0xE177, 0x75CD, 0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9, + 0xE17B, 0x75E3, 0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF, + 0xE180, 0x75FC, 0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA, + 0xE184, 0x75F2, 0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D, + 0xE188, 0x7609, 0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620, + 0xE18C, 0x7621, 0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634, + 0xE190, 0x7630, 0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648, + 0xE194, 0x7646, 0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661, + 0xE198, 0x7662, 0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A, + 0xE19C, 0x7667, 0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672, + 0xE1A0, 0x7676, 0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680, + 0xE1A4, 0x7683, 0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E, + 0xE1A8, 0x7696, 0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A, + 0xE1AC, 0x76B0, 0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9, + 0xE1B0, 0x76BA, 0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6, + 0xE1B4, 0x76D2, 0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5, + 0xE1B8, 0x76E7, 0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB, + 0xE1BC, 0x7708, 0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729, + 0xE1C0, 0x7724, 0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726, + 0xE1C4, 0x771B, 0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747, + 0xE1C8, 0x775A, 0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B, + 0xE1CC, 0x7765, 0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779, + 0xE1D0, 0x778E, 0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0, + 0xE1D4, 0x779E, 0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9, + 0xE1D8, 0x77BF, 0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB, + 0xE1DC, 0x77C7, 0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA, + 0xE1E0, 0x77DC, 0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC, + 0xE1E4, 0x780C, 0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820, + 0xE1E8, 0x792A, 0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874, + 0xE1EC, 0x7886, 0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C, + 0xE1F0, 0x78A3, 0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF, + 0xE1F4, 0x78D1, 0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4, + 0xE1F8, 0x78BE, 0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA, + 0xE1FC, 0x78EC, 0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD, + 0xE243, 0x78F4, 0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911, + 0xE247, 0x7919, 0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940, + 0xE24B, 0x7960, 0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A, + 0xE24F, 0x7955, 0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F, + 0xE253, 0x798A, 0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B, + 0xE257, 0x79AA, 0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9, + 0xE25B, 0x79BA, 0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7, + 0xE25F, 0x79EC, 0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08, + 0xE263, 0x7A0D, 0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20, + 0xE267, 0x7A1F, 0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B, + 0xE26B, 0x7A3E, 0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57, + 0xE26F, 0x7A49, 0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69, + 0xE273, 0x9F9D, 0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D, + 0xE277, 0x7A88, 0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98, + 0xE27B, 0x7A96, 0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0, + 0xE280, 0x7AB6, 0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF, + 0xE284, 0x9083, 0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD, + 0xE288, 0x7ACF, 0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9, + 0xE28C, 0x7ADA, 0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2, + 0xE290, 0x7AE6, 0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02, + 0xE294, 0x7B0F, 0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33, + 0xE298, 0x7B18, 0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35, + 0xE29C, 0x7B28, 0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A, + 0xE2A0, 0x7B04, 0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C, + 0xE2A4, 0x7B45, 0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74, + 0xE2A8, 0x7B67, 0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C, + 0xE2AC, 0x7B6E, 0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F, + 0xE2B0, 0x7B8D, 0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B, + 0xE2B4, 0x7B92, 0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99, + 0xE2B8, 0x7BCB, 0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF, + 0xE2BC, 0x7BB4, 0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9, + 0xE2C0, 0x7C11, 0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5, + 0xE2C4, 0x7C60, 0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13, + 0xE2C8, 0x7BF3, 0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D, + 0xE2CC, 0x7BF6, 0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A, + 0xE2D0, 0x7C1F, 0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D, + 0xE2D4, 0x7C4C, 0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F, + 0xE2D8, 0x7C40, 0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F, + 0xE2DC, 0x7C64, 0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C, + 0xE2E0, 0x7C75, 0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4, + 0xE2E4, 0x7CAD, 0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1, + 0xE2E8, 0x7CA8, 0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1, + 0xE2EC, 0x7CAE, 0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0, + 0xE2F0, 0x7CC5, 0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2, + 0xE2F4, 0x7CDC, 0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF, + 0xE2F8, 0x7CF2, 0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA, + 0xE2FC, 0x7D06, 0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15, + 0xE343, 0x7D0A, 0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E, + 0xE347, 0x7D32, 0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46, + 0xE34B, 0x7D73, 0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72, + 0xE34F, 0x7D68, 0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63, + 0xE353, 0x7D93, 0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F, + 0xE357, 0x7D7D, 0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE, + 0xE35B, 0x7DA3, 0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD, + 0xE35F, 0x7DAB, 0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF, + 0xE363, 0x7DDC, 0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0, + 0xE367, 0x7DD8, 0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE, + 0xE36B, 0x7DFB, 0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05, + 0xE36F, 0x7E0A, 0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12, + 0xE373, 0x7E31, 0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B, + 0xE377, 0x7E22, 0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B, + 0xE37B, 0x7E35, 0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37, + 0xE380, 0x7E32, 0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D, + 0xE384, 0x7E56, 0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A, + 0xE388, 0x7E79, 0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C, + 0xE38C, 0x7E7B, 0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D, + 0xE390, 0x8FAE, 0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89, + 0xE394, 0x7E8C, 0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93, + 0xE398, 0x7E94, 0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B, + 0xE39C, 0x7E9C, 0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45, + 0xE3A0, 0x7F4C, 0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50, + 0xE3A4, 0x7F51, 0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58, + 0xE3A8, 0x7F5F, 0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69, + 0xE3AC, 0x7F67, 0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86, + 0xE3B0, 0x7F83, 0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C, + 0xE3B4, 0x7F94, 0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A, + 0xE3B8, 0x7FA3, 0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9, + 0xE3BC, 0x7FAE, 0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71, + 0xE3C0, 0x7FC5, 0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5, + 0xE3C4, 0x7FD4, 0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9, + 0xE3C8, 0x7FF3, 0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006, + 0xE3CC, 0x8004, 0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018, + 0xE3D0, 0x8019, 0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028, + 0xE3D4, 0x803F, 0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046, + 0xE3D8, 0x8052, 0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F, + 0xE3DC, 0x8062, 0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072, + 0xE3E0, 0x8070, 0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D, + 0xE3E4, 0x807F, 0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085, + 0xE3E8, 0x809B, 0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD, + 0xE3EC, 0x5190, 0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5, + 0xE3F0, 0x80D9, 0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA, + 0xE3F4, 0x80D6, 0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1, + 0xE3F8, 0x811B, 0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F, + 0xE3FC, 0x814B, 0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E, + 0xE443, 0x8153, 0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171, + 0xE447, 0x816E, 0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174, + 0xE44B, 0x8183, 0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180, + 0xE44F, 0x8182, 0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4, + 0xE453, 0x81A3, 0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9, + 0xE457, 0x81B0, 0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8, + 0xE45B, 0x81BD, 0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA, + 0xE45F, 0x81C9, 0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9, + 0xE463, 0x81D8, 0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF, + 0xE467, 0x81E0, 0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB, + 0xE46B, 0x81FE, 0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205, + 0xE46F, 0x8207, 0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210, + 0xE473, 0x8216, 0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238, + 0xE477, 0x8233, 0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258, + 0xE47B, 0x825D, 0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264, + 0xE480, 0x8262, 0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B, + 0xE484, 0x822E, 0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278, + 0xE488, 0x827E, 0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB, + 0xE48C, 0x829F, 0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1, + 0xE490, 0x82E3, 0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4, + 0xE494, 0x82F3, 0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303, + 0xE498, 0x82FB, 0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306, + 0xE49C, 0x82DC, 0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335, + 0xE4A0, 0x8334, 0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331, + 0xE4A4, 0x8340, 0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345, + 0xE4A8, 0x832F, 0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318, + 0xE4AC, 0x8385, 0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F, + 0xE4B0, 0x83A2, 0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E, + 0xE4B4, 0x8387, 0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5, + 0xE4B8, 0x8373, 0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389, + 0xE4BC, 0x83A8, 0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB, + 0xE4C0, 0x83CE, 0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8, + 0xE4C4, 0x840B, 0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407, + 0xE4C8, 0x83E0, 0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422, + 0xE4CC, 0x8420, 0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506, + 0xE4D0, 0x83FB, 0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C, + 0xE4D4, 0x855A, 0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B, + 0xE4D8, 0x84AD, 0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469, + 0xE4DC, 0x8446, 0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479, + 0xE4E0, 0x8435, 0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9, + 0xE4E4, 0x84BF, 0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD, + 0xE4E8, 0x84BB, 0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1, + 0xE4EC, 0x84C6, 0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521, + 0xE4F0, 0x84FF, 0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518, + 0xE4F4, 0x852C, 0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514, + 0xE4F8, 0x84FC, 0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558, + 0xE4FC, 0x8548, 0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B, + 0xE543, 0x8555, 0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588, + 0xE547, 0x8591, 0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D, + 0xE54B, 0x8594, 0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587, + 0xE54F, 0x859C, 0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590, + 0xE553, 0x85C9, 0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9, + 0xE557, 0x85D0, 0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5, + 0xE55B, 0x85DC, 0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613, + 0xE55F, 0x860B, 0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606, + 0xE563, 0x8622, 0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F, + 0xE567, 0x864D, 0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F, + 0xE56B, 0x8667, 0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3, + 0xE56F, 0x86A9, 0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C, + 0xE573, 0x86B6, 0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6, + 0xE577, 0x86B0, 0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB, + 0xE57B, 0x86D4, 0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC, + 0xE580, 0x86DF, 0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712, + 0xE584, 0x8706, 0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703, + 0xE588, 0x86FB, 0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D, + 0xE58C, 0x86F9, 0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F, + 0xE590, 0x8737, 0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729, + 0xE594, 0x871A, 0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778, + 0xE598, 0x874C, 0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757, + 0xE59C, 0x8768, 0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753, + 0xE5A0, 0x8763, 0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2, + 0xE5A4, 0x879F, 0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB, + 0xE5A8, 0x87BD, 0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6, + 0xE5AC, 0x87AB, 0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7, + 0xE5B0, 0x87C6, 0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2, + 0xE5B4, 0x87E0, 0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE, + 0xE5B8, 0x87F6, 0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2, + 0xE5BC, 0x8811, 0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822, + 0xE5C0, 0x8821, 0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839, + 0xE5C4, 0x8827, 0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842, + 0xE5C8, 0x8852, 0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862, + 0xE5CC, 0x886B, 0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E, + 0xE5D0, 0x8875, 0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872, + 0xE5D4, 0x8882, 0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE, + 0xE5D8, 0x8899, 0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4, + 0xE5DC, 0x88B0, 0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3, + 0xE5E0, 0x88C4, 0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9, + 0xE5E4, 0x88DD, 0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC, + 0xE5E8, 0x88F4, 0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904, + 0xE5EC, 0x890C, 0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943, + 0xE5F0, 0x891E, 0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B, + 0xE5F4, 0x8941, 0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936, + 0xE5F8, 0x8938, 0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960, + 0xE5FC, 0x895E, 0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D, + 0xE643, 0x896A, 0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977, + 0xE647, 0x897E, 0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A, + 0xE64B, 0x8993, 0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9, + 0xE64F, 0x89A6, 0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2, + 0xE653, 0x89BA, 0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0, + 0xE657, 0x89DA, 0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7, + 0xE65B, 0x89F4, 0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16, + 0xE65F, 0x8A10, 0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D, + 0xE663, 0x8A25, 0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B, + 0xE667, 0x8A52, 0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C, + 0xE66B, 0x8A6D, 0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85, + 0xE66F, 0x8A82, 0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1, + 0xE673, 0x8A91, 0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A, + 0xE677, 0x8AA3, 0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2, + 0xE67B, 0x8ADA, 0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7, + 0xE680, 0x8AE4, 0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0, + 0xE684, 0x8AE2, 0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB, + 0xE688, 0x8B0C, 0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1, + 0xE68C, 0x8B16, 0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20, + 0xE690, 0x8B33, 0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B, + 0xE694, 0x8B3E, 0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C, + 0xE698, 0x8B4F, 0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56, + 0xE69C, 0x8B5B, 0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F, + 0xE6A0, 0x8B6C, 0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D, + 0xE6A4, 0x8B80, 0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92, + 0xE6A8, 0x8B93, 0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A, + 0xE6AC, 0x8C3A, 0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48, + 0xE6B0, 0x8C4C, 0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55, + 0xE6B4, 0x8C62, 0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A, + 0xE6B8, 0x8C82, 0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A, + 0xE6BC, 0x8C8D, 0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C, + 0xE6C0, 0x8C98, 0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA, + 0xE6C4, 0x8CBD, 0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE, + 0xE6C8, 0x8CB6, 0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4, + 0xE6CC, 0x8CE3, 0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA, + 0xE6D0, 0x8CFB, 0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A, + 0xE6D4, 0x8D07, 0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10, + 0xE6D8, 0x9F4E, 0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14, + 0xE6DC, 0x8D16, 0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71, + 0xE6E0, 0x8D73, 0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2, + 0xE6E4, 0x8DBE, 0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA, + 0xE6E8, 0x8DD6, 0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB, + 0xE6EC, 0x8DEA, 0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3, + 0xE6F0, 0x8DFC, 0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF, + 0xE6F4, 0x8E1D, 0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F, + 0xE6F8, 0x8E42, 0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34, + 0xE6FC, 0x8E4A, 0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C, + 0xE743, 0x8E50, 0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64, + 0xE747, 0x8E60, 0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55, + 0xE74B, 0x8E76, 0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81, + 0xE74F, 0x8E87, 0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B, + 0xE753, 0x8E8A, 0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94, + 0xE757, 0x8E99, 0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC, + 0xE75B, 0x8EB0, 0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE, + 0xE75F, 0x8EC5, 0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB, + 0xE763, 0x8EE3, 0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB, + 0xE767, 0x8EFE, 0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15, + 0xE76B, 0x8F12, 0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C, + 0xE76F, 0x8F1F, 0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26, + 0xE773, 0x8F33, 0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45, + 0xE777, 0x8F42, 0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49, + 0xE77B, 0x8F46, 0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C, + 0xE780, 0x8F62, 0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C, + 0xE784, 0x8F9F, 0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF, + 0xE788, 0x8FB7, 0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2, + 0xE78C, 0x8FEA, 0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4, + 0xE790, 0x9005, 0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011, + 0xE794, 0x9015, 0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E, + 0xE798, 0x9016, 0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036, + 0xE79C, 0x9035, 0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F, + 0xE7A0, 0x9050, 0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E, + 0xE7A4, 0x9049, 0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058, + 0xE7A8, 0x905E, 0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076, + 0xE7AC, 0x96A8, 0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D, + 0xE7B0, 0x9081, 0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089, + 0xE7B4, 0x908F, 0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1, + 0xE7B8, 0x90B5, 0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248, + 0xE7BC, 0x90DB, 0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119, + 0xE7C0, 0x9132, 0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156, + 0xE7C4, 0x9158, 0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169, + 0xE7C8, 0x9173, 0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189, + 0xE7CC, 0x9182, 0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF, + 0xE7D0, 0x91AA, 0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA, + 0xE7D4, 0x91C0, 0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB, + 0xE7D8, 0x91D0, 0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1, + 0xE7DC, 0x91DB, 0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6, + 0xE7E0, 0x921E, 0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C, + 0xE7E4, 0x9215, 0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257, + 0xE7E8, 0x9245, 0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248, + 0xE7EC, 0x9295, 0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250, + 0xE7F0, 0x929C, 0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B, + 0xE7F4, 0x925A, 0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7, + 0xE7F8, 0x92E9, 0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344, + 0xE7FC, 0x932E, 0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A, + 0xE843, 0x9323, 0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B, + 0xE847, 0x935C, 0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E, + 0xE84B, 0x9356, 0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD, + 0xE84F, 0x9394, 0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7, + 0xE853, 0x93E8, 0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3, + 0xE857, 0x93DD, 0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4, + 0xE85B, 0x941A, 0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403, + 0xE85F, 0x9407, 0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B, + 0xE863, 0x9435, 0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441, + 0xE867, 0x9452, 0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460, + 0xE86B, 0x9462, 0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229, + 0xE86F, 0x9470, 0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D, + 0xE873, 0x945A, 0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481, + 0xE877, 0x947F, 0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A, + 0xE87B, 0x9594, 0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599, + 0xE880, 0x95A0, 0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD, + 0xE884, 0x95BC, 0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE, + 0xE888, 0x95CA, 0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD, + 0xE88C, 0x95CC, 0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6, + 0xE890, 0x95DC, 0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2, + 0xE894, 0x9621, 0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F, + 0xE898, 0x9642, 0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B, + 0xE89C, 0x9677, 0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D, + 0xE8A0, 0x965F, 0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C, + 0xE8A4, 0x968D, 0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697, + 0xE8A8, 0x96AA, 0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2, + 0xE8AC, 0x96B0, 0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8, + 0xE8B0, 0x96B9, 0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9, + 0xE8B4, 0x96CD, 0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D, + 0xE8B8, 0x96D5, 0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706, + 0xE8BC, 0x9708, 0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711, + 0xE8C0, 0x970F, 0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724, + 0xE8C4, 0x972A, 0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D, + 0xE8C8, 0x973E, 0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748, + 0xE8CC, 0x9742, 0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760, + 0xE8D0, 0x9764, 0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2, + 0xE8D4, 0x976B, 0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785, + 0xE8D8, 0x977C, 0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786, + 0xE8DC, 0x978B, 0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C, + 0xE8E0, 0x97A8, 0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3, + 0xE8E4, 0x97B4, 0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8, + 0xE8E8, 0x97CB, 0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F, + 0xE8EC, 0x97F2, 0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5, + 0xE8F0, 0x980F, 0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824, + 0xE8F4, 0x9821, 0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846, + 0xE8F8, 0x984F, 0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F, + 0xE8FC, 0x9870, 0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873, + 0xE943, 0x98AA, 0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6, + 0xE947, 0x98C4, 0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9, + 0xE94B, 0x98EB, 0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912, + 0xE94F, 0x9914, 0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D, + 0xE953, 0x991E, 0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C, + 0xE957, 0x992E, 0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942, + 0xE95B, 0x9949, 0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B, + 0xE95F, 0x9951, 0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955, + 0xE963, 0x9997, 0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD, + 0xE967, 0x99AE, 0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB, + 0xE96B, 0x99DD, 0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED, + 0xE96F, 0x99EE, 0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB, + 0xE973, 0x99F8, 0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05, + 0xE977, 0x99E2, 0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37, + 0xE97B, 0x9A45, 0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43, + 0xE980, 0x9A3E, 0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B, + 0xE984, 0x9A57, 0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65, + 0xE988, 0x9A64, 0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A, + 0xE98C, 0x9AAD, 0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0, + 0xE990, 0x9ACF, 0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4, + 0xE994, 0x9ADE, 0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3, + 0xE998, 0x9AE6, 0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE, + 0xE99C, 0x9AF4, 0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB, + 0xE9A0, 0x9B06, 0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F, + 0xE9A4, 0x9B22, 0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27, + 0xE9A8, 0x9B28, 0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E, + 0xE9AC, 0x9B2F, 0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43, + 0xE9B0, 0x9B4F, 0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51, + 0xE9B4, 0x9B58, 0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83, + 0xE9B8, 0x9B91, 0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F, + 0xE9BC, 0x9BA0, 0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0, + 0xE9C0, 0x9BCA, 0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF, + 0xE9C4, 0x9BD1, 0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2, + 0xE9C8, 0x9BE4, 0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A, + 0xE9CC, 0x9BF2, 0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15, + 0xE9D0, 0x9C14, 0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C, + 0xE9D4, 0x9C06, 0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A, + 0xE9D8, 0x9C04, 0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25, + 0xE9DC, 0x9C24, 0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47, + 0xE9E0, 0x9C32, 0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A, + 0xE9E4, 0x9C60, 0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78, + 0xE9E8, 0x9CE7, 0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09, + 0xE9EC, 0x9D08, 0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06, + 0xE9F0, 0x9D2A, 0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23, + 0xE9F4, 0x9D1F, 0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12, + 0xE9F8, 0x9D41, 0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46, + 0xE9FC, 0x9D48, 0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64, + 0xEA43, 0x9D51, 0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72, + 0xEA47, 0x9D89, 0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F, + 0xEA4B, 0x9D7A, 0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9, + 0xEA4F, 0x9DB2, 0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB, + 0xEA53, 0x9DB8, 0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF, + 0xEA57, 0x9DC2, 0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8, + 0xEA5B, 0x9DE6, 0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD, + 0xEA5F, 0x9E1A, 0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75, + 0xEA63, 0x9E79, 0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88, + 0xEA67, 0x9E8B, 0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95, + 0xEA6B, 0x9E91, 0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9, + 0xEA6F, 0x9EB8, 0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761, + 0xEA73, 0x9ECC, 0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0, + 0xEA77, 0x9ED4, 0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD, + 0xEA7B, 0x9EE0, 0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF, + 0xEA80, 0x9EF4, 0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9, + 0xEA84, 0x9EFB, 0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07, + 0xEA88, 0x9F08, 0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21, + 0xEA8C, 0x9F2C, 0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52, + 0xEA90, 0x9F54, 0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60, + 0xEA94, 0x9F61, 0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C, + 0xEA98, 0x9F6A, 0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76, + 0xEA9C, 0x9F95, 0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F, + 0xEAA0, 0x69C7, 0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC, + 0xEAA4, 0x7199, 0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172, + 0xFA43, 0x2173, 0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176, + 0xFA47, 0x2177, 0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4, + 0xFA56, 0xFF07, 0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C, + 0xFA5E, 0x9348, 0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9, + 0xFA62, 0x70BB, 0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9, + 0xFA66, 0x66FB, 0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1, + 0xFA6A, 0x4EFC, 0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39, + 0xFA6E, 0x4F56, 0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A, + 0xFA72, 0x4F94, 0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022, + 0xFA76, 0x4FFF, 0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070, + 0xFA7A, 0x5042, 0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8, + 0xFA7E, 0x514A, 0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE, + 0xFA83, 0x51EC, 0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6, + 0xFA87, 0x52C0, 0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307, + 0xFA8B, 0x5324, 0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2, + 0xFA8F, 0x53DD, 0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A, + 0xFA93, 0x54A9, 0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759, + 0xFA97, 0x5765, 0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7, + 0xFA9B, 0xFA0F, 0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2, + 0xFA9F, 0x590B, 0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D, + 0xFAA3, 0x5963, 0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56, + 0xFAA7, 0x5BC0, 0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC, + 0xFAAB, 0x5C1E, 0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5, + 0xFAAF, 0x5D27, 0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42, + 0xFAB3, 0x5D6D, 0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0, + 0xFAB7, 0x5F21, 0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7, + 0xFABB, 0x5FDE, 0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A, + 0xFABF, 0x60DE, 0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2, + 0xFAC3, 0x6111, 0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198, + 0xFAC7, 0x6213, 0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460, + 0xFACB, 0x649D, 0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600, + 0xFACF, 0x6615, 0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E, + 0xFAD3, 0x661E, 0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657, + 0xFAD7, 0x6659, 0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699, + 0xFADB, 0x66A0, 0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA, + 0xFADF, 0x670E, 0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB, + 0xFAE3, 0x6852, 0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844, + 0xFAE7, 0x68CF, 0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14, + 0xFAEB, 0x6998, 0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B, + 0xFAEF, 0x6A46, 0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2, + 0xFAF3, 0x6AE4, 0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C, + 0xFAF7, 0x6C86, 0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04, + 0xFAFB, 0x6D87, 0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC, + 0xFB42, 0x6DCF, 0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC, + 0xFB46, 0x6E39, 0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C, + 0xFB4A, 0x6EBF, 0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5, + 0xFB4E, 0x7005, 0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085, + 0xFB52, 0x70AB, 0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C, + 0xFB56, 0x7146, 0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1, + 0xFB5A, 0x71FE, 0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324, + 0xFB5E, 0xFA16, 0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9, + 0xFB62, 0x73D6, 0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407, + 0xFB66, 0x73F5, 0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429, + 0xFB6A, 0x742E, 0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F, + 0xFB6E, 0x7501, 0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C, + 0xFB72, 0x769E, 0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17, + 0xFB76, 0x7746, 0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E, + 0xFB7A, 0x7864, 0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18, + 0xFB7E, 0xFA19, 0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B, + 0xFB83, 0x799B, 0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C, + 0xFB87, 0x7AEB, 0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48, + 0xFB8B, 0x7D5C, 0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6, + 0xFB8F, 0x7E52, 0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E, + 0xFB93, 0x8301, 0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7, + 0xFB97, 0x83F6, 0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553, + 0xFB9B, 0x8559, 0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0, + 0xFB9F, 0xFA20, 0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5, + 0xFBA3, 0x8A12, 0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7, + 0xFBA7, 0x8ABE, 0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6, + 0xFBAB, 0x8B53, 0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4, + 0xFBAF, 0x8D12, 0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF, + 0xFBB3, 0xFA24, 0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE, + 0xFBB7, 0xFA26, 0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA, + 0xFBBB, 0x91D7, 0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE, + 0xFBBF, 0x91E4, 0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210, + 0xFBC3, 0x920A, 0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C, + 0xFBC7, 0x924E, 0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239, + 0xFBCB, 0x9267, 0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278, + 0xFBCF, 0x92E7, 0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0, + 0xFBD3, 0xFA27, 0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3, + 0xFBD7, 0x9325, 0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28, + 0xFBDB, 0x931E, 0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302, + 0xFBDF, 0x9370, 0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6, + 0xFBE3, 0x93DE, 0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445, + 0xFBE7, 0x9448, 0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29, + 0xFBEB, 0x969D, 0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B, + 0xFBEF, 0x9743, 0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751, + 0xFBF3, 0x9755, 0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A, + 0xFBF7, 0xFA2B, 0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E, + 0xFBFB, 0x9A4E, 0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75, + 0xFC42, 0x9B72, 0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB, + 0xFC46, 0x9C00, 0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D, + 0xFC4A, 0x9E19, 0xFC4B, 0x9ED1, 0, 0 +}; +#endif + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (src <= 0x80) { /* ASCII */ + c = src; + } else { +#if !_TINY_TABLE + if (dir) { /* OEMCP to unicode */ + p = sjis2uni; + hi = sizeof(sjis2uni) / 4 - 1; + } else { /* Unicode to OEMCP */ + p = uni2sjis; + hi = sizeof(uni2sjis) / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (src == p[i * 2]) break; + if (src > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; +#else + if (dir) { /* OEMCP to unicode (Incremental search)*/ + p = &uni2sjis[1]; + do { + c = *p; + p += 2; + } while (c && c != src); + p -= 3; + c = *p; + } else { /* Unicode to OEMCP */ + li = 0; hi = sizeof(uni2sjis) / 4 - 1; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (src == uni2sjis[i * 2]) break; + if (src > uni2sjis[i * 2]) + li = i; + else + hi = i; + } + c = n ? uni2sjis[i * 2 + 1] : 0; + } +#endif + } + + return c; +} + + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/Lib/Fat/src/option/cc936.c b/Lib/Fat/src/option/cc936.c new file mode 100644 index 0000000..6e58e89 --- /dev/null +++ b/Lib/Fat/src/option/cc936.c @@ -0,0 +1,10973 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ +/* */ +/* CP936 (Simplified Chinese GBK) */ +/*------------------------------------------------------------------------*/ + +#include "../ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 936 +#error This file is not needed in current configuration. Remove from the project. +#endif + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3, + 0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4, + 0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA, + 0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE, + 0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9, + 0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9, + 0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1, + 0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3, + 0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8, + 0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5, + 0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1, + 0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5, + 0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9, + 0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD, + 0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1, + 0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5, + 0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1, + 0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5, + 0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9, + 0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD, + 0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1, + 0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5, + 0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7, + 0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4, + 0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9, + 0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD, + 0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1, + 0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5, + 0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9, + 0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD, + 0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1, + 0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4, + 0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9, + 0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD, + 0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1, + 0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5, + 0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9, + 0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED, + 0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1, + 0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA, + 0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF, + 0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD, + 0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846, + 0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847, + 0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1, + 0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5, + 0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9, + 0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1, + 0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5, + 0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9, + 0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA, + 0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B, + 0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6, + 0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE, + 0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE, + 0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8, + 0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF, + 0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6, + 0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4, + 0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852, + 0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1, + 0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9, + 0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD, + 0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1, + 0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7, + 0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB, + 0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF, + 0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3, + 0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7, + 0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3, + 0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7, + 0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB, + 0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF, + 0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3, + 0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6, + 0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA, + 0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE, + 0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2, + 0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6, + 0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA, + 0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE, + 0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2, + 0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6, + 0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA, + 0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE, + 0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2, + 0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6, + 0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA, + 0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE, + 0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2, + 0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6, + 0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA, + 0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE, + 0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856, + 0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A, + 0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E, + 0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862, + 0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866, + 0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A, + 0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E, + 0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872, + 0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876, + 0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A, + 0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E, + 0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883, + 0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887, + 0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6, + 0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B, + 0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0, + 0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E, + 0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE, + 0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1, + 0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9, + 0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5, + 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, + 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF, + 0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3, + 0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895, + 0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943, + 0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947, + 0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3, + 0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7, + 0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB, + 0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF, + 0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3, + 0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7, + 0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB, + 0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF, + 0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3, + 0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7, + 0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB, + 0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF, + 0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3, + 0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7, + 0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB, + 0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF, + 0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3, + 0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7, + 0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB, + 0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF, + 0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3, + 0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967, + 0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4, + 0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8, + 0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC, + 0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0, + 0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4, + 0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8, + 0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC, + 0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0, + 0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4, + 0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8, + 0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC, + 0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0, + 0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4, + 0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8, + 0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC, + 0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0, + 0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4, + 0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8, + 0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC, + 0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0, + 0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4, + 0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963, + 0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7, + 0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB, + 0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF, + 0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3, + 0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7, + 0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB, + 0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF, + 0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3, + 0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7, + 0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6, + 0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA, + 0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE, + 0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B, + 0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F, + 0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953, + 0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140, + 0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143, + 0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF, + 0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB, + 0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145, + 0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0, + 0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5, + 0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9, + 0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA, + 0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B, + 0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6, + 0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D, + 0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE, + 0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC, + 0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA, + 0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9, + 0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156, + 0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158, + 0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159, + 0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5, + 0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9, + 0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4, + 0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D, + 0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2, + 0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F, + 0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9, + 0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165, + 0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169, + 0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B, + 0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E, + 0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172, + 0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC, + 0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179, + 0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB, + 0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E, + 0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA, + 0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5, + 0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181, + 0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7, + 0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186, + 0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA, + 0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0, + 0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188, + 0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1, + 0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7, + 0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D, + 0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB, + 0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193, + 0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC, + 0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD, + 0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1, + 0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3, + 0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198, + 0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB, + 0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199, + 0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0, + 0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D, + 0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E, + 0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7, + 0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2, + 0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9, + 0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE, + 0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8, + 0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA, + 0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC, + 0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0, + 0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1, + 0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF, + 0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5, + 0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9, + 0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1, + 0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1, + 0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3, + 0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7, + 0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1, + 0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2, + 0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3, + 0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6, + 0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5, + 0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9, + 0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD, + 0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB, + 0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3, + 0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD, + 0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6, + 0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8, + 0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD, + 0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA, + 0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA, + 0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB, + 0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD, + 0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0, + 0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2, + 0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5, + 0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7, + 0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB, + 0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB, + 0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED, + 0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF, + 0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1, + 0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3, + 0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6, + 0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9, + 0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB, + 0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE, + 0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC, + 0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD, + 0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA, + 0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245, + 0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248, + 0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C, + 0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250, + 0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253, + 0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254, + 0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1, + 0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE, + 0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B, + 0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F, + 0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5, + 0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1, + 0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263, + 0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1, + 0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3, + 0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE, + 0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A, + 0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D, + 0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3, + 0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2, + 0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276, + 0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A, + 0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E, + 0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281, + 0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9, + 0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286, + 0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0, + 0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A, + 0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C, + 0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB, + 0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF, + 0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0, + 0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294, + 0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298, + 0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE, + 0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3, + 0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1, + 0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4, + 0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6, + 0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB, + 0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB, + 0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE, + 0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6, + 0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4, + 0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8, + 0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB, + 0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF, + 0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2, + 0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6, + 0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC, + 0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC, + 0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7, + 0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0, + 0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3, + 0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6, + 0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9, + 0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD, + 0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1, + 0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5, + 0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9, + 0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED, + 0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF, + 0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0, + 0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3, + 0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1, + 0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA, + 0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1, + 0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341, + 0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345, + 0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349, + 0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D, + 0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351, + 0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354, + 0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2, + 0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5, + 0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E, + 0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362, + 0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6, + 0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368, + 0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7, + 0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D, + 0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F, + 0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373, + 0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376, + 0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A, + 0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3, + 0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381, + 0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384, + 0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5, + 0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B, + 0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F, + 0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393, + 0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396, + 0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A, + 0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E, + 0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2, + 0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6, + 0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA, + 0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE, + 0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2, + 0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3, + 0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7, + 0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5, + 0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7, + 0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA, + 0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0, + 0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3, + 0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1, + 0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4, + 0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7, + 0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA, + 0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2, + 0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC, + 0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4, + 0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD, + 0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE, + 0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7, + 0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2, + 0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4, + 0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6, + 0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0, + 0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2, + 0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD, + 0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF, + 0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3, + 0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3, + 0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7, + 0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9, + 0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5, + 0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1, + 0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED, + 0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE, + 0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1, + 0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC, + 0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5, + 0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7, + 0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9, + 0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD, + 0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442, + 0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444, + 0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446, + 0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449, + 0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D, + 0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F, + 0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451, + 0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7, + 0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6, + 0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454, + 0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6, + 0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6, + 0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF, + 0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8, + 0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE, + 0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE, + 0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5, + 0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460, + 0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463, + 0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466, + 0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468, + 0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE, + 0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C, + 0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6, + 0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC, + 0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470, + 0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1, + 0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473, + 0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7, + 0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478, + 0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A, + 0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA, + 0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481, + 0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE, + 0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486, + 0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489, + 0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4, + 0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E, + 0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE, + 0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494, + 0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498, + 0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B, + 0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3, + 0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0, + 0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3, + 0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7, + 0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA, + 0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD, + 0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1, + 0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC, + 0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD, + 0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5, + 0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC, + 0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7, + 0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2, + 0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC, + 0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0, + 0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0, + 0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6, + 0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9, + 0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB, + 0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE, + 0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5, + 0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3, + 0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6, + 0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA, + 0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD, + 0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0, + 0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4, + 0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8, + 0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB, + 0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF, + 0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7, + 0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4, + 0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6, + 0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2, + 0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB, + 0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE, + 0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541, + 0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF, + 0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE, + 0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547, + 0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549, + 0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0, + 0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB, + 0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1, + 0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555, + 0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559, + 0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8, + 0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2, + 0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F, + 0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561, + 0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB, + 0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA, + 0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4, + 0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4, + 0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9, + 0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5, + 0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC, + 0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4, + 0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D, + 0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4, + 0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570, + 0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571, + 0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1, + 0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576, + 0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7, + 0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA, + 0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C, + 0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D, + 0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582, + 0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585, + 0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1, + 0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A, + 0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1, + 0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3, + 0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F, + 0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB, + 0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596, + 0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC, + 0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D, + 0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0, + 0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE, + 0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5, + 0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0, + 0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7, + 0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA, + 0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1, + 0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD, + 0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0, + 0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2, + 0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED, + 0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB, + 0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3, + 0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7, + 0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6, + 0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5, + 0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6, + 0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9, + 0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA, + 0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5, + 0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3, + 0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8, + 0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9, + 0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0, + 0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC, + 0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2, + 0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1, + 0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5, + 0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1, + 0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5, + 0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8, + 0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA, + 0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1, + 0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE, + 0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4, + 0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6, + 0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5, + 0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC, + 0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF, + 0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8, + 0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA, + 0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8, + 0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF, + 0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2, + 0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6, + 0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA, + 0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE, + 0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB, + 0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC, + 0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6, + 0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8, + 0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4, + 0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC, + 0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4, + 0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7, + 0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB, + 0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB, + 0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640, + 0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7, + 0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4, + 0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642, + 0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644, + 0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646, + 0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649, + 0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B, + 0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3, + 0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF, + 0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E, + 0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5, + 0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5, + 0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650, + 0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1, + 0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8, + 0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655, + 0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6, + 0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4, + 0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8, + 0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC, + 0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F, + 0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8, + 0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664, + 0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666, + 0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4, + 0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B, + 0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F, + 0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670, + 0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673, + 0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677, + 0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A, + 0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF, + 0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E, + 0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4, + 0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB, + 0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684, + 0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687, + 0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A, + 0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9, + 0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E, + 0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC, + 0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1, + 0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695, + 0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698, + 0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2, + 0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E, + 0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1, + 0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4, + 0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2, + 0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE, + 0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6, + 0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC, + 0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4, + 0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0, + 0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1, + 0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9, + 0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4, + 0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0, + 0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7, + 0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9, + 0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC, + 0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE, + 0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0, + 0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3, + 0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7, + 0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA, + 0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE, + 0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1, + 0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3, + 0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5, + 0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7, + 0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA, + 0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC, + 0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF, + 0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1, + 0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA, + 0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2, + 0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8, + 0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA, + 0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC, + 0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2, + 0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA, + 0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0, + 0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7, + 0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4, + 0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7, + 0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5, + 0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB, + 0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740, + 0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742, + 0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2, + 0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747, + 0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B, + 0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E, + 0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF, + 0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753, + 0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755, + 0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758, + 0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A, + 0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0, + 0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB, + 0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761, + 0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764, + 0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767, + 0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B, + 0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F, + 0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD, + 0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774, + 0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777, + 0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778, + 0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B, + 0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE, + 0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782, + 0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB, + 0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785, + 0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788, + 0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1, + 0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F, + 0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791, + 0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795, + 0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3, + 0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B, + 0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF, + 0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1, + 0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4, + 0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8, + 0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC, + 0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0, + 0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3, + 0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7, + 0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB, + 0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE, + 0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2, + 0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5, + 0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8, + 0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC, + 0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0, + 0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2, + 0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7, + 0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB, + 0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE, + 0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4, + 0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8, + 0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5, + 0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4, + 0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8, + 0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA, + 0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC, + 0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE, + 0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC, + 0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC, + 0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5, + 0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2, + 0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5, + 0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB, + 0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840, + 0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844, + 0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848, + 0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B, + 0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E, + 0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851, + 0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9, + 0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC, + 0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855, + 0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858, + 0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1, + 0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8, + 0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0, + 0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862, + 0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB, + 0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2, + 0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866, + 0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A, + 0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1, + 0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB, + 0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D, + 0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9, + 0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA, + 0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872, + 0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875, + 0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9, + 0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A, + 0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C, + 0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9, + 0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4, + 0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884, + 0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886, + 0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD, + 0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C, + 0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890, + 0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893, + 0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8, + 0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1, + 0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897, + 0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5, + 0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE, + 0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E, + 0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1, + 0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5, + 0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1, + 0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB, + 0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF, + 0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7, + 0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8, + 0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5, + 0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6, + 0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9, + 0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB, + 0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE, + 0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2, + 0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5, + 0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8, + 0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB, + 0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9, + 0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF, + 0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3, + 0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1, + 0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7, + 0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9, + 0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC, + 0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF, + 0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2, + 0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6, + 0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7, + 0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA, + 0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0, + 0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1, + 0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4, + 0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7, + 0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB, + 0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940, + 0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944, + 0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947, + 0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B, + 0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D, + 0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950, + 0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953, + 0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956, + 0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB, + 0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D, + 0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960, + 0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964, + 0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966, + 0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A, + 0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E, + 0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972, + 0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3, + 0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977, + 0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979, + 0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C, + 0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981, + 0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA, + 0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987, + 0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE, + 0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6, + 0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F, + 0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993, + 0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995, + 0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999, + 0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D, + 0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1, + 0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5, + 0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8, + 0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB, + 0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE, + 0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2, + 0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6, + 0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9, + 0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC, + 0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0, + 0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4, + 0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8, + 0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB, + 0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF, + 0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3, + 0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3, + 0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8, + 0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8, + 0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC, + 0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA, + 0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2, + 0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5, + 0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8, + 0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB, + 0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2, + 0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0, + 0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1, + 0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4, + 0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6, + 0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB, + 0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB, + 0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA, + 0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD, + 0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1, + 0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41, + 0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC, + 0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46, + 0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47, + 0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC, + 0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B, + 0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1, + 0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9, + 0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51, + 0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD, + 0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56, + 0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A, + 0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E, + 0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62, + 0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC, + 0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65, + 0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68, + 0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7, + 0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1, + 0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1, + 0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F, + 0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA, + 0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD, + 0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76, + 0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4, + 0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D, + 0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E, + 0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD, + 0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD, + 0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7, + 0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88, + 0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B, + 0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA, + 0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91, + 0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7, + 0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2, + 0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A, + 0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6, + 0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D, + 0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6, + 0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0, + 0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4, + 0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6, + 0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9, + 0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC, + 0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0, + 0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4, + 0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7, + 0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA, + 0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC, + 0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC, + 0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD, + 0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0, + 0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3, + 0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6, + 0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9, + 0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC, + 0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE, + 0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0, + 0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3, + 0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7, + 0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4, + 0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2, + 0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF, + 0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2, + 0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5, + 0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5, + 0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB, + 0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE, + 0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2, + 0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5, + 0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9, + 0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC, + 0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE, + 0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44, + 0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7, + 0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A, + 0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E, + 0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4, + 0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4, + 0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55, + 0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58, + 0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C, + 0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60, + 0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64, + 0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD, + 0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B, + 0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4, + 0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71, + 0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75, + 0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79, + 0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1, + 0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81, + 0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7, + 0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86, + 0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89, + 0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5, + 0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9, + 0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92, + 0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95, + 0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98, + 0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8, + 0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE, + 0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0, + 0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3, + 0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5, + 0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF, + 0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA, + 0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD, + 0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0, + 0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4, + 0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8, + 0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC, + 0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0, + 0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4, + 0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7, + 0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB, + 0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF, + 0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4, + 0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5, + 0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9, + 0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD, + 0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1, + 0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5, + 0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9, + 0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5, + 0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF, + 0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2, + 0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6, + 0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9, + 0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD, + 0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42, + 0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46, + 0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48, + 0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49, + 0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA, + 0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A, + 0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF, + 0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7, + 0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF, + 0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51, + 0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53, + 0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55, + 0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6, + 0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B, + 0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D, + 0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E, + 0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F, + 0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61, + 0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64, + 0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66, + 0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8, + 0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5, + 0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD, + 0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2, + 0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC, + 0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D, + 0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70, + 0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2, + 0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72, + 0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6, + 0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5, + 0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC, + 0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A, + 0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D, + 0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE, + 0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83, + 0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87, + 0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF, + 0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B, + 0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D, + 0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90, + 0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC, + 0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96, + 0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A, + 0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2, + 0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D, + 0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F, + 0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB, + 0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0, + 0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7, + 0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9, + 0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2, + 0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0, + 0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE, + 0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC, + 0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3, + 0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6, + 0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9, + 0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC, + 0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF, + 0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF, + 0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2, + 0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3, + 0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3, + 0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC, + 0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA, + 0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7, + 0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA, + 0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD, + 0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4, + 0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2, + 0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0, + 0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7, + 0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8, + 0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC, + 0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0, + 0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8, + 0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6, + 0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1, + 0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB, + 0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE, + 0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0, + 0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2, + 0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB, + 0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0, + 0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6, + 0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3, + 0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC, + 0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40, + 0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41, + 0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44, + 0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46, + 0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48, + 0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B, + 0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D, + 0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50, + 0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54, + 0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57, + 0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC, + 0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E, + 0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61, + 0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65, + 0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68, + 0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD, + 0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8, + 0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E, + 0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71, + 0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75, + 0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79, + 0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C, + 0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0, + 0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7, + 0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85, + 0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9, + 0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C, + 0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2, + 0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92, + 0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6, + 0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98, + 0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3, + 0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C, + 0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4, + 0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2, + 0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5, + 0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9, + 0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA, + 0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF, + 0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3, + 0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3, + 0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7, + 0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB, + 0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF, + 0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2, + 0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4, + 0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8, + 0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC, + 0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF, + 0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1, + 0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4, + 0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7, + 0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB, + 0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF, + 0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6, + 0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6, + 0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA, + 0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE, + 0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2, + 0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6, + 0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9, + 0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC, + 0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41, + 0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45, + 0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49, + 0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D, + 0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51, + 0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55, + 0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58, + 0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C, + 0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60, + 0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63, + 0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67, + 0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A, + 0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E, + 0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72, + 0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76, + 0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD, + 0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2, + 0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3, + 0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C, + 0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE, + 0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1, + 0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82, + 0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85, + 0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED, + 0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0, + 0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB, + 0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D, + 0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90, + 0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91, + 0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB, + 0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3, + 0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94, + 0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98, + 0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8, + 0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E, + 0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF, + 0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3, + 0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7, + 0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9, + 0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA, + 0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD, + 0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF, + 0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3, + 0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6, + 0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA, + 0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC, + 0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0, + 0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5, + 0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1, + 0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8, + 0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC, + 0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0, + 0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9, + 0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2, + 0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB, + 0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7, + 0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9, + 0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC, + 0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2, + 0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0, + 0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1, + 0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2, + 0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD, + 0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3, + 0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6, + 0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8, + 0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB, + 0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE, + 0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2, + 0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC, + 0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4, + 0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7, + 0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB, + 0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40, + 0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8, + 0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46, + 0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA, + 0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE, + 0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E, + 0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51, + 0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55, + 0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59, + 0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE, + 0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F, + 0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63, + 0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3, + 0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8, + 0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3, + 0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC, + 0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C, + 0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7, + 0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71, + 0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73, + 0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75, + 0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77, + 0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A, + 0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C, + 0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2, + 0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2, + 0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83, + 0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85, + 0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89, + 0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF, + 0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E, + 0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91, + 0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95, + 0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99, + 0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D, + 0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9, + 0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8, + 0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2, + 0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5, + 0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE, + 0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5, + 0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB, + 0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD, + 0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF, + 0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2, + 0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4, + 0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6, + 0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE, + 0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9, + 0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2, + 0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB, + 0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD, + 0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0, + 0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1, + 0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4, + 0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7, + 0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB, + 0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD, + 0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2, + 0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3, + 0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6, + 0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9, + 0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB, + 0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF, + 0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4, + 0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2, + 0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4, + 0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF, + 0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2, + 0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8, + 0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB, + 0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED, + 0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0, + 0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC, + 0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5, + 0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6, + 0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9, + 0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC, + 0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9, + 0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB, + 0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB, + 0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7, + 0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5, + 0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD, + 0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0, + 0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049, + 0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A, + 0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C, + 0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1, + 0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6, + 0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051, + 0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054, + 0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057, + 0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B, + 0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D, + 0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE, + 0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061, + 0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065, + 0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067, + 0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3, + 0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C, + 0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3, + 0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071, + 0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6, + 0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076, + 0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1, + 0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077, + 0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079, + 0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1, + 0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD, + 0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D, + 0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081, + 0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083, + 0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086, + 0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088, + 0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8, + 0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3, + 0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4, + 0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092, + 0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094, + 0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3, + 0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099, + 0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A, + 0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF, + 0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E, + 0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1, + 0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3, + 0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7, + 0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0, + 0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA, + 0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF, + 0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2, + 0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5, + 0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1, + 0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9, + 0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB, + 0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB, + 0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF, + 0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC, + 0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1, + 0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC, + 0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA, + 0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8, + 0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA, + 0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9, + 0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF, + 0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9, + 0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4, + 0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7, + 0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE, + 0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE, + 0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0, + 0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4, + 0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4, + 0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7, + 0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB, + 0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF, + 0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3, + 0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7, + 0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA, + 0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE, + 0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB, + 0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7, + 0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146, + 0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149, + 0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D, + 0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150, + 0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD, + 0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157, + 0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159, + 0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D, + 0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160, + 0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163, + 0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166, + 0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A, + 0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E, + 0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172, + 0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176, + 0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7, + 0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C, + 0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180, + 0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184, + 0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187, + 0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B, + 0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F, + 0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190, + 0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193, + 0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197, + 0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B, + 0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E, + 0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6, + 0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE, + 0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8, + 0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3, + 0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD, + 0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1, + 0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2, + 0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6, + 0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA, + 0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE, + 0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3, + 0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5, + 0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9, + 0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD, + 0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0, + 0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4, + 0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8, + 0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB, + 0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0, + 0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC, + 0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6, + 0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4, + 0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2, + 0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD, + 0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6, + 0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB, + 0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9, + 0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8, + 0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE, + 0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2, + 0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4, + 0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7, + 0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5, + 0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA, + 0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD, + 0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE, + 0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA, + 0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7, + 0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243, + 0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246, + 0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249, + 0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D, + 0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4, + 0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1, + 0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7, + 0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252, + 0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6, + 0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257, + 0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2, + 0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B, + 0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E, + 0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1, + 0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264, + 0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3, + 0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6, + 0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7, + 0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B, + 0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0, + 0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D, + 0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270, + 0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272, + 0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275, + 0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278, + 0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B, + 0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C, + 0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7, + 0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0, + 0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4, + 0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0, + 0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC, + 0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF, + 0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5, + 0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286, + 0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3, + 0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9, + 0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A, + 0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7, + 0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D, + 0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9, + 0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291, + 0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0, + 0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2, + 0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297, + 0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298, + 0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6, + 0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E, + 0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA, + 0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF, + 0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2, + 0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8, + 0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6, + 0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2, + 0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB, + 0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD, + 0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1, + 0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6, + 0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6, + 0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6, + 0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6, + 0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD, + 0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3, + 0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF, + 0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2, + 0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6, + 0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC, + 0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB, + 0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD, + 0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF, + 0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD, + 0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4, + 0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7, + 0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0, + 0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC, + 0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0, + 0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2, + 0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5, + 0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1, + 0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5, + 0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4, + 0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB, + 0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF, + 0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD, + 0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3, + 0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB, + 0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7, + 0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7, + 0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9, + 0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4, + 0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2, + 0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341, + 0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1, + 0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346, + 0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF, + 0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5, + 0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE, + 0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350, + 0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE, + 0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355, + 0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358, + 0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE, + 0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D, + 0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9, + 0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE, + 0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365, + 0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368, + 0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7, + 0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B, + 0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F, + 0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371, + 0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373, + 0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375, + 0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379, + 0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3, + 0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C, + 0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9, + 0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2, + 0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385, + 0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389, + 0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C, + 0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF, + 0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392, + 0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394, + 0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA, + 0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF, + 0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A, + 0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0, + 0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0, + 0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3, + 0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB, + 0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA, + 0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE, + 0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0, + 0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3, + 0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7, + 0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB, + 0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1, + 0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0, + 0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC, + 0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5, + 0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8, + 0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC, + 0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6, + 0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE, + 0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3, + 0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2, + 0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA, + 0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD, + 0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0, + 0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9, + 0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4, + 0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7, + 0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5, + 0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB, + 0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE, + 0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0, + 0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4, + 0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6, + 0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC, + 0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC, + 0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE, + 0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3, + 0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA, + 0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1, + 0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B, + 0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F, + 0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453, + 0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457, + 0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B, + 0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F, + 0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462, + 0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466, + 0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469, + 0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D, + 0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC, + 0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474, + 0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477, + 0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B, + 0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480, + 0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483, + 0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487, + 0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD, + 0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C, + 0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5, + 0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F, + 0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5, + 0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494, + 0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497, + 0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499, + 0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C, + 0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E, + 0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD, + 0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3, + 0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8, + 0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2, + 0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8, + 0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD, + 0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF, + 0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3, + 0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4, + 0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7, + 0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB, + 0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF, + 0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3, + 0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6, + 0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8, + 0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA, + 0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD, + 0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF, + 0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1, + 0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3, + 0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5, + 0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7, + 0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9, + 0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB, + 0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF, + 0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2, + 0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4, + 0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7, + 0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7, + 0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB, + 0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB, + 0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC, + 0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD, + 0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4, + 0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8, + 0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8, + 0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9, + 0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD, + 0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8, + 0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540, + 0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1, + 0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA, + 0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549, + 0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA, + 0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5, + 0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB, + 0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7, + 0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555, + 0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556, + 0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559, + 0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C, + 0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E, + 0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561, + 0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563, + 0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566, + 0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568, + 0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6, + 0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D, + 0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4, + 0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572, + 0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575, + 0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579, + 0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B, + 0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9, + 0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD, + 0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED, + 0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584, + 0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586, + 0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE, + 0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B, + 0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5, + 0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590, + 0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7, + 0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7, + 0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0, + 0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD, + 0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D, + 0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0, + 0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3, + 0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6, + 0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF, + 0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC, + 0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF, + 0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3, + 0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7, + 0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9, + 0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA, + 0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0, + 0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3, + 0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6, + 0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5, + 0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD, + 0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1, + 0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5, + 0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9, + 0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD, + 0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1, + 0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4, + 0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5, + 0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9, + 0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8, + 0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF, + 0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3, + 0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA, + 0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7, + 0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9, + 0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8, + 0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD, + 0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642, + 0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3, + 0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645, + 0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648, + 0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A, + 0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D, + 0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F, + 0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652, + 0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC, + 0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4, + 0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658, + 0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A, + 0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C, + 0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA, + 0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662, + 0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3, + 0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB, + 0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668, + 0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE, + 0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B, + 0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8, + 0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671, + 0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD, + 0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674, + 0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677, + 0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2, + 0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B, + 0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD, + 0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E, + 0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682, + 0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9, + 0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686, + 0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689, + 0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B, + 0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E, + 0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691, + 0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694, + 0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6, + 0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8, + 0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0, + 0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B, + 0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9, + 0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E, + 0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0, + 0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC, + 0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3, + 0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7, + 0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA, + 0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC, + 0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0, + 0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4, + 0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2, + 0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6, + 0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6, + 0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5, + 0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC, + 0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD, + 0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0, + 0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3, + 0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4, + 0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6, + 0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA, + 0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD, + 0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF, + 0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2, + 0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0, + 0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD, + 0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5, + 0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC, + 0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA, + 0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD, + 0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0, + 0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4, + 0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA, + 0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA, + 0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0, + 0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0, + 0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1, + 0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF, + 0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0, + 0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2, + 0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0, + 0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4, + 0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8, + 0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9, + 0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD, + 0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742, + 0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5, + 0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB, + 0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744, + 0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747, + 0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B, + 0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0, + 0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750, + 0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754, + 0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757, + 0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0, + 0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C, + 0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760, + 0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763, + 0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766, + 0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769, + 0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D, + 0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2, + 0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE, + 0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775, + 0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778, + 0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A, + 0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C, + 0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781, + 0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785, + 0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9, + 0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B, + 0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E, + 0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790, + 0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4, + 0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796, + 0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF, + 0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C, + 0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F, + 0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2, + 0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6, + 0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD, + 0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB, + 0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE, + 0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7, + 0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3, + 0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6, + 0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9, + 0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD, + 0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5, + 0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7, + 0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4, + 0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8, + 0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC, + 0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE, + 0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1, + 0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5, + 0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8, + 0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB, + 0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE, + 0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1, + 0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4, + 0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB, + 0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA, + 0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE, + 0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2, + 0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6, + 0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9, + 0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE, + 0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3, + 0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841, + 0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8, + 0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847, + 0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA, + 0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C, + 0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850, + 0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851, + 0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854, + 0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5, + 0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC, + 0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859, + 0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C, + 0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860, + 0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862, + 0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865, + 0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867, + 0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B, + 0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F, + 0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871, + 0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873, + 0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876, + 0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879, + 0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C, + 0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880, + 0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883, + 0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887, + 0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3, + 0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6, + 0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F, + 0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892, + 0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896, + 0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899, + 0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B, + 0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F, + 0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3, + 0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6, + 0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE, + 0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD, + 0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1, + 0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4, + 0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7, + 0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB, + 0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE, + 0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2, + 0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6, + 0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA, + 0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC, + 0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0, + 0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2, + 0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6, + 0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1, + 0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC, + 0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE, + 0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1, + 0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5, + 0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0, + 0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB, + 0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE, + 0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1, + 0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5, + 0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8, + 0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC, + 0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE, + 0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942, + 0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945, + 0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948, + 0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C, + 0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950, + 0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953, + 0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957, + 0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A, + 0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D, + 0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960, + 0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963, + 0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967, + 0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5, + 0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C, + 0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970, + 0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973, + 0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977, + 0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A, + 0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E, + 0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982, + 0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984, + 0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988, + 0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C, + 0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990, + 0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994, + 0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998, + 0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C, + 0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0, + 0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4, + 0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8, + 0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC, + 0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0, + 0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4, + 0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8, + 0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC, + 0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0, + 0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4, + 0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8, + 0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC, + 0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0, + 0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4, + 0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8, + 0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC, + 0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0, + 0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4, + 0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8, + 0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC, + 0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0, + 0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4, + 0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6, + 0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7, + 0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA, + 0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE, + 0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB, + 0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46, + 0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB, + 0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE, + 0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E, + 0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7, + 0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52, + 0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55, + 0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59, + 0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D, + 0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60, + 0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64, + 0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9, + 0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4, + 0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1, + 0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D, + 0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71, + 0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75, + 0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78, + 0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A, + 0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3, + 0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9, + 0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2, + 0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81, + 0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6, + 0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3, + 0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9, + 0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C, + 0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F, + 0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93, + 0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC, + 0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A, + 0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E, + 0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F, + 0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2, + 0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6, + 0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1, + 0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA, + 0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE, + 0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0, + 0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE, + 0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1, + 0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4, + 0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7, + 0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA, + 0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE, + 0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4, + 0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4, + 0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7, + 0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9, + 0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC, + 0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF, + 0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3, + 0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB, + 0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8, + 0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB, + 0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC, + 0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA, + 0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0, + 0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0, + 0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2, + 0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4, + 0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4, + 0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA, + 0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5, + 0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9, + 0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC, + 0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF, + 0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3, + 0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0, + 0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2, + 0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8, + 0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB, + 0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD, + 0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41, + 0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF, + 0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42, + 0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45, + 0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4, + 0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A, + 0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3, + 0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB, + 0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51, + 0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA, + 0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA, + 0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC, + 0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58, + 0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B, + 0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D, + 0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F, + 0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62, + 0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65, + 0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67, + 0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9, + 0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6, + 0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA, + 0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5, + 0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E, + 0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70, + 0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4, + 0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73, + 0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75, + 0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4, + 0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A, + 0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D, + 0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7, + 0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81, + 0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2, + 0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8, + 0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86, + 0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1, + 0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA, + 0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B, + 0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4, + 0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8, + 0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE, + 0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90, + 0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93, + 0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96, + 0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9, + 0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7, + 0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E, + 0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE, + 0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4, + 0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5, + 0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8, + 0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9, + 0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC, + 0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE, + 0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0, + 0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3, + 0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9, + 0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6, + 0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC, + 0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7, + 0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3, + 0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0, + 0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC, + 0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3, + 0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7, + 0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3, + 0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6, + 0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB, + 0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1, + 0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD, + 0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0, + 0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2, + 0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5, + 0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF, + 0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB, + 0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD, + 0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1, + 0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2, + 0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3, + 0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7, + 0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5, + 0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9, + 0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3, + 0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2, + 0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC, + 0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA, + 0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1, + 0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4, + 0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8, + 0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA, + 0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD, + 0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE, + 0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41, + 0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44, + 0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7, + 0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49, + 0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1, + 0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D, + 0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6, + 0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53, + 0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4, + 0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57, + 0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A, + 0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C, + 0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E, + 0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62, + 0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65, + 0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8, + 0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2, + 0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B, + 0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9, + 0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE, + 0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72, + 0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74, + 0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75, + 0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78, + 0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A, + 0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6, + 0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80, + 0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC, + 0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86, + 0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A, + 0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C, + 0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90, + 0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF, + 0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96, + 0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE, + 0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A, + 0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D, + 0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0, + 0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4, + 0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8, + 0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE, + 0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE, + 0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2, + 0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6, + 0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5, + 0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC, + 0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3, + 0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0, + 0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4, + 0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6, + 0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA, + 0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD, + 0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0, + 0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7, + 0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5, + 0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA, + 0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB, + 0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1, + 0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC, + 0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7, + 0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2, + 0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8, + 0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8, + 0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB, + 0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE, + 0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0, + 0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1, + 0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6, + 0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD, + 0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE, + 0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0, + 0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9, + 0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD, + 0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42, + 0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45, + 0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48, + 0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C, + 0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF, + 0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1, + 0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55, + 0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59, + 0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C, + 0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D, + 0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61, + 0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65, + 0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68, + 0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B, + 0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4, + 0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F, + 0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71, + 0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1, + 0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77, + 0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA, + 0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E, + 0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB, + 0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85, + 0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87, + 0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B, + 0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F, + 0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92, + 0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA, + 0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA, + 0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA, + 0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E, + 0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1, + 0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB, + 0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6, + 0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD, + 0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB, + 0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF, + 0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2, + 0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4, + 0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC, + 0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9, + 0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD, + 0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1, + 0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4, + 0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7, + 0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB, + 0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE, + 0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2, + 0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6, + 0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4, + 0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB, + 0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF, + 0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5, + 0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5, + 0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8, + 0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC, + 0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4, + 0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2, + 0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6, + 0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8, + 0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB, + 0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40, + 0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44, + 0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7, + 0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A, + 0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E, + 0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52, + 0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56, + 0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A, + 0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E, + 0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62, + 0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66, + 0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69, + 0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D, + 0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB, + 0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73, + 0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77, + 0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A, + 0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E, + 0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83, + 0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87, + 0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A, + 0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D, + 0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91, + 0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95, + 0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99, + 0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D, + 0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0, + 0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3, + 0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7, + 0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB, + 0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1, + 0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2, + 0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6, + 0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA, + 0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB, + 0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD, + 0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE, + 0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2, + 0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6, + 0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6, + 0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9, + 0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6, + 0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7, + 0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4, + 0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0, + 0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5, + 0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7, + 0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB, + 0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF, + 0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3, + 0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA, + 0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5, + 0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8, + 0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9, + 0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA, + 0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3, + 0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE, + 0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8, + 0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4, + 0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8, + 0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC, + 0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE, + 0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42, + 0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45, + 0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3, + 0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48, + 0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49, + 0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C, + 0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50, + 0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52, + 0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55, + 0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59, + 0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D, + 0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8, + 0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63, + 0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66, + 0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB, + 0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9, + 0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C, + 0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70, + 0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9, + 0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77, + 0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B, + 0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C, + 0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB, + 0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84, + 0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88, + 0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C, + 0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F, + 0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3, + 0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5, + 0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98, + 0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C, + 0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0, + 0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7, + 0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6, + 0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3, + 0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA, + 0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3, + 0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2, + 0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3, + 0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5, + 0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8, + 0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC, + 0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF, + 0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC, + 0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6, + 0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9, + 0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC, + 0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE, + 0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2, + 0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4, + 0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8, + 0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB, + 0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE, + 0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2, + 0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4, + 0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7, + 0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB, + 0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF, + 0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2, + 0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6, + 0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7, + 0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD, + 0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040, + 0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044, + 0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048, + 0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B, + 0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E, + 0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051, + 0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6, + 0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058, + 0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C, + 0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F, + 0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063, + 0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067, + 0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC, + 0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E, + 0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072, + 0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076, + 0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A, + 0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E, + 0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082, + 0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086, + 0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A, + 0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6, + 0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F, + 0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091, + 0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8, + 0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094, + 0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096, + 0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099, + 0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D, + 0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F, + 0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1, + 0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA, + 0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB, + 0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA, + 0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC, + 0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE, + 0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3, + 0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2, + 0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0, + 0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC, + 0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA, + 0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE, + 0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5, + 0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0, + 0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3, + 0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF, + 0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8, + 0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB, + 0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE, + 0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2, + 0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6, + 0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9, + 0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD, + 0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1, + 0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3, + 0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5, + 0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4, + 0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8, + 0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC, + 0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1, + 0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0, + 0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3, + 0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2, + 0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4, + 0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB, + 0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD, + 0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC, + 0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43, + 0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47, + 0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49, + 0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8, + 0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8, + 0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C, + 0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE, + 0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F, + 0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52, + 0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55, + 0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5, + 0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4, + 0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F, + 0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE, + 0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63, + 0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6, + 0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9, + 0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68, + 0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED, + 0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7, + 0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E, + 0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71, + 0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72, + 0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB, + 0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78, + 0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C, + 0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81, + 0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84, + 0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1, + 0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A, + 0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D, + 0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91, + 0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94, + 0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98, + 0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C, + 0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E, + 0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40, + 0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44, + 0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48, + 0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5, + 0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F, + 0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52, + 0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54, + 0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0, + 0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59, + 0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1, + 0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60, + 0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63, + 0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3, + 0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69, + 0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C, + 0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2, + 0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1, + 0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72, + 0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4, + 0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77, + 0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6, + 0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D, + 0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA, + 0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82, + 0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83, + 0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87, + 0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A, + 0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3, + 0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90, + 0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93, + 0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95, + 0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98, + 0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5, + 0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F, + 0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42, + 0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46, + 0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A, + 0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED, + 0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0, + 0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51, + 0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53, + 0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57, + 0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2, + 0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D, + 0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1, + 0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9, + 0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7, + 0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD, + 0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69, + 0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3, + 0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D, + 0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70, + 0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73, + 0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77, + 0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B, + 0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80, + 0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84, + 0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87, + 0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7, + 0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0, + 0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C, + 0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90, + 0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94, + 0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97, + 0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A, + 0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE, + 0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0, + 0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA, + 0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44, + 0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47, + 0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A, + 0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC, + 0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F, + 0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53, + 0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57, + 0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1, + 0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D, + 0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61, + 0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62, + 0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66, + 0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A, + 0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E, + 0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7, + 0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75, + 0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79, + 0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D, + 0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82, + 0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86, + 0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6, + 0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D, + 0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91, + 0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC, + 0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0, + 0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF, + 0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A, + 0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD, + 0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0, + 0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF, + 0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44, + 0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48, + 0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B, + 0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E, + 0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52, + 0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55, + 0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57, + 0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A, + 0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5, + 0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E, + 0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61, + 0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64, + 0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66, + 0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67, + 0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7, + 0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69, + 0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE, + 0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE, + 0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F, + 0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72, + 0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75, + 0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0, + 0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79, + 0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C, + 0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE, + 0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81, + 0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85, + 0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8, + 0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC, + 0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E, + 0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4, + 0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94, + 0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96, + 0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A, + 0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D, + 0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE, + 0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42, + 0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45, + 0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA, + 0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC, + 0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE, + 0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C, + 0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D, + 0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E, + 0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52, + 0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF, + 0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3, + 0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54, + 0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56, + 0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2, + 0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8, + 0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B, + 0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC, + 0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E, + 0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7, + 0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9, + 0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65, + 0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6, + 0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1, + 0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED, + 0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE, + 0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F, + 0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71, + 0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74, + 0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77, + 0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A, + 0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B, + 0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D, + 0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA, + 0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84, + 0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87, + 0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A, + 0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B, + 0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E, + 0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3, + 0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD, + 0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1, + 0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94, + 0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97, + 0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98, + 0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B, + 0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB, + 0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F, + 0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041, + 0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045, + 0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047, + 0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B, + 0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1, + 0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051, + 0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE, + 0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057, + 0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A, + 0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E, + 0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061, + 0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064, + 0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068, + 0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B, + 0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9, + 0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED, + 0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4, + 0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073, + 0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8, + 0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078, + 0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE, + 0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D, + 0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082, + 0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086, + 0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089, + 0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D, + 0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4, + 0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4, + 0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095, + 0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099, + 0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D, + 0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB, + 0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8, + 0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6, + 0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB, + 0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0, + 0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7, + 0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148, + 0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B, + 0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E, + 0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151, + 0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155, + 0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF, + 0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4, + 0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C, + 0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E, + 0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC, + 0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163, + 0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166, + 0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167, + 0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169, + 0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D, + 0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171, + 0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2, + 0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177, + 0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3, + 0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6, + 0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D, + 0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181, + 0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184, + 0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4, + 0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7, + 0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A, + 0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C, + 0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F, + 0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192, + 0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196, + 0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198, + 0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C, + 0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD, + 0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241, + 0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1, + 0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0, + 0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247, + 0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249, + 0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D, + 0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251, + 0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254, + 0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA, + 0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258, + 0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A, + 0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E, + 0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9, + 0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7, + 0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265, + 0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269, + 0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D, + 0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB, + 0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271, + 0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9, + 0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275, + 0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278, + 0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A, + 0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E, + 0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281, + 0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284, + 0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288, + 0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C, + 0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F, + 0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293, + 0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297, + 0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A, + 0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C, + 0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8, + 0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340, + 0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342, + 0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB, + 0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346, + 0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6, + 0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B, + 0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF, + 0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0, + 0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351, + 0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354, + 0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356, + 0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8, + 0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9, + 0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2, + 0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D, + 0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360, + 0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE, + 0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363, + 0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365, + 0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368, + 0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B, + 0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2, + 0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9, + 0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F, + 0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372, + 0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375, + 0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA, + 0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8, + 0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC, + 0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E, + 0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382, + 0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386, + 0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A, + 0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2, + 0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7, + 0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391, + 0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395, + 0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398, + 0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B, + 0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F, + 0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442, + 0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444, + 0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9, + 0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448, + 0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B, + 0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5, + 0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E, + 0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450, + 0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452, + 0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455, + 0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459, + 0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA, + 0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C, + 0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F, + 0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB, + 0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465, + 0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468, + 0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA, + 0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D, + 0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470, + 0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472, + 0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475, + 0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479, + 0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D, + 0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482, + 0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485, + 0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488, + 0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1, + 0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E, + 0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7, + 0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494, + 0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497, + 0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A, + 0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E, + 0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541, + 0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545, + 0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548, + 0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C, + 0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6, + 0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553, + 0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556, + 0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A, + 0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E, + 0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562, + 0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565, + 0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE, + 0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7, + 0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B, + 0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC, + 0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570, + 0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574, + 0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578, + 0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6, + 0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1, + 0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1, + 0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2, + 0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581, + 0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583, + 0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586, + 0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589, + 0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D, + 0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7, + 0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592, + 0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594, + 0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596, + 0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9, + 0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D, + 0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0, + 0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643, + 0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA, + 0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A, + 0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E, + 0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652, + 0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655, + 0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659, + 0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D, + 0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660, + 0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE, + 0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC, + 0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665, + 0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1, + 0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A, + 0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C, + 0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB, + 0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671, + 0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674, + 0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678, + 0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B, + 0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8, + 0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E, + 0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681, + 0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683, + 0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687, + 0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A, + 0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C, + 0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC, + 0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9, + 0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694, + 0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0, + 0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699, + 0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C, + 0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9, + 0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD, + 0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743, + 0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746, + 0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A, + 0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E, + 0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752, + 0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755, + 0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757, + 0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758, + 0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B, + 0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2, + 0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762, + 0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766, + 0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769, + 0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D, + 0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770, + 0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774, + 0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778, + 0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C, + 0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781, + 0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785, + 0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788, + 0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF, + 0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5, + 0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E, + 0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F, + 0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9, + 0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793, + 0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796, + 0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF, + 0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1, + 0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C, + 0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E, + 0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0, + 0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC, + 0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844, + 0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846, + 0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A, + 0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D, + 0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851, + 0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855, + 0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858, + 0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C, + 0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860, + 0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863, + 0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867, + 0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA, + 0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D, + 0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA, + 0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872, + 0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5, + 0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877, + 0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A, + 0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D, + 0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882, + 0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3, + 0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887, + 0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A, + 0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA, + 0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9, + 0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890, + 0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892, + 0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894, + 0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897, + 0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7, + 0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C, + 0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB, + 0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE, + 0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0, + 0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942, + 0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945, + 0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3, + 0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6, + 0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D, + 0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950, + 0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952, + 0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954, + 0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2, + 0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF, + 0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9, + 0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A, + 0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1, + 0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960, + 0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964, + 0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF, + 0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2, + 0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C, + 0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E, + 0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9, + 0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973, + 0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976, + 0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A, + 0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D, + 0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981, + 0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983, + 0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986, + 0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988, + 0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE, + 0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5, + 0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC, + 0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E, + 0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991, + 0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994, + 0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997, + 0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B, + 0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E, + 0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD, + 0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43, + 0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46, + 0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49, + 0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C, + 0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5, + 0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51, + 0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54, + 0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7, + 0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8, + 0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA, + 0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F, + 0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63, + 0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66, + 0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA, + 0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C, + 0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70, + 0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73, + 0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75, + 0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78, + 0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD, + 0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80, + 0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84, + 0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87, + 0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3, + 0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2, + 0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90, + 0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94, + 0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98, + 0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B, + 0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F, + 0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0, + 0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43, + 0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47, + 0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A, + 0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E, + 0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52, + 0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56, + 0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A, + 0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E, + 0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62, + 0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66, + 0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A, + 0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E, + 0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70, + 0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74, + 0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75, + 0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79, + 0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D, + 0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81, + 0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85, + 0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3, + 0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A, + 0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C, + 0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1, + 0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2, + 0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91, + 0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0, + 0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8, + 0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3, + 0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C, + 0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F, + 0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB, + 0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42, + 0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45, + 0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD, + 0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48, + 0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C, + 0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7, + 0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50, + 0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53, + 0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55, + 0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59, + 0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C, + 0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60, + 0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63, + 0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67, + 0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A, + 0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D, + 0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71, + 0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75, + 0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9, + 0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C, + 0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81, + 0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85, + 0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89, + 0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D, + 0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7, + 0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93, + 0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96, + 0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99, + 0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C, + 0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0, + 0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43, + 0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47, + 0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B, + 0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F, + 0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53, + 0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57, + 0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B, + 0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F, + 0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63, + 0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67, + 0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B, + 0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F, + 0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73, + 0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5, + 0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A, + 0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E, + 0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82, + 0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86, + 0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A, + 0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E, + 0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92, + 0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96, + 0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A, + 0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E, + 0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41, + 0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45, + 0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49, + 0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB, + 0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50, + 0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC, + 0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57, + 0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B, + 0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F, + 0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63, + 0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67, + 0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B, + 0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F, + 0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73, + 0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77, + 0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B, + 0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80, + 0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84, + 0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88, + 0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C, + 0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90, + 0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94, + 0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98, + 0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C, + 0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0, + 0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43, + 0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47, + 0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B, + 0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F, + 0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53, + 0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57, + 0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B, + 0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F, + 0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63, + 0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67, + 0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B, + 0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F, + 0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73, + 0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77, + 0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B, + 0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80, + 0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83, + 0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86, + 0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A, + 0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D, + 0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91, + 0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95, + 0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99, + 0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D, + 0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040, + 0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044, + 0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048, + 0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C, + 0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050, + 0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054, + 0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058, + 0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C, + 0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060, + 0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB, + 0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067, + 0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B, + 0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F, + 0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073, + 0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077, + 0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B, + 0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E, + 0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC, + 0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC, + 0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD, + 0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080, + 0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9, + 0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA, + 0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4, + 0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3, + 0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6, + 0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8, + 0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED, + 0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF, + 0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE, + 0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084, + 0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4, + 0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA, + 0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE, + 0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0, + 0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7, + 0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2, + 0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5, + 0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7, + 0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8, + 0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA, + 0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC, + 0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2, + 0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088, + 0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0, + 0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4, + 0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0, + 0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF, + 0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A, + 0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB, + 0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF, + 0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1, + 0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9, + 0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8, + 0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE, + 0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1, + 0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090, + 0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF, + 0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095, + 0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099, + 0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D, + 0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F, + 0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140, + 0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3, + 0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145, + 0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5, + 0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A, + 0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF, + 0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3, + 0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0, + 0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153, + 0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156, + 0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0, + 0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C, + 0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160, + 0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2, + 0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0, + 0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169, + 0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C, + 0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7, + 0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF, + 0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173, + 0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176, + 0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179, + 0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D, + 0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB, + 0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183, + 0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185, + 0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187, + 0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189, + 0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C, + 0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4, + 0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1, + 0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195, + 0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197, + 0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A, + 0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E, + 0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F, + 0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5, + 0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243, + 0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7, + 0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248, + 0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B, + 0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F, + 0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251, + 0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253, + 0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8, + 0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257, + 0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258, + 0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7, + 0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9, + 0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C, + 0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F, + 0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC, + 0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE, + 0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5, + 0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267, + 0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A, + 0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE, + 0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D, + 0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F, + 0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4, + 0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6, + 0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4, + 0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277, + 0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8, + 0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D, + 0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB, + 0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284, + 0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288, + 0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C, + 0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF, + 0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292, + 0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295, + 0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299, + 0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D, + 0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340, + 0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342, + 0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1, + 0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345, + 0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347, + 0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B, + 0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4, + 0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7, + 0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350, + 0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB, + 0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352, + 0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE, + 0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9, + 0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD, + 0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359, + 0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE, + 0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6, + 0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF, + 0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8, + 0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361, + 0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5, + 0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366, + 0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6, + 0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF, + 0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB, + 0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D, + 0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F, + 0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD, + 0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370, + 0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC, + 0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA, + 0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7, + 0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375, + 0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC, + 0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0, + 0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9, + 0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB, + 0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF, + 0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1, + 0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5, + 0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2, + 0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A, + 0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E, + 0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392, + 0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395, + 0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5, + 0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1, + 0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C, + 0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2, + 0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442, + 0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3, + 0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0, + 0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449, + 0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B, + 0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C, + 0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB, + 0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452, + 0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455, + 0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458, + 0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A, + 0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9, + 0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E, + 0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461, + 0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9, + 0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA, + 0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6, + 0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468, + 0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2, + 0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E, + 0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470, + 0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474, + 0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477, + 0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478, + 0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C, + 0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2, + 0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA, + 0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485, + 0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489, + 0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C, + 0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF, + 0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492, + 0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB, + 0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC, + 0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD, + 0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B, + 0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F, + 0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542, + 0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546, + 0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A, + 0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E, + 0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551, + 0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4, + 0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555, + 0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559, + 0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B, + 0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F, + 0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7, + 0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9, + 0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF, + 0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566, + 0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568, + 0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6, + 0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D, + 0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571, + 0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8, + 0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE, + 0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576, + 0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD, + 0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579, + 0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A, + 0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0, + 0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B, + 0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8, + 0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582, + 0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585, + 0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587, + 0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A, + 0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D, + 0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591, + 0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD, + 0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597, + 0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A, + 0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E, + 0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640, + 0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE, + 0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB, + 0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646, + 0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5, + 0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC, + 0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA, + 0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F, + 0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7, + 0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA, + 0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2, + 0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657, + 0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658, + 0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A, + 0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C, + 0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB, + 0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE, + 0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7, + 0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F, + 0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661, + 0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662, + 0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0, + 0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667, + 0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A, + 0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3, + 0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1, + 0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB, + 0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D, + 0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F, + 0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA, + 0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671, + 0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0, + 0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675, + 0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678, + 0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A, + 0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D, + 0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680, + 0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683, + 0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF, + 0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2, + 0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686, + 0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5, + 0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A, + 0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C, + 0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1, + 0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690, + 0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694, + 0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698, + 0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A, + 0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B, + 0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D, + 0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8, + 0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB, + 0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740, + 0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743, + 0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3, + 0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747, + 0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B, + 0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4, + 0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E, + 0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4, + 0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1, + 0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753, + 0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD, + 0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5, + 0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7, + 0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756, + 0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A, + 0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C, + 0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D, + 0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761, + 0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE, + 0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766, + 0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF, + 0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC, + 0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F, + 0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772, + 0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8, + 0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776, + 0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A, + 0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD, + 0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E, + 0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB, + 0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2, + 0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA, + 0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783, + 0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785, + 0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788, + 0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5, + 0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D, + 0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790, + 0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5, + 0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795, + 0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797, + 0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798, + 0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B, + 0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0, + 0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840, + 0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6, + 0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845, + 0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847, + 0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A, + 0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D, + 0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9, + 0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852, + 0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE, + 0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854, + 0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858, + 0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B, + 0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D, + 0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861, + 0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3, + 0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864, + 0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868, + 0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B, + 0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F, + 0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872, + 0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874, + 0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878, + 0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1, + 0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880, + 0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884, + 0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887, + 0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B, + 0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8, + 0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E, + 0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891, + 0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894, + 0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897, + 0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898, + 0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B, + 0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3, + 0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD, + 0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941, + 0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9, + 0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948, + 0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949, + 0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5, + 0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E, + 0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952, + 0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954, + 0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957, + 0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A, + 0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E, + 0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962, + 0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966, + 0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1, + 0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B, + 0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0, + 0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F, + 0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971, + 0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974, + 0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE, + 0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979, + 0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B, + 0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD, + 0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982, + 0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985, + 0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987, + 0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB, + 0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C, + 0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F, + 0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992, + 0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996, + 0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A, + 0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D, + 0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0, + 0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43, + 0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47, + 0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A, + 0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D, + 0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50, + 0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5, + 0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56, + 0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58, + 0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C, + 0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60, + 0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62, + 0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66, + 0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A, + 0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE, + 0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B, + 0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F, + 0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72, + 0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF, + 0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77, + 0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B, + 0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1, + 0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82, + 0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9, + 0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89, + 0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C, + 0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F, + 0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93, + 0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD, + 0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99, + 0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA, + 0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9, + 0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40, + 0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42, + 0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45, + 0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49, + 0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C, + 0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50, + 0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54, + 0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56, + 0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A, + 0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D, + 0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD, + 0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4, + 0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64, + 0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68, + 0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A, + 0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E, + 0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71, + 0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75, + 0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78, + 0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C, + 0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E, + 0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81, + 0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85, + 0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88, + 0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C, + 0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F, + 0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92, + 0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96, + 0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A, + 0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E, + 0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41, + 0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44, + 0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47, + 0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A, + 0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E, + 0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52, + 0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55, + 0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1, + 0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C, + 0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60, + 0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64, + 0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68, + 0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A, + 0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E, + 0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72, + 0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76, + 0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79, + 0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C, + 0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81, + 0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85, + 0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89, + 0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2, + 0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C, + 0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F, + 0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9, + 0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD, + 0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD, + 0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C, + 0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0, + 0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1, + 0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43, + 0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47, + 0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3, + 0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA, + 0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC, + 0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D, + 0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3, + 0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51, + 0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55, + 0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57, + 0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B, + 0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D, + 0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61, + 0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63, + 0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD, + 0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66, + 0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67, + 0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0, + 0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5, + 0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F, + 0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72, + 0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9, + 0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6, + 0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3, + 0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78, + 0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B, + 0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D, + 0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2, + 0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83, + 0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86, + 0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89, + 0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9, + 0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD, + 0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E, + 0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90, + 0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA, + 0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4, + 0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98, + 0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB, + 0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B, + 0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1, + 0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0, + 0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3, + 0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0, + 0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC, + 0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46, + 0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49, + 0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2, + 0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F, + 0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52, + 0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55, + 0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4, + 0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A, + 0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E, + 0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F, + 0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB, + 0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65, + 0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68, + 0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A, + 0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E, + 0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71, + 0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72, + 0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76, + 0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3, + 0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C, + 0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB, + 0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83, + 0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE, + 0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB, + 0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88, + 0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B, + 0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D, + 0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91, + 0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94, + 0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97, + 0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B, + 0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E, + 0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41, + 0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44, + 0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45, + 0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48, + 0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A, + 0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD, + 0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50, + 0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53, + 0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1, + 0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1, + 0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C, + 0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE, + 0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61, + 0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65, + 0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68, + 0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B, + 0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E, + 0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3, + 0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5, + 0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78, + 0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C, + 0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80, + 0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8, + 0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87, + 0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A, + 0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9, + 0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91, + 0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95, + 0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6, + 0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A, + 0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D, + 0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0, + 0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042, + 0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046, + 0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A, + 0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3, + 0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051, + 0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054, + 0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057, + 0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A, + 0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C, + 0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060, + 0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062, + 0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066, + 0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069, + 0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B, + 0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F, + 0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9, + 0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072, + 0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074, + 0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2, + 0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4, + 0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B, + 0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E, + 0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0, + 0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7, + 0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084, + 0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087, + 0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089, + 0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB, + 0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4, + 0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093, + 0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096, + 0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8, + 0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C, + 0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0, + 0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141, + 0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144, + 0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148, + 0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B, + 0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E, + 0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1, + 0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9, + 0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155, + 0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE, + 0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6, + 0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D, + 0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F, + 0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163, + 0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD, + 0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166, + 0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169, + 0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D, + 0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F, + 0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171, + 0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173, + 0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5, + 0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3, + 0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C, + 0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB, + 0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184, + 0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD, + 0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189, + 0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2, + 0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E, + 0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191, + 0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194, + 0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA, + 0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A, + 0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D, + 0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE, + 0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242, + 0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246, + 0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249, + 0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C, + 0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250, + 0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254, + 0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258, + 0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C, + 0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260, + 0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5, + 0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266, + 0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0, + 0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D, + 0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271, + 0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275, + 0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279, + 0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D, + 0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281, + 0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283, + 0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2, + 0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289, + 0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D, + 0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291, + 0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295, + 0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299, + 0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D, + 0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340, + 0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344, + 0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348, + 0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C, + 0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350, + 0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354, + 0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358, + 0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C, + 0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB, + 0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3, + 0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9, + 0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC, + 0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7, + 0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB, + 0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD, + 0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC, + 0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C, + 0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5, + 0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371, + 0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374, + 0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377, + 0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A, + 0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E, + 0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383, + 0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386, + 0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A, + 0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D, + 0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391, + 0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395, + 0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399, + 0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D, + 0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440, + 0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444, + 0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448, + 0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C, + 0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450, + 0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454, + 0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458, + 0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C, + 0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4, + 0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463, + 0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467, + 0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A, + 0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E, + 0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472, + 0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476, + 0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A, + 0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E, + 0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483, + 0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487, + 0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B, + 0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F, + 0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493, + 0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497, + 0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A, + 0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E, + 0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541, + 0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545, + 0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC, + 0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B, + 0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F, + 0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552, + 0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556, + 0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A, + 0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E, + 0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562, + 0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566, + 0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A, + 0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E, + 0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572, + 0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576, + 0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A, + 0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E, + 0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583, + 0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587, + 0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B, + 0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F, + 0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593, + 0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597, + 0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B, + 0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F, + 0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642, + 0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646, + 0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A, + 0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E, + 0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652, + 0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656, + 0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A, + 0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E, + 0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662, + 0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665, + 0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669, + 0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D, + 0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671, + 0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675, + 0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679, + 0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D, + 0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5, + 0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685, + 0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689, + 0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D, + 0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691, + 0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695, + 0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699, + 0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D, + 0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740, + 0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744, + 0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748, + 0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C, + 0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750, + 0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754, + 0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758, + 0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C, + 0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF, + 0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763, + 0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766, + 0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A, + 0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E, + 0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772, + 0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776, + 0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A, + 0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E, + 0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783, + 0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787, + 0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B, + 0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F, + 0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793, + 0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797, + 0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9, + 0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6, + 0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8, + 0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9, + 0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2, + 0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8, + 0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB, + 0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8, + 0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC, + 0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6, + 0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF, + 0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0, + 0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1, + 0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4, + 0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF, + 0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE, + 0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF, + 0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA, + 0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E, + 0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD, + 0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5, + 0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0, + 0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5, + 0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE, + 0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5, + 0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB, + 0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA, + 0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1, + 0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB, + 0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE, + 0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8, + 0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0, + 0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB, + 0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB, + 0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8, + 0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA, + 0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC, + 0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF, + 0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842, + 0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846, + 0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849, + 0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9, + 0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E, + 0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851, + 0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855, + 0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858, + 0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0, + 0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F, + 0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF, + 0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865, + 0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0, + 0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B, + 0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F, + 0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872, + 0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2, + 0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877, + 0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5, + 0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D, + 0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6, + 0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883, + 0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887, + 0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A, + 0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D, + 0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891, + 0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895, + 0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899, + 0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D, + 0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940, + 0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944, + 0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948, + 0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C, + 0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950, + 0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954, + 0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958, + 0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C, + 0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960, + 0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964, + 0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968, + 0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C, + 0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970, + 0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974, + 0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978, + 0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C, + 0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981, + 0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985, + 0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989, + 0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D, + 0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991, + 0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995, + 0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999, + 0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D, + 0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40, + 0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44, + 0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48, + 0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C, + 0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA, + 0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6, + 0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB, + 0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0, + 0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC, + 0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA, + 0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC, + 0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8, + 0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6, + 0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8, + 0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1, + 0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE, + 0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA, + 0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51, + 0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5, + 0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC, + 0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE, + 0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE, + 0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2, + 0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57, + 0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59, + 0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C, + 0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF, + 0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F, + 0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63, + 0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66, + 0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68, + 0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD, + 0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E, + 0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71, + 0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74, + 0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78, + 0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C, + 0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80, + 0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83, + 0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87, + 0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B, + 0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E, + 0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F, + 0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3, + 0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA, + 0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96, + 0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC, + 0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B, + 0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9, + 0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E, + 0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5, + 0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7, + 0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8, + 0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46, + 0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48, + 0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2, + 0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C, + 0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F, + 0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51, + 0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5, + 0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53, + 0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57, + 0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A, + 0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB, + 0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F, + 0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62, + 0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65, + 0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69, + 0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1, + 0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF, + 0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70, + 0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9, + 0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA, + 0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76, + 0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79, + 0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD, + 0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E, + 0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5, + 0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83, + 0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8, + 0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86, + 0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7, + 0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C, + 0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F, + 0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93, + 0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97, + 0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4, + 0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D, + 0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F, + 0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7, + 0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA, + 0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45, + 0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48, + 0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A, + 0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D, + 0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50, + 0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54, + 0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56, + 0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59, + 0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D, + 0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3, + 0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63, + 0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67, + 0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B, + 0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D, + 0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3, + 0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73, + 0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9, + 0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A, + 0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E, + 0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83, + 0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87, + 0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6, + 0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E, + 0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92, + 0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96, + 0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A, + 0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E, + 0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41, + 0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45, + 0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49, + 0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D, + 0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51, + 0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55, + 0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59, + 0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D, + 0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61, + 0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65, + 0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69, + 0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D, + 0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71, + 0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75, + 0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79, + 0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D, + 0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82, + 0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86, + 0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A, + 0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E, + 0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92, + 0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96, + 0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A, + 0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E, + 0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41, + 0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45, + 0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49, + 0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D, + 0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51, + 0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55, + 0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59, + 0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D, + 0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5, + 0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61, + 0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6, + 0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0, + 0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3, + 0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7, + 0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9, + 0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB, + 0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE, + 0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5, + 0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2, + 0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64, + 0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD, + 0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5, + 0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7, + 0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68, + 0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B, + 0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D, + 0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70, + 0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72, + 0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1, + 0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78, + 0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF, + 0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8, + 0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E, + 0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81, + 0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD, + 0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86, + 0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87, + 0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89, + 0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC, + 0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6, + 0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8, + 0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF, + 0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5, + 0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91, + 0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94, + 0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95, + 0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98, + 0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA, + 0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6, + 0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7, + 0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D, + 0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD, + 0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1, + 0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8, + 0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1, + 0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA, + 0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE, + 0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48, + 0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE, + 0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D, + 0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4, + 0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52, + 0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2, + 0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC, + 0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58, + 0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B, + 0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E, + 0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9, + 0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61, + 0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63, + 0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66, + 0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD, + 0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B, + 0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E, + 0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA, + 0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74, + 0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76, + 0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A, + 0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D, + 0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2, + 0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82, + 0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85, + 0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88, + 0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B, + 0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D, + 0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F, + 0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91, + 0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF, + 0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE, + 0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0, + 0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA, + 0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B, + 0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD, + 0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE, + 0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5, + 0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040, + 0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042, + 0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC, + 0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9, + 0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048, + 0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B, + 0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E, + 0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F, + 0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB, + 0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA, + 0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056, + 0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058, + 0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B, + 0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E, + 0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061, + 0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1, + 0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5, + 0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069, + 0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D, + 0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071, + 0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075, + 0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079, + 0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C, + 0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4, + 0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3, + 0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086, + 0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A, + 0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E, + 0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090, + 0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094, + 0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097, + 0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B, + 0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F, + 0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA, + 0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA, + 0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC, + 0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6, + 0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147, + 0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3, + 0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA, + 0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1, + 0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E, + 0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2, + 0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA, + 0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8, + 0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8, + 0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154, + 0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7, + 0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159, + 0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C, + 0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E, + 0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F, + 0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1, + 0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164, + 0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1, + 0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A, + 0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0, + 0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170, + 0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2, + 0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4, + 0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178, + 0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A, + 0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8, + 0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182, + 0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186, + 0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A, + 0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD, + 0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0, + 0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E, + 0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192, + 0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196, + 0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199, + 0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D, + 0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240, + 0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244, + 0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248, + 0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C, + 0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250, + 0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254, + 0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258, + 0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C, + 0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260, + 0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264, + 0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268, + 0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C, + 0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270, + 0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274, + 0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278, + 0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C, + 0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281, + 0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285, + 0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289, + 0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D, + 0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291, + 0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295, + 0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299, + 0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D, + 0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340, + 0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344, + 0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348, + 0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C, + 0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350, + 0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354, + 0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358, + 0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C, + 0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360, + 0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364, + 0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368, + 0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C, + 0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F, + 0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373, + 0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377, + 0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B, + 0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380, + 0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384, + 0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6, + 0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B, + 0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F, + 0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393, + 0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397, + 0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B, + 0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F, + 0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442, + 0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7, + 0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449, + 0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D, + 0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451, + 0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455, + 0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459, + 0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D, + 0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460, + 0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464, + 0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468, + 0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C, + 0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470, + 0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474, + 0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478, + 0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C, + 0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481, + 0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485, + 0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489, + 0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D, + 0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491, + 0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495, + 0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499, + 0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D, + 0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540, + 0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544, + 0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548, + 0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C, + 0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550, + 0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554, + 0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558, + 0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C, + 0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560, + 0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564, + 0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568, + 0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C, + 0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570, + 0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9, + 0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577, + 0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B, + 0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580, + 0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584, + 0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588, + 0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C, + 0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590, + 0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594, + 0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598, + 0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C, + 0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA, + 0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642, + 0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646, + 0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A, + 0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E, + 0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652, + 0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656, + 0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A, + 0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E, + 0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662, + 0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665, + 0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669, + 0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D, + 0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671, + 0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675, + 0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679, + 0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D, + 0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682, + 0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686, + 0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A, + 0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E, + 0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692, + 0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696, + 0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A, + 0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB, + 0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740, + 0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744, + 0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9, + 0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B, + 0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F, + 0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753, + 0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757, + 0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B, + 0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F, + 0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763, + 0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767, + 0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B, + 0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F, + 0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773, + 0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777, + 0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B, + 0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780, + 0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784, + 0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788, + 0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C, + 0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790, + 0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794, + 0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798, + 0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C, + 0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0, + 0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843, + 0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847, + 0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B, + 0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD, + 0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852, + 0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856, + 0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A, + 0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E, + 0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862, + 0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866, + 0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A, + 0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E, + 0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872, + 0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876, + 0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A, + 0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D, + 0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882, + 0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886, + 0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A, + 0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E, + 0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892, + 0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5, + 0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8, + 0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5, + 0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0, + 0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896, + 0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0, + 0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE, + 0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6, + 0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5, + 0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6, + 0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5, + 0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB, + 0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD, + 0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1, + 0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8, + 0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC, + 0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD, + 0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8, + 0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC, + 0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF, + 0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1, + 0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C, + 0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6, + 0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9, + 0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D, + 0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE, + 0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3, + 0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9, + 0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8, + 0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC, + 0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4, + 0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE, + 0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF, + 0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2, + 0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4, + 0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6, + 0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA, + 0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA, + 0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE, + 0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0, + 0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5, + 0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1, + 0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC, + 0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6, + 0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8, + 0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1, + 0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC, + 0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE, + 0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2, + 0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7, + 0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5, + 0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7, + 0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA, + 0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947, + 0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF, + 0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3, + 0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6, + 0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA, + 0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949, + 0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF, + 0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2, + 0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F, + 0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953, + 0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956, + 0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A, + 0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E, + 0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962, + 0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966, + 0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A, + 0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E, + 0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972, + 0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976, + 0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A, + 0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E, + 0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983, + 0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987, + 0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B, + 0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F, + 0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993, + 0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997, + 0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B, + 0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F, + 0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42, + 0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46, + 0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A, + 0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E, + 0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52, + 0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56, + 0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A, + 0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1, + 0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA, + 0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0, + 0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA, + 0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB, + 0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC, + 0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2, + 0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF, + 0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1, + 0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6, + 0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6, + 0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8, + 0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB, + 0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62, + 0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3, + 0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67, + 0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6, + 0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE, + 0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0, + 0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7, + 0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73, + 0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74, + 0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9, + 0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD, + 0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77, + 0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78, + 0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B, + 0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D, + 0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82, + 0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85, + 0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA, + 0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89, + 0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3, + 0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C, + 0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF, + 0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5, + 0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93, + 0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97, + 0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B, + 0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1, + 0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0, + 0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41, + 0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43, + 0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46, + 0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47, + 0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A, + 0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E, + 0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52, + 0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55, + 0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59, + 0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C, + 0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5, + 0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61, + 0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1, + 0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64, + 0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF, + 0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67, + 0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2, + 0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3, + 0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D, + 0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71, + 0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75, + 0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78, + 0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C, + 0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9, + 0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82, + 0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85, + 0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3, + 0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89, + 0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED, + 0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E, + 0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA, + 0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91, + 0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE, + 0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96, + 0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8, + 0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C, + 0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC, + 0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41, + 0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45, + 0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF, + 0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B, + 0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6, + 0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51, + 0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53, + 0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2, + 0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A, + 0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E, + 0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62, + 0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66, + 0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0, + 0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8, + 0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E, + 0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7, + 0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6, + 0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74, + 0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77, + 0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B, + 0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80, + 0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0, + 0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85, + 0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88, + 0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C, + 0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F, + 0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93, + 0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95, + 0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3, + 0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A, + 0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D, + 0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40, + 0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43, + 0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46, + 0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A, + 0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C, + 0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8, + 0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51, + 0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55, + 0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59, + 0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D, + 0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61, + 0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65, + 0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69, + 0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D, + 0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71, + 0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75, + 0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79, + 0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D, + 0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4, + 0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8, + 0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83, + 0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87, + 0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8, + 0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C, + 0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90, + 0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94, + 0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98, + 0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C, + 0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0, + 0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43, + 0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47, + 0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B, + 0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F, + 0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53, + 0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57, + 0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B, + 0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F, + 0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63, + 0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67, + 0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B, + 0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F, + 0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73, + 0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77, + 0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B, + 0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80, + 0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84, + 0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88, + 0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C, + 0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90, + 0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94, + 0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98, + 0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C, + 0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0, + 0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43, + 0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5, + 0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3, + 0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB, + 0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC, + 0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC, + 0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5, + 0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47, + 0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48, + 0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1, + 0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6, + 0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8, + 0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB, + 0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD, + 0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E, + 0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52, + 0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56, + 0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A, + 0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E, + 0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62, + 0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66, + 0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A, + 0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E, + 0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7, + 0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA, + 0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75, + 0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE, + 0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9, + 0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C, + 0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81, + 0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83, + 0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87, + 0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B, + 0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F, + 0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93, + 0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97, + 0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B, + 0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F, + 0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042, + 0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045, + 0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048, + 0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C, + 0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050, + 0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054, + 0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058, + 0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C, + 0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060, + 0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1, + 0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067, + 0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B, + 0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F, + 0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073, + 0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077, + 0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B, + 0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080, + 0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084, + 0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088, + 0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A, + 0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E, + 0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092, + 0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096, + 0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098, + 0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF, + 0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB, + 0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7, + 0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4, + 0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8, + 0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D, + 0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E, + 0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD, + 0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8, + 0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141, + 0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8, + 0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7, + 0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142, + 0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146, + 0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A, + 0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D, + 0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150, + 0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154, + 0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158, + 0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C, + 0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160, + 0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164, + 0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168, + 0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C, + 0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170, + 0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174, + 0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178, + 0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C, + 0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181, + 0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185, + 0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189, + 0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D, + 0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191, + 0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195, + 0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199, + 0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D, + 0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240, + 0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244, + 0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248, + 0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C, + 0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250, + 0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254, + 0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258, + 0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C, + 0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260, + 0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264, + 0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268, + 0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C, + 0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270, + 0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274, + 0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278, + 0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C, + 0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281, + 0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285, + 0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289, + 0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D, + 0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291, + 0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295, + 0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299, + 0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D, + 0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340, + 0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344, + 0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348, + 0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C, + 0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350, + 0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4, + 0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352, + 0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB, + 0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3, + 0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD, + 0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE, + 0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6, + 0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA, + 0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356, + 0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC, + 0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE, + 0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7, + 0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9, + 0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5, + 0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A, + 0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C, + 0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360, + 0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362, + 0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE, + 0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF, + 0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369, + 0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4, + 0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D, + 0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371, + 0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373, + 0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376, + 0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379, + 0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C, + 0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381, + 0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383, + 0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6, + 0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A, + 0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C, + 0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F, + 0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393, + 0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396, + 0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399, + 0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D, + 0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0, + 0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442, + 0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446, + 0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449, + 0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C, + 0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450, + 0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454, + 0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457, + 0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A, + 0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E, + 0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462, + 0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA, + 0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468, + 0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C, + 0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E, + 0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA, + 0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471, + 0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472, + 0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475, + 0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477, + 0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A, + 0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E, + 0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483, + 0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487, + 0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B, + 0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F, + 0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493, + 0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497, + 0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B, + 0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F, + 0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542, + 0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546, + 0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A, + 0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E, + 0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552, + 0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556, + 0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A, + 0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E, + 0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562, + 0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566, + 0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A, + 0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E, + 0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572, + 0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576, + 0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A, + 0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E, + 0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583, + 0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587, + 0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B, + 0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F, + 0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593, + 0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597, + 0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B, + 0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F, + 0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642, + 0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646, + 0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A, + 0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E, + 0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652, + 0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656, + 0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A, + 0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E, + 0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662, + 0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666, + 0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A, + 0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E, + 0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672, + 0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676, + 0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A, + 0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E, + 0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683, + 0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687, + 0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B, + 0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F, + 0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693, + 0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697, + 0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B, + 0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F, + 0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742, + 0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746, + 0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A, + 0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E, + 0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752, + 0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756, + 0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A, + 0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E, + 0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762, + 0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766, + 0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A, + 0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E, + 0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772, + 0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776, + 0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A, + 0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E, + 0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782, + 0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0, + 0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2, + 0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787, + 0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7, + 0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA, + 0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B, + 0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD, + 0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF, + 0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3, + 0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6, + 0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790, + 0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC, + 0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF, + 0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3, + 0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5, + 0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794, + 0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798, + 0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB, + 0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD, + 0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3, + 0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C, + 0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE, + 0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D, + 0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB, + 0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF, + 0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843, + 0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847, + 0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B, + 0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F, + 0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853, + 0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857, + 0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B, + 0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F, + 0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863, + 0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867, + 0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B, + 0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F, + 0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873, + 0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877, + 0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B, + 0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880, + 0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884, + 0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888, + 0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C, + 0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890, + 0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894, + 0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898, + 0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C, + 0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0, + 0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943, + 0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947, + 0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B, + 0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F, + 0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953, + 0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957, + 0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B, + 0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F, + 0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963, + 0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967, + 0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B, + 0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F, + 0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973, + 0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977, + 0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B, + 0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980, + 0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984, + 0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988, + 0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C, + 0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990, + 0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994, + 0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998, + 0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C, + 0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0, + 0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43, + 0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47, + 0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B, + 0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F, + 0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53, + 0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57, + 0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B, + 0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F, + 0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63, + 0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67, + 0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B, + 0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F, + 0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73, + 0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77, + 0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B, + 0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80, + 0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84, + 0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88, + 0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C, + 0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90, + 0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94, + 0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98, + 0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C, + 0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0, + 0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43, + 0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47, + 0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B, + 0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F, + 0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53, + 0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57, + 0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B, + 0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0, + 0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB, + 0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3, + 0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E, + 0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6, + 0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8, + 0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC, + 0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD, + 0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF, + 0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1, + 0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5, + 0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7, + 0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66, + 0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69, + 0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB, + 0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE, + 0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F, + 0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0, + 0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4, + 0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71, + 0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73, + 0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76, + 0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A, + 0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA, + 0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4, + 0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84, + 0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86, + 0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89, + 0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8, + 0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F, + 0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93, + 0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96, + 0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99, + 0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3, + 0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0, + 0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43, + 0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47, + 0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A, + 0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D, + 0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2, + 0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52, + 0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55, + 0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58, + 0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8, + 0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C, + 0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F, + 0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62, + 0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63, + 0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1, + 0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67, + 0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5, + 0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C, + 0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F, + 0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73, + 0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76, + 0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC, + 0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B, + 0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80, + 0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84, + 0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6, + 0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88, + 0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B, + 0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D, + 0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91, + 0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7, + 0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97, + 0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B, + 0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E, + 0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40, + 0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44, + 0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46, + 0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD, + 0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B, + 0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E, + 0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52, + 0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56, + 0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58, + 0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C, + 0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60, + 0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64, + 0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68, + 0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C, + 0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70, + 0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74, + 0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78, + 0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C, + 0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81, + 0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85, + 0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87, + 0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6, + 0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA, + 0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89, + 0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D, + 0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91, + 0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8, + 0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96, + 0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98, + 0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C, + 0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0, + 0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43, + 0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47, + 0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B, + 0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F, + 0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5, + 0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1, + 0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF, + 0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5, + 0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB, + 0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B, + 0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F, + 0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973, + 0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977, + 0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B, + 0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980, + 0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984, + 0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988, + 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7, + 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC, + 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA, + 0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4, + 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05, + 0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17, + 0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23, + 0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F, + 0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37, + 0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42, + 0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51, + 0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B, + 0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65, + 0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B, + 0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F, + 0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76, + 0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A, + 0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F, + 0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83, + 0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A, + 0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99, + 0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3, + 0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1, + 0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8, + 0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE, + 0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0, + 0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC, + 0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7, + 0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF, + 0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9, + 0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00, + 0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05, + 0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B, + 0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14, + 0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D, + 0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29, + 0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31, + 0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39, + 0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40, + 0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45, + 0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A, + 0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54, + 0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66, + 0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D, + 0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75, + 0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A, + 0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82, + 0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A, + 0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92, + 0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98, + 0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E, + 0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4, + 0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1, + 0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6, + 0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA, + 0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE, + 0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6, + 0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB, + 0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3, + 0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9, + 0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4, + 0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC, + 0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5, + 0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB, + 0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000, + 0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004, + 0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008, + 0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E, + 0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015, + 0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D, + 0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023, + 0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F, + 0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033, + 0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037, + 0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D, + 0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042, + 0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049, + 0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050, + 0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054, + 0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059, + 0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F, + 0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063, + 0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068, + 0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D, + 0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071, + 0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075, + 0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C, + 0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083, + 0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089, + 0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E, + 0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092, + 0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096, + 0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A, + 0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E, + 0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2, + 0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB, + 0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0, + 0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5, + 0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9, + 0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF, + 0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3, + 0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7, + 0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB, + 0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0, + 0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4, + 0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9, + 0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE, + 0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2, + 0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8, + 0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF, + 0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4, + 0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9, + 0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE, + 0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102, + 0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108, + 0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D, + 0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111, + 0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116, + 0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A, + 0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E, + 0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123, + 0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127, + 0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B, + 0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F, + 0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133, + 0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137, + 0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B, + 0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142, + 0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E, + 0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153, + 0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B, + 0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160, + 0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166, + 0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F, + 0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F, + 0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187, + 0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F, + 0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194, + 0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E, + 0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6, + 0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA, + 0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8, + 0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF, + 0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5, + 0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE, + 0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4, + 0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8, + 0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE, + 0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5, + 0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9, + 0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1, + 0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE, + 0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B, + 0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213, + 0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E, + 0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223, + 0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A, + 0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232, + 0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E, + 0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247, + 0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E, + 0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255, + 0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A, + 0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260, + 0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266, + 0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D, + 0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273, + 0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277, + 0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B, + 0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283, + 0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287, + 0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C, + 0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291, + 0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296, + 0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A, + 0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6, + 0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0, + 0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7, + 0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB, + 0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1, + 0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6, + 0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD, + 0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3, + 0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9, + 0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD, + 0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2, + 0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7, + 0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB, + 0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF, + 0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4, + 0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8, + 0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301, + 0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307, + 0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C, + 0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313, + 0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C, + 0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324, + 0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329, + 0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F, + 0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333, + 0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337, + 0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340, + 0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B, + 0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354, + 0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D, + 0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C, + 0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379, + 0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E, + 0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387, + 0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F, + 0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393, + 0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399, + 0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0, + 0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA, + 0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF, + 0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3, + 0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8, + 0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD, + 0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4, + 0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE, + 0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3, + 0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD, + 0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7, + 0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF, + 0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407, + 0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419, + 0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424, + 0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433, + 0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D, + 0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444, + 0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C, + 0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451, + 0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F, + 0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465, + 0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B, + 0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F, + 0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A, + 0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483, + 0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489, + 0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493, + 0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E, + 0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2, + 0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2, + 0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9, + 0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3, + 0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6, + 0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1, + 0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB, + 0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1, + 0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7, + 0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE, + 0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504, + 0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B, + 0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512, + 0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517, + 0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C, + 0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521, + 0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529, + 0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534, + 0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539, + 0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540, + 0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548, + 0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E, + 0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553, + 0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559, + 0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E, + 0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563, + 0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F, + 0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573, + 0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D, + 0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C, + 0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592, + 0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597, + 0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0, + 0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4, + 0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9, + 0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD, + 0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2, + 0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA, + 0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1, + 0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7, + 0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE, + 0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7, + 0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB, + 0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7, + 0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0, + 0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8, + 0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC, + 0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604, + 0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A, + 0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611, + 0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615, + 0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A, + 0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621, + 0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628, + 0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E, + 0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635, + 0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C, + 0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641, + 0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645, + 0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649, + 0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650, + 0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655, + 0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D, + 0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661, + 0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667, + 0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670, + 0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675, + 0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A, + 0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680, + 0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684, + 0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A, + 0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690, + 0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695, + 0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699, + 0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D, + 0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1, + 0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6, + 0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA, + 0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE, + 0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3, + 0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8, + 0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD, + 0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1, + 0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5, + 0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9, + 0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE, + 0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2, + 0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8, + 0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5, + 0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9, + 0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF, + 0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7, + 0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700, + 0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707, + 0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E, + 0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712, + 0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716, + 0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A, + 0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720, + 0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725, + 0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731, + 0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736, + 0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D, + 0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744, + 0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749, + 0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754, + 0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759, + 0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767, + 0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771, + 0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778, + 0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E, + 0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787, + 0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D, + 0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791, + 0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797, + 0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C, + 0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5, + 0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF, + 0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5, + 0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA, + 0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE, + 0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4, + 0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8, + 0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD, + 0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6, + 0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE, + 0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5, + 0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9, + 0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE, + 0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3, + 0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB, + 0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801, + 0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808, + 0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E, + 0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813, + 0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818, + 0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D, + 0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825, + 0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829, + 0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E, + 0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833, + 0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838, + 0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C, + 0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840, + 0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845, + 0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849, + 0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F, + 0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855, + 0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A, + 0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F, + 0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863, + 0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868, + 0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E, + 0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872, + 0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876, + 0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A, + 0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F, + 0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887, + 0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C, + 0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890, + 0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896, + 0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C, + 0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2, + 0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6, + 0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC, + 0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0, + 0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4, + 0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8, + 0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD, + 0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2, + 0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7, + 0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB, + 0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF, + 0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4, + 0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9, + 0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD, + 0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1, + 0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6, + 0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA, + 0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2, + 0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8, + 0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD, + 0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901, + 0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908, + 0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C, + 0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912, + 0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B, + 0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921, + 0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928, + 0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933, + 0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D, + 0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943, + 0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C, + 0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953, + 0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D, + 0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963, + 0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968, + 0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C, + 0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970, + 0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977, + 0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E, + 0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989, + 0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F, + 0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995, + 0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C, + 0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1, + 0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC, + 0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3, + 0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7, + 0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD, + 0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2, + 0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7, + 0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD, + 0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6, + 0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF, + 0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4, + 0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA, + 0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF, + 0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3, + 0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7, + 0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD, + 0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A, + 0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F, + 0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15, + 0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A, + 0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21, + 0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27, + 0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C, + 0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30, + 0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38, + 0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D, + 0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42, + 0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47, + 0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D, + 0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51, + 0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56, + 0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B, + 0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F, + 0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64, + 0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69, + 0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E, + 0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72, + 0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B, + 0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80, + 0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84, + 0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88, + 0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C, + 0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90, + 0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95, + 0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99, + 0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F, + 0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3, + 0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7, + 0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC, + 0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0, + 0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7, + 0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC, + 0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3, + 0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7, + 0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD, + 0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1, + 0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9, + 0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE, + 0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5, + 0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC, + 0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0, + 0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5, + 0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9, + 0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD, + 0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01, + 0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05, + 0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A, + 0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E, + 0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12, + 0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18, + 0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C, + 0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20, + 0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24, + 0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28, + 0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C, + 0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30, + 0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36, + 0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B, + 0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F, + 0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44, + 0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48, + 0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C, + 0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52, + 0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61, + 0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D, + 0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74, + 0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79, + 0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F, + 0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D, + 0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92, + 0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7, + 0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD, + 0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2, + 0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC, + 0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8, + 0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD, + 0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4, + 0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8, + 0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC, + 0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6, + 0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB, + 0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1, + 0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5, + 0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE, + 0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05, + 0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C, + 0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12, + 0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B, + 0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21, + 0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29, + 0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E, + 0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33, + 0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43, + 0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C, + 0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54, + 0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A, + 0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F, + 0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68, + 0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C, + 0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73, + 0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77, + 0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D, + 0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84, + 0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89, + 0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F, + 0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D, + 0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1, + 0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7, + 0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF, + 0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6, + 0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC, + 0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3, + 0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8, + 0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD, + 0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1, + 0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6, + 0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB, + 0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF, + 0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7, + 0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE, + 0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3, + 0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7, + 0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC, + 0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00, + 0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08, + 0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C, + 0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11, + 0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17, + 0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C, + 0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21, + 0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28, + 0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F, + 0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33, + 0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38, + 0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C, + 0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42, + 0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46, + 0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E, + 0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52, + 0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56, + 0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C, + 0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61, + 0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65, + 0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A, + 0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71, + 0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76, + 0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A, + 0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E, + 0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83, + 0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87, + 0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B, + 0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F, + 0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93, + 0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97, + 0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C, + 0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1, + 0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5, + 0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9, + 0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD, + 0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1, + 0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5, + 0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA, + 0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE, + 0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2, + 0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7, + 0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB, + 0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0, + 0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4, + 0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8, + 0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF, + 0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA, + 0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5, + 0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA, + 0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00, + 0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A, + 0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12, + 0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F, + 0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23, + 0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29, + 0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F, + 0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34, + 0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A, + 0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41, + 0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48, + 0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D, + 0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51, + 0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57, + 0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C, + 0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63, + 0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67, + 0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B, + 0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F, + 0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77, + 0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82, + 0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89, + 0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92, + 0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1, + 0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8, + 0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC, + 0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1, + 0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB, + 0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0, + 0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4, + 0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8, + 0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE, + 0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5, + 0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA, + 0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF, + 0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3, + 0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7, + 0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED, + 0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1, + 0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8, + 0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD, + 0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09, + 0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10, + 0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19, + 0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E, + 0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24, + 0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E, + 0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34, + 0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38, + 0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F, + 0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44, + 0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48, + 0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C, + 0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51, + 0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B, + 0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60, + 0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68, + 0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72, + 0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78, + 0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F, + 0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E, + 0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94, + 0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D, + 0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2, + 0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6, + 0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC, + 0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2, + 0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8, + 0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE, + 0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2, + 0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB, + 0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5, + 0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE, + 0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5, + 0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC, + 0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3, + 0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9, + 0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008, + 0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010, + 0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018, + 0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022, + 0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D, + 0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032, + 0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037, + 0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D, + 0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045, + 0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049, + 0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F, + 0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056, + 0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C, + 0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061, + 0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071, + 0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077, + 0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082, + 0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088, + 0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F, + 0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095, + 0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C, + 0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4, + 0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA, + 0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5, + 0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA, + 0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0, + 0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4, + 0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC, + 0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0, + 0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6, + 0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE, + 0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4, + 0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2, + 0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB, + 0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF, + 0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105, + 0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C, + 0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113, + 0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118, + 0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D, + 0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125, + 0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C, + 0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130, + 0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134, + 0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138, + 0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C, + 0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141, + 0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145, + 0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B, + 0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152, + 0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157, + 0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B, + 0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160, + 0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165, + 0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B, + 0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F, + 0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174, + 0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A, + 0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E, + 0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182, + 0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186, + 0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A, + 0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190, + 0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195, + 0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199, + 0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E, + 0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2, + 0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6, + 0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE, + 0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2, + 0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6, + 0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB, + 0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0, + 0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5, + 0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC, + 0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0, + 0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7, + 0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB, + 0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF, + 0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3, + 0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8, + 0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC, + 0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0, + 0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4, + 0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9, + 0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD, + 0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202, + 0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207, + 0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219, + 0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220, + 0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228, + 0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F, + 0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235, + 0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A, + 0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244, + 0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F, + 0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257, + 0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D, + 0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261, + 0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268, + 0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275, + 0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B, + 0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283, + 0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288, + 0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E, + 0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299, + 0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3, + 0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA, + 0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0, + 0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6, + 0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE, + 0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB, + 0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD, + 0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4, + 0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2, + 0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA, + 0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304, + 0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B, + 0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310, + 0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315, + 0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C, + 0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C, + 0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331, + 0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336, + 0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C, + 0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341, + 0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A, + 0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354, + 0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359, + 0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D, + 0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366, + 0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C, + 0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373, + 0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379, + 0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F, + 0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385, + 0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391, + 0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397, + 0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C, + 0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1, + 0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF, + 0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6, + 0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF, + 0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3, + 0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA, + 0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3, + 0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8, + 0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC, + 0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4, + 0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8, + 0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF, + 0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5, + 0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB, + 0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404, + 0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409, + 0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411, + 0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417, + 0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D, + 0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424, + 0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429, + 0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430, + 0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435, + 0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439, + 0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440, + 0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B, + 0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F, + 0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455, + 0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A, + 0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F, + 0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463, + 0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468, + 0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E, + 0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472, + 0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476, + 0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D, + 0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481, + 0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489, + 0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D, + 0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493, + 0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A, + 0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F, + 0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3, + 0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8, + 0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1, + 0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6, + 0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE, + 0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4, + 0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9, + 0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF, + 0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5, + 0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB, + 0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0, + 0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7, + 0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB, + 0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF, + 0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3, + 0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7, + 0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB, + 0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF, + 0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504, + 0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508, + 0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D, + 0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511, + 0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516, + 0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B, + 0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F, + 0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523, + 0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528, + 0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D, + 0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533, + 0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D, + 0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543, + 0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A, + 0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550, + 0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557, + 0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F, + 0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565, + 0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A, + 0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571, + 0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578, + 0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C, + 0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580, + 0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584, + 0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589, + 0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F, + 0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596, + 0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E, + 0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6, + 0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE, + 0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4, + 0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8, + 0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF, + 0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8, + 0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0, + 0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5, + 0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB, + 0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF, + 0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA, + 0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4, + 0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB, + 0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF, + 0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607, + 0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D, + 0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616, + 0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B, + 0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622, + 0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629, + 0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E, + 0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637, + 0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B, + 0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642, + 0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647, + 0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D, + 0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658, + 0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D, + 0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663, + 0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A, + 0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671, + 0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678, + 0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D, + 0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683, + 0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689, + 0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E, + 0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693, + 0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699, + 0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E, + 0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2, + 0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6, + 0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC, + 0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1, + 0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6, + 0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB, + 0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0, + 0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4, + 0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8, + 0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC, + 0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0, + 0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4, + 0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8, + 0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0, + 0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4, + 0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA, + 0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE, + 0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6, + 0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD, + 0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704, + 0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C, + 0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712, + 0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719, + 0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720, + 0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724, + 0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E, + 0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736, + 0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B, + 0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741, + 0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A, + 0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754, + 0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759, + 0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762, + 0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767, + 0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771, + 0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779, + 0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780, + 0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786, + 0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D, + 0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792, + 0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799, + 0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1, + 0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC, + 0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4, + 0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC, + 0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0, + 0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7, + 0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB, + 0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5, + 0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF, + 0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6, + 0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB, + 0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5, + 0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9, + 0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE, + 0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804, + 0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812, + 0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819, + 0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E, + 0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823, + 0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827, + 0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D, + 0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831, + 0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A, + 0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B, + 0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856, + 0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A, + 0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E, + 0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D, + 0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871, + 0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878, + 0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C, + 0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880, + 0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888, + 0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C, + 0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891, + 0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896, + 0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B, + 0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F, + 0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4, + 0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB, + 0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2, + 0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8, + 0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC, + 0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1, + 0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6, + 0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC, + 0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1, + 0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7, + 0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD, + 0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2, + 0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7, + 0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB, + 0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2, + 0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7, + 0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE, + 0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903, + 0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908, + 0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F, + 0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915, + 0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919, + 0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D, + 0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923, + 0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928, + 0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C, + 0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932, + 0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937, + 0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C, + 0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943, + 0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947, + 0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B, + 0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F, + 0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953, + 0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959, + 0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961, + 0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967, + 0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C, + 0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972, + 0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976, + 0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E, + 0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985, + 0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E, + 0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992, + 0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999, + 0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F, + 0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3, + 0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9, + 0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF, + 0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5, + 0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA, + 0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF, + 0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4, + 0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8, + 0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF, + 0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5, + 0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9, + 0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE, + 0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4, + 0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8, + 0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC, + 0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1, + 0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6, + 0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA, + 0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00, + 0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04, + 0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08, + 0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D, + 0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11, + 0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15, + 0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B, + 0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20, + 0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25, + 0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B, + 0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30, + 0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36, + 0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A, + 0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40, + 0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45, + 0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A, + 0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E, + 0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53, + 0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57, + 0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E, + 0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63, + 0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68, + 0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C, + 0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70, + 0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75, + 0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A, + 0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F, + 0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85, + 0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89, + 0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D, + 0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94, + 0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99, + 0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D, + 0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2, + 0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6, + 0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD, + 0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1, + 0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5, + 0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9, + 0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD, + 0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1, + 0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5, + 0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9, + 0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD, + 0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1, + 0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5, + 0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9, + 0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD, + 0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1, + 0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5, + 0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9, + 0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED, + 0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1, + 0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5, + 0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9, + 0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD, + 0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01, + 0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05, + 0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09, + 0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D, + 0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11, + 0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15, + 0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19, + 0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D, + 0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26, + 0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B, + 0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F, + 0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34, + 0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B, + 0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40, + 0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45, + 0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D, + 0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51, + 0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55, + 0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A, + 0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E, + 0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68, + 0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D, + 0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71, + 0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75, + 0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A, + 0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80, + 0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E, + 0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94, + 0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99, + 0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F, + 0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4, + 0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8, + 0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD, + 0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1, + 0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9, + 0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD, + 0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4, + 0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9, + 0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0, + 0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC, + 0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0, + 0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5, + 0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9, + 0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0, + 0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6, + 0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB, + 0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00, + 0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04, + 0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B, + 0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17, + 0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20, + 0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C, + 0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36, + 0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B, + 0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43, + 0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B, + 0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F, + 0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56, + 0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62, + 0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67, + 0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E, + 0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75, + 0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B, + 0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84, + 0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D, + 0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95, + 0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A, + 0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0, + 0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF, + 0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6, + 0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1, + 0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7, + 0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE, + 0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8, + 0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD, + 0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7, + 0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2, + 0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00, + 0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06, + 0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D, + 0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13, + 0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18, + 0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20, + 0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24, + 0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C, + 0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34, + 0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A, + 0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44, + 0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55, + 0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B, + 0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62, + 0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68, + 0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70, + 0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75, + 0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B, + 0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80, + 0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86, + 0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D, + 0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96, + 0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A, + 0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC, + 0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3, + 0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9, + 0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD, + 0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3, + 0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD, + 0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2, + 0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7, + 0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF, + 0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7, + 0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED, + 0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4, + 0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA, + 0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00, + 0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04, + 0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09, + 0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13, + 0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B, + 0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22, + 0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A, + 0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31, + 0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37, + 0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D, + 0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41, + 0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47, + 0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B, + 0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51, + 0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59, + 0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E, + 0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63, + 0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67, + 0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C, + 0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71, + 0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75, + 0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79, + 0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D, + 0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84, + 0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B, + 0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91, + 0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95, + 0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A, + 0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0, + 0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6, + 0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC, + 0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3, + 0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC, + 0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3, + 0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8, + 0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD, + 0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6, + 0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC, + 0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA, + 0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE, + 0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2, + 0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7, + 0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC, + 0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00, + 0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05, + 0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B, + 0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10, + 0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17, + 0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B, + 0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F, + 0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25, + 0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C, + 0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34, + 0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39, + 0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D, + 0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42, + 0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48, + 0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E, + 0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52, + 0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56, + 0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B, + 0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61, + 0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67, + 0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B, + 0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71, + 0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77, + 0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E, + 0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82, + 0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87, + 0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90, + 0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94, + 0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98, + 0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D, + 0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2, + 0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6, + 0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB, + 0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF, + 0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4, + 0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA, + 0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE, + 0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4, + 0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8, + 0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD, + 0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3, + 0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7, + 0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB, + 0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2, + 0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6, + 0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA, + 0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0, + 0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4, + 0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8, + 0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC, + 0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000, + 0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004, + 0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008, + 0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C, + 0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010, + 0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015, + 0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019, + 0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F, + 0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024, + 0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028, + 0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C, + 0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030, + 0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034, + 0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A, + 0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E, + 0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042, + 0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046, + 0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A, + 0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050, + 0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054, + 0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058, + 0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C, + 0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061, + 0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065, + 0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069, + 0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072, + 0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079, + 0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081, + 0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086, + 0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C, + 0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091, + 0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A, + 0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0, + 0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4, + 0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8, + 0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2, + 0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA, + 0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5, + 0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB, + 0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF, + 0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3, + 0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7, + 0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE, + 0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3, + 0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0, + 0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4, + 0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA, + 0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF, + 0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103, + 0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107, + 0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D, + 0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112, + 0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C, + 0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120, + 0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124, + 0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129, + 0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D, + 0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134, + 0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139, + 0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D, + 0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141, + 0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146, + 0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B, + 0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151, + 0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155, + 0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159, + 0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F, + 0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163, + 0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B, + 0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170, + 0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176, + 0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C, + 0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181, + 0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186, + 0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B, + 0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190, + 0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195, + 0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B, + 0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1, + 0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5, + 0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA, + 0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF, + 0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4, + 0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA, + 0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE, + 0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2, + 0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7, + 0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB, + 0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0, + 0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6, + 0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA, + 0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE, + 0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3, + 0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9, + 0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED, + 0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2, + 0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6, + 0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB, + 0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF, + 0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203, + 0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208, + 0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C, + 0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210, + 0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214, + 0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218, + 0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C, + 0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221, + 0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225, + 0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B, + 0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232, + 0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C, + 0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242, + 0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246, + 0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E, + 0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253, + 0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258, + 0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260, + 0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268, + 0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D, + 0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274, + 0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B, + 0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283, + 0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288, + 0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290, + 0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295, + 0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299, + 0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D, + 0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2, + 0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6, + 0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA, + 0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2, + 0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB, + 0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF, + 0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7, + 0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC, + 0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4, + 0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA, + 0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, + 0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8, + 0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E, + 0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019, + 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, + 0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, + 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, + 0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011, + 0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236, + 0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F, + 0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237, + 0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220, + 0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E, + 0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D, + 0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F, + 0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235, + 0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0, + 0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04, + 0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030, + 0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605, + 0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7, + 0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3, + 0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190, + 0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170, + 0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174, + 0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178, + 0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A, + 0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E, + 0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492, + 0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496, + 0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A, + 0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476, + 0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A, + 0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E, + 0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482, + 0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486, + 0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462, + 0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466, + 0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220, + 0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224, + 0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228, + 0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162, + 0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166, + 0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A, + 0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, + 0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, + 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, + 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, + 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, + 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, + 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, + 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, + 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, + 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, + 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, + 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, + 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, + 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, + 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, + 0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, + 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, + 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, + 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, + 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, + 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, + 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, + 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, + 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041, + 0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045, + 0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049, + 0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D, + 0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051, + 0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055, + 0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059, + 0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D, + 0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061, + 0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065, + 0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069, + 0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D, + 0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071, + 0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075, + 0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079, + 0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D, + 0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081, + 0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085, + 0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089, + 0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D, + 0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091, + 0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2, + 0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6, + 0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA, + 0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE, + 0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2, + 0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6, + 0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA, + 0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE, + 0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2, + 0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6, + 0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA, + 0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE, + 0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2, + 0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6, + 0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA, + 0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE, + 0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2, + 0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6, + 0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA, + 0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE, + 0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2, + 0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6, + 0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394, + 0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398, + 0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C, + 0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0, + 0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5, + 0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9, + 0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4, + 0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8, + 0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC, + 0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0, + 0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5, + 0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9, + 0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A, + 0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E, + 0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44, + 0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38, + 0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410, + 0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414, + 0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417, + 0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B, + 0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F, + 0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423, + 0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427, + 0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B, + 0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F, + 0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433, + 0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436, + 0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A, + 0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E, + 0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442, + 0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446, + 0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A, + 0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E, + 0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9, + 0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035, + 0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197, + 0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F, + 0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267, + 0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552, + 0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556, + 0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A, + 0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E, + 0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562, + 0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566, + 0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A, + 0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E, + 0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572, + 0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583, + 0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587, + 0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B, + 0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F, + 0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC, + 0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4, + 0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012, + 0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1, + 0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9, + 0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED, + 0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3, + 0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA, + 0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8, + 0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA, + 0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261, + 0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108, + 0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C, + 0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110, + 0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114, + 0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118, + 0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C, + 0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120, + 0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124, + 0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128, + 0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023, + 0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027, + 0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E, + 0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E, + 0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1, + 0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2, + 0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010, + 0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD, + 0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E, + 0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C, + 0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50, + 0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55, + 0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A, + 0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E, + 0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62, + 0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66, + 0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B, + 0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502, + 0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506, + 0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A, + 0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E, + 0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512, + 0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516, + 0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A, + 0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E, + 0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522, + 0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526, + 0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A, + 0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E, + 0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532, + 0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536, + 0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A, + 0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E, + 0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542, + 0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546, + 0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A, + 0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF, + 0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5, + 0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB, + 0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD, + 0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302, + 0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307, + 0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C, + 0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311, + 0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319, + 0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323, + 0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328, + 0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332, + 0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A, + 0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340, + 0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344, + 0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348, + 0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C, + 0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353, + 0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358, + 0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C, + 0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361, + 0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365, + 0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369, + 0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370, + 0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374, + 0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378, + 0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C, + 0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381, + 0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386, + 0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D, + 0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393, + 0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398, + 0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D, + 0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3, + 0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7, + 0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD, + 0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6, + 0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD, + 0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3, + 0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7, + 0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2, + 0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6, + 0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB, + 0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1, + 0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6, + 0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC, + 0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1, + 0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6, + 0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA, + 0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE, + 0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402, + 0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B, + 0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411, + 0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415, + 0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419, + 0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F, + 0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424, + 0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D, + 0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437, + 0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B, + 0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440, + 0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445, + 0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449, + 0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D, + 0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451, + 0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456, + 0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461, + 0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465, + 0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469, + 0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E, + 0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473, + 0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479, + 0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D, + 0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485, + 0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A, + 0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491, + 0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495, + 0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499, + 0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F, + 0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3, + 0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA, + 0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE, + 0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2, + 0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6, + 0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB, + 0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF, + 0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3, + 0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7, + 0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB, + 0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF, + 0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4, + 0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8, + 0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD, + 0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7, + 0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB, + 0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1, + 0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8, + 0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC, + 0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501, + 0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506, + 0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A, + 0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510, + 0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516, + 0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E, + 0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523, + 0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A, + 0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539, + 0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541, + 0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546, + 0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D, + 0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553, + 0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558, + 0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560, + 0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564, + 0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B, + 0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F, + 0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575, + 0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B, + 0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580, + 0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585, + 0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A, + 0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590, + 0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B, + 0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6, + 0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA, + 0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA, + 0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1, + 0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE, + 0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3, + 0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC, + 0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1, + 0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED, + 0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3, + 0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8, + 0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE, + 0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607, + 0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D, + 0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612, + 0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A, + 0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621, + 0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C, + 0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632, + 0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A, + 0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642, + 0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647, + 0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B, + 0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651, + 0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657, + 0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B, + 0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661, + 0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666, + 0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A, + 0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670, + 0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674, + 0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679, + 0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680, + 0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689, + 0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F, + 0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695, + 0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B, + 0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F, + 0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3, + 0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8, + 0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC, + 0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3, + 0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8, + 0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC, + 0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1, + 0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3, + 0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0, + 0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE, + 0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698, + 0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA, + 0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA, + 0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE, + 0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1, + 0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA, + 0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252, + 0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B, + 0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB, + 0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D, + 0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D, + 0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70, + 0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591, + 0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C, + 0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E, + 0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A, + 0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E, + 0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1, + 0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551, + 0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE, + 0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4, + 0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC, + 0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA, + 0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0, + 0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4, + 0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9, + 0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED, + 0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6, + 0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD, + 0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703, + 0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C, + 0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711, + 0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715, + 0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B, + 0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721, + 0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727, + 0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E, + 0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733, + 0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D, + 0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744, + 0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749, + 0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D, + 0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753, + 0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757, + 0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584, + 0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971, + 0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4, + 0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F, + 0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317, + 0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1, + 0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB, + 0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF, + 0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7, + 0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8, + 0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119, + 0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6, + 0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6, + 0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED, + 0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F, + 0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B, + 0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C, + 0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E, + 0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D, + 0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868, + 0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A, + 0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8, + 0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0, + 0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C, + 0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F, + 0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769, + 0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F, + 0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773, + 0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777, + 0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C, + 0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786, + 0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A, + 0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793, + 0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797, + 0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B, + 0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1, + 0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8, + 0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF, + 0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6, + 0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA, + 0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1, + 0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5, + 0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9, + 0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE, + 0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2, + 0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6, + 0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD, + 0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1, + 0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB, + 0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5, + 0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F, + 0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B, + 0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24, + 0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C, + 0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D, + 0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8, + 0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1, + 0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C, + 0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC, + 0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695, + 0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F, + 0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7, + 0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD, + 0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56, + 0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42, + 0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C, + 0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D, + 0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7, + 0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400, + 0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17, + 0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610, + 0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6, + 0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0, + 0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5, + 0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB, + 0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805, + 0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A, + 0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810, + 0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B, + 0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822, + 0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B, + 0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832, + 0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D, + 0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843, + 0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849, + 0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F, + 0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858, + 0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C, + 0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861, + 0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865, + 0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869, + 0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872, + 0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876, + 0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B, + 0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880, + 0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A, + 0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F, + 0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545, + 0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284, + 0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E, + 0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66, + 0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B, + 0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0, + 0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89, + 0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491, + 0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210, + 0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9, + 0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E, + 0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4, + 0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF, + 0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F, + 0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5, + 0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2, + 0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD, + 0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20, + 0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8, + 0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D, + 0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87, + 0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664, + 0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886, + 0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F, + 0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895, + 0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E, + 0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6, + 0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB, + 0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF, + 0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8, + 0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD, + 0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3, + 0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8, + 0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF, + 0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6, + 0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB, + 0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF, + 0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3, + 0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7, + 0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED, + 0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1, + 0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8, + 0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD, + 0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902, + 0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907, + 0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B, + 0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7, + 0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3, + 0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20, + 0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE, + 0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF, + 0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376, + 0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F, + 0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF, + 0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5, + 0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E, + 0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64, + 0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A, + 0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE, + 0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B, + 0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1, + 0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC, + 0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC, + 0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8, + 0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA, + 0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE, + 0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927, + 0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234, + 0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37, + 0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D, + 0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911, + 0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916, + 0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A, + 0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F, + 0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923, + 0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928, + 0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C, + 0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930, + 0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935, + 0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939, + 0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943, + 0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A, + 0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E, + 0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952, + 0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959, + 0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966, + 0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C, + 0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972, + 0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976, + 0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D, + 0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983, + 0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989, + 0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E, + 0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020, + 0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355, + 0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6, + 0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1, + 0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53, + 0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863, + 0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012, + 0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230, + 0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7, + 0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C, + 0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA, + 0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E, + 0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B, + 0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1, + 0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482, + 0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012, + 0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7, + 0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B, + 0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538, + 0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0, + 0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5, + 0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A, + 0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239, + 0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D, + 0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995, + 0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999, + 0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E, + 0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2, + 0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6, + 0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB, + 0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF, + 0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4, + 0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8, + 0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4, + 0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA, + 0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0, + 0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7, + 0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC, + 0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1, + 0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA, + 0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2, + 0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6, + 0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC, + 0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04, + 0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09, + 0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10, + 0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15, + 0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B, + 0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE, + 0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D, + 0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C, + 0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8, + 0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB, + 0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597, + 0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8, + 0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A, + 0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779, + 0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A, + 0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF, + 0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD, + 0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F, + 0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72, + 0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D, + 0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6, + 0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2, + 0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241, + 0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8, + 0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9, + 0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C, + 0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069, + 0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14, + 0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D, + 0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24, + 0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28, + 0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C, + 0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30, + 0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35, + 0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E, + 0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43, + 0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48, + 0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C, + 0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50, + 0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55, + 0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A, + 0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E, + 0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62, + 0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66, + 0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A, + 0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E, + 0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73, + 0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D, + 0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87, + 0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C, + 0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93, + 0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B, + 0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30, + 0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10, + 0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0, + 0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB, + 0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41, + 0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4, + 0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D, + 0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9, + 0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8, + 0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E, + 0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE, + 0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420, + 0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39, + 0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B, + 0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A, + 0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD, + 0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30, + 0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0, + 0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD, + 0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD, + 0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426, + 0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75, + 0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45, + 0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8, + 0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7, + 0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE, + 0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2, + 0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7, + 0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB, + 0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0, + 0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4, + 0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8, + 0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD, + 0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1, + 0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5, + 0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB, + 0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2, + 0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9, + 0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE, + 0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3, + 0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7, + 0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE, + 0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05, + 0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D, + 0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13, + 0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A, + 0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21, + 0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29, + 0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F, + 0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A, + 0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7, + 0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150, + 0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B, + 0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C, + 0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC, + 0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A, + 0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5, + 0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6, + 0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746, + 0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76, + 0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63, + 0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38, + 0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F, + 0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8, + 0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E, + 0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5, + 0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D, + 0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769, + 0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601, + 0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404, + 0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015, + 0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F, + 0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35, + 0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B, + 0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41, + 0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46, + 0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E, + 0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59, + 0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61, + 0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66, + 0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A, + 0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F, + 0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76, + 0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D, + 0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83, + 0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88, + 0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C, + 0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92, + 0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99, + 0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F, + 0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5, + 0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2, + 0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7, + 0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC, + 0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0, + 0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2, + 0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B, + 0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B, + 0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13, + 0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21, + 0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F, + 0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784, + 0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7, + 0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD, + 0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4, + 0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1, + 0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7, + 0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1, + 0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0, + 0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98, + 0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986, + 0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F, + 0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470, + 0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52, + 0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C, + 0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC, + 0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A, + 0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED, + 0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7, + 0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9, + 0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE, + 0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4, + 0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8, + 0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF, + 0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4, + 0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB, + 0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0, + 0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5, + 0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA, + 0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00, + 0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04, + 0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09, + 0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10, + 0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14, + 0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19, + 0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D, + 0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22, + 0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28, + 0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D, + 0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31, + 0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35, + 0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A, + 0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E, + 0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77, + 0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87, + 0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9, + 0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD, + 0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC, + 0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D, + 0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F, + 0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E, + 0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D, + 0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475, + 0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838, + 0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408, + 0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3, + 0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64, + 0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5, + 0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC, + 0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052, + 0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679, + 0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18, + 0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334, + 0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E, + 0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A, + 0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774, + 0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43, + 0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47, + 0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B, + 0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50, + 0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54, + 0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58, + 0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C, + 0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60, + 0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64, + 0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68, + 0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C, + 0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70, + 0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76, + 0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A, + 0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81, + 0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85, + 0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A, + 0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E, + 0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94, + 0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B, + 0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6, + 0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB, + 0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0, + 0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7, + 0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27, + 0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92, + 0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7, + 0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B, + 0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0, + 0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F, + 0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8, + 0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524, + 0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3, + 0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C, + 0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27, + 0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C, + 0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E, + 0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD, + 0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1, + 0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0, + 0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A, + 0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2, + 0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A, + 0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41, + 0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7, + 0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27, + 0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA, + 0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF, + 0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2, + 0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9, + 0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0, + 0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4, + 0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD, + 0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3, + 0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7, + 0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC, + 0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1, + 0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5, + 0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA, + 0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF, + 0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03, + 0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07, + 0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C, + 0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10, + 0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14, + 0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18, + 0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C, + 0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21, + 0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26, + 0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C, + 0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31, + 0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35, + 0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9, + 0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC, + 0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781, + 0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6, + 0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72, + 0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324, + 0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF, + 0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E, + 0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E, + 0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0, + 0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993, + 0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7, + 0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0, + 0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532, + 0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7, + 0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C, + 0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A, + 0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9, + 0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327, + 0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877, + 0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED, + 0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB, + 0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1, + 0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37, + 0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B, + 0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F, + 0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43, + 0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47, + 0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B, + 0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F, + 0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53, + 0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57, + 0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B, + 0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F, + 0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63, + 0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67, + 0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B, + 0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70, + 0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74, + 0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79, + 0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D, + 0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81, + 0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85, + 0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89, + 0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D, + 0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91, + 0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95, + 0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065, + 0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10, + 0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5, + 0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F, + 0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956, + 0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D, + 0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126, + 0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47, + 0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405, + 0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A, + 0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34, + 0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175, + 0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96, + 0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8, + 0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB, + 0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377, + 0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3, + 0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9, + 0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB, + 0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE, + 0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA, + 0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526, + 0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773, + 0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC, + 0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B, + 0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F, + 0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3, + 0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8, + 0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC, + 0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1, + 0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5, + 0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9, + 0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD, + 0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1, + 0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5, + 0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9, + 0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD, + 0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1, + 0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5, + 0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9, + 0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD, + 0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1, + 0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5, + 0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9, + 0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED, + 0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1, + 0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5, + 0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9, + 0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346, + 0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676, + 0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE, + 0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66, + 0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883, + 0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9, + 0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0, + 0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76, + 0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45, + 0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9, + 0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205, + 0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0, + 0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45, + 0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480, + 0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A, + 0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177, + 0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1, + 0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267, + 0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026, + 0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485, + 0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014, + 0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0, + 0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7, + 0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB, + 0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF, + 0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03, + 0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07, + 0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B, + 0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F, + 0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13, + 0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17, + 0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B, + 0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F, + 0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23, + 0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27, + 0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B, + 0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F, + 0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33, + 0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37, + 0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C, + 0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40, + 0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45, + 0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A, + 0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E, + 0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52, + 0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56, + 0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A, + 0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA, + 0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F, + 0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF, + 0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF, + 0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8, + 0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7, + 0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297, + 0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7, + 0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB, + 0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897, + 0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF, + 0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2, + 0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6, + 0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A, + 0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0, + 0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF, + 0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177, + 0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE, + 0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757, + 0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD, + 0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2, + 0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7, + 0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF, + 0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41, + 0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60, + 0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64, + 0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68, + 0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C, + 0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70, + 0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74, + 0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78, + 0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C, + 0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80, + 0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85, + 0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89, + 0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D, + 0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91, + 0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95, + 0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99, + 0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E, + 0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC, + 0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9, + 0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37, + 0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D, + 0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41, + 0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48, + 0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C, + 0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52, + 0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83, + 0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0, + 0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614, + 0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721, + 0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1, + 0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A, + 0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611, + 0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD, + 0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2, + 0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC, + 0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A, + 0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001, + 0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9, + 0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7, + 0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F, + 0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B, + 0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E, + 0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281, + 0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB, + 0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC, + 0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354, + 0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389, + 0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229, + 0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56, + 0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D, + 0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64, + 0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B, + 0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70, + 0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77, + 0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C, + 0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82, + 0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86, + 0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B, + 0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91, + 0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96, + 0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B, + 0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3, + 0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9, + 0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD, + 0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4, + 0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA, + 0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2, + 0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7, + 0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD, + 0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2, + 0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9, + 0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD, + 0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2, + 0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6, + 0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9, + 0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570, + 0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18, + 0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B, + 0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9, + 0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24, + 0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE, + 0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA, + 0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD, + 0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563, + 0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2, + 0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433, + 0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34, + 0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB, + 0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2, + 0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3, + 0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075, + 0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6, + 0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4, + 0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218, + 0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D, + 0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C, + 0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8, + 0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED, + 0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5, + 0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9, + 0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF, + 0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009, + 0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011, + 0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D, + 0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023, + 0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D, + 0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032, + 0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C, + 0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044, + 0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049, + 0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051, + 0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057, + 0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D, + 0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061, + 0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065, + 0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B, + 0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F, + 0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074, + 0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078, + 0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C, + 0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2, + 0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402, + 0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6, + 0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089, + 0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81, + 0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF, + 0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984, + 0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74, + 0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5, + 0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651, + 0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4, + 0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A, + 0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0, + 0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26, + 0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA, + 0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B, + 0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8, + 0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC, + 0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801, + 0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B, + 0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6, + 0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792, + 0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513, + 0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E, + 0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088, + 0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F, + 0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094, + 0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E, + 0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8, + 0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5, + 0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB, + 0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9, + 0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0, + 0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4, + 0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0, + 0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE, + 0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB, + 0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101, + 0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107, + 0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115, + 0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C, + 0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121, + 0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125, + 0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129, + 0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E, + 0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135, + 0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B, + 0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29, + 0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13, + 0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305, + 0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6, + 0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D, + 0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB, + 0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709, + 0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92, + 0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627, + 0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8, + 0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499, + 0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B, + 0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A, + 0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C, + 0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5, + 0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42, + 0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195, + 0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05, + 0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784, + 0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99, + 0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11, + 0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF, + 0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23, + 0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C, + 0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142, + 0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147, + 0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F, + 0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158, + 0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E, + 0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163, + 0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A, + 0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172, + 0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177, + 0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184, + 0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189, + 0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E, + 0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194, + 0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199, + 0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0, + 0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5, + 0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC, + 0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0, + 0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5, + 0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9, + 0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF, + 0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8, + 0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE, + 0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2, + 0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21, + 0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54, + 0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8, + 0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE, + 0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0, + 0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6, + 0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55, + 0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE, + 0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF, + 0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3, + 0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43, + 0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357, + 0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320, + 0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6, + 0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9, + 0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A, + 0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60, + 0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA, + 0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE, + 0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18, + 0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F, + 0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A, + 0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0, + 0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4, + 0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8, + 0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC, + 0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0, + 0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5, + 0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB, + 0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1, + 0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7, + 0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD, + 0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208, + 0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E, + 0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215, + 0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219, + 0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224, + 0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229, + 0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C, + 0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241, + 0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246, + 0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D, + 0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252, + 0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256, + 0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C, + 0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261, + 0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265, + 0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7, + 0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE, + 0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C, + 0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012, + 0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F, + 0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA, + 0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4, + 0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4, + 0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15, + 0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392, + 0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E, + 0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0, + 0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB, + 0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A, + 0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228, + 0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1, + 0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4, + 0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69, + 0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830, + 0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D, + 0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7, + 0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367, + 0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739, + 0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435, + 0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C, + 0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276, + 0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C, + 0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285, + 0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C, + 0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295, + 0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E, + 0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7, + 0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA, + 0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0, + 0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6, + 0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9, + 0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7, + 0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC, + 0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2, + 0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8, + 0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE, + 0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B, + 0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313, + 0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D, + 0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321, + 0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325, + 0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E, + 0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B, + 0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2, + 0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB, + 0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F, + 0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02, + 0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5, + 0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1, + 0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9, + 0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6, + 0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC, + 0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44, + 0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251, + 0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461, + 0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734, + 0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31, + 0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A, + 0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03, + 0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F, + 0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67, + 0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50, + 0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91, + 0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01, + 0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668, + 0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D, + 0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E, + 0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344, + 0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B, + 0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353, + 0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358, + 0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370, + 0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374, + 0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A, + 0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381, + 0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387, + 0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C, + 0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391, + 0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397, + 0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F, + 0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4, + 0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC, + 0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5, + 0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2, + 0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8, + 0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE, + 0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3, + 0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA, + 0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3, + 0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8, + 0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070, + 0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E, + 0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E, + 0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4, + 0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C, + 0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811, + 0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA, + 0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899, + 0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47, + 0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865, + 0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7, + 0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED, + 0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304, + 0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6, + 0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434, + 0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD, + 0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B, + 0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05, + 0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5, + 0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C, + 0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1, + 0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B, + 0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6, + 0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71, + 0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3, + 0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7, + 0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE, + 0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405, + 0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A, + 0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414, + 0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419, + 0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F, + 0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423, + 0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C, + 0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430, + 0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435, + 0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A, + 0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440, + 0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444, + 0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449, + 0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D, + 0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452, + 0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456, + 0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F, + 0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465, + 0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A, + 0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472, + 0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B, + 0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B, + 0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7, + 0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168, + 0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238, + 0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638, + 0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E, + 0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136, + 0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4, + 0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9, + 0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9, + 0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA, + 0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4, + 0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254, + 0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338, + 0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194, + 0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197, + 0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339, + 0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982, + 0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165, + 0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A, + 0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6, + 0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12, + 0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E, + 0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D, + 0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481, + 0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486, + 0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490, + 0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494, + 0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A, + 0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F, + 0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4, + 0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8, + 0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC, + 0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1, + 0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7, + 0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0, + 0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6, + 0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC, + 0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4, + 0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9, + 0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE, + 0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7, + 0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB, + 0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1, + 0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5, + 0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9, + 0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE, + 0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E, + 0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27, + 0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2, + 0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE, + 0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740, + 0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB, + 0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652, + 0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71, + 0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA, + 0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3, + 0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E, + 0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F, + 0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3, + 0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7, + 0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11, + 0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962, + 0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D, + 0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151, + 0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837, + 0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB, + 0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E, + 0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A, + 0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0, + 0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347, + 0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505, + 0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509, + 0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E, + 0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514, + 0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519, + 0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E, + 0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524, + 0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528, + 0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E, + 0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532, + 0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536, + 0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541, + 0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546, + 0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D, + 0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551, + 0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555, + 0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B, + 0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560, + 0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565, + 0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A, + 0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E, + 0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573, + 0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578, + 0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580, + 0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269, + 0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931, + 0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7, + 0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3, + 0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF, + 0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2, + 0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76, + 0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB, + 0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED, + 0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F, + 0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5, + 0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F, + 0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6, + 0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996, + 0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E, + 0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C, + 0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292, + 0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1, + 0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70, + 0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9, + 0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20, + 0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811, + 0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885, + 0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582, + 0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589, + 0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D, + 0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592, + 0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596, + 0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A, + 0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0, + 0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5, + 0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB, + 0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2, + 0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6, + 0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC, + 0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0, + 0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5, + 0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA, + 0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE, + 0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6, + 0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA, + 0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF, + 0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3, + 0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8, + 0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED, + 0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1, + 0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5, + 0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055, + 0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870, + 0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4, + 0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01, + 0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E, + 0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4, + 0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF, + 0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1, + 0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086, + 0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A, + 0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E, + 0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001, + 0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C, + 0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF, + 0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F, + 0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF, + 0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178, + 0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B, + 0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E, + 0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7, + 0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B, + 0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29, + 0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240, + 0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979, + 0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC, + 0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601, + 0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606, + 0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A, + 0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E, + 0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613, + 0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618, + 0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C, + 0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620, + 0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624, + 0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A, + 0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E, + 0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632, + 0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636, + 0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B, + 0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640, + 0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644, + 0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648, + 0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C, + 0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656, + 0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B, + 0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660, + 0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665, + 0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669, + 0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B, + 0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC, + 0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A, + 0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A, + 0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B, + 0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D, + 0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892, + 0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD, + 0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802, + 0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6, + 0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F, + 0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4, + 0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003, + 0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957, + 0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC, + 0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22, + 0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44, + 0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F, + 0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49, + 0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530, + 0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146, + 0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A, + 0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16, + 0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D, + 0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673, + 0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677, + 0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685, + 0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689, + 0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691, + 0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697, + 0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B, + 0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1, + 0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB, + 0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3, + 0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB, + 0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF, + 0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5, + 0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2, + 0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7, + 0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0, + 0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5, + 0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA, + 0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5, + 0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB, + 0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701, + 0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B, + 0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710, + 0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40, + 0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD, + 0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850, + 0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC, + 0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345, + 0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077, + 0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8, + 0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92, + 0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F, + 0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2, + 0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715, + 0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F, + 0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131, + 0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C, + 0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E, + 0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C, + 0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A, + 0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E, + 0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7, + 0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A, + 0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49, + 0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B, + 0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80, + 0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984, + 0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D, + 0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726, + 0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B, + 0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730, + 0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736, + 0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C, + 0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742, + 0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746, + 0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F, + 0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754, + 0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A, + 0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E, + 0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766, + 0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A, + 0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F, + 0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775, + 0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A, + 0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784, + 0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A, + 0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790, + 0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795, + 0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A, + 0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E, + 0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3, + 0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371, + 0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4, + 0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D, + 0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4, + 0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC, + 0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F, + 0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D, + 0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170, + 0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A, + 0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B, + 0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1, + 0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717, + 0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1, + 0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB, + 0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61, + 0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C, + 0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB, + 0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348, + 0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E, + 0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269, + 0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF, + 0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F, + 0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B, + 0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5, + 0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA, + 0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2, + 0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8, + 0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE, + 0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3, + 0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8, + 0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE, + 0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5, + 0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9, + 0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE, + 0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3, + 0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8, + 0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED, + 0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2, + 0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6, + 0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB, + 0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800, + 0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805, + 0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809, + 0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E, + 0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812, + 0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819, + 0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E, + 0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00, + 0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D, + 0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF, + 0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84, + 0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3, + 0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB, + 0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E, + 0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96, + 0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED, + 0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413, + 0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9, + 0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24, + 0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E, + 0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669, + 0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A, + 0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677, + 0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2, + 0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944, + 0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965, + 0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB, + 0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF, + 0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D, + 0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3, + 0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6, + 0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826, + 0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A, + 0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E, + 0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833, + 0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837, + 0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D, + 0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842, + 0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848, + 0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E, + 0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852, + 0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858, + 0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D, + 0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866, + 0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F, + 0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875, + 0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A, + 0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883, + 0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A, + 0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890, + 0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895, + 0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A, + 0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F, + 0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5, + 0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9, + 0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821, + 0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548, + 0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E, + 0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A, + 0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10, + 0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9, + 0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22, + 0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C, + 0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB, + 0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F, + 0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174, + 0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2, + 0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F, + 0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6, + 0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4, + 0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E, + 0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0, + 0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C, + 0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B, + 0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157, + 0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C, + 0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA, + 0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3, + 0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC, + 0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2, + 0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6, + 0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB, + 0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0, + 0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8, + 0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD, + 0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3, + 0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB, + 0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0, + 0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9, + 0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED, + 0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5, + 0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB, + 0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901, + 0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906, + 0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B, + 0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F, + 0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916, + 0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D, + 0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922, + 0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927, + 0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D, + 0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932, + 0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009, + 0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774, + 0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA, + 0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA, + 0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F, + 0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD, + 0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B, + 0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440, + 0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C, + 0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5, + 0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109, + 0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9, + 0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712, + 0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C, + 0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944, + 0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14, + 0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C, + 0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66, + 0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C, + 0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7, + 0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1, + 0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27, + 0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837, + 0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996, + 0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A, + 0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E, + 0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943, + 0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948, + 0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C, + 0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950, + 0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954, + 0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958, + 0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C, + 0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962, + 0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967, + 0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B, + 0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F, + 0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973, + 0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977, + 0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C, + 0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982, + 0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988, + 0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C, + 0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990, + 0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994, + 0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998, + 0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C, + 0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0, + 0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065, + 0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC, + 0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000, + 0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237, + 0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875, + 0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3, + 0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00, + 0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1, + 0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890, + 0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA, + 0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C, + 0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681, + 0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3, + 0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613, + 0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79, + 0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB, + 0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5, + 0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2, + 0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1, + 0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE, + 0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7, + 0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F, + 0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E, + 0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2, + 0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6, + 0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA, + 0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE, + 0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2, + 0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6, + 0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA, + 0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE, + 0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD, + 0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7, + 0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD, + 0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2, + 0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9, + 0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE, + 0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4, + 0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8, + 0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC, + 0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01, + 0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05, + 0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A, + 0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E, + 0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12, + 0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16, + 0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A, + 0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370, + 0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70, + 0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424, + 0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE, + 0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896, + 0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5, + 0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8, + 0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F, + 0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F, + 0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18, + 0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531, + 0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9, + 0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB, + 0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1, + 0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4, + 0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E, + 0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE, + 0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D, + 0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31, + 0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9, + 0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389, + 0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401, + 0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1, + 0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2, + 0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20, + 0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24, + 0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28, + 0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C, + 0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30, + 0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34, + 0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38, + 0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C, + 0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41, + 0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45, + 0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A, + 0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E, + 0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52, + 0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56, + 0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A, + 0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E, + 0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62, + 0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66, + 0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A, + 0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E, + 0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72, + 0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76, + 0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B, + 0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F, + 0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5, + 0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33, + 0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3, + 0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95, + 0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F, + 0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1, + 0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0, + 0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5, + 0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6, + 0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7, + 0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0, + 0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5, + 0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742, + 0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0, + 0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1, + 0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43, + 0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF, + 0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9, + 0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A, + 0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5, + 0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD, + 0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E, + 0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3, + 0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81, + 0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85, + 0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B, + 0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F, + 0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94, + 0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98, + 0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C, + 0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0, + 0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4, + 0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8, + 0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC, + 0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0, + 0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4, + 0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8, + 0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC, + 0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0, + 0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4, + 0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8, + 0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC, + 0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0, + 0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4, + 0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8, + 0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC, + 0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0, + 0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1, + 0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8, + 0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8, + 0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84, + 0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1, + 0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF, + 0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55, + 0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218, + 0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F, + 0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20, + 0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08, + 0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0, + 0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D, + 0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167, + 0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC, + 0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0, + 0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517, + 0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F, + 0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB, + 0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795, + 0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F, + 0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323, + 0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89, + 0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63, + 0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6, + 0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA, + 0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE, + 0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2, + 0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6, + 0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA, + 0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE, + 0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02, + 0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06, + 0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B, + 0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F, + 0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13, + 0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17, + 0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B, + 0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F, + 0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23, + 0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28, + 0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C, + 0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30, + 0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34, + 0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38, + 0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C, + 0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40, + 0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44, + 0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1, + 0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F, + 0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2, + 0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7, + 0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96, + 0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740, + 0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA, + 0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A, + 0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E, + 0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A, + 0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099, + 0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92, + 0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F, + 0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF, + 0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F, + 0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC, + 0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A, + 0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C, + 0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB, + 0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB, + 0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E, + 0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B, + 0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0, + 0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46, + 0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A, + 0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E, + 0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52, + 0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56, + 0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A, + 0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E, + 0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62, + 0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67, + 0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B, + 0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70, + 0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74, + 0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78, + 0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C, + 0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80, + 0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84, + 0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88, + 0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C, + 0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90, + 0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94, + 0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98, + 0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C, + 0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC, + 0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0, + 0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F, + 0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293, + 0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816, + 0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6, + 0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986, + 0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E, + 0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760, + 0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349, + 0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422, + 0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740, + 0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8, + 0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4, + 0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D, + 0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D, + 0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A, + 0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5, + 0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD, + 0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF, + 0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4, + 0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189, + 0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075, + 0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE, + 0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7, + 0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B, + 0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F, + 0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44, + 0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B, + 0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50, + 0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54, + 0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59, + 0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E, + 0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64, + 0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68, + 0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E, + 0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72, + 0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77, + 0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E, + 0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83, + 0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88, + 0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F, + 0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93, + 0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99, + 0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D, + 0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1, + 0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5, + 0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9, + 0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD, + 0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10, + 0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98, + 0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669, + 0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315, + 0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E, + 0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997, + 0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36, + 0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69, + 0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C, + 0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D, + 0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765, + 0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326, + 0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366, + 0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E, + 0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240, + 0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C, + 0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281, + 0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54, + 0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2, + 0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE, + 0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64, + 0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09, + 0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538, + 0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF, + 0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3, + 0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7, + 0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB, + 0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF, + 0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3, + 0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7, + 0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB, + 0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF, + 0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3, + 0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7, + 0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB, + 0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF, + 0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3, + 0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7, + 0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB, + 0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF, + 0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3, + 0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7, + 0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB, + 0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF, + 0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03, + 0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07, + 0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B, + 0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57, + 0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74, + 0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F, + 0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C, + 0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8, + 0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3, + 0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8, + 0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C, + 0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE, + 0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028, + 0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048, + 0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5, + 0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6, + 0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6, + 0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD, + 0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE, + 0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E, + 0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181, + 0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07, + 0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155, + 0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E, + 0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2, + 0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8, + 0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC, + 0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11, + 0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15, + 0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19, + 0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20, + 0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F, + 0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A, + 0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71, + 0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A, + 0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E, + 0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83, + 0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89, + 0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F, + 0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95, + 0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99, + 0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D, + 0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2, + 0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7, + 0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB, + 0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF, + 0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7, + 0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0, + 0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7, + 0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD, + 0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4, + 0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5, + 0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA, + 0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2, + 0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE, + 0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6, + 0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF, + 0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9, + 0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6, + 0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00, + 0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C, + 0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14, + 0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B, + 0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20, + 0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A, + 0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32, + 0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369, + 0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621, + 0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C, + 0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F, + 0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674, + 0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0, + 0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099, + 0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3, + 0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8, + 0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1, + 0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7, + 0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0, + 0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6, + 0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00, + 0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04, + 0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B, + 0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11, + 0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16, + 0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A, + 0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21, + 0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27, + 0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30, + 0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36, + 0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C, + 0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45, + 0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E, + 0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54, + 0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58, + 0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D, + 0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61, + 0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65, + 0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B, + 0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0, + 0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0, + 0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6, + 0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB, + 0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104, + 0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131, + 0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146, + 0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC, + 0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0, + 0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE, + 0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC, + 0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A, + 0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1, + 0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1, + 0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733, + 0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C, + 0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785, + 0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B, + 0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773, + 0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2, + 0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793, + 0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA, + 0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4, + 0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD, + 0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78, + 0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D, + 0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83, + 0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89, + 0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D, + 0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93, + 0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98, + 0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D, + 0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2, + 0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6, + 0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA, + 0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1, + 0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6, + 0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB, + 0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF, + 0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3, + 0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7, + 0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB, + 0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0, + 0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4, + 0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8, + 0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC, + 0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0, + 0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4, + 0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED, + 0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844, + 0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881, + 0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8, + 0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D, + 0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8, + 0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297, + 0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE, + 0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3, + 0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB, + 0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4, + 0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4, + 0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309, + 0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307, + 0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8, + 0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311, + 0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315, + 0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351, + 0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392, + 0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B, + 0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347, + 0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317, + 0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333, + 0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6, + 0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA, + 0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE, + 0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2, + 0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6, + 0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA, + 0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE, + 0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02, + 0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06, + 0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A, + 0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E, + 0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12, + 0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16, + 0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A, + 0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E, + 0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22, + 0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26, + 0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A, + 0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E, + 0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32, + 0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36, + 0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A, + 0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E, + 0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42, + 0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B, + 0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D, + 0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3, + 0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393, + 0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6, + 0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B, + 0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA, + 0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5, + 0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B, + 0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C, + 0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4, + 0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8, + 0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0, + 0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C, + 0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473, + 0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489, + 0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469, + 0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431, + 0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0, + 0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA, + 0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1, + 0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5, + 0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538, + 0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A, + 0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48, + 0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C, + 0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50, + 0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54, + 0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58, + 0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C, + 0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60, + 0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64, + 0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C, + 0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1, + 0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6, + 0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD, + 0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3, + 0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8, + 0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF, + 0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9, + 0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD, + 0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7, + 0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3, + 0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1, + 0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6, + 0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE, + 0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C, + 0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018, + 0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC, + 0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564, + 0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543, + 0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8, + 0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE, + 0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7, + 0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC, + 0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629, + 0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08, + 0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955, + 0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22, + 0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C, + 0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA, + 0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322, + 0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343, + 0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A, + 0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC, + 0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC, + 0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF, + 0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452, + 0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441, + 0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C, + 0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484, + 0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C, + 0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027, + 0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B, + 0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032, + 0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039, + 0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040, + 0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048, + 0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C, + 0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056, + 0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D, + 0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061, + 0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069, + 0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F, + 0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073, + 0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079, + 0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E, + 0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086, + 0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C, + 0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090, + 0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098, + 0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F, + 0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7, + 0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD, + 0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD, + 0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7, + 0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0, + 0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2, + 0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B, + 0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F, + 0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8, + 0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406, + 0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454, + 0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457, + 0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482, + 0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464, + 0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476, + 0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD, + 0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7, + 0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472, + 0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF, + 0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC, + 0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD, + 0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7, + 0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3, + 0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511, + 0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F, + 0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541, + 0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C, + 0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8, + 0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD, + 0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6, + 0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE, + 0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4, + 0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC, + 0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2, + 0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7, + 0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC, + 0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103, + 0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108, + 0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C, + 0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110, + 0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114, + 0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118, + 0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D, + 0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124, + 0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128, + 0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C, + 0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132, + 0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136, + 0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B, + 0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F, + 0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144, + 0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576, + 0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C, + 0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1, + 0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F, + 0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B, + 0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594, + 0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9, + 0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC, + 0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4, + 0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3, + 0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5, + 0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608, + 0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623, + 0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D, + 0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C, + 0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C, + 0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664, + 0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C, + 0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4, + 0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5, + 0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704, + 0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F, + 0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31, + 0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147, + 0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154, + 0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159, + 0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160, + 0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B, + 0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B, + 0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182, + 0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188, + 0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193, + 0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197, + 0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D, + 0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1, + 0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7, + 0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC, + 0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3, + 0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9, + 0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE, + 0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2, + 0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6, + 0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2, + 0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6, + 0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA, + 0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF, + 0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3, + 0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44, + 0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61, + 0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90, + 0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99, + 0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5, + 0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB, + 0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7, + 0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB, + 0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27, + 0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E, + 0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E, + 0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B, + 0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B, + 0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82, + 0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7, + 0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82, + 0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95, + 0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD, + 0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61, + 0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7, + 0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE, + 0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF, + 0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7, + 0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA, + 0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9, + 0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED, + 0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1, + 0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5, + 0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9, + 0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD, + 0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201, + 0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205, + 0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209, + 0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D, + 0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211, + 0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215, + 0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219, + 0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D, + 0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221, + 0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225, + 0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229, + 0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D, + 0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231, + 0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235, + 0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239, + 0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D, + 0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241, + 0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245, + 0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321, + 0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315, + 0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C, + 0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D, + 0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F, + 0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7, + 0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967, + 0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B, + 0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D, + 0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A, + 0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993, + 0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91, + 0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0, + 0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3, + 0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB, + 0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4, + 0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003, + 0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4, + 0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA, + 0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035, + 0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D, + 0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F, + 0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B, + 0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247, + 0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B, + 0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F, + 0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253, + 0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257, + 0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B, + 0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F, + 0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263, + 0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267, + 0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B, + 0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F, + 0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273, + 0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278, + 0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C, + 0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280, + 0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284, + 0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288, + 0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C, + 0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291, + 0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295, + 0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299, + 0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D, + 0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1, + 0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5, + 0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D, + 0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D, + 0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B, + 0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD, + 0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4, + 0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123, + 0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B, + 0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194, + 0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5, + 0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB, + 0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6, + 0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604, + 0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B, + 0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612, + 0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619, + 0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215, + 0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A, + 0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94, + 0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74, + 0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0, + 0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8, + 0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0, + 0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE, + 0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE, + 0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB, + 0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0, + 0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4, + 0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8, + 0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC, + 0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0, + 0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4, + 0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9, + 0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD, + 0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1, + 0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5, + 0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9, + 0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD, + 0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1, + 0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5, + 0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9, + 0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED, + 0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1, + 0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5, + 0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9, + 0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD, + 0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301, + 0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305, + 0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309, + 0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43, + 0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19, + 0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E, + 0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52, + 0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F, + 0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93, + 0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C, + 0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5, + 0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0, + 0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9, + 0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE, + 0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B, + 0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53, + 0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44, + 0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0, + 0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7, + 0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7, + 0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2, + 0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47, + 0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F, + 0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A, + 0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D, + 0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C, + 0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B, + 0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F, + 0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313, + 0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317, + 0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B, + 0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F, + 0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323, + 0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327, + 0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B, + 0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F, + 0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333, + 0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337, + 0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B, + 0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340, + 0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344, + 0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348, + 0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C, + 0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350, + 0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354, + 0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358, + 0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C, + 0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360, + 0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364, + 0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368, + 0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7, + 0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1, + 0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF, + 0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039, + 0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80, + 0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5, + 0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434, + 0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0, + 0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3, + 0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4, + 0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8, + 0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026, + 0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021, + 0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F, + 0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050, + 0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B, + 0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082, + 0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50, + 0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B, + 0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71, + 0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A, + 0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C, + 0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983, + 0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3, + 0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F, + 0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373, + 0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377, + 0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B, + 0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F, + 0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383, + 0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387, + 0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B, + 0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390, + 0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394, + 0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398, + 0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C, + 0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0, + 0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4, + 0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8, + 0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC, + 0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0, + 0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4, + 0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8, + 0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC, + 0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0, + 0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4, + 0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8, + 0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD, + 0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E, + 0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF, + 0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06, + 0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8, + 0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32, + 0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13, + 0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55, + 0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC, + 0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A, + 0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2, + 0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3, + 0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8, + 0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16, + 0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15, + 0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73, + 0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75, + 0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F, + 0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85, + 0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92, + 0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B, + 0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0, + 0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7, + 0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5, + 0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF, + 0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3, + 0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8, + 0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC, + 0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0, + 0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4, + 0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8, + 0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC, + 0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0, + 0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4, + 0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8, + 0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC, + 0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400, + 0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404, + 0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408, + 0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C, + 0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410, + 0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414, + 0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418, + 0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C, + 0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420, + 0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424, + 0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428, + 0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C, + 0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0, + 0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2, + 0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0, + 0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0, + 0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE, + 0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D, + 0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE, + 0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07, + 0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F, + 0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19, + 0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21, + 0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25, + 0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B, + 0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30, + 0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35, + 0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E, + 0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE, + 0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2, + 0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0, + 0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9, + 0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7, + 0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F, + 0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425, + 0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C, + 0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432, + 0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436, + 0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A, + 0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F, + 0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443, + 0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447, + 0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B, + 0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F, + 0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453, + 0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457, + 0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B, + 0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F, + 0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463, + 0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467, + 0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C, + 0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470, + 0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474, + 0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478, + 0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C, + 0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480, + 0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484, + 0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7, + 0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA, + 0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520, + 0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C, + 0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477, + 0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E, + 0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B, + 0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490, + 0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA, + 0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753, + 0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5, + 0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798, + 0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E, + 0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C, + 0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A, + 0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9, + 0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD, + 0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2, + 0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832, + 0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E, + 0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883, + 0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841, + 0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A, + 0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F, + 0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B, + 0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F, + 0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533, + 0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B, + 0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E, + 0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578, + 0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C, + 0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581, + 0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585, + 0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589, + 0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D, + 0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591, + 0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595, + 0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599, + 0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D, + 0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1, + 0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5, + 0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9, + 0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD, + 0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1, + 0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5, + 0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9, + 0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD, + 0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1, + 0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5, + 0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9, + 0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0, + 0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3, + 0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960, + 0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B, + 0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934, + 0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE, + 0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979, + 0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB, + 0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1, + 0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0, + 0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED, + 0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2, + 0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50, + 0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79, + 0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C, + 0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97, + 0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81, + 0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92, + 0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B, + 0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D, + 0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75, + 0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79, + 0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81, + 0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B, + 0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF, + 0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3, + 0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7, + 0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB, + 0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF, + 0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3, + 0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7, + 0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613, + 0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620, + 0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626, + 0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B, + 0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630, + 0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A, + 0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A, + 0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652, + 0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658, + 0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D, + 0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665, + 0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E, + 0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673, + 0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B, + 0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F, + 0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683, + 0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A, + 0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98, + 0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217, + 0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221, + 0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7, + 0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F, + 0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE, + 0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619, + 0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600, + 0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634, + 0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006, + 0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F, + 0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677, + 0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D, + 0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6, + 0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36, + 0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45, + 0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47, + 0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7, + 0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE, + 0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E, + 0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F, + 0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B, + 0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308, + 0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E, + 0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695, + 0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D, + 0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1, + 0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5, + 0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA, + 0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE, + 0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4, + 0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA, + 0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3, + 0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0, + 0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6, + 0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA, + 0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE, + 0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3, + 0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7, + 0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE, + 0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4, + 0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB, + 0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702, + 0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B, + 0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712, + 0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718, + 0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D, + 0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8, + 0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD, + 0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07, + 0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18, + 0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29, + 0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535, + 0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252, + 0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216, + 0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC, + 0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB, + 0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7, + 0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB, + 0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD, + 0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB, + 0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D, + 0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715, + 0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E, + 0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148, + 0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159, + 0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169, + 0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167, + 0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182, + 0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA, + 0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB, + 0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724, + 0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728, + 0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E, + 0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734, + 0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A, + 0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F, + 0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743, + 0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747, + 0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B, + 0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F, + 0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755, + 0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C, + 0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764, + 0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A, + 0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E, + 0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772, + 0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779, + 0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E, + 0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782, + 0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787, + 0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C, + 0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793, + 0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799, + 0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D, + 0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37, + 0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59, + 0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5, + 0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40, + 0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51, + 0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4, + 0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2, + 0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096, + 0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7, + 0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA, + 0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F, + 0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168, + 0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178, + 0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5, + 0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4, + 0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228, + 0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9, + 0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248, + 0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946, + 0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953, + 0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960, + 0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985, + 0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3, + 0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F, + 0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5, + 0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9, + 0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0, + 0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6, + 0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA, + 0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE, + 0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2, + 0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6, + 0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA, + 0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE, + 0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2, + 0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6, + 0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA, + 0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE, + 0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2, + 0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8, + 0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1, + 0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8, + 0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC, + 0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800, + 0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804, + 0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808, + 0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C, + 0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D, + 0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059, + 0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D, + 0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB, + 0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F, + 0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6, + 0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817, + 0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D, + 0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A, + 0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825, + 0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E, + 0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826, + 0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A, + 0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887, + 0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2, + 0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9, + 0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905, + 0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E, + 0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB, + 0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D, + 0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A, + 0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726, + 0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751, + 0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768, + 0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812, + 0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816, + 0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A, + 0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E, + 0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822, + 0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826, + 0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A, + 0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E, + 0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832, + 0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836, + 0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A, + 0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E, + 0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842, + 0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846, + 0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A, + 0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E, + 0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852, + 0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856, + 0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A, + 0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E, + 0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862, + 0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866, + 0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A, + 0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E, + 0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D, + 0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791, + 0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5, + 0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E, + 0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572, + 0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61, + 0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74, + 0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E, + 0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485, + 0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A, + 0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490, + 0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A, + 0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4, + 0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC, + 0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4, + 0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9, + 0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF, + 0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA, + 0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE, + 0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5, + 0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8, + 0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0, + 0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7, + 0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870, + 0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874, + 0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895, + 0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9, + 0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD, + 0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1, + 0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5, + 0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9, + 0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD, + 0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1, + 0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5, + 0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9, + 0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD, + 0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6, + 0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD, + 0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3, + 0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9, + 0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED, + 0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1, + 0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5, + 0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9, + 0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD, + 0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901, + 0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905, + 0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB, + 0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4, + 0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC, + 0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502, + 0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A, + 0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512, + 0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516, + 0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E, + 0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B, + 0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532, + 0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538, + 0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542, + 0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546, + 0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F, + 0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556, + 0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B, + 0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561, + 0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566, + 0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A, + 0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571, + 0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7, + 0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED, + 0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47, + 0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14, + 0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B, + 0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911, + 0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915, + 0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919, + 0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D, + 0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921, + 0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925, + 0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929, + 0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D, + 0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932, + 0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936, + 0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A, + 0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E, + 0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942, + 0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946, + 0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A, + 0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E, + 0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952, + 0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958, + 0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C, + 0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960, + 0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966, + 0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B, + 0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989, + 0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF, + 0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E, + 0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE, + 0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22, + 0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B, + 0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36, + 0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A, + 0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44, + 0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49, + 0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51, + 0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B, + 0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66, + 0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A, + 0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D, + 0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596, + 0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3, + 0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4, + 0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2, + 0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8, + 0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7, + 0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF, + 0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C, + 0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618, + 0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E, + 0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D, + 0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1, + 0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6, + 0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB, + 0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF, + 0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3, + 0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7, + 0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB, + 0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF, + 0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3, + 0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7, + 0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB, + 0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF, + 0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3, + 0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7, + 0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB, + 0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF, + 0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3, + 0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7, + 0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB, + 0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF, + 0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3, + 0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7, + 0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C, + 0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D, + 0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643, + 0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E, + 0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B, + 0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78, + 0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88, + 0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC, + 0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864, + 0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F, + 0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7, + 0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE, + 0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A, + 0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0, + 0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B, + 0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936, + 0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B, + 0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC, + 0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C, + 0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026, + 0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031, + 0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046, + 0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071, + 0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883, + 0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD, + 0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01, + 0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05, + 0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09, + 0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D, + 0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11, + 0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15, + 0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19, + 0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D, + 0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21, + 0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25, + 0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29, + 0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D, + 0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31, + 0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35, + 0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39, + 0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D, + 0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41, + 0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45, + 0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49, + 0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D, + 0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51, + 0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55, + 0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59, + 0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F, + 0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E, + 0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5, + 0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C, + 0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C, + 0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B, + 0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3, + 0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6, + 0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0, + 0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9, + 0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1, + 0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0, + 0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF, + 0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707, + 0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D, + 0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E, + 0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E, + 0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729, + 0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722, + 0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760, + 0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B, + 0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764, + 0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF, + 0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B, + 0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F, + 0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63, + 0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67, + 0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B, + 0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D, + 0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99, + 0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB, + 0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF, + 0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5, + 0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE, + 0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6, + 0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA, + 0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0, + 0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6, + 0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB, + 0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0, + 0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5, + 0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA, + 0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1, + 0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5, + 0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA, + 0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF, + 0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04, + 0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788, + 0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783, + 0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5, + 0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD, + 0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB, + 0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816, + 0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B, + 0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36, + 0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210, + 0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03, + 0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B, + 0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A, + 0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20, + 0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E, + 0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45, + 0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60, + 0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72, + 0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7, + 0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8, + 0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2, + 0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1, + 0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5, + 0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE, + 0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B, + 0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B, + 0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10, + 0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15, + 0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19, + 0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D, + 0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22, + 0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27, + 0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B, + 0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30, + 0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35, + 0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39, + 0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F, + 0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B, + 0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52, + 0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57, + 0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B, + 0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F, + 0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63, + 0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67, + 0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B, + 0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F, + 0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73, + 0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77, + 0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B, + 0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38, + 0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201, + 0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844, + 0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D, + 0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238, + 0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E, + 0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F, + 0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E, + 0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF, + 0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7, + 0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C, + 0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C, + 0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC, + 0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC, + 0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7, + 0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF, + 0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1, + 0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3, + 0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE, + 0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4, + 0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91, + 0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47, + 0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E, + 0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D, + 0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81, + 0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85, + 0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89, + 0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D, + 0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91, + 0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95, + 0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99, + 0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D, + 0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1, + 0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5, + 0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9, + 0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD, + 0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1, + 0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5, + 0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9, + 0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD, + 0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1, + 0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5, + 0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9, + 0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD, + 0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1, + 0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5, + 0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9, + 0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161, + 0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D, + 0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179, + 0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D, + 0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA, + 0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5, + 0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E, + 0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59, + 0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC, + 0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7, + 0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF, + 0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7, + 0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB, + 0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14, + 0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E, + 0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40, + 0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31, + 0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51, + 0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76, + 0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85, + 0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C, + 0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A, + 0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B, + 0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC, + 0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF, + 0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3, + 0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7, + 0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB, + 0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF, + 0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3, + 0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7, + 0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB, + 0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF, + 0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03, + 0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07, + 0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B, + 0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F, + 0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13, + 0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17, + 0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B, + 0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F, + 0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23, + 0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27, + 0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B, + 0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F, + 0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33, + 0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37, + 0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B, + 0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E, + 0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3, + 0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708, + 0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D, + 0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83, + 0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88, + 0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE, + 0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC, + 0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF, + 0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8, + 0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F, + 0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82, + 0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88, + 0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90, + 0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95, + 0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F, + 0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3, + 0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8, + 0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE, + 0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3, + 0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7, + 0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD, + 0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7, + 0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D, + 0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41, + 0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45, + 0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49, + 0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D, + 0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51, + 0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55, + 0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59, + 0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D, + 0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61, + 0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65, + 0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69, + 0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D, + 0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71, + 0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75, + 0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79, + 0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E, + 0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89, + 0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93, + 0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99, + 0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF, + 0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0, + 0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9, + 0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB, + 0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD, + 0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3, + 0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8, + 0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF, + 0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791, + 0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB, + 0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1, + 0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6, + 0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0, + 0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC, + 0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47, + 0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51, + 0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955, + 0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6, + 0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED, + 0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13, + 0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE, + 0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88, + 0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D, + 0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD, + 0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9, + 0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF, + 0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39, + 0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44, + 0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6, + 0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA, + 0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE, + 0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2, + 0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6, + 0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA, + 0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE, + 0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02, + 0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06, + 0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A, + 0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E, + 0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12, + 0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16, + 0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A, + 0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E, + 0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22, + 0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26, + 0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A, + 0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E, + 0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32, + 0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36, + 0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A, + 0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E, + 0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42, + 0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46, + 0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A, + 0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E, + 0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52, + 0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56, + 0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A, + 0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E, + 0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62, + 0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66, + 0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A, + 0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E, + 0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72, + 0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76, + 0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A, + 0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E, + 0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82, + 0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86, + 0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A, + 0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E, + 0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92, + 0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96, + 0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A, + 0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E, + 0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2, + 0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6, + 0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA, + 0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE, + 0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2, + 0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6, + 0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA, + 0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE, + 0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2, + 0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6, + 0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA, + 0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE, + 0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2, + 0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6, + 0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA, + 0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE, + 0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2, + 0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6, + 0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA, + 0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE, + 0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2, + 0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6, + 0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA, + 0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE, + 0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02, + 0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06, + 0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A, + 0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E, + 0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12, + 0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16, + 0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A, + 0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E, + 0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30, + 0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40, + 0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53, + 0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D, + 0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62, + 0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72, + 0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77, + 0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B, + 0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81, + 0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86, + 0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D, + 0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91, + 0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97, + 0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B, + 0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1, + 0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5, + 0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA, + 0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE, + 0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2, + 0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7, + 0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF, + 0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3, + 0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8, + 0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0, + 0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6, + 0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE, + 0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6, + 0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED, + 0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2, + 0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6, + 0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD, + 0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02, + 0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06, + 0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A, + 0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12, + 0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18, + 0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D, + 0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23, + 0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27, + 0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B, + 0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31, + 0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35, + 0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C, + 0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42, + 0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47, + 0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B, + 0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F, + 0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55, + 0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59, + 0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D, + 0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61, + 0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65, + 0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69, + 0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D, + 0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71, + 0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75, + 0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79, + 0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D, + 0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D, + 0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91, + 0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95, + 0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C, + 0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2, + 0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C, + 0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1, + 0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F, + 0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18, + 0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23, + 0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29, + 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (src < 0x80) { /* ASCII */ + c = src; + } else { + if (dir) { /* OEMCP to unicode */ + p = oem2uni; + hi = sizeof(oem2uni) / 4 - 1; + } else { /* Unicode to OEMCP */ + p = uni2oem; + hi = sizeof(uni2oem) / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (src == p[i * 2]) break; + if (src > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/Lib/Fat/src/option/cc949.c b/Lib/Fat/src/option/cc949.c new file mode 100644 index 0000000..626268b --- /dev/null +++ b/Lib/Fat/src/option/cc949.c @@ -0,0 +1,8603 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ +/* */ +/* CP949 (Korean EUC-KR) */ +/*------------------------------------------------------------------------*/ + +#include "../ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 949 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7, + 0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6, + 0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5, + 0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6, + 0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA, + 0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF, + 0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1, + 0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD, + 0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5, + 0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8, + 0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0, + 0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB, + 0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0, + 0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD, + 0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3, + 0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7, + 0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB, + 0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF, + 0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3, + 0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7, + 0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3, + 0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7, + 0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB, + 0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF, + 0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3, + 0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7, + 0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2, + 0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6, + 0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB, + 0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF, + 0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3, + 0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7, + 0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB, + 0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF, + 0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2, + 0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6, + 0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB, + 0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF, + 0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3, + 0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7, + 0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB, + 0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF, + 0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA, + 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, + 0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6, + 0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8, + 0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC, + 0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9, + 0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5, + 0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7, + 0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD, + 0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2, + 0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6, + 0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1, + 0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5, + 0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9, + 0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6, + 0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8, + 0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1, + 0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4, + 0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3, + 0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4, + 0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD, + 0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3, + 0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD, + 0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5, + 0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED, + 0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7, + 0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7, + 0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB, + 0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF, + 0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3, + 0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8, + 0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC, + 0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0, + 0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4, + 0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF, + 0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3, + 0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7, + 0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB, + 0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF, + 0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3, + 0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD, + 0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1, + 0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5, + 0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9, + 0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD, + 0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1, + 0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5, + 0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2, + 0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7, + 0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1, + 0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5, + 0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3, + 0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9, + 0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC, + 0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD, + 0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0, + 0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2, + 0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4, + 0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6, + 0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8, + 0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA, + 0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0, + 0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0, + 0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4, + 0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0, + 0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB, + 0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3, + 0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5, + 0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF, + 0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD, + 0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA, + 0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0, + 0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC, + 0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE, + 0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC, + 0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2, + 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5, + 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, + 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD, + 0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1, + 0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5, + 0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9, + 0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD, + 0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1, + 0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5, + 0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9, + 0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD, + 0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1, + 0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5, + 0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9, + 0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD, + 0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1, + 0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5, + 0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9, + 0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD, + 0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1, + 0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5, + 0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9, + 0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED, + 0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1, + 0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2, + 0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6, + 0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA, + 0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE, + 0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2, + 0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6, + 0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA, + 0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE, + 0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2, + 0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6, + 0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA, + 0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE, + 0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2, + 0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6, + 0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA, + 0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE, + 0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2, + 0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6, + 0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA, + 0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE, + 0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2, + 0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6, + 0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4, + 0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8, + 0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC, + 0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0, + 0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4, + 0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8, + 0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC, + 0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0, + 0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4, + 0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8, + 0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC, + 0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0, + 0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4, + 0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8, + 0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC, + 0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0, + 0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4, + 0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8, + 0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC, + 0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0, + 0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4, + 0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8, + 0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC, + 0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2, + 0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6, + 0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA, + 0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE, + 0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2, + 0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6, + 0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA, + 0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1, + 0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5, + 0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9, + 0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD, + 0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1, + 0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5, + 0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9, + 0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE, + 0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC, + 0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC, + 0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7, + 0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6, + 0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2, + 0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC, + 0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0, + 0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4, + 0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA, + 0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6, + 0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2, + 0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1, + 0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5, + 0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE, + 0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2, + 0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3, + 0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF, + 0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5, + 0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF, + 0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9, + 0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2, + 0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB, + 0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0, + 0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA, + 0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1, + 0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9, + 0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9, + 0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA, + 0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC, + 0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB, + 0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0, + 0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6, + 0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6, + 0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1, + 0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB, + 0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5, + 0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2, + 0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF, + 0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2, + 0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE, + 0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4, + 0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0, + 0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5, + 0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1, + 0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1, + 0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4, + 0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7, + 0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC, + 0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9, + 0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5, + 0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD, + 0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0, + 0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6, + 0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD, + 0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA, + 0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5, + 0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5, + 0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB, + 0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4, + 0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF, + 0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC, + 0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF, + 0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1, + 0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8, + 0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA, + 0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7, + 0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2, + 0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6, + 0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9, + 0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE, + 0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF, + 0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8, + 0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA, + 0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0, + 0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2, + 0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2, + 0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9, + 0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8, + 0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2, + 0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1, + 0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3, + 0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3, + 0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC, + 0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA, + 0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE, + 0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE, + 0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2, + 0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC, + 0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0, + 0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC, + 0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7, + 0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF, + 0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2, + 0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0, + 0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB, + 0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5, + 0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE, + 0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7, + 0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD, + 0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC, + 0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0, + 0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB, + 0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE, + 0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1, + 0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE, + 0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9, + 0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9, + 0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1, + 0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4, + 0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2, + 0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6, + 0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8, + 0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1, + 0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2, + 0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7, + 0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4, + 0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE, + 0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1, + 0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9, + 0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4, + 0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF, + 0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6, + 0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1, + 0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF, + 0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF, + 0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF, + 0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB, + 0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED, + 0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8, + 0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0, + 0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1, + 0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2, + 0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4, + 0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2, + 0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE, + 0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6, + 0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3, + 0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA, + 0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3, + 0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE, + 0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5, + 0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF, + 0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9, + 0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1, + 0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2, + 0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC, + 0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA, + 0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA, + 0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0, + 0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF, + 0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8, + 0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9, + 0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6, + 0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6, + 0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2, + 0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA, + 0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3, + 0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA, + 0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0, + 0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7, + 0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4, + 0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0, + 0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8, + 0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9, + 0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF, + 0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF, + 0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF, + 0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4, + 0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6, + 0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD, + 0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8, + 0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE, + 0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF, + 0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0, + 0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9, + 0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5, + 0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0, + 0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3, + 0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7, + 0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF, + 0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2, + 0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0, + 0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2, + 0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8, + 0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC, + 0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED, + 0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE, + 0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB, + 0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3, + 0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3, + 0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2, + 0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA, + 0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2, + 0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5, + 0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB, + 0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5, + 0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4, + 0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD, + 0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC, + 0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE, + 0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4, + 0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE, + 0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC, + 0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1, + 0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5, + 0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8, + 0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8, + 0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC, + 0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7, + 0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF, + 0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4, + 0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8, + 0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9, + 0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5, + 0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4, + 0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE, + 0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9, + 0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1, + 0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF, + 0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6, + 0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4, + 0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8, + 0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE, + 0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8, + 0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC, + 0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC, + 0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3, + 0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE, + 0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6, + 0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF, + 0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5, + 0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF, + 0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED, + 0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC, + 0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5, + 0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF, + 0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1, + 0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9, + 0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5, + 0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB, + 0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2, + 0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9, + 0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB, + 0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC, + 0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6, + 0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB, + 0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0, + 0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4, + 0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2, + 0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE, + 0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3, + 0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6, + 0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5, + 0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD, + 0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA, + 0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA, + 0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5, + 0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5, + 0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7, + 0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB, + 0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0, + 0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0, + 0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1, + 0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6, + 0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF, + 0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0, + 0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA, + 0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1, + 0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7, + 0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5, + 0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0, + 0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9, + 0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF, + 0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3, + 0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3, + 0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE, + 0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1, + 0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9, + 0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC, + 0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6, + 0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB, + 0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA, + 0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE, + 0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9, + 0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB, + 0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9, + 0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2, + 0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8, + 0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE, + 0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB, + 0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA, + 0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8, + 0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6, + 0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5, + 0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7, + 0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1, + 0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0, + 0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1, + 0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD, + 0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF, + 0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4, + 0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE, + 0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF, + 0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD, + 0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9, + 0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0, + 0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3, + 0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5, + 0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7, + 0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3, + 0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD, + 0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC, + 0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7, + 0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8, + 0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB, + 0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1, + 0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5, + 0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8, + 0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF, + 0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1, + 0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1, + 0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6, + 0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0, + 0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9, + 0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2, + 0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED, + 0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA, + 0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3, + 0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3, + 0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC, + 0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3, + 0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0, + 0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3, + 0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7, + 0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5, + 0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9, + 0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE, + 0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3, + 0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7, + 0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6, + 0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4, + 0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3, + 0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB, + 0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2, + 0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8, + 0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA, + 0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4, + 0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8, + 0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB, + 0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB, + 0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC, + 0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4, + 0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4, + 0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8, + 0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3, + 0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6, + 0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA, + 0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5, + 0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB, + 0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC, + 0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1, + 0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8, + 0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6, + 0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7, + 0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0, + 0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC, + 0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC, + 0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0, + 0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2, + 0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA, + 0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB, + 0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9, + 0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4, + 0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9, + 0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF, + 0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7, + 0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9, + 0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3, + 0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3, + 0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1, + 0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB, + 0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4, + 0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA, + 0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8, + 0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA, + 0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6, + 0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7, + 0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE, + 0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5, + 0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8, + 0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2, + 0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA, + 0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6, + 0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0, + 0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD, + 0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA, + 0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC, + 0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6, + 0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5, + 0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4, + 0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9, + 0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD, + 0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2, + 0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2, + 0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7, + 0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA, + 0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC, + 0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7, + 0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5, + 0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6, + 0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0, + 0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9, + 0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2, + 0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED, + 0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2, + 0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA, + 0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA, + 0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4, + 0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB, + 0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA, + 0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0, + 0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0, + 0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4, + 0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1, + 0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC, + 0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8, + 0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7, + 0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9, + 0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF, + 0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD, + 0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB, + 0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4, + 0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6, + 0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA, + 0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7, + 0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5, + 0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5, + 0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6, + 0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA, + 0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6, + 0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC, + 0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB, + 0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7, + 0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2, + 0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1, + 0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4, + 0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5, + 0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD, + 0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5, + 0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6, + 0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4, + 0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE, + 0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB, + 0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2, + 0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD, + 0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC, + 0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2, + 0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3, + 0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6, + 0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF, + 0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3, + 0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE, + 0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA, + 0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1, + 0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8, + 0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE, + 0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD, + 0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2, + 0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9, + 0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9, + 0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC, + 0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE, + 0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2, + 0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4, + 0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA, + 0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6, + 0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8, + 0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5, + 0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7, + 0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5, + 0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1, + 0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8, + 0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF, + 0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4, + 0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3, + 0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE, + 0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4, + 0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9, + 0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8, + 0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5, + 0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0, + 0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC, + 0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7, + 0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA, + 0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9, + 0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4, + 0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5, + 0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE, + 0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2, + 0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE, + 0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED, + 0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2, + 0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7, + 0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE, + 0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2, + 0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE, + 0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8, + 0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1, + 0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6, + 0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9, + 0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB, + 0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC, + 0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC, + 0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE, + 0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2, + 0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD, + 0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8, + 0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0, + 0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1, + 0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD, + 0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE, + 0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0, + 0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9, + 0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA, + 0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8, + 0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB, + 0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE, + 0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1, + 0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD, + 0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD, + 0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB, + 0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6, + 0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE, + 0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA, + 0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6, + 0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9, + 0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0, + 0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD, + 0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7, + 0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5, + 0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB, + 0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF, + 0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9, + 0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC, + 0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD, + 0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1, + 0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3, + 0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE, + 0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7, + 0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7, + 0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2, + 0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0, + 0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC, + 0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2, + 0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4, + 0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE, + 0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB, + 0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD, + 0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9, + 0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC, + 0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7, + 0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3, + 0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9, + 0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6, + 0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA, + 0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1, + 0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7, + 0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF, + 0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5, + 0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3, + 0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4, + 0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC, + 0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC, + 0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2, + 0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE, + 0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6, + 0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8, + 0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2, + 0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB, + 0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1, + 0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4, + 0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD, + 0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6, + 0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8, + 0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD, + 0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD, + 0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4, + 0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9, + 0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE, + 0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA, + 0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE, + 0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB, + 0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5, + 0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD, + 0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7, + 0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA, + 0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9, + 0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3, + 0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0, + 0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE, + 0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6, + 0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB, + 0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC, + 0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5, + 0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1, + 0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC, + 0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0, + 0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE, + 0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3, + 0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7, + 0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9, + 0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8, + 0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7, + 0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2, + 0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD, + 0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7, + 0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7, + 0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3, + 0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3, + 0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB, + 0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3, + 0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA, + 0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3, + 0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0, + 0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5, + 0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0, + 0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3, + 0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4, + 0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA, + 0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9, + 0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED, + 0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA, + 0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3, + 0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2, + 0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC, + 0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4, + 0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC, + 0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD, + 0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB, + 0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC, + 0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD, + 0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6, + 0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB, + 0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1, + 0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0, + 0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE, + 0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4, + 0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF, + 0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2, + 0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD, + 0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE, + 0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB, + 0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD, + 0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1, + 0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2, + 0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0, + 0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9, + 0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3, + 0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8, + 0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2, + 0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7, + 0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0, + 0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB, + 0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE, + 0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA, + 0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE, + 0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF, + 0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4, + 0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4, + 0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7, + 0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5, + 0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9, + 0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4, + 0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC, + 0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5, + 0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF, + 0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE, + 0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2, + 0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5, + 0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8, + 0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA, + 0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6, + 0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2, + 0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA, + 0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2, + 0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6, + 0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC, + 0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0, + 0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1, + 0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6, + 0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB, + 0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6, + 0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC, + 0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5, + 0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB, + 0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD, + 0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC, + 0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3, + 0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF, + 0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1, + 0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD, + 0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7, + 0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF, + 0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7, + 0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD, + 0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2, + 0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE, + 0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9, + 0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA, + 0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5, + 0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD, + 0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3, + 0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB, + 0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9, + 0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3, + 0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED, + 0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8, + 0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5, + 0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8, + 0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5, + 0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4, + 0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8, + 0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3, + 0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5, + 0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE, + 0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4, + 0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6, + 0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8, + 0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE, + 0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB, + 0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC, + 0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE, + 0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6, + 0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9, + 0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA, + 0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC, + 0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA, + 0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3, + 0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA, + 0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB, + 0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA, + 0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4, + 0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1, + 0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC, + 0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE, + 0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2, + 0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF, + 0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2, + 0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4, + 0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7, + 0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2, + 0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE, + 0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA, + 0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE, + 0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF, + 0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5, + 0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA, + 0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD, + 0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB, + 0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8, + 0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9, + 0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9, + 0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD, + 0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9, + 0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF, + 0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF, + 0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7, + 0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE, + 0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9, + 0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF, + 0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4, + 0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB, + 0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6, + 0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0, + 0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7, + 0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3, + 0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC, + 0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF, + 0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5, + 0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7, + 0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF, + 0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7, + 0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1, + 0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF, + 0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5, + 0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6, + 0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5, + 0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8, + 0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8, + 0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE, + 0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA, + 0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5, + 0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5, + 0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3, + 0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0, + 0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6, + 0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA, + 0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD, + 0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0, + 0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0, + 0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3, + 0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4, + 0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8, + 0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9, + 0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5, + 0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF, + 0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2, + 0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA, + 0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE, + 0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE, + 0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8, + 0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8, + 0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8, + 0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7, + 0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7, + 0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8, + 0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7, + 0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5, + 0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE, + 0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4, + 0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD, + 0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0, + 0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9, + 0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2, + 0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC, + 0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB, + 0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF, + 0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6, + 0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8, + 0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2, + 0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE, + 0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0, + 0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD, + 0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7, + 0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6, + 0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB, + 0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1, + 0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC, + 0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3, + 0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6, + 0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD, + 0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB, + 0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3, + 0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE, + 0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC, + 0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6, + 0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED, + 0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB, + 0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6, + 0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0, + 0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF, + 0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF, + 0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE, + 0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC, + 0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9, + 0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6, + 0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4, + 0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3, + 0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3, + 0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE, + 0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4, + 0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB, + 0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6, + 0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD, + 0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0, + 0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE, + 0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8, + 0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2, + 0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9, + 0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA, + 0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE, + 0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB, + 0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF, + 0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2, + 0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC, + 0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4, + 0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA, + 0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6, + 0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC, + 0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4, + 0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD, + 0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0, + 0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF, + 0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8, + 0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD, + 0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5, + 0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8, + 0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4, + 0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA, + 0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6, + 0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE, + 0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1, + 0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB, + 0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD, + 0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA, + 0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9, + 0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0, + 0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2, + 0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD, + 0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9, + 0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1, + 0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1, + 0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0, + 0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD, + 0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF, + 0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB, + 0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3, + 0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5, + 0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3, + 0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5, + 0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5, + 0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE, + 0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE, + 0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED, + 0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0, + 0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4, + 0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9, + 0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD, + 0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7, + 0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2, + 0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8, + 0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA, + 0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE, + 0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC, + 0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5, + 0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB, + 0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD, + 0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4, + 0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE, + 0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5, + 0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5, + 0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE, + 0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9, + 0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB, + 0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1, + 0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8, + 0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2, + 0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE, + 0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC, + 0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4, + 0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE, + 0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA, + 0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC, + 0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7, + 0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB, + 0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2, + 0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1, + 0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8, + 0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE, + 0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8, + 0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF, + 0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9, + 0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC, + 0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5, + 0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA, + 0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3, + 0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE, + 0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6, + 0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3, + 0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE, + 0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4, + 0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8, + 0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3, + 0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5, + 0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9, + 0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC, + 0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD, + 0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC, + 0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0, + 0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8, + 0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD, + 0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1, + 0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED, + 0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9, + 0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8, + 0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9, + 0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3, + 0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5, + 0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF, + 0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0, + 0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6, + 0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8, + 0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB, + 0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3, + 0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8, + 0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5, + 0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC, + 0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4, + 0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4, + 0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3, + 0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE, + 0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF, + 0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC, + 0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB, + 0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB, + 0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1, + 0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9, + 0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5, + 0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5, + 0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5, + 0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE, + 0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2, + 0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4, + 0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC, + 0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3, + 0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8, + 0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6, + 0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA, + 0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE, + 0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9, + 0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0, + 0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA, + 0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE, + 0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD, + 0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD, + 0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE, + 0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE, + 0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8, + 0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA, + 0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6, + 0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7, + 0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7, + 0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9, + 0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1, + 0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD, + 0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF, + 0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8, + 0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1, + 0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1, + 0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4, + 0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5, + 0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4, + 0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6, + 0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE, + 0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6, + 0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA, + 0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0, + 0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6, + 0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD, + 0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD, + 0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4, + 0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE, + 0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7, + 0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0, + 0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD, + 0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8, + 0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1, + 0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3, + 0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC, + 0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2, + 0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3, + 0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD, + 0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD, + 0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8, + 0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4, + 0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC, + 0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED, + 0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC, + 0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9, + 0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE, + 0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2, + 0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9, + 0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7, + 0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA, + 0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5, + 0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7, + 0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8, + 0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7, + 0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2, + 0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6, + 0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1, + 0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8, + 0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8, + 0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4, + 0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3, + 0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0, + 0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5, + 0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB, + 0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5, + 0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1, + 0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD, + 0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE, + 0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2, + 0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0, + 0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE, + 0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3, + 0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4, + 0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC, + 0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6, + 0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6, + 0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE, + 0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA, + 0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3, + 0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6, + 0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5, + 0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5, + 0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9, + 0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2, + 0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1, + 0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF, + 0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD, + 0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2, + 0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1, + 0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC, + 0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE, + 0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4, + 0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3, + 0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD, + 0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7, + 0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7, + 0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4, + 0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4, + 0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA, + 0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5, + 0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9, + 0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA, + 0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF, + 0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2, + 0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED, + 0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7, + 0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8, + 0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6, + 0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2, + 0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9, + 0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3, + 0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3, + 0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD, + 0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB, + 0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6, + 0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7, + 0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5, + 0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9, + 0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF, + 0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA, + 0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE, + 0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5, + 0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9, + 0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC, + 0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2, + 0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF, + 0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD, + 0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8, + 0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9, + 0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE, + 0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0, + 0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0, + 0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9, + 0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4, + 0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2, + 0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA, + 0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5, + 0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB, + 0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7, + 0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6, + 0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1, + 0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4, + 0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8, + 0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0, + 0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC, + 0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD, + 0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE, + 0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE, + 0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED, + 0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD, + 0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB, + 0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8, + 0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB, + 0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3, + 0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA, + 0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD, + 0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5, + 0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1, + 0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6, + 0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB, + 0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF, + 0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142, + 0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4, + 0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145, + 0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149, + 0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB, + 0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF, + 0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2, + 0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C, + 0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F, + 0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152, + 0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156, + 0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9, + 0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159, + 0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163, + 0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165, + 0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168, + 0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B, + 0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F, + 0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0, + 0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175, + 0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179, + 0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182, + 0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185, + 0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188, + 0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C, + 0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190, + 0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194, + 0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198, + 0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A, + 0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8, + 0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E, + 0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2, + 0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD, + 0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4, + 0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3, + 0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8, + 0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB, + 0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE, + 0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2, + 0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9, + 0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5, + 0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9, + 0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA, + 0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0, + 0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF, + 0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3, + 0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4, + 0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6, + 0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9, + 0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC, + 0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF, + 0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2, + 0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6, + 0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC, + 0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC, + 0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0, + 0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2, + 0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0, + 0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6, + 0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4, + 0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7, + 0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB, + 0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF, + 0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1, + 0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4, + 0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6, + 0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA, + 0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3, + 0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE, + 0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244, + 0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247, + 0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A, + 0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D, + 0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251, + 0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254, + 0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256, + 0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A, + 0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262, + 0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265, + 0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268, + 0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C, + 0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1, + 0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270, + 0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274, + 0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277, + 0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A, + 0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283, + 0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287, + 0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7, + 0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D, + 0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291, + 0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293, + 0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB, + 0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296, + 0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF, + 0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2, + 0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C, + 0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0, + 0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2, + 0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5, + 0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8, + 0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC, + 0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0, + 0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2, + 0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6, + 0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9, + 0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD, + 0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1, + 0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5, + 0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC, + 0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC, + 0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0, + 0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2, + 0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5, + 0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8, + 0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC, + 0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3, + 0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1, + 0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5, + 0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8, + 0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB, + 0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE, + 0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2, + 0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6, + 0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA, + 0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE, + 0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342, + 0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA, + 0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346, + 0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A, + 0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF, + 0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E, + 0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352, + 0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355, + 0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359, + 0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363, + 0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367, + 0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B, + 0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F, + 0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373, + 0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375, + 0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5, + 0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379, + 0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383, + 0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA, + 0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386, + 0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389, + 0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A, + 0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D, + 0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F, + 0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393, + 0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6, + 0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396, + 0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399, + 0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B, + 0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E, + 0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1, + 0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5, + 0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2, + 0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8, + 0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC, + 0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE, + 0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2, + 0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5, + 0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9, + 0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD, + 0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1, + 0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5, + 0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9, + 0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD, + 0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1, + 0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5, + 0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9, + 0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD, + 0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1, + 0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2, + 0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5, + 0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8, + 0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC, + 0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF, + 0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF, + 0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3, + 0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5, + 0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8, + 0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC, + 0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442, + 0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6, + 0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447, + 0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B, + 0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E, + 0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451, + 0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454, + 0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458, + 0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB, + 0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464, + 0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467, + 0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A, + 0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E, + 0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472, + 0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476, + 0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A, + 0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484, + 0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488, + 0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A, + 0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C, + 0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F, + 0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493, + 0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6, + 0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9, + 0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499, + 0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B, + 0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F, + 0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2, + 0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6, + 0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA, + 0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC, + 0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0, + 0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2, + 0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6, + 0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA, + 0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE, + 0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2, + 0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5, + 0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9, + 0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC, + 0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF, + 0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2, + 0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6, + 0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8, + 0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB, + 0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF, + 0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2, + 0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6, + 0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA, + 0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE, + 0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2, + 0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6, + 0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA, + 0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC, + 0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541, + 0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544, + 0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD, + 0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0, + 0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A, + 0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E, + 0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551, + 0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555, + 0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558, + 0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562, + 0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566, + 0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568, + 0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C, + 0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E, + 0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571, + 0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574, + 0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578, + 0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A, + 0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583, + 0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587, + 0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A, + 0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D, + 0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590, + 0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594, + 0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596, + 0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A, + 0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E, + 0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1, + 0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5, + 0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9, + 0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD, + 0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1, + 0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5, + 0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9, + 0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB, + 0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD, + 0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF, + 0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA, + 0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD, + 0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6, + 0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9, + 0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD, + 0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1, + 0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5, + 0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9, + 0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD, + 0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1, + 0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5, + 0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7, + 0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA, + 0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED, + 0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1, + 0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8, + 0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5, + 0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9, + 0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA, + 0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE, + 0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD, + 0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643, + 0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4, + 0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8, + 0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA, + 0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648, + 0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B, + 0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E, + 0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652, + 0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1, + 0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655, + 0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659, + 0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661, + 0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664, + 0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667, + 0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B, + 0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E, + 0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671, + 0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675, + 0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679, + 0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683, + 0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687, + 0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B, + 0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F, + 0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693, + 0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697, + 0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC, + 0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B, + 0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0, + 0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0, + 0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3, + 0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3, + 0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6, + 0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8, + 0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB, + 0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE, + 0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2, + 0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD, + 0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5, + 0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9, + 0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB, + 0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE, + 0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1, + 0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5, + 0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7, + 0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9, + 0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC, + 0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF, + 0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2, + 0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6, + 0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA, + 0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE, + 0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2, + 0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6, + 0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8, + 0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB, + 0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED, + 0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1, + 0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2, + 0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5, + 0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5, + 0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA, + 0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD, + 0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742, + 0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746, + 0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A, + 0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D, + 0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751, + 0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755, + 0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759, + 0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763, + 0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767, + 0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B, + 0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F, + 0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773, + 0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776, + 0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779, + 0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782, + 0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786, + 0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1, + 0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B, + 0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F, + 0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791, + 0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794, + 0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797, + 0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B, + 0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7, + 0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0, + 0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4, + 0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6, + 0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC, + 0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB, + 0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF, + 0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0, + 0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3, + 0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7, + 0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA, + 0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE, + 0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2, + 0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6, + 0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA, + 0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD, + 0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1, + 0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4, + 0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8, + 0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC, + 0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0, + 0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4, + 0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8, + 0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC, + 0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF, + 0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2, + 0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5, + 0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9, + 0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB, + 0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841, + 0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845, + 0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847, + 0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B, + 0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E, + 0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852, + 0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854, + 0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857, + 0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861, + 0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863, + 0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866, + 0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867, + 0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B, + 0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8, + 0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E, + 0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871, + 0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874, + 0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877, + 0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A, + 0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884, + 0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888, + 0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C, + 0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890, + 0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892, + 0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895, + 0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897, + 0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B, + 0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6, + 0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F, + 0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2, + 0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3, + 0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD, + 0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1, + 0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2, + 0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5, + 0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9, + 0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA, + 0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE, + 0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1, + 0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4, + 0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8, + 0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1, + 0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB, + 0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF, + 0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2, + 0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6, + 0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA, + 0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE, + 0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2, + 0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6, + 0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA, + 0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE, + 0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2, + 0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6, + 0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA, + 0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE, + 0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2, + 0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6, + 0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7, + 0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9, + 0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC, + 0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE, + 0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1, + 0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3, + 0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946, + 0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948, + 0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B, + 0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E, + 0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952, + 0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB, + 0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955, + 0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959, + 0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962, + 0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965, + 0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968, + 0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C, + 0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970, + 0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972, + 0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976, + 0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979, + 0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982, + 0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986, + 0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A, + 0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E, + 0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992, + 0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996, + 0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998, + 0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8, + 0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C, + 0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F, + 0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE, + 0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0, + 0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5, + 0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8, + 0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB, + 0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE, + 0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2, + 0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6, + 0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA, + 0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE, + 0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1, + 0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5, + 0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9, + 0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD, + 0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1, + 0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4, + 0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8, + 0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB, + 0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE, + 0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1, + 0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5, + 0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC, + 0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA, + 0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE, + 0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1, + 0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5, + 0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9, + 0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD, + 0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43, + 0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47, + 0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B, + 0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D, + 0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50, + 0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53, + 0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57, + 0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4, + 0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61, + 0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65, + 0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68, + 0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C, + 0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70, + 0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74, + 0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78, + 0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81, + 0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85, + 0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88, + 0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C, + 0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90, + 0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94, + 0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98, + 0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B, + 0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F, + 0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2, + 0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5, + 0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8, + 0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC, + 0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE, + 0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1, + 0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5, + 0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8, + 0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB, + 0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE, + 0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2, + 0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5, + 0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8, + 0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC, + 0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE, + 0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8, + 0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2, + 0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6, + 0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED, + 0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA, + 0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE, + 0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1, + 0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5, + 0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9, + 0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED, + 0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1, + 0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5, + 0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9, + 0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB, + 0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3, + 0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42, + 0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46, + 0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7, + 0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48, + 0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C, + 0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E, + 0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51, + 0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54, + 0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58, + 0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3, + 0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61, + 0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6, + 0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66, + 0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69, + 0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C, + 0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70, + 0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD, + 0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73, + 0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77, + 0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81, + 0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85, + 0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89, + 0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D, + 0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91, + 0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95, + 0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99, + 0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D, + 0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1, + 0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5, + 0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9, + 0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD, + 0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1, + 0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5, + 0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7, + 0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA, + 0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5, + 0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF, + 0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8, + 0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2, + 0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB, + 0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7, + 0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA, + 0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD, + 0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1, + 0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2, + 0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4, + 0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8, + 0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB, + 0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF, + 0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3, + 0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7, + 0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB, + 0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE, + 0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2, + 0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6, + 0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA, + 0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE, + 0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44, + 0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48, + 0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C, + 0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50, + 0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52, + 0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55, + 0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58, + 0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62, + 0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66, + 0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69, + 0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D, + 0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70, + 0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74, + 0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77, + 0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81, + 0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85, + 0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89, + 0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D, + 0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90, + 0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94, + 0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98, + 0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C, + 0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0, + 0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4, + 0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8, + 0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB, + 0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE, + 0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2, + 0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6, + 0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA, + 0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE, + 0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2, + 0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6, + 0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA, + 0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE, + 0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2, + 0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6, + 0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA, + 0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE, + 0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0, + 0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3, + 0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6, + 0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5, + 0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC, + 0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF, + 0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3, + 0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7, + 0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB, + 0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41, + 0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45, + 0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49, + 0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D, + 0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51, + 0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54, + 0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58, + 0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62, + 0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66, + 0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A, + 0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E, + 0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72, + 0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75, + 0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78, + 0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81, + 0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85, + 0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87, + 0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A, + 0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E, + 0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92, + 0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96, + 0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A, + 0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E, + 0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2, + 0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6, + 0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA, + 0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC, + 0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2, + 0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1, + 0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5, + 0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6, + 0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA, + 0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE, + 0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1, + 0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4, + 0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7, + 0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB, + 0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD, + 0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1, + 0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5, + 0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8, + 0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB, + 0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE, + 0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2, + 0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1, + 0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6, + 0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA, + 0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC, + 0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF, + 0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2, + 0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6, + 0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9, + 0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8, + 0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE, + 0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC, + 0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41, + 0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44, + 0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48, + 0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7, + 0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B, + 0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F, + 0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51, + 0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54, + 0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58, + 0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62, + 0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD, + 0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68, + 0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C, + 0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70, + 0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74, + 0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78, + 0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82, + 0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86, + 0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A, + 0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E, + 0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90, + 0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93, + 0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96, + 0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A, + 0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5, + 0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D, + 0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8, + 0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2, + 0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5, + 0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8, + 0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC, + 0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF, + 0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0, + 0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4, + 0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6, + 0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9, + 0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC, + 0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0, + 0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7, + 0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3, + 0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7, + 0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA, + 0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD, + 0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1, + 0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5, + 0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD, + 0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB, + 0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF, + 0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1, + 0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4, + 0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7, + 0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB, + 0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4, + 0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF, + 0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3, + 0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6, + 0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9, + 0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD, + 0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43, + 0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47, + 0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A, + 0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E, + 0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52, + 0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56, + 0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A, + 0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64, + 0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68, + 0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B, + 0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F, + 0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72, + 0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75, + 0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78, + 0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82, + 0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF, + 0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86, + 0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A, + 0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D, + 0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90, + 0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93, + 0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97, + 0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5, + 0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C, + 0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0, + 0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2, + 0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5, + 0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8, + 0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC, + 0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED, + 0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0, + 0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4, + 0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7, + 0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB, + 0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF, + 0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3, + 0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7, + 0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA, + 0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE, + 0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1, + 0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5, + 0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9, + 0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD, + 0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1, + 0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5, + 0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9, + 0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB, + 0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE, + 0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1, + 0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5, + 0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7, + 0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA, + 0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE, + 0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042, + 0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045, + 0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048, + 0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C, + 0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1, + 0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050, + 0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054, + 0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056, + 0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059, + 0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062, + 0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066, + 0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9, + 0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069, + 0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B, + 0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F, + 0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073, + 0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077, + 0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081, + 0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085, + 0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089, + 0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D, + 0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F, + 0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092, + 0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095, + 0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099, + 0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4, + 0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D, + 0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1, + 0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3, + 0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA, + 0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5, + 0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9, + 0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0, + 0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC, + 0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4, + 0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0, + 0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3, + 0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6, + 0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA, + 0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB, + 0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC, + 0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0, + 0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2, + 0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6, + 0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9, + 0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD, + 0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1, + 0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4, + 0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8, + 0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC, + 0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0, + 0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4, + 0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8, + 0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC, + 0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0, + 0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4, + 0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6, + 0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9, + 0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB, + 0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141, + 0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA, + 0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144, + 0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD, + 0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149, + 0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C, + 0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F, + 0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153, + 0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4, + 0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156, + 0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A, + 0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162, + 0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165, + 0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168, + 0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C, + 0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB, + 0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE, + 0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174, + 0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177, + 0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181, + 0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185, + 0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189, + 0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D, + 0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191, + 0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195, + 0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2, + 0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199, + 0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B, + 0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F, + 0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8, + 0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3, + 0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7, + 0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA, + 0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD, + 0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1, + 0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5, + 0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9, + 0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB, + 0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF, + 0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3, + 0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7, + 0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB, + 0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF, + 0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3, + 0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7, + 0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB, + 0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE, + 0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1, + 0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4, + 0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8, + 0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4, + 0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED, + 0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1, + 0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4, + 0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7, + 0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA, + 0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE, + 0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA, + 0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246, + 0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A, + 0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B, + 0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF, + 0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E, + 0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252, + 0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5, + 0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256, + 0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8, + 0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261, + 0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264, + 0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267, + 0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B, + 0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD, + 0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271, + 0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275, + 0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278, + 0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282, + 0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286, + 0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A, + 0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E, + 0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292, + 0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296, + 0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299, + 0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C, + 0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F, + 0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3, + 0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7, + 0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB, + 0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF, + 0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2, + 0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5, + 0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8, + 0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC, + 0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6, + 0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2, + 0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6, + 0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9, + 0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC, + 0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF, + 0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3, + 0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB, + 0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9, + 0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD, + 0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1, + 0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5, + 0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9, + 0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED, + 0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1, + 0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5, + 0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9, + 0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB, + 0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF, + 0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341, + 0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345, + 0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4, + 0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7, + 0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A, + 0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC, + 0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE, + 0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2, + 0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350, + 0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5, + 0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354, + 0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357, + 0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359, + 0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362, + 0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365, + 0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369, + 0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE, + 0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C, + 0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F, + 0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371, + 0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374, + 0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378, + 0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382, + 0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385, + 0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389, + 0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D, + 0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391, + 0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395, + 0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399, + 0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D, + 0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1, + 0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5, + 0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9, + 0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB, + 0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9, + 0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF, + 0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3, + 0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE, + 0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6, + 0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA, + 0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC, + 0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6, + 0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1, + 0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5, + 0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA, + 0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8, + 0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC, + 0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE, + 0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1, + 0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4, + 0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8, + 0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2, + 0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC, + 0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF, + 0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2, + 0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5, + 0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9, + 0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED, + 0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1, + 0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5, + 0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9, + 0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA, + 0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD, + 0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442, + 0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446, + 0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF, + 0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A, + 0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E, + 0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451, + 0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454, + 0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458, + 0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462, + 0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466, + 0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469, + 0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D, + 0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470, + 0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474, + 0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478, + 0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482, + 0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486, + 0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489, + 0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D, + 0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F, + 0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492, + 0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495, + 0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499, + 0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B, + 0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F, + 0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3, + 0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6, + 0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9, + 0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD, + 0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1, + 0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5, + 0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9, + 0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD, + 0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF, + 0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1, + 0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2, + 0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6, + 0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7, + 0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA, + 0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC, + 0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF, + 0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3, + 0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6, + 0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA, + 0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE, + 0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1, + 0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5, + 0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8, + 0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC, + 0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0, + 0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4, + 0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8, + 0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC, + 0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542, + 0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544, + 0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547, + 0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A, + 0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E, + 0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552, + 0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555, + 0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559, + 0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562, + 0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565, + 0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568, + 0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C, + 0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8, + 0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571, + 0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575, + 0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577, + 0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A, + 0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583, + 0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587, + 0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0, + 0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C, + 0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590, + 0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594, + 0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598, + 0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C, + 0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0, + 0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4, + 0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8, + 0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC, + 0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE, + 0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1, + 0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3, + 0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7, + 0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8, + 0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB, + 0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD, + 0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF, + 0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2, + 0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4, + 0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8, + 0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5, + 0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB, + 0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8, + 0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0, + 0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3, + 0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6, + 0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA, + 0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF, + 0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD, + 0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1, + 0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3, + 0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7, + 0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB, + 0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF, + 0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2, + 0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6, + 0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA, + 0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE, + 0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644, + 0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648, + 0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C, + 0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650, + 0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654, + 0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658, + 0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A, + 0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8, + 0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665, + 0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669, + 0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB, + 0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D, + 0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671, + 0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674, + 0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678, + 0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682, + 0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686, + 0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A, + 0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D, + 0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691, + 0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693, + 0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697, + 0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B, + 0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F, + 0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4, + 0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2, + 0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6, + 0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA, + 0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE, + 0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2, + 0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6, + 0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA, + 0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE, + 0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2, + 0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4, + 0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7, + 0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA, + 0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE, + 0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0, + 0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3, + 0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7, + 0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB, + 0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF, + 0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3, + 0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7, + 0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB, + 0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF, + 0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3, + 0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7, + 0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB, + 0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741, + 0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745, + 0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749, + 0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D, + 0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751, + 0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754, + 0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758, + 0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762, + 0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766, + 0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A, + 0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E, + 0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772, + 0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775, + 0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779, + 0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783, + 0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787, + 0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B, + 0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E, + 0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792, + 0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794, + 0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797, + 0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A, + 0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E, + 0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6, + 0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3, + 0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7, + 0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB, + 0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF, + 0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3, + 0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7, + 0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB, + 0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF, + 0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3, + 0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7, + 0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB, + 0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF, + 0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3, + 0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7, + 0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB, + 0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF, + 0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3, + 0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7, + 0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB, + 0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF, + 0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3, + 0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7, + 0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB, + 0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE, + 0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844, + 0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848, + 0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C, + 0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850, + 0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853, + 0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857, + 0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A, + 0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863, + 0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866, + 0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A, + 0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C, + 0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870, + 0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874, + 0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878, + 0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882, + 0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886, + 0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A, + 0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E, + 0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892, + 0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896, + 0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898, + 0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B, + 0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E, + 0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2, + 0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5, + 0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6, + 0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA, + 0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9, + 0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB, + 0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE, + 0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2, + 0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1, + 0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5, + 0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8, + 0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA, + 0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD, + 0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0, + 0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4, + 0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB, + 0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7, + 0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB, + 0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD, + 0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0, + 0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3, + 0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7, + 0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6, + 0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB, + 0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF, + 0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2, + 0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5, + 0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8, + 0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC, + 0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF, + 0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2, + 0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6, + 0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0, + 0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2, + 0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5, + 0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD, + 0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8, + 0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942, + 0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945, + 0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947, + 0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A, + 0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D, + 0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951, + 0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2, + 0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954, + 0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958, + 0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A, + 0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963, + 0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966, + 0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A, + 0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB, + 0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D, + 0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971, + 0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974, + 0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977, + 0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A, + 0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984, + 0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988, + 0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B, + 0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F, + 0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990, + 0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993, + 0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995, + 0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999, + 0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA, + 0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D, + 0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0, + 0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2, + 0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5, + 0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8, + 0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC, + 0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0, + 0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3, + 0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7, + 0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA, + 0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD, + 0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0, + 0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4, + 0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6, + 0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9, + 0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD, + 0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0, + 0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3, + 0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6, + 0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA, + 0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED, + 0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF, + 0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3, + 0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5, + 0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8, + 0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB, + 0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF, + 0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4, + 0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3, + 0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7, + 0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9, + 0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9, + 0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE, + 0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44, + 0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD, + 0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1, + 0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49, + 0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C, + 0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50, + 0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54, + 0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58, + 0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62, + 0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65, + 0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69, + 0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B, + 0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E, + 0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71, + 0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75, + 0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78, + 0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81, + 0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85, + 0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87, + 0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A, + 0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D, + 0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91, + 0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2, + 0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95, + 0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99, + 0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B, + 0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F, + 0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2, + 0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6, + 0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8, + 0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB, + 0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF, + 0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1, + 0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4, + 0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6, + 0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA, + 0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1, + 0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE, + 0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2, + 0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6, + 0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA, + 0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE, + 0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2, + 0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6, + 0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA, + 0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE, + 0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0, + 0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6, + 0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5, + 0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8, + 0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB, + 0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC, + 0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF, + 0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0, + 0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3, + 0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6, + 0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA, + 0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC, + 0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE, + 0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7, + 0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45, + 0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48, + 0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B, + 0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F, + 0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51, + 0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53, + 0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57, + 0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61, + 0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65, + 0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69, + 0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D, + 0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71, + 0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74, + 0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78, + 0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82, + 0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86, + 0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A, + 0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E, + 0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92, + 0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96, + 0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A, + 0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C, + 0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F, + 0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1, + 0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5, + 0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7, + 0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9, + 0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD, + 0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0, + 0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3, + 0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6, + 0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA, + 0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE, + 0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2, + 0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6, + 0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA, + 0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE, + 0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2, + 0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6, + 0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA, + 0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE, + 0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2, + 0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6, + 0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9, + 0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED, + 0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1, + 0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5, + 0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9, + 0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD, + 0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41, + 0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1, + 0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45, + 0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49, + 0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B, + 0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E, + 0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52, + 0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54, + 0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57, + 0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61, + 0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65, + 0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69, + 0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C, + 0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70, + 0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73, + 0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77, + 0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81, + 0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85, + 0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89, + 0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C, + 0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90, + 0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93, + 0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96, + 0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99, + 0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D, + 0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F, + 0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3, + 0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7, + 0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA, + 0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE, + 0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2, + 0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6, + 0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA, + 0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE, + 0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2, + 0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4, + 0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7, + 0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA, + 0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE, + 0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0, + 0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3, + 0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7, + 0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA, + 0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE, + 0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2, + 0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6, + 0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA, + 0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED, + 0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1, + 0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4, + 0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8, + 0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC, + 0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42, + 0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46, + 0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A, + 0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E, + 0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51, + 0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54, + 0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58, + 0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62, + 0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66, + 0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A, + 0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E, + 0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72, + 0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76, + 0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A, + 0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84, + 0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88, + 0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B, + 0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F, + 0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91, + 0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94, + 0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96, + 0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7, + 0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B, + 0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F, + 0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3, + 0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6, + 0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9, + 0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC, + 0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0, + 0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3, + 0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7, + 0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB, + 0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD, + 0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0, + 0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3, + 0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7, + 0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4, + 0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB, + 0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF, + 0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1, + 0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2, + 0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3, + 0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE, + 0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1, + 0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9, + 0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB, + 0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD, + 0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0, + 0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3, + 0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7, + 0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC, + 0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA, + 0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE, + 0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0, + 0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3, + 0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3, + 0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9, + 0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6, + 0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD, + 0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9, + 0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44, + 0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47, + 0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A, + 0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E, + 0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51, + 0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55, + 0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59, + 0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61, + 0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2, + 0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63, + 0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67, + 0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9, + 0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68, + 0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A, + 0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C, + 0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F, + 0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72, + 0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76, + 0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7, + 0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A, + 0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84, + 0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85, + 0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88, + 0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF, + 0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D, + 0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3, + 0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F, + 0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8, + 0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93, + 0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96, + 0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99, + 0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D, + 0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE, + 0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1, + 0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5, + 0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7, + 0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA, + 0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB, + 0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7, + 0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA, + 0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC, + 0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4, + 0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6, + 0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9, + 0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC, + 0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0, + 0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3, + 0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3, + 0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7, + 0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9, + 0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC, + 0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0, + 0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4, + 0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA, + 0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9, + 0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD, + 0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF, + 0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2, + 0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5, + 0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9, + 0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2, + 0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED, + 0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1, + 0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3, + 0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6, + 0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9, + 0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD, + 0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA, + 0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43, + 0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47, + 0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49, + 0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C, + 0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D, + 0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51, + 0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4, + 0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55, + 0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59, + 0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61, + 0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64, + 0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67, + 0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B, + 0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D, + 0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F, + 0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73, + 0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75, + 0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78, + 0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81, + 0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85, + 0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87, + 0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A, + 0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E, + 0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90, + 0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93, + 0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96, + 0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A, + 0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD, + 0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E, + 0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2, + 0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4, + 0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7, + 0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA, + 0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE, + 0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5, + 0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7, + 0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5, + 0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7, + 0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA, + 0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD, + 0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0, + 0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF, + 0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2, + 0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6, + 0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5, + 0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8, + 0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB, + 0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF, + 0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB, + 0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5, + 0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9, + 0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB, + 0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE, + 0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF, + 0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2, + 0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5, + 0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4, + 0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7, + 0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9, + 0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE, + 0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC, + 0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0, + 0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3, + 0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2, + 0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6, + 0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8, + 0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB, + 0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE, + 0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044, + 0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED, + 0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047, + 0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B, + 0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D, + 0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F, + 0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052, + 0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056, + 0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059, + 0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062, + 0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066, + 0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069, + 0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C, + 0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F, + 0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073, + 0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077, + 0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081, + 0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085, + 0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087, + 0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A, + 0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C, + 0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090, + 0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3, + 0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093, + 0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097, + 0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099, + 0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C, + 0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F, + 0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3, + 0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC, + 0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7, + 0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB, + 0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE, + 0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1, + 0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4, + 0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8, + 0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA, + 0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC, + 0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0, + 0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3, + 0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7, + 0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB, + 0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF, + 0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3, + 0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7, + 0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB, + 0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD, + 0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0, + 0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2, + 0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6, + 0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD, + 0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0, + 0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1, + 0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED, + 0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1, + 0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4, + 0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8, + 0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6, + 0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD, + 0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143, + 0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146, + 0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A, + 0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E, + 0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152, + 0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156, + 0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158, + 0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162, + 0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165, + 0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168, + 0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B, + 0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F, + 0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0, + 0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173, + 0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177, + 0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179, + 0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182, + 0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186, + 0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A, + 0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E, + 0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191, + 0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195, + 0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197, + 0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A, + 0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B, + 0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F, + 0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE, + 0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243, + 0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247, + 0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A, + 0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E, + 0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252, + 0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256, + 0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A, + 0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263, + 0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267, + 0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A, + 0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E, + 0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272, + 0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276, + 0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A, + 0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284, + 0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288, + 0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A, + 0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D, + 0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290, + 0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294, + 0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9, + 0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299, + 0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D, + 0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0, + 0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343, + 0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346, + 0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A, + 0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D, + 0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351, + 0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355, + 0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357, + 0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A, + 0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363, + 0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367, + 0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4, + 0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B, + 0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F, + 0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373, + 0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377, + 0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381, + 0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385, + 0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389, + 0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D, + 0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391, + 0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393, + 0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9, + 0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397, + 0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B, + 0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE, + 0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E, + 0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0, + 0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442, + 0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444, + 0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA, + 0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A, + 0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD, + 0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D, + 0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451, + 0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453, + 0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456, + 0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459, + 0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463, + 0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6, + 0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466, + 0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A, + 0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D, + 0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470, + 0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474, + 0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478, + 0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482, + 0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485, + 0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489, + 0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D, + 0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491, + 0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495, + 0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499, + 0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D, + 0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541, + 0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545, + 0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547, + 0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A, + 0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D, + 0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551, + 0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2, + 0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554, + 0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558, + 0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561, + 0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565, + 0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569, + 0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D, + 0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571, + 0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574, + 0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578, + 0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581, + 0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585, + 0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589, + 0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D, + 0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591, + 0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594, + 0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598, + 0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C, + 0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0, + 0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644, + 0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648, + 0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C, + 0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650, + 0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654, + 0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656, + 0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659, + 0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662, + 0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666, + 0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF, + 0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1, + 0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D, + 0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F, + 0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673, + 0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676, + 0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A, + 0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684, + 0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687, + 0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B, + 0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E, + 0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692, + 0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696, + 0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A, + 0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E, + 0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741, + 0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745, + 0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748, + 0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B, + 0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E, + 0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752, + 0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754, + 0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758, + 0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762, + 0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766, + 0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A, + 0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E, + 0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772, + 0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776, + 0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779, + 0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783, + 0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785, + 0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788, + 0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B, + 0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F, + 0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791, + 0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794, + 0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798, + 0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B, + 0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F, + 0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843, + 0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847, + 0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B, + 0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D, + 0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851, + 0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855, + 0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859, + 0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863, + 0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867, + 0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B, + 0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F, + 0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873, + 0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876, + 0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A, + 0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884, + 0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888, + 0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C, + 0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890, + 0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894, + 0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897, + 0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B, + 0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F, + 0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943, + 0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947, + 0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B, + 0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F, + 0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952, + 0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956, + 0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A, + 0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964, + 0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC, + 0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969, + 0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D, + 0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971, + 0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975, + 0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979, + 0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983, + 0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987, + 0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B, + 0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F, + 0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991, + 0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994, + 0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997, + 0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B, + 0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D, + 0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F, + 0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6, + 0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44, + 0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46, + 0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49, + 0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D, + 0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE, + 0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F, + 0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53, + 0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55, + 0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58, + 0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61, + 0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65, + 0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA, + 0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68, + 0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C, + 0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F, + 0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71, + 0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74, + 0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78, + 0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81, + 0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84, + 0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88, + 0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C, + 0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90, + 0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94, + 0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98, + 0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C, + 0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0, + 0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44, + 0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46, + 0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49, + 0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C, + 0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50, + 0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9, + 0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53, + 0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57, + 0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59, + 0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62, + 0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65, + 0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69, + 0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2, + 0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D, + 0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71, + 0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74, + 0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77, + 0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81, + 0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85, + 0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89, + 0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C, + 0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90, + 0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93, + 0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96, + 0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A, + 0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E, + 0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42, + 0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45, + 0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49, + 0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B, + 0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E, + 0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51, + 0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55, + 0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0, + 0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59, + 0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63, + 0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66, + 0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69, + 0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C, + 0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70, + 0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74, + 0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77, + 0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81, + 0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85, + 0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89, + 0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D, + 0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91, + 0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95, + 0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99, + 0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D, + 0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0, + 0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43, + 0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46, + 0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A, + 0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB, + 0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E, + 0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52, + 0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55, + 0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59, + 0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63, + 0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67, + 0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A, + 0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E, + 0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72, + 0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74, + 0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77, + 0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A, + 0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84, + 0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5, + 0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88, + 0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C, + 0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F, + 0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93, + 0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97, + 0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B, + 0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F, + 0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42, + 0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46, + 0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49, + 0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C, + 0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50, + 0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54, + 0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58, + 0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62, + 0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66, + 0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69, + 0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C, + 0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F, + 0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73, + 0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0, + 0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77, + 0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81, + 0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84, + 0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87, + 0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A, + 0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E, + 0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91, + 0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94, + 0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98, + 0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A, + 0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D, + 0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0, + 0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44, + 0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD, + 0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48, + 0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C, + 0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50, + 0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54, + 0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58, + 0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62, + 0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66, + 0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A, + 0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E, + 0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70, + 0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4, + 0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74, + 0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78, + 0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9, + 0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82, + 0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86, + 0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88, + 0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B, + 0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E, + 0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92, + 0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1, + 0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96, + 0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A, + 0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C, + 0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F, + 0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042, + 0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046, + 0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9, + 0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049, + 0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D, + 0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F, + 0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053, + 0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057, + 0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061, + 0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065, + 0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068, + 0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C, + 0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070, + 0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074, + 0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078, + 0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082, + 0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086, + 0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A, + 0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E, + 0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090, + 0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2, + 0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095, + 0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099, + 0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6, + 0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C, + 0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0, + 0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142, + 0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145, + 0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148, + 0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C, + 0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF, + 0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150, + 0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154, + 0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157, + 0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A, + 0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163, + 0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167, + 0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6, + 0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A, + 0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E, + 0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171, + 0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175, + 0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179, + 0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183, + 0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187, + 0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B, + 0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F, + 0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191, + 0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194, + 0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197, + 0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B, + 0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0, + 0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F, + 0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243, + 0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245, + 0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248, + 0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B, + 0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F, + 0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252, + 0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255, + 0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259, + 0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262, + 0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266, + 0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A, + 0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E, + 0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272, + 0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275, + 0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279, + 0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282, + 0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286, + 0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289, + 0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D, + 0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291, + 0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295, + 0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299, + 0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C, + 0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0, + 0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344, + 0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348, + 0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C, + 0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350, + 0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354, + 0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356, + 0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359, + 0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362, + 0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366, + 0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3, + 0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A, + 0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E, + 0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371, + 0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374, + 0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377, + 0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381, + 0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385, + 0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388, + 0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C, + 0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F, + 0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393, + 0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397, + 0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B, + 0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F, + 0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442, + 0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446, + 0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448, + 0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B, + 0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E, + 0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452, + 0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3, + 0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456, + 0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A, + 0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463, + 0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466, + 0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469, + 0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D, + 0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470, + 0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474, + 0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478, + 0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A, + 0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483, + 0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486, + 0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A, + 0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C, + 0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F, + 0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493, + 0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497, + 0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B, + 0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F, + 0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543, + 0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547, + 0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B, + 0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F, + 0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551, + 0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554, + 0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557, + 0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561, + 0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6, + 0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565, + 0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569, + 0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B, + 0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E, + 0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570, + 0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574, + 0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF, + 0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577, + 0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581, + 0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583, + 0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586, + 0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589, + 0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D, + 0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8, + 0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590, + 0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594, + 0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597, + 0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B, + 0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F, + 0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643, + 0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647, + 0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A, + 0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E, + 0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652, + 0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656, + 0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A, + 0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664, + 0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668, + 0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C, + 0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670, + 0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672, + 0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675, + 0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677, + 0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681, + 0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4, + 0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684, + 0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688, + 0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A, + 0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D, + 0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690, + 0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694, + 0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD, + 0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698, + 0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C, + 0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F, + 0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742, + 0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746, + 0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A, + 0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E, + 0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751, + 0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755, + 0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758, + 0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761, + 0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765, + 0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769, + 0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D, + 0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771, + 0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775, + 0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777, + 0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A, + 0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783, + 0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787, + 0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA, + 0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B, + 0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E, + 0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791, + 0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794, + 0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798, + 0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C, + 0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0, + 0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844, + 0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848, + 0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B, + 0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F, + 0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853, + 0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857, + 0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861, + 0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865, + 0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869, + 0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C, + 0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F, + 0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873, + 0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877, + 0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2, + 0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883, + 0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887, + 0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A, + 0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E, + 0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892, + 0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896, + 0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A, + 0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E, + 0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942, + 0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944, + 0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947, + 0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A, + 0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E, + 0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB, + 0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952, + 0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956, + 0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959, + 0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963, + 0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967, + 0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B, + 0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F, + 0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972, + 0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976, + 0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979, + 0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983, + 0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987, + 0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B, + 0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F, + 0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993, + 0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997, + 0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999, + 0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C, + 0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F, + 0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43, + 0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45, + 0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48, + 0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C, + 0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F, + 0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52, + 0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55, + 0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59, + 0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62, + 0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65, + 0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69, + 0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B, + 0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1, + 0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F, + 0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73, + 0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6, + 0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78, + 0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82, + 0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85, + 0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88, + 0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B, + 0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F, + 0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91, + 0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95, + 0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99, + 0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B, + 0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E, + 0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41, + 0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45, + 0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2, + 0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49, + 0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D, + 0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E, + 0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51, + 0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53, + 0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57, + 0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC, + 0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A, + 0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63, + 0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65, + 0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68, + 0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B, + 0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F, + 0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6, + 0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72, + 0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76, + 0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78, + 0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82, + 0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86, + 0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A, + 0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E, + 0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92, + 0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96, + 0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A, + 0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E, + 0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42, + 0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46, + 0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A, + 0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E, + 0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52, + 0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54, + 0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57, + 0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A, + 0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64, + 0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1, + 0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67, + 0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B, + 0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D, + 0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70, + 0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73, + 0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77, + 0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA, + 0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81, + 0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85, + 0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88, + 0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B, + 0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E, + 0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92, + 0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94, + 0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96, + 0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A, + 0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D, + 0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41, + 0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44, + 0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48, + 0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6, + 0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E, + 0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52, + 0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54, + 0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57, + 0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A, + 0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64, + 0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD, + 0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68, + 0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C, + 0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F, + 0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73, + 0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77, + 0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81, + 0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85, + 0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88, + 0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C, + 0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90, + 0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94, + 0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98, + 0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C, + 0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0, + 0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44, + 0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48, + 0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B, + 0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E, + 0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52, + 0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56, + 0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A, + 0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64, + 0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68, + 0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B, + 0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E, + 0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71, + 0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75, + 0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9, + 0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81, + 0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85, + 0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87, + 0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD, + 0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B, + 0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F, + 0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2, + 0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93, + 0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97, + 0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A, + 0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E, + 0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42, + 0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46, + 0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A, + 0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D, + 0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51, + 0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55, + 0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59, + 0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63, + 0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67, + 0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B, + 0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F, + 0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73, + 0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76, + 0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79, + 0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82, + 0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86, + 0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA, + 0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C, + 0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90, + 0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93, + 0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96, + 0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99, + 0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D, + 0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF, + 0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042, + 0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046, + 0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049, + 0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C, + 0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F, + 0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053, + 0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6, + 0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058, + 0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062, + 0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066, + 0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A, + 0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E, + 0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072, + 0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076, + 0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A, + 0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084, + 0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086, + 0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089, + 0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C, + 0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090, + 0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD, + 0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094, + 0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098, + 0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A, + 0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D, + 0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0, + 0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143, + 0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6, + 0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147, + 0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B, + 0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D, + 0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150, + 0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153, + 0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157, + 0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE, + 0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A, + 0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164, + 0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167, + 0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B, + 0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F, + 0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173, + 0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177, + 0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A, + 0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184, + 0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188, + 0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C, + 0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190, + 0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194, + 0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198, + 0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C, + 0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0, + 0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242, + 0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245, + 0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247, + 0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B, + 0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA, + 0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F, + 0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253, + 0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255, + 0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258, + 0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261, + 0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265, + 0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2, + 0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269, + 0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D, + 0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F, + 0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272, + 0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275, + 0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279, + 0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA, + 0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282, + 0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286, + 0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289, + 0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C, + 0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F, + 0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293, + 0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296, + 0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A, + 0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E, + 0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0, + 0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343, + 0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346, + 0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349, + 0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA, + 0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D, + 0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350, + 0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352, + 0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355, + 0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358, + 0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362, + 0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1, + 0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368, + 0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C, + 0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E, + 0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371, + 0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375, + 0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379, + 0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6, + 0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385, + 0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389, + 0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B, + 0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E, + 0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391, + 0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395, + 0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD, + 0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A, + 0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E, + 0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441, + 0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444, + 0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447, + 0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B, + 0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3, + 0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451, + 0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455, + 0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457, + 0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A, + 0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463, + 0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466, + 0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA, + 0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B, + 0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F, + 0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472, + 0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475, + 0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478, + 0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482, + 0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485, + 0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488, + 0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C, + 0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E, + 0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491, + 0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494, + 0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498, + 0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C, + 0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F, + 0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543, + 0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545, + 0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548, + 0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B, + 0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F, + 0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC, + 0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553, + 0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557, + 0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559, + 0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562, + 0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565, + 0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569, + 0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3, + 0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E, + 0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572, + 0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574, + 0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9, + 0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577, + 0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581, + 0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE, + 0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585, + 0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588, + 0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B, + 0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E, + 0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591, + 0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595, + 0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597, + 0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A, + 0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E, + 0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0, + 0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643, + 0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646, + 0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A, + 0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD, + 0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E, + 0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652, + 0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF, + 0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2, + 0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4, + 0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC, + 0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0, + 0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5, + 0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA, + 0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0, + 0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC, + 0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3, + 0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA, + 0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE, + 0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6, + 0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA, + 0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF, + 0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3, + 0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7, + 0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF, + 0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5, + 0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9, + 0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1, + 0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5, + 0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC, + 0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8, + 0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5, + 0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5, + 0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3, + 0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD, + 0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9, + 0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9, + 0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE, + 0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA, + 0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1, + 0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF, + 0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7, + 0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6, + 0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6, + 0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1, + 0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8, + 0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF, + 0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6, + 0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6, + 0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD, + 0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6, + 0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF, + 0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4, + 0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8, + 0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9, + 0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC, + 0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5, + 0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE, + 0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA, + 0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1, + 0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC, + 0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2, + 0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA, + 0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2, + 0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0, + 0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9, + 0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE, + 0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8, + 0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1, + 0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB, + 0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7, + 0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8, + 0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0, + 0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9, + 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4, + 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC, + 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC, + 0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC, + 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06, + 0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E, + 0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F, + 0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25, + 0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29, + 0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32, + 0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36, + 0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D, + 0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42, + 0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46, + 0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A, + 0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50, + 0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55, + 0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A, + 0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F, + 0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63, + 0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67, + 0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B, + 0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F, + 0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76, + 0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D, + 0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87, + 0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F, + 0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95, + 0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99, + 0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2, + 0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6, + 0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE, + 0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4, + 0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA, + 0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2, + 0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7, + 0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD, + 0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1, + 0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6, + 0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB, + 0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF, + 0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6, + 0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE, + 0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8, + 0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE, + 0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03, + 0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09, + 0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10, + 0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15, + 0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A, + 0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F, + 0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24, + 0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28, + 0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F, + 0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33, + 0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A, + 0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F, + 0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43, + 0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B, + 0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F, + 0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55, + 0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A, + 0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E, + 0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64, + 0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68, + 0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E, + 0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77, + 0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E, + 0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85, + 0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B, + 0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91, + 0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95, + 0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99, + 0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F, + 0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3, + 0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8, + 0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC, + 0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0, + 0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4, + 0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9, + 0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD, + 0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3, + 0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9, + 0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD, + 0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4, + 0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8, + 0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD, + 0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2, + 0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7, + 0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB, + 0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF, + 0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3, + 0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7, + 0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE, + 0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05, + 0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C, + 0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11, + 0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16, + 0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A, + 0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E, + 0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22, + 0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26, + 0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A, + 0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E, + 0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35, + 0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C, + 0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42, + 0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49, + 0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52, + 0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58, + 0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E, + 0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66, + 0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D, + 0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72, + 0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76, + 0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F, + 0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83, + 0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89, + 0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E, + 0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92, + 0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96, + 0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A, + 0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E, + 0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2, + 0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6, + 0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA, + 0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE, + 0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2, + 0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6, + 0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA, + 0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2, + 0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7, + 0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB, + 0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4, + 0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA, + 0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF, + 0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3, + 0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7, + 0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE, + 0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2, + 0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7, + 0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD, + 0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01, + 0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05, + 0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B, + 0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11, + 0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15, + 0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19, + 0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D, + 0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21, + 0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25, + 0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29, + 0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F, + 0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36, + 0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A, + 0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44, + 0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A, + 0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E, + 0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53, + 0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57, + 0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B, + 0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61, + 0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67, + 0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B, + 0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F, + 0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73, + 0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77, + 0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C, + 0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81, + 0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86, + 0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B, + 0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F, + 0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96, + 0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A, + 0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F, + 0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3, + 0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7, + 0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB, + 0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF, + 0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3, + 0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7, + 0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE, + 0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3, + 0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA, + 0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1, + 0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6, + 0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA, + 0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF, + 0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3, + 0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7, + 0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED, + 0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3, + 0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9, + 0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD, + 0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003, + 0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008, + 0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D, + 0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012, + 0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017, + 0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B, + 0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021, + 0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025, + 0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A, + 0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E, + 0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032, + 0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036, + 0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A, + 0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E, + 0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042, + 0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049, + 0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050, + 0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058, + 0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E, + 0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062, + 0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066, + 0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A, + 0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E, + 0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072, + 0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076, + 0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A, + 0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081, + 0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086, + 0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A, + 0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092, + 0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096, + 0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E, + 0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6, + 0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2, + 0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA, + 0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF, + 0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3, + 0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC, + 0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2, + 0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7, + 0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC, + 0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1, + 0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6, + 0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA, + 0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE, + 0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2, + 0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6, + 0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA, + 0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE, + 0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102, + 0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106, + 0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E, + 0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115, + 0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E, + 0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122, + 0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A, + 0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F, + 0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133, + 0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C, + 0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142, + 0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147, + 0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C, + 0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152, + 0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159, + 0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E, + 0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163, + 0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167, + 0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B, + 0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F, + 0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173, + 0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177, + 0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E, + 0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184, + 0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A, + 0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190, + 0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197, + 0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D, + 0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1, + 0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5, + 0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA, + 0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE, + 0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2, + 0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6, + 0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA, + 0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE, + 0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2, + 0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6, + 0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA, + 0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF, + 0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5, + 0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9, + 0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0, + 0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4, + 0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA, + 0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF, + 0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4, + 0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8, + 0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF, + 0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203, + 0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A, + 0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210, + 0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216, + 0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C, + 0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221, + 0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225, + 0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229, + 0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D, + 0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231, + 0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236, + 0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A, + 0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F, + 0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243, + 0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247, + 0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B, + 0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F, + 0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253, + 0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257, + 0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D, + 0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262, + 0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266, + 0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C, + 0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270, + 0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276, + 0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A, + 0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F, + 0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283, + 0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A, + 0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E, + 0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295, + 0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C, + 0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2, + 0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9, + 0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF, + 0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5, + 0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9, + 0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD, + 0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1, + 0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5, + 0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB, + 0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1, + 0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6, + 0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE, + 0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3, + 0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0, + 0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC, + 0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303, + 0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309, + 0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D, + 0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316, + 0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A, + 0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F, + 0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323, + 0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327, + 0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B, + 0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F, + 0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333, + 0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337, + 0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B, + 0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F, + 0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343, + 0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347, + 0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B, + 0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F, + 0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353, + 0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D, + 0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363, + 0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C, + 0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373, + 0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379, + 0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D, + 0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386, + 0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A, + 0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F, + 0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395, + 0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399, + 0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D, + 0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3, + 0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7, + 0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD, + 0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1, + 0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5, + 0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9, + 0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD, + 0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1, + 0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7, + 0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF, + 0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6, + 0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE, + 0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3, + 0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9, + 0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED, + 0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1, + 0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5, + 0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9, + 0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE, + 0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402, + 0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406, + 0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A, + 0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E, + 0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413, + 0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417, + 0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D, + 0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422, + 0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426, + 0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D, + 0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431, + 0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436, + 0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A, + 0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E, + 0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442, + 0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446, + 0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A, + 0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E, + 0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455, + 0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A, + 0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E, + 0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466, + 0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A, + 0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F, + 0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473, + 0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477, + 0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B, + 0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F, + 0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484, + 0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489, + 0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D, + 0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491, + 0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495, + 0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499, + 0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E, + 0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2, + 0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7, + 0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD, + 0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1, + 0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6, + 0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC, + 0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1, + 0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6, + 0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB, + 0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF, + 0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4, + 0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9, + 0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF, + 0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7, + 0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB, + 0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3, + 0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7, + 0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC, + 0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500, + 0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504, + 0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508, + 0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C, + 0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510, + 0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516, + 0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D, + 0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521, + 0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B, + 0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F, + 0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536, + 0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B, + 0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F, + 0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548, + 0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F, + 0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555, + 0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559, + 0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562, + 0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566, + 0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A, + 0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E, + 0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572, + 0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576, + 0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A, + 0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E, + 0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582, + 0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586, + 0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A, + 0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E, + 0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592, + 0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596, + 0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A, + 0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E, + 0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5, + 0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC, + 0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2, + 0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9, + 0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1, + 0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6, + 0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA, + 0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3, + 0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7, + 0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC, + 0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0, + 0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4, + 0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8, + 0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED, + 0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1, + 0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5, + 0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9, + 0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD, + 0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601, + 0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605, + 0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609, + 0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D, + 0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613, + 0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619, + 0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D, + 0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621, + 0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626, + 0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A, + 0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F, + 0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633, + 0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638, + 0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C, + 0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640, + 0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644, + 0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649, + 0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D, + 0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651, + 0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655, + 0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659, + 0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D, + 0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661, + 0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666, + 0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B, + 0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F, + 0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673, + 0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677, + 0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B, + 0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F, + 0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683, + 0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687, + 0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B, + 0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F, + 0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693, + 0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697, + 0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B, + 0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2, + 0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7, + 0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD, + 0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2, + 0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6, + 0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA, + 0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE, + 0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2, + 0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6, + 0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA, + 0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE, + 0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2, + 0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7, + 0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB, + 0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF, + 0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3, + 0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7, + 0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB, + 0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF, + 0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5, + 0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA, + 0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE, + 0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704, + 0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709, + 0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D, + 0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711, + 0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715, + 0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719, + 0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D, + 0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721, + 0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725, + 0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B, + 0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732, + 0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736, + 0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D, + 0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741, + 0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746, + 0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B, + 0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750, + 0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756, + 0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A, + 0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E, + 0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763, + 0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769, + 0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D, + 0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774, + 0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779, + 0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F, + 0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785, + 0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789, + 0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793, + 0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B, + 0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1, + 0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5, + 0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE, + 0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2, + 0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9, + 0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD, + 0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1, + 0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5, + 0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB, + 0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF, + 0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3, + 0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7, + 0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB, + 0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF, + 0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3, + 0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7, + 0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB, + 0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2, + 0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7, + 0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB, + 0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804, + 0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B, + 0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811, + 0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815, + 0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C, + 0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821, + 0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827, + 0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D, + 0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831, + 0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A, + 0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E, + 0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843, + 0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848, + 0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C, + 0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850, + 0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856, + 0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A, + 0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861, + 0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866, + 0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A, + 0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872, + 0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876, + 0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B, + 0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880, + 0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884, + 0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888, + 0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C, + 0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891, + 0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895, + 0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899, + 0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D, + 0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1, + 0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5, + 0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA, + 0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE, + 0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3, + 0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9, + 0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD, + 0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4, + 0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9, + 0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE, + 0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3, + 0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8, + 0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC, + 0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3, + 0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7, + 0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE, + 0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3, + 0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7, + 0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF, + 0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903, + 0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908, + 0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C, + 0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910, + 0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914, + 0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919, + 0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D, + 0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922, + 0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926, + 0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A, + 0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E, + 0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932, + 0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936, + 0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A, + 0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941, + 0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946, + 0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A, + 0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950, + 0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955, + 0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B, + 0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961, + 0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965, + 0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C, + 0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971, + 0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977, + 0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D, + 0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981, + 0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988, + 0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990, + 0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994, + 0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998, + 0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C, + 0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0, + 0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4, + 0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8, + 0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE, + 0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3, + 0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8, + 0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE, + 0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4, + 0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA, + 0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4, + 0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA, + 0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2, + 0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA, + 0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF, + 0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3, + 0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD, + 0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03, + 0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07, + 0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C, + 0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10, + 0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14, + 0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19, + 0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D, + 0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21, + 0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25, + 0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29, + 0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D, + 0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31, + 0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35, + 0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B, + 0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41, + 0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46, + 0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F, + 0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56, + 0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B, + 0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60, + 0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66, + 0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D, + 0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73, + 0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79, + 0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D, + 0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81, + 0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89, + 0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E, + 0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92, + 0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96, + 0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A, + 0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E, + 0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2, + 0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6, + 0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE, + 0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4, + 0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA, + 0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0, + 0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5, + 0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA, + 0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE, + 0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2, + 0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6, + 0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC, + 0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0, + 0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4, + 0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8, + 0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC, + 0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0, + 0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4, + 0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8, + 0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD, + 0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02, + 0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07, + 0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B, + 0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12, + 0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16, + 0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B, + 0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21, + 0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25, + 0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A, + 0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F, + 0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33, + 0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F, + 0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43, + 0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B, + 0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52, + 0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57, + 0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C, + 0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60, + 0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66, + 0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A, + 0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F, + 0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73, + 0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77, + 0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B, + 0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F, + 0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83, + 0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87, + 0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D, + 0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92, + 0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96, + 0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A, + 0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E, + 0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2, + 0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7, + 0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD, + 0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1, + 0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6, + 0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB, + 0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF, + 0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5, + 0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA, + 0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE, + 0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4, + 0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8, + 0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC, + 0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0, + 0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4, + 0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8, + 0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC, + 0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0, + 0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4, + 0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA, + 0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01, + 0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06, + 0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10, + 0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A, + 0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23, + 0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B, + 0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32, + 0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37, + 0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C, + 0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42, + 0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A, + 0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51, + 0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55, + 0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59, + 0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E, + 0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62, + 0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66, + 0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A, + 0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E, + 0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72, + 0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76, + 0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A, + 0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E, + 0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82, + 0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89, + 0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90, + 0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96, + 0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D, + 0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3, + 0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA, + 0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE, + 0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7, + 0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB, + 0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2, + 0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7, + 0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB, + 0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3, + 0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9, + 0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE, + 0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2, + 0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6, + 0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA, + 0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE, + 0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2, + 0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA, + 0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF, + 0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03, + 0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B, + 0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F, + 0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15, + 0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19, + 0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D, + 0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21, + 0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26, + 0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A, + 0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F, + 0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33, + 0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37, + 0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B, + 0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F, + 0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44, + 0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A, + 0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F, + 0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54, + 0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A, + 0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E, + 0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62, + 0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67, + 0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C, + 0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70, + 0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74, + 0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78, + 0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C, + 0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82, + 0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B, + 0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F, + 0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97, + 0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E, + 0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2, + 0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7, + 0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB, + 0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF, + 0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4, + 0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9, + 0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD, + 0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1, + 0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5, + 0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9, + 0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD, + 0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1, + 0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7, + 0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD, + 0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1, + 0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5, + 0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA, + 0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE, + 0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3, + 0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9, + 0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD, + 0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02, + 0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08, + 0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E, + 0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13, + 0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18, + 0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E, + 0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23, + 0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27, + 0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B, + 0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F, + 0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33, + 0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37, + 0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B, + 0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F, + 0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43, + 0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A, + 0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50, + 0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56, + 0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E, + 0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65, + 0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B, + 0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F, + 0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78, + 0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F, + 0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85, + 0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89, + 0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92, + 0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96, + 0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C, + 0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0, + 0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4, + 0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9, + 0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD, + 0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1, + 0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5, + 0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9, + 0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD, + 0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1, + 0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5, + 0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9, + 0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD, + 0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3, + 0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA, + 0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE, + 0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6, + 0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA, + 0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF, + 0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3, + 0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7, + 0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB, + 0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF, + 0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04, + 0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A, + 0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E, + 0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12, + 0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16, + 0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F, + 0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23, + 0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27, + 0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B, + 0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F, + 0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33, + 0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37, + 0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B, + 0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F, + 0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46, + 0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B, + 0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F, + 0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56, + 0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A, + 0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E, + 0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62, + 0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66, + 0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A, + 0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E, + 0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72, + 0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76, + 0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A, + 0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E, + 0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82, + 0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86, + 0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A, + 0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E, + 0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92, + 0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97, + 0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B, + 0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F, + 0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3, + 0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7, + 0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB, + 0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF, + 0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4, + 0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8, + 0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC, + 0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0, + 0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4, + 0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9, + 0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF, + 0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5, + 0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9, + 0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE, + 0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4, + 0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8, + 0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC, + 0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0, + 0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4, + 0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8, + 0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC, + 0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000, + 0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004, + 0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008, + 0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C, + 0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010, + 0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014, + 0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018, + 0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C, + 0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020, + 0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024, + 0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028, + 0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C, + 0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030, + 0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034, + 0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038, + 0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D, + 0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041, + 0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045, + 0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049, + 0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D, + 0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052, + 0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056, + 0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B, + 0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061, + 0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065, + 0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B, + 0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F, + 0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073, + 0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077, + 0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B, + 0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F, + 0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083, + 0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087, + 0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B, + 0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F, + 0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096, + 0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B, + 0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F, + 0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7, + 0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB, + 0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7, + 0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB, + 0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4, + 0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB, + 0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1, + 0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5, + 0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE, + 0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2, + 0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9, + 0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE, + 0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2, + 0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA, + 0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE, + 0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103, + 0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109, + 0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D, + 0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112, + 0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117, + 0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B, + 0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128, + 0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E, + 0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135, + 0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D, + 0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142, + 0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146, + 0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F, + 0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153, + 0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A, + 0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F, + 0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163, + 0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C, + 0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171, + 0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176, + 0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B, + 0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F, + 0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183, + 0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188, + 0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F, + 0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195, + 0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A, + 0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2, + 0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7, + 0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE, + 0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3, + 0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7, + 0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB, + 0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0, + 0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5, + 0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA, + 0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF, + 0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3, + 0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA, + 0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE, + 0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3, + 0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9, + 0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED, + 0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4, + 0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8, + 0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE, + 0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203, + 0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208, + 0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E, + 0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214, + 0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A, + 0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221, + 0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225, + 0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C, + 0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235, + 0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239, + 0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D, + 0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241, + 0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245, + 0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A, + 0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E, + 0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255, + 0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A, + 0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E, + 0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263, + 0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268, + 0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E, + 0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273, + 0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278, + 0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E, + 0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284, + 0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A, + 0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E, + 0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293, + 0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297, + 0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E, + 0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2, + 0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9, + 0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF, + 0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3, + 0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB, + 0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF, + 0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3, + 0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7, + 0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB, + 0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF, + 0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3, + 0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7, + 0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB, + 0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2, + 0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8, + 0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0, + 0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5, + 0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE, + 0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303, + 0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307, + 0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F, + 0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316, + 0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B, + 0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320, + 0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326, + 0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C, + 0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330, + 0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334, + 0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338, + 0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C, + 0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340, + 0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344, + 0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349, + 0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D, + 0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351, + 0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355, + 0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359, + 0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D, + 0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361, + 0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365, + 0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B, + 0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371, + 0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376, + 0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E, + 0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382, + 0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387, + 0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D, + 0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391, + 0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395, + 0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399, + 0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D, + 0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1, + 0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5, + 0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9, + 0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD, + 0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1, + 0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5, + 0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9, + 0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD, + 0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2, + 0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6, + 0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA, + 0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE, + 0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2, + 0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6, + 0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD, + 0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4, + 0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA, + 0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF, + 0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3, + 0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA, + 0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE, + 0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402, + 0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406, + 0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B, + 0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F, + 0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414, + 0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418, + 0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C, + 0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420, + 0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425, + 0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429, + 0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E, + 0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433, + 0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438, + 0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E, + 0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442, + 0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446, + 0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B, + 0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F, + 0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453, + 0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457, + 0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B, + 0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F, + 0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463, + 0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A, + 0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F, + 0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473, + 0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A, + 0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E, + 0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483, + 0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487, + 0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B, + 0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F, + 0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493, + 0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498, + 0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D, + 0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1, + 0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5, + 0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9, + 0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD, + 0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1, + 0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5, + 0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA, + 0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF, + 0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3, + 0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7, + 0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB, + 0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF, + 0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3, + 0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7, + 0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB, + 0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF, + 0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3, + 0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7, + 0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC, + 0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2, + 0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7, + 0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD, + 0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504, + 0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508, + 0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D, + 0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512, + 0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517, + 0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B, + 0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520, + 0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524, + 0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A, + 0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F, + 0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534, + 0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A, + 0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540, + 0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546, + 0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550, + 0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A, + 0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562, + 0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567, + 0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C, + 0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572, + 0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579, + 0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F, + 0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585, + 0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A, + 0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592, + 0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599, + 0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E, + 0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3, + 0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7, + 0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC, + 0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0, + 0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6, + 0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0, + 0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB, + 0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3, + 0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9, + 0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD, + 0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4, + 0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9, + 0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1, + 0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8, + 0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602, + 0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A, + 0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F, + 0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614, + 0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A, + 0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620, + 0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626, + 0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B, + 0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636, + 0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D, + 0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643, + 0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649, + 0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D, + 0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656, + 0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A, + 0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661, + 0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665, + 0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669, + 0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E, + 0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674, + 0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A, + 0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F, + 0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684, + 0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A, + 0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690, + 0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696, + 0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B, + 0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0, + 0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6, + 0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC, + 0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2, + 0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7, + 0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE, + 0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6, + 0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA, + 0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1, + 0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6, + 0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA, + 0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2, + 0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6, + 0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED, + 0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2, + 0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6, + 0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC, + 0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701, + 0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707, + 0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D, + 0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711, + 0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718, + 0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D, + 0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723, + 0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729, + 0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D, + 0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734, + 0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A, + 0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741, + 0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746, + 0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B, + 0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A, + 0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F, + 0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764, + 0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769, + 0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E, + 0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772, + 0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779, + 0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780, + 0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B, + 0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792, + 0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B, + 0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F, + 0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9, + 0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF, + 0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5, + 0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9, + 0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2, + 0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6, + 0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD, + 0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3, + 0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7, + 0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC, + 0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1, + 0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6, + 0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB, + 0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0, + 0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4, + 0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8, + 0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC, + 0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802, + 0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807, + 0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D, + 0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814, + 0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A, + 0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821, + 0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826, + 0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A, + 0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832, + 0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836, + 0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B, + 0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841, + 0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845, + 0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B, + 0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851, + 0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856, + 0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A, + 0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E, + 0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862, + 0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866, + 0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A, + 0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E, + 0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875, + 0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B, + 0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F, + 0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889, + 0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890, + 0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895, + 0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899, + 0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E, + 0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4, + 0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9, + 0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD, + 0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1, + 0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5, + 0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9, + 0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF, + 0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3, + 0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9, + 0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE, + 0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2, + 0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA, + 0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE, + 0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5, + 0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9, + 0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED, + 0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1, + 0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6, + 0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA, + 0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901, + 0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908, + 0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E, + 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, + 0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003, + 0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C, + 0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C, + 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, + 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C, + 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010, + 0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7, + 0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E, + 0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033, + 0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1, + 0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220, + 0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207, + 0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B, + 0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF, + 0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1, + 0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD, + 0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191, + 0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A, + 0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D, + 0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208, + 0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282, + 0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227, + 0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912, + 0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916, + 0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B, + 0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F, + 0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923, + 0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927, + 0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B, + 0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930, + 0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935, + 0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939, + 0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D, + 0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941, + 0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945, + 0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949, + 0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D, + 0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953, + 0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959, + 0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D, + 0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964, + 0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968, + 0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D, + 0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4, + 0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E, + 0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA, + 0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1, + 0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211, + 0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030, + 0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6, + 0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665, + 0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8, + 0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592, + 0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7, + 0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F, + 0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6, + 0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197, + 0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D, + 0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F, + 0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122, + 0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC, + 0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973, + 0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978, + 0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D, + 0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981, + 0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985, + 0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B, + 0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991, + 0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995, + 0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C, + 0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1, + 0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5, + 0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9, + 0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD, + 0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1, + 0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5, + 0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9, + 0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD, + 0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3, + 0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB, + 0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF, + 0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8, + 0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, + 0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, + 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, + 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, + 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, + 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, + 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, + 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, + 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, + 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, + 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, + 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, + 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, + 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, + 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, + 0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, + 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, + 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, + 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, + 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, + 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, + 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, + 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, + 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE, + 0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5, + 0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA, + 0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3, + 0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7, + 0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE, + 0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03, + 0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07, + 0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10, + 0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15, + 0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A, + 0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E, + 0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22, + 0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26, + 0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B, + 0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F, + 0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33, + 0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37, + 0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B, + 0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F, + 0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43, + 0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131, + 0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135, + 0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139, + 0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D, + 0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141, + 0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145, + 0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149, + 0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D, + 0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151, + 0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155, + 0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159, + 0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D, + 0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161, + 0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165, + 0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169, + 0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D, + 0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171, + 0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175, + 0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179, + 0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D, + 0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181, + 0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185, + 0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189, + 0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D, + 0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49, + 0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F, + 0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55, + 0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59, + 0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62, + 0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66, + 0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B, + 0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F, + 0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73, + 0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77, + 0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B, + 0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80, + 0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85, + 0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89, + 0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D, + 0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91, + 0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95, + 0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A, + 0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E, + 0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2, + 0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6, + 0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172, + 0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176, + 0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160, + 0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164, + 0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168, + 0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393, + 0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397, + 0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B, + 0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F, + 0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4, + 0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8, + 0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3, + 0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7, + 0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB, + 0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF, + 0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4, + 0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8, + 0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA, + 0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE, + 0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2, + 0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6, + 0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA, + 0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1, + 0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6, + 0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA, + 0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2, + 0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7, + 0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD, + 0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2, + 0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6, + 0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA, + 0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF, + 0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3, + 0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8, + 0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC, + 0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00, + 0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04, + 0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09, + 0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C, + 0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C, + 0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C, + 0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513, + 0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533, + 0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520, + 0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F, + 0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538, + 0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A, + 0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E, + 0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521, + 0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529, + 0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531, + 0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539, + 0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540, + 0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545, + 0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549, + 0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D, + 0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12, + 0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17, + 0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C, + 0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22, + 0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26, + 0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A, + 0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E, + 0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32, + 0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36, + 0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A, + 0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E, + 0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43, + 0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47, + 0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E, + 0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53, + 0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57, + 0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E, + 0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62, + 0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67, + 0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B, + 0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397, + 0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3, + 0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399, + 0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D, + 0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1, + 0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E, + 0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389, + 0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0, + 0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4, + 0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8, + 0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382, + 0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB, + 0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF, + 0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393, + 0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1, + 0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6, + 0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF, + 0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB, + 0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3, + 0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6, + 0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70, + 0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74, + 0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A, + 0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E, + 0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82, + 0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86, + 0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A, + 0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E, + 0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92, + 0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96, + 0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A, + 0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F, + 0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3, + 0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7, + 0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB, + 0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF, + 0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3, + 0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7, + 0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC, + 0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0, + 0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4, + 0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126, + 0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8, + 0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166, + 0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262, + 0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266, + 0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A, + 0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E, + 0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272, + 0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276, + 0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A, + 0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2, + 0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6, + 0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA, + 0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE, + 0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2, + 0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6, + 0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460, + 0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464, + 0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468, + 0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C, + 0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153, + 0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B, + 0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5, + 0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9, + 0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD, + 0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1, + 0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6, + 0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA, + 0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE, + 0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2, + 0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8, + 0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED, + 0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1, + 0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5, + 0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9, + 0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD, + 0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01, + 0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05, + 0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09, + 0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F, + 0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15, + 0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19, + 0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F, + 0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6, + 0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131, + 0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142, + 0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE, + 0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200, + 0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204, + 0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208, + 0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C, + 0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210, + 0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214, + 0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218, + 0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C, + 0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0, + 0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4, + 0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8, + 0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC, + 0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0, + 0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4, + 0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476, + 0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A, + 0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E, + 0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482, + 0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074, + 0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083, + 0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A, + 0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31, + 0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35, + 0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F, + 0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43, + 0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A, + 0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F, + 0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53, + 0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C, + 0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61, + 0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67, + 0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C, + 0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71, + 0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76, + 0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A, + 0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E, + 0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82, + 0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86, + 0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A, + 0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E, + 0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92, + 0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043, + 0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047, + 0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B, + 0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F, + 0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053, + 0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057, + 0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B, + 0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F, + 0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063, + 0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067, + 0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B, + 0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F, + 0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073, + 0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077, + 0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B, + 0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F, + 0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083, + 0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087, + 0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B, + 0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F, + 0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093, + 0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97, + 0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E, + 0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3, + 0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7, + 0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0, + 0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6, + 0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB, + 0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0, + 0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6, + 0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC, + 0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1, + 0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6, + 0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA, + 0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE, + 0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2, + 0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7, + 0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB, + 0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1, + 0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5, + 0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9, + 0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD, + 0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4, + 0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8, + 0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC, + 0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0, + 0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4, + 0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8, + 0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC, + 0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0, + 0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4, + 0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8, + 0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC, + 0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0, + 0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4, + 0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8, + 0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC, + 0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0, + 0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4, + 0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8, + 0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC, + 0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0, + 0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4, + 0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF, + 0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04, + 0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A, + 0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F, + 0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14, + 0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A, + 0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20, + 0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25, + 0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A, + 0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F, + 0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33, + 0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37, + 0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C, + 0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40, + 0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44, + 0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48, + 0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C, + 0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50, + 0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54, + 0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58, + 0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D, + 0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411, + 0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415, + 0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418, + 0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C, + 0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420, + 0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424, + 0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428, + 0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C, + 0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430, + 0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434, + 0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437, + 0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B, + 0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F, + 0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443, + 0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447, + 0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B, + 0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F, + 0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65, + 0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69, + 0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70, + 0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75, + 0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A, + 0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E, + 0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82, + 0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86, + 0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B, + 0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F, + 0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93, + 0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A, + 0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F, + 0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3, + 0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB, + 0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF, + 0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4, + 0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8, + 0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC, + 0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0, + 0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5, + 0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9, + 0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE, + 0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3, + 0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7, + 0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB, + 0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF, + 0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3, + 0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7, + 0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED, + 0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2, + 0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6, + 0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE, + 0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02, + 0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07, + 0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D, + 0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11, + 0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16, + 0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B, + 0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F, + 0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26, + 0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B, + 0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F, + 0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37, + 0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B, + 0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F, + 0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43, + 0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47, + 0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B, + 0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F, + 0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53, + 0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57, + 0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E, + 0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65, + 0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C, + 0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71, + 0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77, + 0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D, + 0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81, + 0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88, + 0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D, + 0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93, + 0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99, + 0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D, + 0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6, + 0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA, + 0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0, + 0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4, + 0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8, + 0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC, + 0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0, + 0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5, + 0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9, + 0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD, + 0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1, + 0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5, + 0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9, + 0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD, + 0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1, + 0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7, + 0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE, + 0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2, + 0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB, + 0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF, + 0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07, + 0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10, + 0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14, + 0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19, + 0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D, + 0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D, + 0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38, + 0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B, + 0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C, + 0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77, + 0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81, + 0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86, + 0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C, + 0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D, + 0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8, + 0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF, + 0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB, + 0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4, + 0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7, + 0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7, + 0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF, + 0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5, + 0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00, + 0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03, + 0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09, + 0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D, + 0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14, + 0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19, + 0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E, + 0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23, + 0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28, + 0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E, + 0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35, + 0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A, + 0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E, + 0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42, + 0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46, + 0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A, + 0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E, + 0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52, + 0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59, + 0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E, + 0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62, + 0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A, + 0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D, + 0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C, + 0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D, + 0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C, + 0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49, + 0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61, + 0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70, + 0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76, + 0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F, + 0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89, + 0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D, + 0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1, + 0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1, + 0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4, + 0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF, + 0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09, + 0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30, + 0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38, + 0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43, + 0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C, + 0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54, + 0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F, + 0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68, + 0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78, + 0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72, + 0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77, + 0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C, + 0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81, + 0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86, + 0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A, + 0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F, + 0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93, + 0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97, + 0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B, + 0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F, + 0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4, + 0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9, + 0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD, + 0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2, + 0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6, + 0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA, + 0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE, + 0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2, + 0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7, + 0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB, + 0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D, + 0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC, + 0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4, + 0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0, + 0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC, + 0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4, + 0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08, + 0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D, + 0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C, + 0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42, + 0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50, + 0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65, + 0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88, + 0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C, + 0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0, + 0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB, + 0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC, + 0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1, + 0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001, + 0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014, + 0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044, + 0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C, + 0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055, + 0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD, + 0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1, + 0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5, + 0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9, + 0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD, + 0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3, + 0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9, + 0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED, + 0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4, + 0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9, + 0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE, + 0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003, + 0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008, + 0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C, + 0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010, + 0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015, + 0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A, + 0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E, + 0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022, + 0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026, + 0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A, + 0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C, + 0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C, + 0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098, + 0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F, + 0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8, + 0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD, + 0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3, + 0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC, + 0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8, + 0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4, + 0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108, + 0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110, + 0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119, + 0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123, + 0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C, + 0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138, + 0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144, + 0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154, + 0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160, + 0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180, + 0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B, + 0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194, + 0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC, + 0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD, + 0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031, + 0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037, + 0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D, + 0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041, + 0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048, + 0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D, + 0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052, + 0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057, + 0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C, + 0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061, + 0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065, + 0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069, + 0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F, + 0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075, + 0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079, + 0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F, + 0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084, + 0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088, + 0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C, + 0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090, + 0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094, + 0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC, + 0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD, + 0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B, + 0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217, + 0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C, + 0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268, + 0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C, + 0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290, + 0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299, + 0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3, + 0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC, + 0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9, + 0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8, + 0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2, + 0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8, + 0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE, + 0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5, + 0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA, + 0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301, + 0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311, + 0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C, + 0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358, + 0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F, + 0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096, + 0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A, + 0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E, + 0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2, + 0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9, + 0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE, + 0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2, + 0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA, + 0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE, + 0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5, + 0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB, + 0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF, + 0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8, + 0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE, + 0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3, + 0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8, + 0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE, + 0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5, + 0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA, + 0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE, + 0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102, + 0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369, + 0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371, + 0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381, + 0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C, + 0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1, + 0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5, + 0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE, + 0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7, + 0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0, + 0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410, + 0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428, + 0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450, + 0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460, + 0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C, + 0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4, + 0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7, + 0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8, + 0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD, + 0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6, + 0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1, + 0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518, + 0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525, + 0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A, + 0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538, + 0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108, + 0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C, + 0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111, + 0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115, + 0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119, + 0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D, + 0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121, + 0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125, + 0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129, + 0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D, + 0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133, + 0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139, + 0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E, + 0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147, + 0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B, + 0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152, + 0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157, + 0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B, + 0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163, + 0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167, + 0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D, + 0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544, + 0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D, + 0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D, + 0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0, + 0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA, + 0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3, + 0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC, + 0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC, + 0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1, + 0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611, + 0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C, + 0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668, + 0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4, + 0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4, + 0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700, + 0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729, + 0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738, + 0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748, + 0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760, + 0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771, + 0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D, + 0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D, + 0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792, + 0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F, + 0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173, + 0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177, + 0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B, + 0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180, + 0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185, + 0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A, + 0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E, + 0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192, + 0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196, + 0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A, + 0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E, + 0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5, + 0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA, + 0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE, + 0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6, + 0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB, + 0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1, + 0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5, + 0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9, + 0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD, + 0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799, + 0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9, + 0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4, + 0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9, + 0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4, + 0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800, + 0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809, + 0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819, + 0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825, + 0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835, + 0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840, + 0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C, + 0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C, + 0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878, + 0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0, + 0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1, + 0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0, + 0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1, + 0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0, + 0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD, + 0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C, + 0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C, + 0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959, + 0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969, + 0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3, + 0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7, + 0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC, + 0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0, + 0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4, + 0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8, + 0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC, + 0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0, + 0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5, + 0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA, + 0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE, + 0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202, + 0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206, + 0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C, + 0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211, + 0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215, + 0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219, + 0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D, + 0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221, + 0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225, + 0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229, + 0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975, + 0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985, + 0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D, + 0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0, + 0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF, + 0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC, + 0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1, + 0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB, + 0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3, + 0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC, + 0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8, + 0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01, + 0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39, + 0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48, + 0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E, + 0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58, + 0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67, + 0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71, + 0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84, + 0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8, + 0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0, + 0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB, + 0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8, + 0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B, + 0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232, + 0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237, + 0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B, + 0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243, + 0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247, + 0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C, + 0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250, + 0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254, + 0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258, + 0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D, + 0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261, + 0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266, + 0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A, + 0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E, + 0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272, + 0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276, + 0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A, + 0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E, + 0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285, + 0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A, + 0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04, + 0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18, + 0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B, + 0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38, + 0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E, + 0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49, + 0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54, + 0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C, + 0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4, + 0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7, + 0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0, + 0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC, + 0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08, + 0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D, + 0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15, + 0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B, + 0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F, + 0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29, + 0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34, + 0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43, + 0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C, + 0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84, + 0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C, + 0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97, + 0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292, + 0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297, + 0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B, + 0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1, + 0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6, + 0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA, + 0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF, + 0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4, + 0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA, + 0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1, + 0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6, + 0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD, + 0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1, + 0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6, + 0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB, + 0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0, + 0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6, + 0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA, + 0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE, + 0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5, + 0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA, + 0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1, + 0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0, + 0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5, + 0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4, + 0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1, + 0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4, + 0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC, + 0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09, + 0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C, + 0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C, + 0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64, + 0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84, + 0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A, + 0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95, + 0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4, + 0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5, + 0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0, + 0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03, + 0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10, + 0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F, + 0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C, + 0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57, + 0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60, + 0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC, + 0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302, + 0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308, + 0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F, + 0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315, + 0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A, + 0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323, + 0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A, + 0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F, + 0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334, + 0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A, + 0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341, + 0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347, + 0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B, + 0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F, + 0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353, + 0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357, + 0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B, + 0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F, + 0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363, + 0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367, + 0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A, + 0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74, + 0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D, + 0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D, + 0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98, + 0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1, + 0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0, + 0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC, + 0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18, + 0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D, + 0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48, + 0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94, + 0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD, + 0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF, + 0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058, + 0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069, + 0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098, + 0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5, + 0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0, + 0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6, + 0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0, + 0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9, + 0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9, + 0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4, + 0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D, + 0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371, + 0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375, + 0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379, + 0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F, + 0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385, + 0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389, + 0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392, + 0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396, + 0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D, + 0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2, + 0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6, + 0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE, + 0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2, + 0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7, + 0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD, + 0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1, + 0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7, + 0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD, + 0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2, + 0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6, + 0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4, + 0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100, + 0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115, + 0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F, + 0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126, + 0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F, + 0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138, + 0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148, + 0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D, + 0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C, + 0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168, + 0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178, + 0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E, + 0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C, + 0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5, + 0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0, + 0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC, + 0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0, + 0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1, + 0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200, + 0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F, + 0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C, + 0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229, + 0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9, + 0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD, + 0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2, + 0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7, + 0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB, + 0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2, + 0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7, + 0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB, + 0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403, + 0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407, + 0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C, + 0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410, + 0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414, + 0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418, + 0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C, + 0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421, + 0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425, + 0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429, + 0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D, + 0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431, + 0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435, + 0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231, + 0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250, + 0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260, + 0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270, + 0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F, + 0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290, + 0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4, + 0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD, + 0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9, + 0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3, + 0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED, + 0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8, + 0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300, + 0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D, + 0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318, + 0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328, + 0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369, + 0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378, + 0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384, + 0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8, + 0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0, + 0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED, + 0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408, + 0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430, + 0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B, + 0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F, + 0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445, + 0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449, + 0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D, + 0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451, + 0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455, + 0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459, + 0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E, + 0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463, + 0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468, + 0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C, + 0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472, + 0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476, + 0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D, + 0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484, + 0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A, + 0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490, + 0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495, + 0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499, + 0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D, + 0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448, + 0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C, + 0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480, + 0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC, + 0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4, + 0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500, + 0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514, + 0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C, + 0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B, + 0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548, + 0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D, + 0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555, + 0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D, + 0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564, + 0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573, + 0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D, + 0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C, + 0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595, + 0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0, + 0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8, + 0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD, + 0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6, + 0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA, + 0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F, + 0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3, + 0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7, + 0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC, + 0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0, + 0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4, + 0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8, + 0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC, + 0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0, + 0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4, + 0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8, + 0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD, + 0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2, + 0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7, + 0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB, + 0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1, + 0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5, + 0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA, + 0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF, + 0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4, + 0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9, + 0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1, + 0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1, + 0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED, + 0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6, + 0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE, + 0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605, + 0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C, + 0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B, + 0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628, + 0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630, + 0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637, + 0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641, + 0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651, + 0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C, + 0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F, + 0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C, + 0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B, + 0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698, + 0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7, + 0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4, + 0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0, + 0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC, + 0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC, + 0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8, + 0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501, + 0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506, + 0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B, + 0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510, + 0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516, + 0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B, + 0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F, + 0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523, + 0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527, + 0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B, + 0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F, + 0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533, + 0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537, + 0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B, + 0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542, + 0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547, + 0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B, + 0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553, + 0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557, + 0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E, + 0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563, + 0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8, + 0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705, + 0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715, + 0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721, + 0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731, + 0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C, + 0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A, + 0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751, + 0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755, + 0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C, + 0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774, + 0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D, + 0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785, + 0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A, + 0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794, + 0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A, + 0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4, + 0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD, + 0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD, + 0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8, + 0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0, + 0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8, + 0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804, + 0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566, + 0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E, + 0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572, + 0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579, + 0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E, + 0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582, + 0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B, + 0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F, + 0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594, + 0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598, + 0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C, + 0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0, + 0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4, + 0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9, + 0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD, + 0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1, + 0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5, + 0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9, + 0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD, + 0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1, + 0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5, + 0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811, + 0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C, + 0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C, + 0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838, + 0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849, + 0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870, + 0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A, + 0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885, + 0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C, + 0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F, + 0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD, + 0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4, + 0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0, + 0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC, + 0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905, + 0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F, + 0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934, + 0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958, + 0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C, + 0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988, + 0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998, + 0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0, + 0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8, + 0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3, + 0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE, + 0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4, + 0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA, + 0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0, + 0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6, + 0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB, + 0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0, + 0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6, + 0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC, + 0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602, + 0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607, + 0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C, + 0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612, + 0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619, + 0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E, + 0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623, + 0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628, + 0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C, + 0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631, + 0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635, + 0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B, + 0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA, + 0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2, + 0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED, + 0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8, + 0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08, + 0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D, + 0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C, + 0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C, + 0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61, + 0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98, + 0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4, + 0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1, + 0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0, + 0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10, + 0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21, + 0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C, + 0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D, + 0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C, + 0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7, + 0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10, + 0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21, + 0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29, + 0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38, + 0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E, + 0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643, + 0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A, + 0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650, + 0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657, + 0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D, + 0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661, + 0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665, + 0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B, + 0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F, + 0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676, + 0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A, + 0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E, + 0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682, + 0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688, + 0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E, + 0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693, + 0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698, + 0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C, + 0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3, + 0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7, + 0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D, + 0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48, + 0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57, + 0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64, + 0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75, + 0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0, + 0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC, + 0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8, + 0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7, + 0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4, + 0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08, + 0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18, + 0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24, + 0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C, + 0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D, + 0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88, + 0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C, + 0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9, + 0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0, + 0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8, + 0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04, + 0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19, + 0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28, + 0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35, + 0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF, + 0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4, + 0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8, + 0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE, + 0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2, + 0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9, + 0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE, + 0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3, + 0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA, + 0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE, + 0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3, + 0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9, + 0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED, + 0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2, + 0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7, + 0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB, + 0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702, + 0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707, + 0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B, + 0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F, + 0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714, + 0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F, + 0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69, + 0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75, + 0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85, + 0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91, + 0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1, + 0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC, + 0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5, + 0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4, + 0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9, + 0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08, + 0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15, + 0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C, + 0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31, + 0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58, + 0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67, + 0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74, + 0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C, + 0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4, + 0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8, + 0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5, + 0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011, + 0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035, + 0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716, + 0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D, + 0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722, + 0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726, + 0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E, + 0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732, + 0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739, + 0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E, + 0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742, + 0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748, + 0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D, + 0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753, + 0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C, + 0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762, + 0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768, + 0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E, + 0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773, + 0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778, + 0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E, + 0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783, + 0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787, + 0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045, + 0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054, + 0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D, + 0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D, + 0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8, + 0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7, + 0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4, + 0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1, + 0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC, + 0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC, + 0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1, + 0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131, + 0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140, + 0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145, + 0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154, + 0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161, + 0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184, + 0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4, + 0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3, + 0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0, + 0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207, + 0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D, + 0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D, + 0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C, + 0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791, + 0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795, + 0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C, + 0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1, + 0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280, + 0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290, + 0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0, + 0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8, + 0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0, + 0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB, + 0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4, + 0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4, + 0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303, + 0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E, + 0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C, + 0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321, + 0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C, + 0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B, + 0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345, + 0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384, + 0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390, + 0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C, + 0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB, + 0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC, + 0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9, + 0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3, + 0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4, + 0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401, + 0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444, + 0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D, + 0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C, + 0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488, + 0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494, + 0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4, + 0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC, + 0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD, + 0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514, + 0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D, + 0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D, + 0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559, + 0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568, + 0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574, + 0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584, + 0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589, + 0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9, + 0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8, + 0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4, + 0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4, + 0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600, + 0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610, + 0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615, + 0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D, + 0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640, + 0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B, + 0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655, + 0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669, + 0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683, + 0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690, + 0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1, + 0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9, + 0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8, + 0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7, + 0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8, + 0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD, + 0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718, + 0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728, + 0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734, + 0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744, + 0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751, + 0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758, + 0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763, + 0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770, + 0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781, + 0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790, + 0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D, + 0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9, + 0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5, + 0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687, + 0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C, + 0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB, + 0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36, + 0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6, + 0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404, + 0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF, + 0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3, + 0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978, + 0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7, + 0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F, + 0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5, + 0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D, + 0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593, + 0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34, + 0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910, + 0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E, + 0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE, + 0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44, + 0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3, + 0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451, + 0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC, + 0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598, + 0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1, + 0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A, + 0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586, + 0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C, + 0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941, + 0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47, + 0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1, + 0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168, + 0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5, + 0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5, + 0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B, + 0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901, + 0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028, + 0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2, + 0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20, + 0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E, + 0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8, + 0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE, + 0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171, + 0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B, + 0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840, + 0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2, + 0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB, + 0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9, + 0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84, + 0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694, + 0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504, + 0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B, + 0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289, + 0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A, + 0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D, + 0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC, + 0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106, + 0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770, + 0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176, + 0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F, + 0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87, + 0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5, + 0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC, + 0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93, + 0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396, + 0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1, + 0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8, + 0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951, + 0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212, + 0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA, + 0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D, + 0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08, + 0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4, + 0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471, + 0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B, + 0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545, + 0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1, + 0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E, + 0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1, + 0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0, + 0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5, + 0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7, + 0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED, + 0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40, + 0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764, + 0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD, + 0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4, + 0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B, + 0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54, + 0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1, + 0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A, + 0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32, + 0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC, + 0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2, + 0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846, + 0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED, + 0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC, + 0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C, + 0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50, + 0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC, + 0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC, + 0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321, + 0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38, + 0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50, + 0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B, + 0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A, + 0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0, + 0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18, + 0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1, + 0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0, + 0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821, + 0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF, + 0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E, + 0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA, + 0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18, + 0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1, + 0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3, + 0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775, + 0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0, + 0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8, + 0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6, + 0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078, + 0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF, + 0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009, + 0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF, + 0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0, + 0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6, + 0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7, + 0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA, + 0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B, + 0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD, + 0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398, + 0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79, + 0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026, + 0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708, + 0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3, + 0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568, + 0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3, + 0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B, + 0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4, + 0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D, + 0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA, + 0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE, + 0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035, + 0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547, + 0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908, + 0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287, + 0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699, + 0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3, + 0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E, + 0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2, + 0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909, + 0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611, + 0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD, + 0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F, + 0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA, + 0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A, + 0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC, + 0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176, + 0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B, + 0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947, + 0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E, + 0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280, + 0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F, + 0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F, + 0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82, + 0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A, + 0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F, + 0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947, + 0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00, + 0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D, + 0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48, + 0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2, + 0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65, + 0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409, + 0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB, + 0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C, + 0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF, + 0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911, + 0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914, + 0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918, + 0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B, + 0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156, + 0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920, + 0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921, + 0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922, + 0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925, + 0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872, + 0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929, + 0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43, + 0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0, + 0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74, + 0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C, + 0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7, + 0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29, + 0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932, + 0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935, + 0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1, + 0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C, + 0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940, + 0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3, + 0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2, + 0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166, + 0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A, + 0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E, + 0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9, + 0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952, + 0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956, + 0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959, + 0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA, + 0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6, + 0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7, + 0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80, + 0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF, + 0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892, + 0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE, + 0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556, + 0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7, + 0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9, + 0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541, + 0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F, + 0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F, + 0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858, + 0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0, + 0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8, + 0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927, + 0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85, + 0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA, + 0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB, + 0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012, + 0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835, + 0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6, + 0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC, + 0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843, + 0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21, + 0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC, + 0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404, + 0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48, + 0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD, + 0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2, + 0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368, + 0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B, + 0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566, + 0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E, + 0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D, + 0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD, + 0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771, + 0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C, + 0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4, + 0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597, + 0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7, + 0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017, + 0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A, + 0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97, + 0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B, + 0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127, + 0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B, + 0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA, + 0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B, + 0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D, + 0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E, + 0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12, + 0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E, + 0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5, + 0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43, + 0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD, + 0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA, + 0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405, + 0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86, + 0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7, + 0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006, + 0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11, + 0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F, + 0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6, + 0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC, + 0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA, + 0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823, + 0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97, + 0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77, + 0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742, + 0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23, + 0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F, + 0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A, + 0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C, + 0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582, + 0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375, + 0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F, + 0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2, + 0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046, + 0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748, + 0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7, + 0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE, + 0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3, + 0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7, + 0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF, + 0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA, + 0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0, + 0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93, + 0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727, + 0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E, + 0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA, + 0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7, + 0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6, + 0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD, + 0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27, + 0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62, + 0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B, + 0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938, + 0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2, + 0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C, + 0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559, + 0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E, + 0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96, + 0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8, + 0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817, + 0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B, + 0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C, + 0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA, + 0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E, + 0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8, + 0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406, + 0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C, + 0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF, + 0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2, + 0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0, + 0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3, + 0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB, + 0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C, + 0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469, + 0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8, + 0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE, + 0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB, + 0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29, + 0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D, + 0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B, + 0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513, + 0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B, + 0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB, + 0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1, + 0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B, + 0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B, + 0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB, + 0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627, + 0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164, + 0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081, + 0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C, + 0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13, + 0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C, + 0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195, + 0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704, + 0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762, + 0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5, + 0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D, + 0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791, + 0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169, + 0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE, + 0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D, + 0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE, + 0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB, + 0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738, + 0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305, + 0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728, + 0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766, + 0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92, + 0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F, + 0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF, + 0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B, + 0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9, + 0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A, + 0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959, + 0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7, + 0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302, + 0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727, + 0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011, + 0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587, + 0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E, + 0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF, + 0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A, + 0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE, + 0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C, + 0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E, + 0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761, + 0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D, + 0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC, + 0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9, + 0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C, + 0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD, + 0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38, + 0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94, + 0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236, + 0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1, + 0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB, + 0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591, + 0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED, + 0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC, + 0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46, + 0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812, + 0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5, + 0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB, + 0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43, + 0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8, + 0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F, + 0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609, + 0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5, + 0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B, + 0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A, + 0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90, + 0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9, + 0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F, + 0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC, + 0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919, + 0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A, + 0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF, + 0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44, + 0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4, + 0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543, + 0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F, + 0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06, + 0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB, + 0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5, + 0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1, + 0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656, + 0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739, + 0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A, + 0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225, + 0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19, + 0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77, + 0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5, + 0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9, + 0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08, + 0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6, + 0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A, + 0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9, + 0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14, + 0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C, + 0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F, + 0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907, + 0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5, + 0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8, + 0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0, + 0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2, + 0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702, + 0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D, + 0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256, + 0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0, + 0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75, + 0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276, + 0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5, + 0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36, + 0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240, + 0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0, + 0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA, + 0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644, + 0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206, + 0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954, + 0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E, + 0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6, + 0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC, + 0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B, + 0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29, + 0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43, + 0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315, + 0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62, + 0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249, + 0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7, + 0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8, + 0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA, + 0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8, + 0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5, + 0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A, + 0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB, + 0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B, + 0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C, + 0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1, + 0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7, + 0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37, + 0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B, + 0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C, + 0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2, + 0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB, + 0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB, + 0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B, + 0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C, + 0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD, + 0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23, + 0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E, + 0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9, + 0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D, + 0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF, + 0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC, + 0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC, + 0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969, + 0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A, + 0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA, + 0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C, + 0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492, + 0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09, + 0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17, + 0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7, + 0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A, + 0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546, + 0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19, + 0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0, + 0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61, + 0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0, + 0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4, + 0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61, + 0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD, + 0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61, + 0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F, + 0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885, + 0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6, + 0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F, + 0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8, + 0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E, + 0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72, + 0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F, + 0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD, + 0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D, + 0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790, + 0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3, + 0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B, + 0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584, + 0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E, + 0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401, + 0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C, + 0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8, + 0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A, + 0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078, + 0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE, + 0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4, + 0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B, + 0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA, + 0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2, + 0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583, + 0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE, + 0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC, + 0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F, + 0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB, + 0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072, + 0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16, + 0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05, + 0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0, + 0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5, + 0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240, + 0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3, + 0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F, + 0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F, + 0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0, + 0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C, + 0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D, + 0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6, + 0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F, + 0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16, + 0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD, + 0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1, + 0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E, + 0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001, + 0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051, + 0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7, + 0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA, + 0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88, + 0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101, + 0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C, + 0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A, + 0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7, + 0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2, + 0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57, + 0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC, + 0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331, + 0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896, + 0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042, + 0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9, + 0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6, + 0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3, + 0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919, + 0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A, + 0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085, + 0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA, + 0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F, + 0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3, + 0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D, + 0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340, + 0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4, + 0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4, + 0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265, + 0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F, + 0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE, + 0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E, + 0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347, + 0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805, + 0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636, + 0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E, + 0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043, + 0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE, + 0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A, + 0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996, + 0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55, + 0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F, + 0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96, + 0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755, + 0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE, + 0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B, + 0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0, + 0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E, + 0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398, + 0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A, + 0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5, + 0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089, + 0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81, + 0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A, + 0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341, + 0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E, + 0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25, + 0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD, + 0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D, + 0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09, + 0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD, + 0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1, + 0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354, + 0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89, + 0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848, + 0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854, + 0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB, + 0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6, + 0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4, + 0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE, + 0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F, + 0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26, + 0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16, + 0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D, + 0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384, + 0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A, + 0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C, + 0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B, + 0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6, + 0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974, + 0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976, + 0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB, + 0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F, + 0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43, + 0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D, + 0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23, + 0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2, + 0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B, + 0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D, + 0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E, + 0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC, + 0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E, + 0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104, + 0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6, + 0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109, + 0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616, + 0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944, + 0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D, + 0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F, + 0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982, + 0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984, + 0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207, + 0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D, + 0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988, + 0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF, + 0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C, + 0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D, + 0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827, + 0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E, + 0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350, + 0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87, + 0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5, + 0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136, + 0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5, + 0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995, + 0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F, + 0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998, + 0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B, + 0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E, + 0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1, + 0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD, + 0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3, + 0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430, + 0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB, + 0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7, + 0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9, + 0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8, + 0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E, + 0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3, + 0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B, + 0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370, + 0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4, + 0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF, + 0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE, + 0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719, + 0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A, + 0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3, + 0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F, + 0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602, + 0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D, + 0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8, + 0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D, + 0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E, + 0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA, + 0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F, + 0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF, + 0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3, + 0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D, + 0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07, + 0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389, + 0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F, + 0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140, + 0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515, + 0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD, + 0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9, + 0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778, + 0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B, + 0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9, + 0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9, + 0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E, + 0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0, + 0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A, + 0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A, + 0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD, + 0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB, + 0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D, + 0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC, + 0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416, + 0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC, + 0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF, + 0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF, + 0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170, + 0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20, + 0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952, + 0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F, + 0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD, + 0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889, + 0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995, + 0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194, + 0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073, + 0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394, + 0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51, + 0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB, + 0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24, + 0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B, + 0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950, + 0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD, + 0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2, + 0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685, + 0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67, + 0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C, + 0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91, + 0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90, + 0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553, + 0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB, + 0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A, + 0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1, + 0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B, + 0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F, + 0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72, + 0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457, + 0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060, + 0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B, + 0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D, + 0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D, + 0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170, + 0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B, + 0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466, + 0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918, + 0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F, + 0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A, + 0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A, + 0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE, + 0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109, + 0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8, + 0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961, + 0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA, + 0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336, + 0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531, + 0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF, + 0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5, + 0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30, + 0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A, + 0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0, + 0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3, + 0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4, + 0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5, + 0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4, + 0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F, + 0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB, + 0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68, + 0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069, + 0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280, + 0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB, + 0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE, + 0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD, + 0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D, + 0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F, + 0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5, + 0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264, + 0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC, + 0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5, + 0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937, + 0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B, + 0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1, + 0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5, + 0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5, + 0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033, + 0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7, + 0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087, + 0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C, + 0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA, + 0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A, + 0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370, + 0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB, + 0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E, + 0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335, + 0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1, + 0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3, + 0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9, + 0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0, + 0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A, + 0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5, + 0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3, + 0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8, + 0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55, + 0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8, + 0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57, + 0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB, + 0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7, + 0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005, + 0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9, + 0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C, + 0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628, + 0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD, + 0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72, + 0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A, + 0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B, + 0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC, + 0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834, + 0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07, + 0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C, + 0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3, + 0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA, + 0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7, + 0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A, + 0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF, + 0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577, + 0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728, + 0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D, + 0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D, + 0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09, + 0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F, + 0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E, + 0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95, + 0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17, + 0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A, + 0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7, + 0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B, + 0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8, + 0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A, + 0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575, + 0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684, + 0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E, + 0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA, + 0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA, + 0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43, + 0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178, + 0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C, + 0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB, + 0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF, + 0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420, + 0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672, + 0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6, + 0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49, + 0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B, + 0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E, + 0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59, + 0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76, + 0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38, + 0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E, + 0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776, + 0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C, + 0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A, + 0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81, + 0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574, + 0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE, + 0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40, + 0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E, + 0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD, + 0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E, + 0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E, + 0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E, + 0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266, + 0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756, + 0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236, + 0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D, + 0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF, + 0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD, + 0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44, + 0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D, + 0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146, + 0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14, + 0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9, + 0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D, + 0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15, + 0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A, + 0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A, + 0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97, + 0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087, + 0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF, + 0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D, + 0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5, + 0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3, + 0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9, + 0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E, + 0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9, + 0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C, + 0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35, + 0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750, + 0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A, + 0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A, + 0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468, + 0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE, + 0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1, + 0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A, + 0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587, + 0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2, + 0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85, + 0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031, + 0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0, + 0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101, + 0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB, + 0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96, + 0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3, + 0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB, + 0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2, + 0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB, + 0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E, + 0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD, + 0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8, + 0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA, + 0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7, + 0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F, + 0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3, + 0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C, + 0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957, + 0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3, + 0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C, + 0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072, + 0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54, + 0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875, + 0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B, + 0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25, + 0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1, + 0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E, + 0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D, + 0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A, + 0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032, + 0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707, + 0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9, + 0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE, + 0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED, + 0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F, + 0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57, + 0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6, + 0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14, + 0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF, + 0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64, + 0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49, + 0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E, + 0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F, + 0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6, + 0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12, + 0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A, + 0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C, + 0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D, + 0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879, + 0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC, + 0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009, + 0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C, + 0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E, + 0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD, + 0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621, + 0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6, + 0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0, + 0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826, + 0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7, + 0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56, + 0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD, + 0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254, + 0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3, + 0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620, + 0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB, + 0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929, + 0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA, + 0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6, + 0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7, + 0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8, + 0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4, + 0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D, + 0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE, + 0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D, + 0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E, + 0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252, + 0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC, + 0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8, + 0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751, + 0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF, + 0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6, + 0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D, + 0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284, + 0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A, + 0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D, + 0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D, + 0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349, + 0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162, + 0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1, + 0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8, + 0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8, + 0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4, + 0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070, + 0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC, + 0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD, + 0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E, + 0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB, + 0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD, + 0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310, + 0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36, + 0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D, + 0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E, + 0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8, + 0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443, + 0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145, + 0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D, + 0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403, + 0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634, + 0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0, + 0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3, + 0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074, + 0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C, + 0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4, + 0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894, + 0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4, + 0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49, + 0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4, + 0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3, + 0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED, + 0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06, + 0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88, + 0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD, + 0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31, + 0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E, + 0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253, + 0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235, + 0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C, + 0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01, + 0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B, + 0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422, + 0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451, + 0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A, + 0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB, + 0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2, + 0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854, + 0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11, + 0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C, + 0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B, + 0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E, + 0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0, + 0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4, + 0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410, + 0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876, + 0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71, + 0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F, + 0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078, + 0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F, + 0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6, + 0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A, + 0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2, + 0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834, + 0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817, + 0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248, + 0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211, + 0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C, + 0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557, + 0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD, + 0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D, + 0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E, + 0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247, + 0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D, + 0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A, + 0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55, + 0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2, + 0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D, + 0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305, + 0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA, + 0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B, + 0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1, + 0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE, + 0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2, + 0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA, + 0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4, + 0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07, + 0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153, + 0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2, + 0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7, + 0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F, + 0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8, + 0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2, + 0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642, + 0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC, + 0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46, + 0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C, + 0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F, + 0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455, + 0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050, + 0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78, + 0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2, + 0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57, + 0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55, + 0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650, + 0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD, + 0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A, + 0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266, + 0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408, + 0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4, + 0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09, + 0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052, + 0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86, + 0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A, + 0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5, + 0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A, + 0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977, + 0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3, + 0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED, + 0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016, + 0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C, + 0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6, + 0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957, + 0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B, + 0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B, + 0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57, + 0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769, + 0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8, + 0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384, + 0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D, + 0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237, + 0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249, + 0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840, + 0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354, + 0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79, + 0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2, + 0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144, + 0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2, + 0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF, + 0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A, + 0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2, + 0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57, + 0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559, + 0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E, + 0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA, + 0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236, + 0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB, + 0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8, + 0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D, + 0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0, + 0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E, + 0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF, + 0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77, + 0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865, + 0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A, + 0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F, + 0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F, + 0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3, + 0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679, + 0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C, + 0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575, + 0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF, + 0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774, + 0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA, + 0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A, + 0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3, + 0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853, + 0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08, + 0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B, + 0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA, + 0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D, + 0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643, + 0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F, + 0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C, + 0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352, + 0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3, + 0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A, + 0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666, + 0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE, + 0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE, + 0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4, + 0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B, + 0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D, + 0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F, + 0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4, + 0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019, + 0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589, + 0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D, + 0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB, + 0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104, + 0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13, + 0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684, + 0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599, + 0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE, + 0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D, + 0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB, + 0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E, + 0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308, + 0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615, + 0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403, + 0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20, + 0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070, + 0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6, + 0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD, + 0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199, + 0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6, + 0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7, + 0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70, + 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (src < 0x80) { /* ASCII */ + c = src; + } else { + if (dir) { /* OEMCP to unicode */ + p = oem2uni; + hi = sizeof(oem2uni) / 4 - 1; + } else { /* Unicode to OEMCP */ + p = uni2oem; + hi = sizeof(uni2oem) / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (src == p[i * 2]) break; + if (src > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/Lib/Fat/src/option/cc950.c b/Lib/Fat/src/option/cc950.c new file mode 100644 index 0000000..f58c9a4 --- /dev/null +++ b/Lib/Fat/src/option/cc950.c @@ -0,0 +1,6829 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ +/* */ +/* CP950 (Traditional Chinese Big5) */ +/*------------------------------------------------------------------------*/ + +#include "../ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 950 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3, + 0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE, + 0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5, + 0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346, + 0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A, + 0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E, + 0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352, + 0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356, + 0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A, + 0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E, + 0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362, + 0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366, + 0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A, + 0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E, + 0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372, + 0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5, + 0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C, + 0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB, + 0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1, + 0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB, + 0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF, + 0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6, + 0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8, + 0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241, + 0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7, + 0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5, + 0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE, + 0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8, + 0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6, + 0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A, + 0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275, + 0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271, + 0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6, + 0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1, + 0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3, + 0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5, + 0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7, + 0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7, + 0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6, + 0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3, + 0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1, + 0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2, + 0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE, + 0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264, + 0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268, + 0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E, + 0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A, + 0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD, + 0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF, + 0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3, + 0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9, + 0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8, + 0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142, + 0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172, + 0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176, + 0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A, + 0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9, + 0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5, + 0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9, + 0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375, + 0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379, + 0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D, + 0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3, + 0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7, + 0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB, + 0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF, + 0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3, + 0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7, + 0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0, + 0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251, + 0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253, + 0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440, + 0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456, + 0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946, + 0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2, + 0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540, + 0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1, + 0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950, + 0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1, + 0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964, + 0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947, + 0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547, + 0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4, + 0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445, + 0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5, + 0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1, + 0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6, + 0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA, + 0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB, + 0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45, + 0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8, + 0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA, + 0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3, + 0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF, + 0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2, + 0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5, + 0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B, + 0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550, + 0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551, + 0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F, + 0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5, + 0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA, + 0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4, + 0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8, + 0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3, + 0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE, + 0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0, + 0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED, + 0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7, + 0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4, + 0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9, + 0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7, + 0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA, + 0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D, + 0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED, + 0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E, + 0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF, + 0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2, + 0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63, + 0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE, + 0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF, + 0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB, + 0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6, + 0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1, + 0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5, + 0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2, + 0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4, + 0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA, + 0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4, + 0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA, + 0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0, + 0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7, + 0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8, + 0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE, + 0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED, + 0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58, + 0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54, + 0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E, + 0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4, + 0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6, + 0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F, + 0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48, + 0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1, + 0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4, + 0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA, + 0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA, + 0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF, + 0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB, + 0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6, + 0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA, + 0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9, + 0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0, + 0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0, + 0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3, + 0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC, + 0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8, + 0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C, + 0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6, + 0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456, + 0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451, + 0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458, + 0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D, + 0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460, + 0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E, + 0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464, + 0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465, + 0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD, + 0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E, + 0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855, + 0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7, + 0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9, + 0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851, + 0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3, + 0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7, + 0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6, + 0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3, + 0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC, + 0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE, + 0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6, + 0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9, + 0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4, + 0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF, + 0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7, + 0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE, + 0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7, + 0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD, + 0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4, + 0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9, + 0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6, + 0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5, + 0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB, + 0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF, + 0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5, + 0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8, + 0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD, + 0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA, + 0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8, + 0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078, + 0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7, + 0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C, + 0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461, + 0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552, + 0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA, + 0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0, + 0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259, + 0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C, + 0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8, + 0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE, + 0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB, + 0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4, + 0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC, + 0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641, + 0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0, + 0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955, + 0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE, + 0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642, + 0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B, + 0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2, + 0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1, + 0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5, + 0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140, + 0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C, + 0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9, + 0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557, + 0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E, + 0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2, + 0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646, + 0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD, + 0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC, + 0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F, + 0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED, + 0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2, + 0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9, + 0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63, + 0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1, + 0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65, + 0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB, + 0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6, + 0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6, + 0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469, + 0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6, + 0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0, + 0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9, + 0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142, + 0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40, + 0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2, + 0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0, + 0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1, + 0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648, + 0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754, + 0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1, + 0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C, + 0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A, + 0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA, + 0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8, + 0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2, + 0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3, + 0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45, + 0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079, + 0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3, + 0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D, + 0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6, + 0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC, + 0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450, + 0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943, + 0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B, + 0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA, + 0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC, + 0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8, + 0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF, + 0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD, + 0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8, + 0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3, + 0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3, + 0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB, + 0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6, + 0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C, + 0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A, + 0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F, + 0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC, + 0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9, + 0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9, + 0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED, + 0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6, + 0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46, + 0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1, + 0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD, + 0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC, + 0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F, + 0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574, + 0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573, + 0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569, + 0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B, + 0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570, + 0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B, + 0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651, + 0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A, + 0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C, + 0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C, + 0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770, + 0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761, + 0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774, + 0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76, + 0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F, + 0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B, + 0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772, + 0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A, + 0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769, + 0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB, + 0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF, + 0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950, + 0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49, + 0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6, + 0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941, + 0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952, + 0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD, + 0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB, + 0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8, + 0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947, + 0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E, + 0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD, + 0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7, + 0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC, + 0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5, + 0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77, + 0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C, + 0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E, + 0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46, + 0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76, + 0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E, + 0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6, + 0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF, + 0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA, + 0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5, + 0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141, + 0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1, + 0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6, + 0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140, + 0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44, + 0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8, + 0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41, + 0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2, + 0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2, + 0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A, + 0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8, + 0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7, + 0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3, + 0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474, + 0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478, + 0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8, + 0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8, + 0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3, + 0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472, + 0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875, + 0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871, + 0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2, + 0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3, + 0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F, + 0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1, + 0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA, + 0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A, + 0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868, + 0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0, + 0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6, + 0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870, + 0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0, + 0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6, + 0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF, + 0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC, + 0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6, + 0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB, + 0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD, + 0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA, + 0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB, + 0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2, + 0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155, + 0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE, + 0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150, + 0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5, + 0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C, + 0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3, + 0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0, + 0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147, + 0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47, + 0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542, + 0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546, + 0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543, + 0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA, + 0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6, + 0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F, + 0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2, + 0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE, + 0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941, + 0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3, + 0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC, + 0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940, + 0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7, + 0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B, + 0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4, + 0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1, + 0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C, + 0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA, + 0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE, + 0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456, + 0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1, + 0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459, + 0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A, + 0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9, + 0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7, + 0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9, + 0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5, + 0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C, + 0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D, + 0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8, + 0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778, + 0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA, + 0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46, + 0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB, + 0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9, + 0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE, + 0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B, + 0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F, + 0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664, + 0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661, + 0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3, + 0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1, + 0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC, + 0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4, + 0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE, + 0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958, + 0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2, + 0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC, + 0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956, + 0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9, + 0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54, + 0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E, + 0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D, + 0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52, + 0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53, + 0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153, + 0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151, + 0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47, + 0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49, + 0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156, + 0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1, + 0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF, + 0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5, + 0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC, + 0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9, + 0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5, + 0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD, + 0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6, + 0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF, + 0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE, + 0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2, + 0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA, + 0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB, + 0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8, + 0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4, + 0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3, + 0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB, + 0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E, + 0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF, + 0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4, + 0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA, + 0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2, + 0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED, + 0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB, + 0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4, + 0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3, + 0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0, + 0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166, + 0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C, + 0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2, + 0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165, + 0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162, + 0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3, + 0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B, + 0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552, + 0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5, + 0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A, + 0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D, + 0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1, + 0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3, + 0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B, + 0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD, + 0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA, + 0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8, + 0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363, + 0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2, + 0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7, + 0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2, + 0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A, + 0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159, + 0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469, + 0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668, + 0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB, + 0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3, + 0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1, + 0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A, + 0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961, + 0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E, + 0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7, + 0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3, + 0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD, + 0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8, + 0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D, + 0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4, + 0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1, + 0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD, + 0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC, + 0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B, + 0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6, + 0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2, + 0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE, + 0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB, + 0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4, + 0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967, + 0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970, + 0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966, + 0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50, + 0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D, + 0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52, + 0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B, + 0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968, + 0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E, + 0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8, + 0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62, + 0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1, + 0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56, + 0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D, + 0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B, + 0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A, + 0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65, + 0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162, + 0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55, + 0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51, + 0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163, + 0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A, + 0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164, + 0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3, + 0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE, + 0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0, + 0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB, + 0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6, + 0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0, + 0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142, + 0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2, + 0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB, + 0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9, + 0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8, + 0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9, + 0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6, + 0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB, + 0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443, + 0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5, + 0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF, + 0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE, + 0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF, + 0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8, + 0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9, + 0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46, + 0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD, + 0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9, + 0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3, + 0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5, + 0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2, + 0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170, + 0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178, + 0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174, + 0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B, + 0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177, + 0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555, + 0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A, + 0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556, + 0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559, + 0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E, + 0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957, + 0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951, + 0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5, + 0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1, + 0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3, + 0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE, + 0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0, + 0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA, + 0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D, + 0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB, + 0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C, + 0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5, + 0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7, + 0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973, + 0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56, + 0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0, + 0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446, + 0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9, + 0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972, + 0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674, + 0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9, + 0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57, + 0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A, + 0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8, + 0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6, + 0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167, + 0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62, + 0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65, + 0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149, + 0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146, + 0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1, + 0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448, + 0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49, + 0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E, + 0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED, + 0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB, + 0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65, + 0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8, + 0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F, + 0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67, + 0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C, + 0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9, + 0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974, + 0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B, + 0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE, + 0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E, + 0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8, + 0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0, + 0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59, + 0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D, + 0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB, + 0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B, + 0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3, + 0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0, + 0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561, + 0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD, + 0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473, + 0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7, + 0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7, + 0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3, + 0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1, + 0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3, + 0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D, + 0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C, + 0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60, + 0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61, + 0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B, + 0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A, + 0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4, + 0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D, + 0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79, + 0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6, + 0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2, + 0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F, + 0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E, + 0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71, + 0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D, + 0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72, + 0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9, + 0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158, + 0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E, + 0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6, + 0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157, + 0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC, + 0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544, + 0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3, + 0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9, + 0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED, + 0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC, + 0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452, + 0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F, + 0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5, + 0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56, + 0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54, + 0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744, + 0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0, + 0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD, + 0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3, + 0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC, + 0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565, + 0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563, + 0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A, + 0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B, + 0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960, + 0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964, + 0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967, + 0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF, + 0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4, + 0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445, + 0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA, + 0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD, + 0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B, + 0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F, + 0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8, + 0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476, + 0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1, + 0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D, + 0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C, + 0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE, + 0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D, + 0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD, + 0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0, + 0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3, + 0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75, + 0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163, + 0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456, + 0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454, + 0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B, + 0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7, + 0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3, + 0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D, + 0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4, + 0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E, + 0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5, + 0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A, + 0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D, + 0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE, + 0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A, + 0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE, + 0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1, + 0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1, + 0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6, + 0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA, + 0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177, + 0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176, + 0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B, + 0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164, + 0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A, + 0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F, + 0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459, + 0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6, + 0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA, + 0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB, + 0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72, + 0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575, + 0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971, + 0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366, + 0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF, + 0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8, + 0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD, + 0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9, + 0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749, + 0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1, + 0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3, + 0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73, + 0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8, + 0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A, + 0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A, + 0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF, + 0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576, + 0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573, + 0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B, + 0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE, + 0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D, + 0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E, + 0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C, + 0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4, + 0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76, + 0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75, + 0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC, + 0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1, + 0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F, + 0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E, + 0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174, + 0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461, + 0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B, + 0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577, + 0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD, + 0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD, + 0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF, + 0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4, + 0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6, + 0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3, + 0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78, + 0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE, + 0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6, + 0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5, + 0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2, + 0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF, + 0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2, + 0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7, + 0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3, + 0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6, + 0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD, + 0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5, + 0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6, + 0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB, + 0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A, + 0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4, + 0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0, + 0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE, + 0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6, + 0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3, + 0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4, + 0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8, + 0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC, + 0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0, + 0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1, + 0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1, + 0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176, + 0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8, + 0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3, + 0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB, + 0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC, + 0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA, + 0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9, + 0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A, + 0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C, + 0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA, + 0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5, + 0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565, + 0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1, + 0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8, + 0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564, + 0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557, + 0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B, + 0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C, + 0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB, + 0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F, + 0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944, + 0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753, + 0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948, + 0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A, + 0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755, + 0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D, + 0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474, + 0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942, + 0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467, + 0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C, + 0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2, + 0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B, + 0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A, + 0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758, + 0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F, + 0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757, + 0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8, + 0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5, + 0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C, + 0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43, + 0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A, + 0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB, + 0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA, + 0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79, + 0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1, + 0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579, + 0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3, + 0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC, + 0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978, + 0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5, + 0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5, + 0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7, + 0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3, + 0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB, + 0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2, + 0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1, + 0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979, + 0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3, + 0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF, + 0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8, + 0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4, + 0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0, + 0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA, + 0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A, + 0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A, + 0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC, + 0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9, + 0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0, + 0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7, + 0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9, + 0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF, + 0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72, + 0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76, + 0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49, + 0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4, + 0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1, + 0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0, + 0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3, + 0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476, + 0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3, + 0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4, + 0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB, + 0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA, + 0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5, + 0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA, + 0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5, + 0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3, + 0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3, + 0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE, + 0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE, + 0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2, + 0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED, + 0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB, + 0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1, + 0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF, + 0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF, + 0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8, + 0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD, + 0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7, + 0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6, + 0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF, + 0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4, + 0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD, + 0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB, + 0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4, + 0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA, + 0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1, + 0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF, + 0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3, + 0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42, + 0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45, + 0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6, + 0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8, + 0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1, + 0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1, + 0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4, + 0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6, + 0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA, + 0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE, + 0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8, + 0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9, + 0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC, + 0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4, + 0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2, + 0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1, + 0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7, + 0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579, + 0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA, + 0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6, + 0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B, + 0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569, + 0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573, + 0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478, + 0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574, + 0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3, + 0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE, + 0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E, + 0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477, + 0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0, + 0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5, + 0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954, + 0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A, + 0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77, + 0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C, + 0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E, + 0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1, + 0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970, + 0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB, + 0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D, + 0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956, + 0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA, + 0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958, + 0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B, + 0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE, + 0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6, + 0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769, + 0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B, + 0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5, + 0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764, + 0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8, + 0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB, + 0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9, + 0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0, + 0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF, + 0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767, + 0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE, + 0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5, + 0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA, + 0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB, + 0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F, + 0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3, + 0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0, + 0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0, + 0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD, + 0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E, + 0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1, + 0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A, + 0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5, + 0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB, + 0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2, + 0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3, + 0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0, + 0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7, + 0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0, + 0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB, + 0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9, + 0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6, + 0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5, + 0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7, + 0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6, + 0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4, + 0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC, + 0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC, + 0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB, + 0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE, + 0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258, + 0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D, + 0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1, + 0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2, + 0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246, + 0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243, + 0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C, + 0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD, + 0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0, + 0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD, + 0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC, + 0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4, + 0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7, + 0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1, + 0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8, + 0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5, + 0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7, + 0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1, + 0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD, + 0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975, + 0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977, + 0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56, + 0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD, + 0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE, + 0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF, + 0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248, + 0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3, + 0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE, + 0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7, + 0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5, + 0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8, + 0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48, + 0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773, + 0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F, + 0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3, + 0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2, + 0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF, + 0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD, + 0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE, + 0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9, + 0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E, + 0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE, + 0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE, + 0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB, + 0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4, + 0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB, + 0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD, + 0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4, + 0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC, + 0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF, + 0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD, + 0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D, + 0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B, + 0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3, + 0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52, + 0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE, + 0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0, + 0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5, + 0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB, + 0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF, + 0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3, + 0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0, + 0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7, + 0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7, + 0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9, + 0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC, + 0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4, + 0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777, + 0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0, + 0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6, + 0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A, + 0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7, + 0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5, + 0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9, + 0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9, + 0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6, + 0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4, + 0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8, + 0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7, + 0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7, + 0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB, + 0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D, + 0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450, + 0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA, + 0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2, + 0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1, + 0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0, + 0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA, + 0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2, + 0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA, + 0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3, + 0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2, + 0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB, + 0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC, + 0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE, + 0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5, + 0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3, + 0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF, + 0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE, + 0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42, + 0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7, + 0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA, + 0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9, + 0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE, + 0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D, + 0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48, + 0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49, + 0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8, + 0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F, + 0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3, + 0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44, + 0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52, + 0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8, + 0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2, + 0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0, + 0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56, + 0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B, + 0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE, + 0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51, + 0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58, + 0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63, + 0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66, + 0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56, + 0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63, + 0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67, + 0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48, + 0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E, + 0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59, + 0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57, + 0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D, + 0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E, + 0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA, + 0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB, + 0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9, + 0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE, + 0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5, + 0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2, + 0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4, + 0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE, + 0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC, + 0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9, + 0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF, + 0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0, + 0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC, + 0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9, + 0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD, + 0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0, + 0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9, + 0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC, + 0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1, + 0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3, + 0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2, + 0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0, + 0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA, + 0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA, + 0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC, + 0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4, + 0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE, + 0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB, + 0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE, + 0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2, + 0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE, + 0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3, + 0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD, + 0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5, + 0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1, + 0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0, + 0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2, + 0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA, + 0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4, + 0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9, + 0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8, + 0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB, + 0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5, + 0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4, + 0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC, + 0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6, + 0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9, + 0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA, + 0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2, + 0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0, + 0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB, + 0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF, + 0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8, + 0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1, + 0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB, + 0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0, + 0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1, + 0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E, + 0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE, + 0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2, + 0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3, + 0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A, + 0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258, + 0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D, + 0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D, + 0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F, + 0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249, + 0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67, + 0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D, + 0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68, + 0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253, + 0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C, + 0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E, + 0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254, + 0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241, + 0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252, + 0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD, + 0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5, + 0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0, + 0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB, + 0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4, + 0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA, + 0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7, + 0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6, + 0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9, + 0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF, + 0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6, + 0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2, + 0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC, + 0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE, + 0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC, + 0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4, + 0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1, + 0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0, + 0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2, + 0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA, + 0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB, + 0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7, + 0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0, + 0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5, + 0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4, + 0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8, + 0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48, + 0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3, + 0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A, + 0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4, + 0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC, + 0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA, + 0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6, + 0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7, + 0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6, + 0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE, + 0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267, + 0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5, + 0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256, + 0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250, + 0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370, + 0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0, + 0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455, + 0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A, + 0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1, + 0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF, + 0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6, + 0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4, + 0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1, + 0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1, + 0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED, + 0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64, + 0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8, + 0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6, + 0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB, + 0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA, + 0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7, + 0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9, + 0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71, + 0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0, + 0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9, + 0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A, + 0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF, + 0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B, + 0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1, + 0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA, + 0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65, + 0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC, + 0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC, + 0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE, + 0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD, + 0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267, + 0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC, + 0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2, + 0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C, + 0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71, + 0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF, + 0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269, + 0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5, + 0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0, + 0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48, + 0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68, + 0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2, + 0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241, + 0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240, + 0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3, + 0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42, + 0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7, + 0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5, + 0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB, + 0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA, + 0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2, + 0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E, + 0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A, + 0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B, + 0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244, + 0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF, + 0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2, + 0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1, + 0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3, + 0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2, + 0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40, + 0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1, + 0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD, + 0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC, + 0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3, + 0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851, + 0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55, + 0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856, + 0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B, + 0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857, + 0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855, + 0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56, + 0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F, + 0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50, + 0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C, + 0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846, + 0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44, + 0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71, + 0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42, + 0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F, + 0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66, + 0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70, + 0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73, + 0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79, + 0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8, + 0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4, + 0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2, + 0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41, + 0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69, + 0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60, + 0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD, + 0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74, + 0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C, + 0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77, + 0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74, + 0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD, + 0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73, + 0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78, + 0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D, + 0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A, + 0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78, + 0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB, + 0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77, + 0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4, + 0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79, + 0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3, + 0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E, + 0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255, + 0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D, + 0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA, + 0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6, + 0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F, + 0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248, + 0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245, + 0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261, + 0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265, + 0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9, + 0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260, + 0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269, + 0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B, + 0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265, + 0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250, + 0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B, + 0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647, + 0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267, + 0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258, + 0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE, + 0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645, + 0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259, + 0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF, + 0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C, + 0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253, + 0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7, + 0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268, + 0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D, + 0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252, + 0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245, + 0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256, + 0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7, + 0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D, + 0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6, + 0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7, + 0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC, + 0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1, + 0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4, + 0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7, + 0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5, + 0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED, + 0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9, + 0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF, + 0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA, + 0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA, + 0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51, + 0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF, + 0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547, + 0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543, + 0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9, + 0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3, + 0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5, + 0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52, + 0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60, + 0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49, + 0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2, + 0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE, + 0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63, + 0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1, + 0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5, + 0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C, + 0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB, + 0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3, + 0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47, + 0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9, + 0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45, + 0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0, + 0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66, + 0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA, + 0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C, + 0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4, + 0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77, + 0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271, + 0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF, + 0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE, + 0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3, + 0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E, + 0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C, + 0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A, + 0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7, + 0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E, + 0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279, + 0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B, + 0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7, + 0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9, + 0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1, + 0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79, + 0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD, + 0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2, + 0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B, + 0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7, + 0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2, + 0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED, + 0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660, + 0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9, + 0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2, + 0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB, + 0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB, + 0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1, + 0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB, + 0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640, + 0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651, + 0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE, + 0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40, + 0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48, + 0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB, + 0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8, + 0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45, + 0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE, + 0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2, + 0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC, + 0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC, + 0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA, + 0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC, + 0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB, + 0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9, + 0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52, + 0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B, + 0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54, + 0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8, + 0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271, + 0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2, + 0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF, + 0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8, + 0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1, + 0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378, + 0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C, + 0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377, + 0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262, + 0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D, + 0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260, + 0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B, + 0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E, + 0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467, + 0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466, + 0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4, + 0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7, + 0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB, + 0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579, + 0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4, + 0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5, + 0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C, + 0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5, + 0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F, + 0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861, + 0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52, + 0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56, + 0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1, + 0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59, + 0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6, + 0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6, + 0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1, + 0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5, + 0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278, + 0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E, + 0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C, + 0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271, + 0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A, + 0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C, + 0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E, + 0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A, + 0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B, + 0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656, + 0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A, + 0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649, + 0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B, + 0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F, + 0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C, + 0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A, + 0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B, + 0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64, + 0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1, + 0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A, + 0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D, + 0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC, + 0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4, + 0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F, + 0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1, + 0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB, + 0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E, + 0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1, + 0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF, + 0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA, + 0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB, + 0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3, + 0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A, + 0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E, + 0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7, + 0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663, + 0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672, + 0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55, + 0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C, + 0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56, + 0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F, + 0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52, + 0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F, + 0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53, + 0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7, + 0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60, + 0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E, + 0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61, + 0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277, + 0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD, + 0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C, + 0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B, + 0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C, + 0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB, + 0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED, + 0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC, + 0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6, + 0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7, + 0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8, + 0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7, + 0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9, + 0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66, + 0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6, + 0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67, + 0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8, + 0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60, + 0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA, + 0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9, + 0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1, + 0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E, + 0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552, + 0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A, + 0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6, + 0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7, + 0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA, + 0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9, + 0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D, + 0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F, + 0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7, + 0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6, + 0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62, + 0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867, + 0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64, + 0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64, + 0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61, + 0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E, + 0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2, + 0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF, + 0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3, + 0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7, + 0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4, + 0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6, + 0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662, + 0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79, + 0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274, + 0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275, + 0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669, + 0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76, + 0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F, + 0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555, + 0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD, + 0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1, + 0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB, + 0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD, + 0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC, + 0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E, + 0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677, + 0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1, + 0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57, + 0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E, + 0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2, + 0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278, + 0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E, + 0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A, + 0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8, + 0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A, + 0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45, + 0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68, + 0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3, + 0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66, + 0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1, + 0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2, + 0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC, + 0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1, + 0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4, + 0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4, + 0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6, + 0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB, + 0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA, + 0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3, + 0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1, + 0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2, + 0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C, + 0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C, + 0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B, + 0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279, + 0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671, + 0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677, + 0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1, + 0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2, + 0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B, + 0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558, + 0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A, + 0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA, + 0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D, + 0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8, + 0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2, + 0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8, + 0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE, + 0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4, + 0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6, + 0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3, + 0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4, + 0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2, + 0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA, + 0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41, + 0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5, + 0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4, + 0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65, + 0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63, + 0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64, + 0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5, + 0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A, + 0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4, + 0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045, + 0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046, + 0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041, + 0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274, + 0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED, + 0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0, + 0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA, + 0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D, + 0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B, + 0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260, + 0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF, + 0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2, + 0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6, + 0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC, + 0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72, + 0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049, + 0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE, + 0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3, + 0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563, + 0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46, + 0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9, + 0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2, + 0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E, + 0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70, + 0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB, + 0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60, + 0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62, + 0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B, + 0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566, + 0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7, + 0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4, + 0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A, + 0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C, + 0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9, + 0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74, + 0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF, + 0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC, + 0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68, + 0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E, + 0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B, + 0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7, + 0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66, + 0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2, + 0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4, + 0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA, + 0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0, + 0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4, + 0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569, + 0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2, + 0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2, + 0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1, + 0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4, + 0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB, + 0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9, + 0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6, + 0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF, + 0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD, + 0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7, + 0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45, + 0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4, + 0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4, + 0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B, + 0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F, + 0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62, + 0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74, + 0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76, + 0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E, + 0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C, + 0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278, + 0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470, + 0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4, + 0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6, + 0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E, + 0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47, + 0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2, + 0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB, + 0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8, + 0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5, + 0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9, + 0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471, + 0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75, + 0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1, + 0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472, + 0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF, + 0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC, + 0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0, + 0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1, + 0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9, + 0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64, + 0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA, + 0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E, + 0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76, + 0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB, + 0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF, + 0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2, + 0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC, + 0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3, + 0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5, + 0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75, + 0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0, + 0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA, + 0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE, + 0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2, + 0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1, + 0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC, + 0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF, + 0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0, + 0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8, + 0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA, + 0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA, + 0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844, + 0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE, + 0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2, + 0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3, + 0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7, + 0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB, + 0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE, + 0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D, + 0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1, + 0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79, + 0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65, + 0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68, + 0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B, + 0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2, + 0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A, + 0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4, + 0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054, + 0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A, + 0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476, + 0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4, + 0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666, + 0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3, + 0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8, + 0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575, + 0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C, + 0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A, + 0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B, + 0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED, + 0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5, + 0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB, + 0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C, + 0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB, + 0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A, + 0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0, + 0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD, + 0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3, + 0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B, + 0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5, + 0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA, + 0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576, + 0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6, + 0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB, + 0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC, + 0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE, + 0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851, + 0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8, + 0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D, + 0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F, + 0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1, + 0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5, + 0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC, + 0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3, + 0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC, + 0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849, + 0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54, + 0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF, + 0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7, + 0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3, + 0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59, + 0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A, + 0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC, + 0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7, + 0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3, + 0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146, + 0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143, + 0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9, + 0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147, + 0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A, + 0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D, + 0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3, + 0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D, + 0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D, + 0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C, + 0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473, + 0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6, + 0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72, + 0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2, + 0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6, + 0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4, + 0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7, + 0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6, + 0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE, + 0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB, + 0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0, + 0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC, + 0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD, + 0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2, + 0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5, + 0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341, + 0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5, + 0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE, + 0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340, + 0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE, + 0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE, + 0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149, + 0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7, + 0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1, + 0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8, + 0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856, + 0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870, + 0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE, + 0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC, + 0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5, + 0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2, + 0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3, + 0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED, + 0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6, + 0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE, + 0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA, + 0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B, + 0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7, + 0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC, + 0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858, + 0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B, + 0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348, + 0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346, + 0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F, + 0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C, + 0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0, + 0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E, + 0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A, + 0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1, + 0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9, + 0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC, + 0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8, + 0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873, + 0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6, + 0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0, + 0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC, + 0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9, + 0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF, + 0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1, + 0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D, + 0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A, + 0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C, + 0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3, + 0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2, + 0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7, + 0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB, + 0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF, + 0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA, + 0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3, + 0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D, + 0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB, + 0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1, + 0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342, + 0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345, + 0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA, + 0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6, + 0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7, + 0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1, + 0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4, + 0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8, + 0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA, + 0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB, + 0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6, + 0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5, + 0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB, + 0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE, + 0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5, + 0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47, + 0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A, + 0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E, + 0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1, + 0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D, + 0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E, + 0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354, + 0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351, + 0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2, + 0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F, + 0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C, + 0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63, + 0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6, + 0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68, + 0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76, + 0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA, + 0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74, + 0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA, + 0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79, + 0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC, + 0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A, + 0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC, + 0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F, + 0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9, + 0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7, + 0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA, + 0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2, + 0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB, + 0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061, + 0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064, + 0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B, + 0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062, + 0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066, + 0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0, + 0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1, + 0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478, + 0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6, + 0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0, + 0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC, + 0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3, + 0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4, + 0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8, + 0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D, + 0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045, + 0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047, + 0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F, + 0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C, + 0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE, + 0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF, + 0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7, + 0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9, + 0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865, + 0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361, + 0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB, + 0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B, + 0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA, + 0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C, + 0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153, + 0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152, + 0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE, + 0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B, + 0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD, + 0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9, + 0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4, + 0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA, + 0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF, + 0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353, + 0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358, + 0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355, + 0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5, + 0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350, + 0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1, + 0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8, + 0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9, + 0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5, + 0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF, + 0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED, + 0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD, + 0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB, + 0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2, + 0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7, + 0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C, + 0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8, + 0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0, + 0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5, + 0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB, + 0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868, + 0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65, + 0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60, + 0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57, + 0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B, + 0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63, + 0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78, + 0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7, + 0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377, + 0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376, + 0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4, + 0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA, + 0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373, + 0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368, + 0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369, + 0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2, + 0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC, + 0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75, + 0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0, + 0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB, + 0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5, + 0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE, + 0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D, + 0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA, + 0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7, + 0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB, + 0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1, + 0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5, + 0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3, + 0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0, + 0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4, + 0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6, + 0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169, + 0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3, + 0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C, + 0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD, + 0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168, + 0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E, + 0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9, + 0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E, + 0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4, + 0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071, + 0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6, + 0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072, + 0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8, + 0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2, + 0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0, + 0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6, + 0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D, + 0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1, + 0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7, + 0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1, + 0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE, + 0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942, + 0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE, + 0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA, + 0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A, + 0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9, + 0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8, + 0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D, + 0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D, + 0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1, + 0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A, + 0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B, + 0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870, + 0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D, + 0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1, + 0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB, + 0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9, + 0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA, + 0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362, + 0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC, + 0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB, + 0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873, + 0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872, + 0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E, + 0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079, + 0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD, + 0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3, + 0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365, + 0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD, + 0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7, + 0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC, + 0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE, + 0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70, + 0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42, + 0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9, + 0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6, + 0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4, + 0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B, + 0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B, + 0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE, + 0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1, + 0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF, + 0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41, + 0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42, + 0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366, + 0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741, + 0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71, + 0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6, + 0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5, + 0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055, + 0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5, + 0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744, + 0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45, + 0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45, + 0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB, + 0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F, + 0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C, + 0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2, + 0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB, + 0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46, + 0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9, + 0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877, + 0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75, + 0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878, + 0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE, + 0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0, + 0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C, + 0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD, + 0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D, + 0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061, + 0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064, + 0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062, + 0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F, + 0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F, + 0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E, + 0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA, + 0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A, + 0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD, + 0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2, + 0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D, + 0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF, + 0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745, + 0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C, + 0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5, + 0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7, + 0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3, + 0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F, + 0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9, + 0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB, + 0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47, + 0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4, + 0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B, + 0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72, + 0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76, + 0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879, + 0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD, + 0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1, + 0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D, + 0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A, + 0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9, + 0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744, + 0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3, + 0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE, + 0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9, + 0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED, + 0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8, + 0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC, + 0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8, + 0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177, + 0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9, + 0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179, + 0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1, + 0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2, + 0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4, + 0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6, + 0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA, + 0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B, + 0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4, + 0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50, + 0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F, + 0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068, + 0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57, + 0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C, + 0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9, + 0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51, + 0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF, + 0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1, + 0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA, + 0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371, + 0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB, + 0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE, + 0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A, + 0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8, + 0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A, + 0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748, + 0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7, + 0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0, + 0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4, + 0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6, + 0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB, + 0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2, + 0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A, + 0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E, + 0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B, + 0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C, + 0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E, + 0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC, + 0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC, + 0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6, + 0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9, + 0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2, + 0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7, + 0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8, + 0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0, + 0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE, + 0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4, + 0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61, + 0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B, + 0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65, + 0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1, + 0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F, + 0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5, + 0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078, + 0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C, + 0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C, + 0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53, + 0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E, + 0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41, + 0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3, + 0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E, + 0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5, + 0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED, + 0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC, + 0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4, + 0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8, + 0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A, + 0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE, + 0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6, + 0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0, + 0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2, + 0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF, + 0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765, + 0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D, + 0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F, + 0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340, + 0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8, + 0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF, + 0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9, + 0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773, + 0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C, + 0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3, + 0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776, + 0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D, + 0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774, + 0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7, + 0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5, + 0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77, + 0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74, + 0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1, + 0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8, + 0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A, + 0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD, + 0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63, + 0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A, + 0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD, + 0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA, + 0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E, + 0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0, + 0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1, + 0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78, + 0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3, + 0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B, + 0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F, + 0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC, + 0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5, + 0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8, + 0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0, + 0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA, + 0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC, + 0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD, + 0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0, + 0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF, + 0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8, + 0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD, + 0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0, + 0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4, + 0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0, + 0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA, + 0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4, + 0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB, + 0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5, + 0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2, + 0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB, + 0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59, + 0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1, + 0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6, + 0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4, + 0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A, + 0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6, + 0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55, + 0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57, + 0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54, + 0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9, + 0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62, + 0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9, + 0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774, + 0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4, + 0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9, + 0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770, + 0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758, + 0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6, + 0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD, + 0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B, + 0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E, + 0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3, + 0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778, + 0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B, + 0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2, + 0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772, + 0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E, + 0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C, + 0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D, + 0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43, + 0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41, + 0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6, + 0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC, + 0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46, + 0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54, + 0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44, + 0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53, + 0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE, + 0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D, + 0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40, + 0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB, + 0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D, + 0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51, + 0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42, + 0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A, + 0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4, + 0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54, + 0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3, + 0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8, + 0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC, + 0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4, + 0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3, + 0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4, + 0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9, + 0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6, + 0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2, + 0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7, + 0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3, + 0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2, + 0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC, + 0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2, + 0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3, + 0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF, + 0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8, + 0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF, + 0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7, + 0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB, + 0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF, + 0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0, + 0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8, + 0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6, + 0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4, + 0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5, + 0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8, + 0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5, + 0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749, + 0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9, + 0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3, + 0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC, + 0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7, + 0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68, + 0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342, + 0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8, + 0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E, + 0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB, + 0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4, + 0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7, + 0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6, + 0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8, + 0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041, + 0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB, + 0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE, + 0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA, + 0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC, + 0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047, + 0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA, + 0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5, + 0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348, + 0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7, + 0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF, + 0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2, + 0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3, + 0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D, + 0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF, + 0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD, + 0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF, + 0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB, + 0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3, + 0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9, + 0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE, + 0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6, + 0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED, + 0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0, + 0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC, + 0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF, + 0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB, + 0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE, + 0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC, + 0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68, + 0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D, + 0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA, + 0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5, + 0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0, + 0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2, + 0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED, + 0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9, + 0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD, + 0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B, + 0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF, + 0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4, + 0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB, + 0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA, + 0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0, + 0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF, + 0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9, + 0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD, + 0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61, + 0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67, + 0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4, + 0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F, + 0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D, + 0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D, + 0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3, + 0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1, + 0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67, + 0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A, + 0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D, + 0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60, + 0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC, + 0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B, + 0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69, + 0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF, + 0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9, + 0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1, + 0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5, + 0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1, + 0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0, + 0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC, + 0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE, + 0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6, + 0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB, + 0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7, + 0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7, + 0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5, + 0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF, + 0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642, + 0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643, + 0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644, + 0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640, + 0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9, + 0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8, + 0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE, + 0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E, + 0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5, + 0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0, + 0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C, + 0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2, + 0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1, + 0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC, + 0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE, + 0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8, + 0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB, + 0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E, + 0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7, + 0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9, + 0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2, + 0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352, + 0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF, + 0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE, + 0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5, + 0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6, + 0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD, + 0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5, + 0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8, + 0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF, + 0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3, + 0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF, + 0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4, + 0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6, + 0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6, + 0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442, + 0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440, + 0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70, + 0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71, + 0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73, + 0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2, + 0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA, + 0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5, + 0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4, + 0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7, + 0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C, + 0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8, + 0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6, + 0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74, + 0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7, + 0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77, + 0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA, + 0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8, + 0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5, + 0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76, + 0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF, + 0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE, + 0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB, + 0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0, + 0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B, + 0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8, + 0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC, + 0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B, + 0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E, + 0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0, + 0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356, + 0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1, + 0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446, + 0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0, + 0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB, + 0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1, + 0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1, + 0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B, + 0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8, + 0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5, + 0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041, + 0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE, + 0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447, + 0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2, + 0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2, + 0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C, + 0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C, + 0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0, + 0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052, + 0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059, + 0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057, + 0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359, + 0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A, + 0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB, + 0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644, + 0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9, + 0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA, + 0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643, + 0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7, + 0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1, + 0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647, + 0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641, + 0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF, + 0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6, + 0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0, + 0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4, + 0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A, + 0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9, + 0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E, + 0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8, + 0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E, + 0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF, + 0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6, + 0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A, + 0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7, + 0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6, + 0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA, + 0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3, + 0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4, + 0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5, + 0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0, + 0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC, + 0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7, + 0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB, + 0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8, + 0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7, + 0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF, + 0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9, + 0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3, + 0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1, + 0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5, + 0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7, + 0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA, + 0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB, + 0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3, + 0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9, + 0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE, + 0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2, + 0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC, + 0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB, + 0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5, + 0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4, + 0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6, + 0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2, + 0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF, + 0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0, + 0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD, + 0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340, + 0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE, + 0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7, + 0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7, + 0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5, + 0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8, + 0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3, + 0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D, + 0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756, + 0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757, + 0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC, + 0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE, + 0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640, + 0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D, + 0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD, + 0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5, + 0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344, + 0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A, + 0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC, + 0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7, + 0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF, + 0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5, + 0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055, + 0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8, + 0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5, + 0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7, + 0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4, + 0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1, + 0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059, + 0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7, + 0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3, + 0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7, + 0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0, + 0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73, + 0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2, + 0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366, + 0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364, + 0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C, + 0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652, + 0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F, + 0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654, + 0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE, + 0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB, + 0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC, + 0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455, + 0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED, + 0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9, + 0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8, + 0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8, + 0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7, + 0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4, + 0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC, + 0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6, + 0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348, + 0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9, + 0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542, + 0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC, + 0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A, + 0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE, + 0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9, + 0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75, + 0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5, + 0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658, + 0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656, + 0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061, + 0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063, + 0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF, + 0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF, + 0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC, + 0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B, + 0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F, + 0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7, + 0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6, + 0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7, + 0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9, + 0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659, + 0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1, + 0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0, + 0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5, + 0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1, + 0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9, + 0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7, + 0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4, + 0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5, + 0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B, + 0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458, + 0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F, + 0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A, + 0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841, + 0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA, + 0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846, + 0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5, + 0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0, + 0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD, + 0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7, + 0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3, + 0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5, + 0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7, + 0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1, + 0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE, + 0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB, + 0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145, + 0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9, + 0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143, + 0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142, + 0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD, + 0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352, + 0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB, + 0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350, + 0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC, + 0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7, + 0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543, + 0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655, + 0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE, + 0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763, + 0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3, + 0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951, + 0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE, + 0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060, + 0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF, + 0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE, + 0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8, + 0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF, + 0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD, + 0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1, + 0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46, + 0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42, + 0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44, + 0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40, + 0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD, + 0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B, + 0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079, + 0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C, + 0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465, + 0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4, + 0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A, + 0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE, + 0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848, + 0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC, + 0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC, + 0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9, + 0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7, + 0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4, + 0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146, + 0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149, + 0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359, + 0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1, + 0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE, + 0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659, + 0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF, + 0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF, + 0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC, + 0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547, + 0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B, + 0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3, + 0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF, + 0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE, + 0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2, + 0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3, + 0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4, + 0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5, + 0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1, + 0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE, + 0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED, + 0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B, + 0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3, + 0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376, + 0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C, + 0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D, + 0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374, + 0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373, + 0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F, + 0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666, + 0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3, + 0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945, + 0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943, + 0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B, + 0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944, + 0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB, + 0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC, + 0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852, + 0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44, + 0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0, + 0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0, + 0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2, + 0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3, + 0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB, + 0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3, + 0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5, + 0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6, + 0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53, + 0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7, + 0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA, + 0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8, + 0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3, + 0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5, + 0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9, + 0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD, + 0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6, + 0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB, + 0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA, + 0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3, + 0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD, + 0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9, + 0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8, + 0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED, + 0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4, + 0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E, + 0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B, + 0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50, + 0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA, + 0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4, + 0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8, + 0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E, + 0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2, + 0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B, + 0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48, + 0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855, + 0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854, + 0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5, + 0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4, + 0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D, + 0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1, + 0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766, + 0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9, + 0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441, + 0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6, + 0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4, + 0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60, + 0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73, + 0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC, + 0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6, + 0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474, + 0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F, + 0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C, + 0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C, + 0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA, + 0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5, + 0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF, + 0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6, + 0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E, + 0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F, + 0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6, + 0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4, + 0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849, + 0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D, + 0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC, + 0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD, + 0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7, + 0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442, + 0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444, + 0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8, + 0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842, + 0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7, + 0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA, + 0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB, + 0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A, + 0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F, + 0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675, + 0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68, + 0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672, + 0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74, + 0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674, + 0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70, + 0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3, + 0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0, + 0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1, + 0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B, + 0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962, + 0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963, + 0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960, + 0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB, + 0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5, + 0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F, + 0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB, + 0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7, + 0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A, + 0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5, + 0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6, + 0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE, + 0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E, + 0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C, + 0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA, + 0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE, + 0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC, + 0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1, + 0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D, + 0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55, + 0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50, + 0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865, + 0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864, + 0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874, + 0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F, + 0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862, + 0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878, + 0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E, + 0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2, + 0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872, + 0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870, + 0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7, + 0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB, + 0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9, + 0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF, + 0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED, + 0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8, + 0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45, + 0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6, + 0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5, + 0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7, + 0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3, + 0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB, + 0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5, + 0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA, + 0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7, + 0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1, + 0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9, + 0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1, + 0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED, + 0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA, + 0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6, + 0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB, + 0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6, + 0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6, + 0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2, + 0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9, + 0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC, + 0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F, + 0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161, + 0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D, + 0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A, + 0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A, + 0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE, + 0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164, + 0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153, + 0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB, + 0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C, + 0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362, + 0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D, + 0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2, + 0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE, + 0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0, + 0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375, + 0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3, + 0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366, + 0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3, + 0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2, + 0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD, + 0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7, + 0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9, + 0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8, + 0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0, + 0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668, + 0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E, + 0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667, + 0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F, + 0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669, + 0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C, + 0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A, + 0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2, + 0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C, + 0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF, + 0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644, + 0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954, + 0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956, + 0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668, + 0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671, + 0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF, + 0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78, + 0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC, + 0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC, + 0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3, + 0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2, + 0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0, + 0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2, + 0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3, + 0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B, + 0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D, + 0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A, + 0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48, + 0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2, + 0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0, + 0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47, + 0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D, + 0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377, + 0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547, + 0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D, + 0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA, + 0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59, + 0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2, + 0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD, + 0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB, + 0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC, + 0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE, + 0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0, + 0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4, + 0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1, + 0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446, + 0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3, + 0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848, + 0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB, + 0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3, + 0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7, + 0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC, + 0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E, + 0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA, + 0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2, + 0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969, + 0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB, + 0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047, + 0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6, + 0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F, + 0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6, + 0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD, + 0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE, + 0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E, + 0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C, + 0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50, + 0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174, + 0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8, + 0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379, + 0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42, + 0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8, + 0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973, + 0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6, + 0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD, + 0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E, + 0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51, + 0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53, + 0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D, + 0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA, + 0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177, + 0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E, + 0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9, + 0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549, + 0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551, + 0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5, + 0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647, + 0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957, + 0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE, + 0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44, + 0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053, + 0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9, + 0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA, + 0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC, + 0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF, + 0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7, + 0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF, + 0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62, + 0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55, + 0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE, + 0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD, + 0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2, + 0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C, + 0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1, + 0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B, + 0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F, + 0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669, + 0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9, + 0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43, + 0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6, + 0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5, + 0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2, + 0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5, + 0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7, + 0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554, + 0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC, + 0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC, + 0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF, + 0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978, + 0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1, + 0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7, + 0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B, + 0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9, + 0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055, + 0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056, + 0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A, + 0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4, + 0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342, + 0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9, + 0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440, + 0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9, + 0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F, + 0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555, + 0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3, + 0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE, + 0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1, + 0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4, + 0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB, + 0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC, + 0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552, + 0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673, + 0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9, + 0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8, + 0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD, + 0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2, + 0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1, + 0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5, + 0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8, + 0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1, + 0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5, + 0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061, + 0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060, + 0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D, + 0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D, + 0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54, + 0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD, + 0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348, + 0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443, + 0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558, + 0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8, + 0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9, + 0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556, + 0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959, + 0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55, + 0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60, + 0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2, + 0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8, + 0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6, + 0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5, + 0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5, + 0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3, + 0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1, + 0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E, + 0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA, + 0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE, + 0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D, + 0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64, + 0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67, + 0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65, + 0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B, + 0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F, + 0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240, + 0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3, + 0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1, + 0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D, + 0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5, + 0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9, + 0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB, + 0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6, + 0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA, + 0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB, + 0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD, + 0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678, + 0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1, + 0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559, + 0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D, + 0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB, + 0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2, + 0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852, + 0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6, + 0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A, + 0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5, + 0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD, + 0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA, + 0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C, + 0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D, + 0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9, + 0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564, + 0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4, + 0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9, + 0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA, + 0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC, + 0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068, + 0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6, + 0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70, + 0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66, + 0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC, + 0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3, + 0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4, + 0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3, + 0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5, + 0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856, + 0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB, + 0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6, + 0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC, + 0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7, + 0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE, + 0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A, + 0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0, + 0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352, + 0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D, + 0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5, + 0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF, + 0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA, + 0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0, + 0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE, + 0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76, + 0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79, + 0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2, + 0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A, + 0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C, + 0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71, + 0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243, + 0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75, + 0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD, + 0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7, + 0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3, + 0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA, + 0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0, + 0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2, + 0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD, + 0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449, + 0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1, + 0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356, + 0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B, + 0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572, + 0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574, + 0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD, + 0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF, + 0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF, + 0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6, + 0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1, + 0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570, + 0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB, + 0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F, + 0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857, + 0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC, + 0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D, + 0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8, + 0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B, + 0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A, + 0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE, + 0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7, + 0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3, + 0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0, + 0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC, + 0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA, + 0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D, + 0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC, + 0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4, + 0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9, + 0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB, + 0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E, + 0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B, + 0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79, + 0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7, + 0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77, + 0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2, + 0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359, + 0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6, + 0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD, + 0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB, + 0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1, + 0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450, + 0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E, + 0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8, + 0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3, + 0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC, + 0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0, + 0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1, + 0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2, + 0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578, + 0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A, + 0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6, + 0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF, + 0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4, + 0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3, + 0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD, + 0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF, + 0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9, + 0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB, + 0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7, + 0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE, + 0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8, + 0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3, + 0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7, + 0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF, + 0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867, + 0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0, + 0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A, + 0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871, + 0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862, + 0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861, + 0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2, + 0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7, + 0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4, + 0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F, + 0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B, + 0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678, + 0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF, + 0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651, + 0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0, + 0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB, + 0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC, + 0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453, + 0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3, + 0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF, + 0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1, + 0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2, + 0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7, + 0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3, + 0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE, + 0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248, + 0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072, + 0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF, + 0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249, + 0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4, + 0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB, + 0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8, + 0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964, + 0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6, + 0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1, + 0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652, + 0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2, + 0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D, + 0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0, + 0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB, + 0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4, + 0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5, + 0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3, + 0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA, + 0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B, + 0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D, + 0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D, + 0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4, + 0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9, + 0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5, + 0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC, + 0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD, + 0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6, + 0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569, + 0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5, + 0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1, + 0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED, + 0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969, + 0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365, + 0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE, + 0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF, + 0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A, + 0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F, + 0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167, + 0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F, + 0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177, + 0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6, + 0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8, + 0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E, + 0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153, + 0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1, + 0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC, + 0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF, + 0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242, + 0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149, + 0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE, + 0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF, + 0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE, + 0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2, + 0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6, + 0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146, + 0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148, + 0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1, + 0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5, + 0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9, + 0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD, + 0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1, + 0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5, + 0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240, + 0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB, + 0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF, + 0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3, + 0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7, + 0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB, + 0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340, + 0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161, + 0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246, + 0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002, + 0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A, + 0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026, + 0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52, + 0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56, + 0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31, + 0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34, + 0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35, + 0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37, + 0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39, + 0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B, + 0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D, + 0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F, + 0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41, + 0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43, + 0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B, + 0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018, + 0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D, + 0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03, + 0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7, + 0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3, + 0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605, + 0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0, + 0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105, + 0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD, + 0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E, + 0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60, + 0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7, + 0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C, + 0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267, + 0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261, + 0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65, + 0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A, + 0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF, + 0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E, + 0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642, + 0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193, + 0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197, + 0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223, + 0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68, + 0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0, + 0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103, + 0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B, + 0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E, + 0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F, + 0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B, + 0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163, + 0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581, + 0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585, + 0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F, + 0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B, + 0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534, + 0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594, + 0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C, + 0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D, + 0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550, + 0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2, + 0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571, + 0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11, + 0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15, + 0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19, + 0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163, + 0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167, + 0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022, + 0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026, + 0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341, + 0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22, + 0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26, + 0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A, + 0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E, + 0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32, + 0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36, + 0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A, + 0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44, + 0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48, + 0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C, + 0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50, + 0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54, + 0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58, + 0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392, + 0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396, + 0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A, + 0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E, + 0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3, + 0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7, + 0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2, + 0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6, + 0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA, + 0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE, + 0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3, + 0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7, + 0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106, + 0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A, + 0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E, + 0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112, + 0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116, + 0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A, + 0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E, + 0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122, + 0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126, + 0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9, + 0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB, + 0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01, + 0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86, + 0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165, + 0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201, + 0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C, + 0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08, + 0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1, + 0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E, + 0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203, + 0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3, + 0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927, + 0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53, + 0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38, + 0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1, + 0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72, + 0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D, + 0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D, + 0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39, + 0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92, + 0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0, + 0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD, + 0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143, + 0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E, + 0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206, + 0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE, + 0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348, + 0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384, + 0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC, + 0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D, + 0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A, + 0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF, + 0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208, + 0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F, + 0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9, + 0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728, + 0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB, + 0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34, + 0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B, + 0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC, + 0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15, + 0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D, + 0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8, + 0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7, + 0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE, + 0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A, + 0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8, + 0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305, + 0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF, + 0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360, + 0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF, + 0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE, + 0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8, + 0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA, + 0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5, + 0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA, + 0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974, + 0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C, + 0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02, + 0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01, + 0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A, + 0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251, + 0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C, + 0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63, + 0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38, + 0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF, + 0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6, + 0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529, + 0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533, + 0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF, + 0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3, + 0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB, + 0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53, + 0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6, + 0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19, + 0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10, + 0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6, + 0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD, + 0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147, + 0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171, + 0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211, + 0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3, + 0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370, + 0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C, + 0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B, + 0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408, + 0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412, + 0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733, + 0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C, + 0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A, + 0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978, + 0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982, + 0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87, + 0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA, + 0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06, + 0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B, + 0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C, + 0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B, + 0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8, + 0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3, + 0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731, + 0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B, + 0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59, + 0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55, + 0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E, + 0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E, + 0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36, + 0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003, + 0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F, + 0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3, + 0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C, + 0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272, + 0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C, + 0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32, + 0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47, + 0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B, + 0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51, + 0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43, + 0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63, + 0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E, + 0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48, + 0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D, + 0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225, + 0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228, + 0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC, + 0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D, + 0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426, + 0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443, + 0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B, + 0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B, + 0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436, + 0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431, + 0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA, + 0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A, + 0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747, + 0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F, + 0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D, + 0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3, + 0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4, + 0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D, + 0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C, + 0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40, + 0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90, + 0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB, + 0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A, + 0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64, + 0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8, + 0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1, + 0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212, + 0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296, + 0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D, + 0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279, + 0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298, + 0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291, + 0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538, + 0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E, + 0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C, + 0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746, + 0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65, + 0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99, + 0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85, + 0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90, + 0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96, + 0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72, + 0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76, + 0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82, + 0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078, + 0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4, + 0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B, + 0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF, + 0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF, + 0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096, + 0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B, + 0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292, + 0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2, + 0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55, + 0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3, + 0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0, + 0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4, + 0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA, + 0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6, + 0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631, + 0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56, + 0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E, + 0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D, + 0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C, + 0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83, + 0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69, + 0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F, + 0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152, + 0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176, + 0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B, + 0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230, + 0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE, + 0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353, + 0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378, + 0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7, + 0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478, + 0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477, + 0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C, + 0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C, + 0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B, + 0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783, + 0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761, + 0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C, + 0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944, + 0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4, + 0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6, + 0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3, + 0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2, + 0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63, + 0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C, + 0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48, + 0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1, + 0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1, + 0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16, + 0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78, + 0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95, + 0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27, + 0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F, + 0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD, + 0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014, + 0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A, + 0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029, + 0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215, + 0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F, + 0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF, + 0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB, + 0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB, + 0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC, + 0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD, + 0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8, + 0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC, + 0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC, + 0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C, + 0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600, + 0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607, + 0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B, + 0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773, + 0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797, + 0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789, + 0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A, + 0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772, + 0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F, + 0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8, + 0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5, + 0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC, + 0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3, + 0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1, + 0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1, + 0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB, + 0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC, + 0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E, + 0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C, + 0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267, + 0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9, + 0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8, + 0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D, + 0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684, + 0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5, + 0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941, + 0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79, + 0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C, + 0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5, + 0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB, + 0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF, + 0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3, + 0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD, + 0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC, + 0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3, + 0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E, + 0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB, + 0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5, + 0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7, + 0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C, + 0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644, + 0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752, + 0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE, + 0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF, + 0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD, + 0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF, + 0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0, + 0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE, + 0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192, + 0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243, + 0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B, + 0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3, + 0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B, + 0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0, + 0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8, + 0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2, + 0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4, + 0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1, + 0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF, + 0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0, + 0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE, + 0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F, + 0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8, + 0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03, + 0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6, + 0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3, + 0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5, + 0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D, + 0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7, + 0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D, + 0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08, + 0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85, + 0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C, + 0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020, + 0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D, + 0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046, + 0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A, + 0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316, + 0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301, + 0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1, + 0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE, + 0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F, + 0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2, + 0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627, + 0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631, + 0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3, + 0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC, + 0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9, + 0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4, + 0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF, + 0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9, + 0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A, + 0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2, + 0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B, + 0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25, + 0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17, + 0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36, + 0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27, + 0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35, + 0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA, + 0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD, + 0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230, + 0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9, + 0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA, + 0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0, + 0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F, + 0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB, + 0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3, + 0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688, + 0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5, + 0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709, + 0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707, + 0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C, + 0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948, + 0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1, + 0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81, + 0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02, + 0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07, + 0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E, + 0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D, + 0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5, + 0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC, + 0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE, + 0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222, + 0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3, + 0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5, + 0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7, + 0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4, + 0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF, + 0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679, + 0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B, + 0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02, + 0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74, + 0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC, + 0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA, + 0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4, + 0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1, + 0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD, + 0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C, + 0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB, + 0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8, + 0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999, + 0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D, + 0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025, + 0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006, + 0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012, + 0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014, + 0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B, + 0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE, + 0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B, + 0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5, + 0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6, + 0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254, + 0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F, + 0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8, + 0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC, + 0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA, + 0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1, + 0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6, + 0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F, + 0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4, + 0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F, + 0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11, + 0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B, + 0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23, + 0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09, + 0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3, + 0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5, + 0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51, + 0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD, + 0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0, + 0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE, + 0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD, + 0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91, + 0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065, + 0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069, + 0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A, + 0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085, + 0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308, + 0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F, + 0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F, + 0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D, + 0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D, + 0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599, + 0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649, + 0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C, + 0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714, + 0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838, + 0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839, + 0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3, + 0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D, + 0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C, + 0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813, + 0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89, + 0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28, + 0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A, + 0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66, + 0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93, + 0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A, + 0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A, + 0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94, + 0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9, + 0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279, + 0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8, + 0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409, + 0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE, + 0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A, + 0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7, + 0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC, + 0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B, + 0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE, + 0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728, + 0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838, + 0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825, + 0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832, + 0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F, + 0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957, + 0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7, + 0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8, + 0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06, + 0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17, + 0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22, + 0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A, + 0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B, + 0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5, + 0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015, + 0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F, + 0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105, + 0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8, + 0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A, + 0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC, + 0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B, + 0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B, + 0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338, + 0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334, + 0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336, + 0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328, + 0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA, + 0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C, + 0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877, + 0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879, + 0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C, + 0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13, + 0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48, + 0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2, + 0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4, + 0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006, + 0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4, + 0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8, + 0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2, + 0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8, + 0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9, + 0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661, + 0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658, + 0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC, + 0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32, + 0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D, + 0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C, + 0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076, + 0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074, + 0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F, + 0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0, + 0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9, + 0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F, + 0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E, + 0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A, + 0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561, + 0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556, + 0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564, + 0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C, + 0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557, + 0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF, + 0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0, + 0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835, + 0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962, + 0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66, + 0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62, + 0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70, + 0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2, + 0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08, + 0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D, + 0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B, + 0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29, + 0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27, + 0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36, + 0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8, + 0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35, + 0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69, + 0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E, + 0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C, + 0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0, + 0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6, + 0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5, + 0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5, + 0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA, + 0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248, + 0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396, + 0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367, + 0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9, + 0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B, + 0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399, + 0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F, + 0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368, + 0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551, + 0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F, + 0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C, + 0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB, + 0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A, + 0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E, + 0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881, + 0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5, + 0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7, + 0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4, + 0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894, + 0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1, + 0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB, + 0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC, + 0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1, + 0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA, + 0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF, + 0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9, + 0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5, + 0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA, + 0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1, + 0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4, + 0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6, + 0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD, + 0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281, + 0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313, + 0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A, + 0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D, + 0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C, + 0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562, + 0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5, + 0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E, + 0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737, + 0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738, + 0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E, + 0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB, + 0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28, + 0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19, + 0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97, + 0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71, + 0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40, + 0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F, + 0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D, + 0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE, + 0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046, + 0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B, + 0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202, + 0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239, + 0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378, + 0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB, + 0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389, + 0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C, + 0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A, + 0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4, + 0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1, + 0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E, + 0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896, + 0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F, + 0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25, + 0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B, + 0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9, + 0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA, + 0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE, + 0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019, + 0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023, + 0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015, + 0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022, + 0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8, + 0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE, + 0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7, + 0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A, + 0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670, + 0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C, + 0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0, + 0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A, + 0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5, + 0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085, + 0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096, + 0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1, + 0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269, + 0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A, + 0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7, + 0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598, + 0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594, + 0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3, + 0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2, + 0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1, + 0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599, + 0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834, + 0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821, + 0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA, + 0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F, + 0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73, + 0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3, + 0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31, + 0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47, + 0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40, + 0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1, + 0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D, + 0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1, + 0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0, + 0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115, + 0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168, + 0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109, + 0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249, + 0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0, + 0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD, + 0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1, + 0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376, + 0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452, + 0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566, + 0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590, + 0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674, + 0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A, + 0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF, + 0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5, + 0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905, + 0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7, + 0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3, + 0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912, + 0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E, + 0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D, + 0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF, + 0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F, + 0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32, + 0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25, + 0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58, + 0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D, + 0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D, + 0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D, + 0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19, + 0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72, + 0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A, + 0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136, + 0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284, + 0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334, + 0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433, + 0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436, + 0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426, + 0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B, + 0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3, + 0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0, + 0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693, + 0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED, + 0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D, + 0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00, + 0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5, + 0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46, + 0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D, + 0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F, + 0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68, + 0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72, + 0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70, + 0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5, + 0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155, + 0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E, + 0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C, + 0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C, + 0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D, + 0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1, + 0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457, + 0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC, + 0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438, + 0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407, + 0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF, + 0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB, + 0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857, + 0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983, + 0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55, + 0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54, + 0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34, + 0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61, + 0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3, + 0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0, + 0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF, + 0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81, + 0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA, + 0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6, + 0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C, + 0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038, + 0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5, + 0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165, + 0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223, + 0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210, + 0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F, + 0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592, + 0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B, + 0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D, + 0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5, + 0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF, + 0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806, + 0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF, + 0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE, + 0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1, + 0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2, + 0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC, + 0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7, + 0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF, + 0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3, + 0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3, + 0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7, + 0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF, + 0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6, + 0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713, + 0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857, + 0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C, + 0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852, + 0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9, + 0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC, + 0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69, + 0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9, + 0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC, + 0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148, + 0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9, + 0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C, + 0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134, + 0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137, + 0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E, + 0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D, + 0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414, + 0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417, + 0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0, + 0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688, + 0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D, + 0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A, + 0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975, + 0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968, + 0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979, + 0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B, + 0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF, + 0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF, + 0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90, + 0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5, + 0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB, + 0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4, + 0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4, + 0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164, + 0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C, + 0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E, + 0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A, + 0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F, + 0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455, + 0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F, + 0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576, + 0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601, + 0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF, + 0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF, + 0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E, + 0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C, + 0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762, + 0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897, + 0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C, + 0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A, + 0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD, + 0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14, + 0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0, + 0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E, + 0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5, + 0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81, + 0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69, + 0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8, + 0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086, + 0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178, + 0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B, + 0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205, + 0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D, + 0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B, + 0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C, + 0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469, + 0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C, + 0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708, + 0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB, + 0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A, + 0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9, + 0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1, + 0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C, + 0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73, + 0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87, + 0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71, + 0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E, + 0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E, + 0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89, + 0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4, + 0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5, + 0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF, + 0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4, + 0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09, + 0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2, + 0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042, + 0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050, + 0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D, + 0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112, + 0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169, + 0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238, + 0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B, + 0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234, + 0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239, + 0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698, + 0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB, + 0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB, + 0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774, + 0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813, + 0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC, + 0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3, + 0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9, + 0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20, + 0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6, + 0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF, + 0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9, + 0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282, + 0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600, + 0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614, + 0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E, + 0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608, + 0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716, + 0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893, + 0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D, + 0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924, + 0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6, + 0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8, + 0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7, + 0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8, + 0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D, + 0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B, + 0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54, + 0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46, + 0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F, + 0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163, + 0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175, + 0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454, + 0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A, + 0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D, + 0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7, + 0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D, + 0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1, + 0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B, + 0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4, + 0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC, + 0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49, + 0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14, + 0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29, + 0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F, + 0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF, + 0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32, + 0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F, + 0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01, + 0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194, + 0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184, + 0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296, + 0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463, + 0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504, + 0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B, + 0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3, + 0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761, + 0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3, + 0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F, + 0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA, + 0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1, + 0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97, + 0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8, + 0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD, + 0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C, + 0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA, + 0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA, + 0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8, + 0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC, + 0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF, + 0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150, + 0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A, + 0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA, + 0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B, + 0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4, + 0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C, + 0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3, + 0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA, + 0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722, + 0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755, + 0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902, + 0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD, + 0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6, + 0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D, + 0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA, + 0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91, + 0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D, + 0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2, + 0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC, + 0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13, + 0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C, + 0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062, + 0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118, + 0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177, + 0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285, + 0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293, + 0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291, + 0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3, + 0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C, + 0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700, + 0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817, + 0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903, + 0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1, + 0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41, + 0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3, + 0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104, + 0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9, + 0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105, + 0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289, + 0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2, + 0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632, + 0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653, + 0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636, + 0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F, + 0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE, + 0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09, + 0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C, + 0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9, + 0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D, + 0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61, + 0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD, + 0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71, + 0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167, + 0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182, + 0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E, + 0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E, + 0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194, + 0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F, + 0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488, + 0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493, + 0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE, + 0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC, + 0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575, + 0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB, + 0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F, + 0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19, + 0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A, + 0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED, + 0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4, + 0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C, + 0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54, + 0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78, + 0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70, + 0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5, + 0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F, + 0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256, + 0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469, + 0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480, + 0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F, + 0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622, + 0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E, + 0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B, + 0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA, + 0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0, + 0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D, + 0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE, + 0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4, + 0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0, + 0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4, + 0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC, + 0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA, + 0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9, + 0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77, + 0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B, + 0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A, + 0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A, + 0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513, + 0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514, + 0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506, + 0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760, + 0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759, + 0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B, + 0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912, + 0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC, + 0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95, + 0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9, + 0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6, + 0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB, + 0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0, + 0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC, + 0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC, + 0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F, + 0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D, + 0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F, + 0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D, + 0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26, + 0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25, + 0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D, + 0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127, + 0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B, + 0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7, + 0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1, + 0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7, + 0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1, + 0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709, + 0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F, + 0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3, + 0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918, + 0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB, + 0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9, + 0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27, + 0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F, + 0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9, + 0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52, + 0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110, + 0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD, + 0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659, + 0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664, + 0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665, + 0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662, + 0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7, + 0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34, + 0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A, + 0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A, + 0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA, + 0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1, + 0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA, + 0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD, + 0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE, + 0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9, + 0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D, + 0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B, + 0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62, + 0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35, + 0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77, + 0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1, + 0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7, + 0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6, + 0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE, + 0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8, + 0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9, + 0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368, + 0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F, + 0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D, + 0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7, + 0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F, + 0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC, + 0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E, + 0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA, + 0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4, + 0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6, + 0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11, + 0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E, + 0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79, + 0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE, + 0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8, + 0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259, + 0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568, + 0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D, + 0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F, + 0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861, + 0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B, + 0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6, + 0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00, + 0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE, + 0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED, + 0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B, + 0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44, + 0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39, + 0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38, + 0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075, + 0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C, + 0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320, + 0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F, + 0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304, + 0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321, + 0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB, + 0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5, + 0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D, + 0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C, + 0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838, + 0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839, + 0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E, + 0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED, + 0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC, + 0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91, + 0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28, + 0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4, + 0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F, + 0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E, + 0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687, + 0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1, + 0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24, + 0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC, + 0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B, + 0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2, + 0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232, + 0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8, + 0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC, + 0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582, + 0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80, + 0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C, + 0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97, + 0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE, + 0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1, + 0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4, + 0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC, + 0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE, + 0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE, + 0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC, + 0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246, + 0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0, + 0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642, + 0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA, + 0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD, + 0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4, + 0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA, + 0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D, + 0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0, + 0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2, + 0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E, + 0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32, + 0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31, + 0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39, + 0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F, + 0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071, + 0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073, + 0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2, + 0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9, + 0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271, + 0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C, + 0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B, + 0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667, + 0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2, + 0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA, + 0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936, + 0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC, + 0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B, + 0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04, + 0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73, + 0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8, + 0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B, + 0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E, + 0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F, + 0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082, + 0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E, + 0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328, + 0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B, + 0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B, + 0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA, + 0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6, + 0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C, + 0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846, + 0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF, + 0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD, + 0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF, + 0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB, + 0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695, + 0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38, + 0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4, + 0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA, + 0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC, + 0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3, + 0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE, + 0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF, + 0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006, + 0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB, + 0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377, + 0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515, + 0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD, + 0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E, + 0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60, + 0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27, + 0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21, + 0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E, + 0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59, + 0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077, + 0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A, + 0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0, + 0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9, + 0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2, + 0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4, + 0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B, + 0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63, + 0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55, + 0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087, + 0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC, + 0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396, + 0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC, + 0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397, + 0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5, + 0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB, + 0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6, + 0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F, + 0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA, + 0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E, + 0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03, + 0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D, + 0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8, + 0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60, + 0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133, + 0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2, + 0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2, + 0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500, + 0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5, + 0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B, + 0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D, + 0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D, + 0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A, + 0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587, + 0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7, + 0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69, + 0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D, + 0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D, + 0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85, + 0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8, + 0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA, + 0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7, + 0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9, + 0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956, + 0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58, + 0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F, + 0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A, + 0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76, + 0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54, + 0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B, + 0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1, + 0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC, + 0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD, + 0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8, + 0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A, + 0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB, + 0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC, + 0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19, + 0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6, + 0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72, + 0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97, + 0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8, + 0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC, + 0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D, + 0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA, + 0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6, + 0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030, + 0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF, + 0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A, + 0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6, + 0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF, + 0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C, + 0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA, + 0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611, + 0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607, + 0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964, + 0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C, + 0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B, + 0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81, + 0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB, + 0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1, + 0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951, + 0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37, + 0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79, + 0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F, + 0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138, + 0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914, + 0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE, + 0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9, + 0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2, + 0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6, + 0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50, + 0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617, + 0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822, + 0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C, + 0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D, + 0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B, + 0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E, + 0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438, + 0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738, + 0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867, + 0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43, + 0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54, + 0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF, + 0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D, + 0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66, + 0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8, + 0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4, + 0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524, + 0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058, + 0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E, + 0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F, + 0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972, + 0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16, + 0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61, + 0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452, + 0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1, + 0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D, + 0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31, + 0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7, + 0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94, + 0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523, + 0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10, + 0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63, + 0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94, + 0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831, + 0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463, + 0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F, + 0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57, + 0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54, + 0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F, + 0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C, + 0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7, + 0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839, + 0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96, + 0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A, + 0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6, + 0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58, + 0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C, + 0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72, + 0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C, + 0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1, + 0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871, + 0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC, + 0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477, + 0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C, + 0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D, + 0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78, + 0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A, + 0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B, + 0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C, + 0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07, + 0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7, + 0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F, + 0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93, + 0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198, + 0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720, + 0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF, + 0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14, + 0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8, + 0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD, + 0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C, + 0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F, + 0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B, + 0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80, + 0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250, + 0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F, + 0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A, + 0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E, + 0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14, + 0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08, + 0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22, + 0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12, + 0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210, + 0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D, + 0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF, + 0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C, + 0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B, + 0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56, + 0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A, + 0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75, + 0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74, + 0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C, + 0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266, + 0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A, + 0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E, + 0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A, + 0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18, + 0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F, + 0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C, + 0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5, + 0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75, + 0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280, + 0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E, + 0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B, + 0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620, + 0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62, + 0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E, + 0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41, + 0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F, + 0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C, + 0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE, + 0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E, + 0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A, + 0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C, + 0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F, + 0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447, + 0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741, + 0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B, + 0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6, + 0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E, + 0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7, + 0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28, + 0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88, + 0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A, + 0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0, + 0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89, + 0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05, + 0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2, + 0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8, + 0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4, + 0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7, + 0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A, + 0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F, + 0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B, + 0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288, + 0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274, + 0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3, + 0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747, + 0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748, + 0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B, + 0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78, + 0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B, + 0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69, + 0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95, + 0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65, + 0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A, + 0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3, + 0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5, + 0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394, + 0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594, + 0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034, + 0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092, + 0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285, + 0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A, + 0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9, + 0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5, + 0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630, + 0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33, + 0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D, + 0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74, + 0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C, + 0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79, + 0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C, + 0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82, + 0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E, + 0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232, + 0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC, + 0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392, + 0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481, + 0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B, + 0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C, + 0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F, + 0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463, + 0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9, + 0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B, + 0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780, + 0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774, + 0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C, + 0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF, + 0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1, + 0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6, + 0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8, + 0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65, + 0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47, + 0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5, + 0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F, + 0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA, + 0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6, + 0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14, + 0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23, + 0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E, + 0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D, + 0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B, + 0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033, + 0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022, + 0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013, + 0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C, + 0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4, + 0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6, + 0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF, + 0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8, + 0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609, + 0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608, + 0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D, + 0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610, + 0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C, + 0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B, + 0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774, + 0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F, + 0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D, + 0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794, + 0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE, + 0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB, + 0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4, + 0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0, + 0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6, + 0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD, + 0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80, + 0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD, + 0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF, + 0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098, + 0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084, + 0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A, + 0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB, + 0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2, + 0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1, + 0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6, + 0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D, + 0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540, + 0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF, + 0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5, + 0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB, + 0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F, + 0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB, + 0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F, + 0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5, + 0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0, + 0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B, + 0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC, + 0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8, + 0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4, + 0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670, + 0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56, + 0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD, + 0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2, + 0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0, + 0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A, + 0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3, + 0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1, + 0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB, + 0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6, + 0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC, + 0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2, + 0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396, + 0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1, + 0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3, + 0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6, + 0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0, + 0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE, + 0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5, + 0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C, + 0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794, + 0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5, + 0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D, + 0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE, + 0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA, + 0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4, + 0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9, + 0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE, + 0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C, + 0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7, + 0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA, + 0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6, + 0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8, + 0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8, + 0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23, + 0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4, + 0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5, + 0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86, + 0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072, + 0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047, + 0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040, + 0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044, + 0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242, + 0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B, + 0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB, + 0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8, + 0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314, + 0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0, + 0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF, + 0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635, + 0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633, + 0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634, + 0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710, + 0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA, + 0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8, + 0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB, + 0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD, + 0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE, + 0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE, + 0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC, + 0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE, + 0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9, + 0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB, + 0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6, + 0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20, + 0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D, + 0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12, + 0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04, + 0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11, + 0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01, + 0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F, + 0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C, + 0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10, + 0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1, + 0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5, + 0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A, + 0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E, + 0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB, + 0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3, + 0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8, + 0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5, + 0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7, + 0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8, + 0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E, + 0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA, + 0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703, + 0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7, + 0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8, + 0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805, + 0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809, + 0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C, + 0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5, + 0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE, + 0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00, + 0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79, + 0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03, + 0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91, + 0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E, + 0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8, + 0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8, + 0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3, + 0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5, + 0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6, + 0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294, + 0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307, + 0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A, + 0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC, + 0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C, + 0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA, + 0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3, + 0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C, + 0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867, + 0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04, + 0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1, + 0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD, + 0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE, + 0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4, + 0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651, + 0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E, + 0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022, + 0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4, + 0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6, + 0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020, + 0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031, + 0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193, + 0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8, + 0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252, + 0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262, + 0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526, + 0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7, + 0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF, + 0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511, + 0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB, + 0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E, + 0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702, + 0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2, + 0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC, + 0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7, + 0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E, + 0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D, + 0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17, + 0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C, + 0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03, + 0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF, + 0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00, + 0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8, + 0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33, + 0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A, + 0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088, + 0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D, + 0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097, + 0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219, + 0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356, + 0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336, + 0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B, + 0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341, + 0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359, + 0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A, + 0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340, + 0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6, + 0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A, + 0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712, + 0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849, + 0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B, + 0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C, + 0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F, + 0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D, + 0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828, + 0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825, + 0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D, + 0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082, + 0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8, + 0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25, + 0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76, + 0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58, + 0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91, + 0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86, + 0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97, + 0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82, + 0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B, + 0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16, + 0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75, + 0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1, + 0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2, + 0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0, + 0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6, + 0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1, + 0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276, + 0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE, + 0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301, + 0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6, + 0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9, + 0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4, + 0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8, + 0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4, + 0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F, + 0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4, + 0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA, + 0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B, + 0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723, + 0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A, + 0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C, + 0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828, + 0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829, + 0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954, + 0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953, + 0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC, + 0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA, + 0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86, + 0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C, + 0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10, + 0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F, + 0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09, + 0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A, + 0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85, + 0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E, + 0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F, + 0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C, + 0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D, + 0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3, + 0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E, + 0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9, + 0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100, + 0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333, + 0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351, + 0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341, + 0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342, + 0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308, + 0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324, + 0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329, + 0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353, + 0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327, + 0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2, + 0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691, + 0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686, + 0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5, + 0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695, + 0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690, + 0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D, + 0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880, + 0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883, + 0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12, + 0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4, + 0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5, + 0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3, + 0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF, + 0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6, + 0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA, + 0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8, + 0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4, + 0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5, + 0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F, + 0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F, + 0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061, + 0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B, + 0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D, + 0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062, + 0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069, + 0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046, + 0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057, + 0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D, + 0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3, + 0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576, + 0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534, + 0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536, + 0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545, + 0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E, + 0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B, + 0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707, + 0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6, + 0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED, + 0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B, + 0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE, + 0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC, + 0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810, + 0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1, + 0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804, + 0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55, + 0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35, + 0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65, + 0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57, + 0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44, + 0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E, + 0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70, + 0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56, + 0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E, + 0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E, + 0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20, + 0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26, + 0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12, + 0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E, + 0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9, + 0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38, + 0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A, + 0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0, + 0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF, + 0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8, + 0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA, + 0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0, + 0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382, + 0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD, + 0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E, + 0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E, + 0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D, + 0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B, + 0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381, + 0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553, + 0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B, + 0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718, + 0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C, + 0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB, + 0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC, + 0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2, + 0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C, + 0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880, + 0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896, + 0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4, + 0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C, + 0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33, + 0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F, + 0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A, + 0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3, + 0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2, + 0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00, + 0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6, + 0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD, + 0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD, + 0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5, + 0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0, + 0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7, + 0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA, + 0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4, + 0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3, + 0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106, + 0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6, + 0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E, + 0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D, + 0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318, + 0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F, + 0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8, + 0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD, + 0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC, + 0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4, + 0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE, + 0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC, + 0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689, + 0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D, + 0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733, + 0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735, + 0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D, + 0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845, + 0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969, + 0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961, + 0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6, + 0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90, + 0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25, + 0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33, + 0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31, + 0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32, + 0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94, + 0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35, + 0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A, + 0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41, + 0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A, + 0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95, + 0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA, + 0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1, + 0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F, + 0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043, + 0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119, + 0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C, + 0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127, + 0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238, + 0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232, + 0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8, + 0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4, + 0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395, + 0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9, + 0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D, + 0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E, + 0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397, + 0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387, + 0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659, + 0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2, + 0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0, + 0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8, + 0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC, + 0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852, + 0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2, + 0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1, + 0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899, + 0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC, + 0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982, + 0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30, + 0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39, + 0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D, + 0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79, + 0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF, + 0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD, + 0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1, + 0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C, + 0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA, + 0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3, + 0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9, + 0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153, + 0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1, + 0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9, + 0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8, + 0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588, + 0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671, + 0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804, + 0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095, + 0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3, + 0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D, + 0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082, + 0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312, + 0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591, + 0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577, + 0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588, + 0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3, + 0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C, + 0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1, + 0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837, + 0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823, + 0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825, + 0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F, + 0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838, + 0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961, + 0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A, + 0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6, + 0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95, + 0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A, + 0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9, + 0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C, + 0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA, + 0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1, + 0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30, + 0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41, + 0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51, + 0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A, + 0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59, + 0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38, + 0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40, + 0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58, + 0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9, + 0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE, + 0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A, + 0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113, + 0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1, + 0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110, + 0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A, + 0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE, + 0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3, + 0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0, + 0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5, + 0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD, + 0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3, + 0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB, + 0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9, + 0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564, + 0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C, + 0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0, + 0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B, + 0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A, + 0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3, + 0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC, + 0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6, + 0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6, + 0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1, + 0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970, + 0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6, + 0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD, + 0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A, + 0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD, + 0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1, + 0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915, + 0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B, + 0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97, + 0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0, + 0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC, + 0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49, + 0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45, + 0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41, + 0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33, + 0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B, + 0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68, + 0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28, + 0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39, + 0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65, + 0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77, + 0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66, + 0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120, + 0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E, + 0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122, + 0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A, + 0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288, + 0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B, + 0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322, + 0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332, + 0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335, + 0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430, + 0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421, + 0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423, + 0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432, + 0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C, + 0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6, + 0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7, + 0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746, + 0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745, + 0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C, + 0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864, + 0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871, + 0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869, + 0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974, + 0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02, + 0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04, + 0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A, + 0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C, + 0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45, + 0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1, + 0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53, + 0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F, + 0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52, + 0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F, + 0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65, + 0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1, + 0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050, + 0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A, + 0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D, + 0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE, + 0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204, + 0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275, + 0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423, + 0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7, + 0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410, + 0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3, + 0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5, + 0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB, + 0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9, + 0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411, + 0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5, + 0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA, + 0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE, + 0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2, + 0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8, + 0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3, + 0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB, + 0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7, + 0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856, + 0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9, + 0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6, + 0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2, + 0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998, + 0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB, + 0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59, + 0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44, + 0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51, + 0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F, + 0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE, + 0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84, + 0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3, + 0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC, + 0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8, + 0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7, + 0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE, + 0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8, + 0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC, + 0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034, + 0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104, + 0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9, + 0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107, + 0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164, + 0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201, + 0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A, + 0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200, + 0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206, + 0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C, + 0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205, + 0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C, + 0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688, + 0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2, + 0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0, + 0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807, + 0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9, + 0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD, + 0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4, + 0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2, + 0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1, + 0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8, + 0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B, + 0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC, + 0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD, + 0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9, + 0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF, + 0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8, + 0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2, + 0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864, + 0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F, + 0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859, + 0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863, + 0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4, + 0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1, + 0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8, + 0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0, + 0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD, + 0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8, + 0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71, + 0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72, + 0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67, + 0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E, + 0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5, + 0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7, + 0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7, + 0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145, + 0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146, + 0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140, + 0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225, + 0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB, + 0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420, + 0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F, + 0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437, + 0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426, + 0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435, + 0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440, + 0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7, + 0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E, + 0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686, + 0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B, + 0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678, + 0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938, + 0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F, + 0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942, + 0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948, + 0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933, + 0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978, + 0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F, + 0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941, + 0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B, + 0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951, + 0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B, + 0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43, + 0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B, + 0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9, + 0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6, + 0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F, + 0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1, + 0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD, + 0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7, + 0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF, + 0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC, + 0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E, + 0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF, + 0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97, + 0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154, + 0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141, + 0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178, + 0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158, + 0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F, + 0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D, + 0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C, + 0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C, + 0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340, + 0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A, + 0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457, + 0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E, + 0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454, + 0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD, + 0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983, + 0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7, + 0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8, + 0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED, + 0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5, + 0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760, + 0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769, + 0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D, + 0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894, + 0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885, + 0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879, + 0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B, + 0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979, + 0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12, + 0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13, + 0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2, + 0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64, + 0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72, + 0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70, + 0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63, + 0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88, + 0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F, + 0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B, + 0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94, + 0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D, + 0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C, + 0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB, + 0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160, + 0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B, + 0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E, + 0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144, + 0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244, + 0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1, + 0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479, + 0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451, + 0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430, + 0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459, + 0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507, + 0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434, + 0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432, + 0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B, + 0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F, + 0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C, + 0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E, + 0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433, + 0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B, + 0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450, + 0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C, + 0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D, + 0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701, + 0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6, + 0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE, + 0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0, + 0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5, + 0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2, + 0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86, + 0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77, + 0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83, + 0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C, + 0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64, + 0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85, + 0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91, + 0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D, + 0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92, + 0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1, + 0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3, + 0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB, + 0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01, + 0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08, + 0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F, + 0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110, + 0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116, + 0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E, + 0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230, + 0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265, + 0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A, + 0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F, + 0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236, + 0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254, + 0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E, + 0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232, + 0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B, + 0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697, + 0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8, + 0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778, + 0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E, + 0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF, + 0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD, + 0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED, + 0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6, + 0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3, + 0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4, + 0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF, + 0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280, + 0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330, + 0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C, + 0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C, + 0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA, + 0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9, + 0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898, + 0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874, + 0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891, + 0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888, + 0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE, + 0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5, + 0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED, + 0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0, + 0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD, + 0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77, + 0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82, + 0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A, + 0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89, + 0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D, + 0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59, + 0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7, + 0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9, + 0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43, + 0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128, + 0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173, + 0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C, + 0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A, + 0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A, + 0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227, + 0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B, + 0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472, + 0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466, + 0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E, + 0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460, + 0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C, + 0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477, + 0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0, + 0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722, + 0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0, + 0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC, + 0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E, + 0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE, + 0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD, + 0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA, + 0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993, + 0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9, + 0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5, + 0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D, + 0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0, + 0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE, + 0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25, + 0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E, + 0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A, + 0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12, + 0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73, + 0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40, + 0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB, + 0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05, + 0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C, + 0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D, + 0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187, + 0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185, + 0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186, + 0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253, + 0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343, + 0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462, + 0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472, + 0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502, + 0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616, + 0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611, + 0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781, + 0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E, + 0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783, + 0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD, + 0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E, + 0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2, + 0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B, + 0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993, + 0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990, + 0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F, + 0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB, + 0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C, + 0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96, + 0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E, + 0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99, + 0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF, + 0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7, + 0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1, + 0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE, + 0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC, + 0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC, + 0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9, + 0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2, + 0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024, + 0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186, + 0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C, + 0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4, + 0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE, + 0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB, + 0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD, + 0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0, + 0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2, + 0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B, + 0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6, + 0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0, + 0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB, + 0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733, + 0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740, + 0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719, + 0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741, + 0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732, + 0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712, + 0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742, + 0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724, + 0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7, + 0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA, + 0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6, + 0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB, + 0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E, + 0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB, + 0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F, + 0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69, + 0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96, + 0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D, + 0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07, + 0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00, + 0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E, + 0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120, + 0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A, + 0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A, + 0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5, + 0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A, + 0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D, + 0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279, + 0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE, + 0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2, + 0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A, + 0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7, + 0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D, + 0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1, + 0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A, + 0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782, + 0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F, + 0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD, + 0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907, + 0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9, + 0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD, + 0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7, + 0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61, + 0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5, + 0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130, + 0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6, + 0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD, + 0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1, + 0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C, + 0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649, + 0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640, + 0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E, + 0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A, + 0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0, + 0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5, + 0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4, + 0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03, + 0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01, + 0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67, + 0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92, + 0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0, + 0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E, + 0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C, + 0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1, + 0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183, + 0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2, + 0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF, + 0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA, + 0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3, + 0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496, + 0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C, + 0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C, + 0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1, + 0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579, + 0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5, + 0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7, + 0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06, + 0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15, + 0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF, + 0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D, + 0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE, + 0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40, + 0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D, + 0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04, + 0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6, + 0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16, + 0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2, + 0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF, + 0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E, + 0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D, + 0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F, + 0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76, + 0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72, + 0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94, + 0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61, + 0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90, + 0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F, + 0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A, + 0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B, + 0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9, + 0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E, + 0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C, + 0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A, + 0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F, + 0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361, + 0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487, + 0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481, + 0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C, + 0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E, + 0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D, + 0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628, + 0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E, + 0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789, + 0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF, + 0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4, + 0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9, + 0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C, + 0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39, + 0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7, + 0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE, + 0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5, + 0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB, + 0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7, + 0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA, + 0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0, + 0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC, + 0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB, + 0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8, + 0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F, + 0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199, + 0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253, + 0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251, + 0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500, + 0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D, + 0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C, + 0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508, + 0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2, + 0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3, + 0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9, + 0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D, + 0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E, + 0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7, + 0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9, + 0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B, + 0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756, + 0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1, + 0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B, + 0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751, + 0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750, + 0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F, + 0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C, + 0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775, + 0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A, + 0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B, + 0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906, + 0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909, + 0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED, + 0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6, + 0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4, + 0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE, + 0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3, + 0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E, + 0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF, + 0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD, + 0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1, + 0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25, + 0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B, + 0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26, + 0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18, + 0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A, + 0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A, + 0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17, + 0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067, + 0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129, + 0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E, + 0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181, + 0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0, + 0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9, + 0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF, + 0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD, + 0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8, + 0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6, + 0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0, + 0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3, + 0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4, + 0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE, + 0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3, + 0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A, + 0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0, + 0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826, + 0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B, + 0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA, + 0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917, + 0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF, + 0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9, + 0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7, + 0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB, + 0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46, + 0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71, + 0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70, + 0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC, + 0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7, + 0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB, + 0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83, + 0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C, + 0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111, + 0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670, + 0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666, + 0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E, + 0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8, + 0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA, + 0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17, + 0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14, + 0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28, + 0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF, + 0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7, + 0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA, + 0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF, + 0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66, + 0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6, + 0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC, + 0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5, + 0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC, + 0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C, + 0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF, + 0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3, + 0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533, + 0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8, + 0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB, + 0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA, + 0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66, + 0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68, + 0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76, + 0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A, + 0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A, + 0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54, + 0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C, + 0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D, + 0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54, + 0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB, + 0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03, + 0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3, + 0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8, + 0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E, + 0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5, + 0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA, + 0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2, + 0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF, + 0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2, + 0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0, + 0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA, + 0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8, + 0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB, + 0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366, + 0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B, + 0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0, + 0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1, + 0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D, + 0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C, + 0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB, + 0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1, + 0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3, + 0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD, + 0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE, + 0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2, + 0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4, + 0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6, + 0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7, + 0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD, + 0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8, + 0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2, + 0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF, + 0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0, + 0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17, + 0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13, + 0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A, + 0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16, + 0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24, + 0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A, + 0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029, + 0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE, + 0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0, + 0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7, + 0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256, + 0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B, + 0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558, + 0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541, + 0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547, + 0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571, + 0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555, + 0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566, + 0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C, + 0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B, + 0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792, + 0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798, + 0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785, + 0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784, + 0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789, + 0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D, + 0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922, + 0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C, + 0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2, + 0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD, + 0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0, + 0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8, + 0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91, + 0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE, + 0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C, + 0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33, + 0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45, + 0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41, + 0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36, + 0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39, + 0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079, + 0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133, + 0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190, + 0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327, + 0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306, + 0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C, + 0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301, + 0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D, + 0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325, + 0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334, + 0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329, + 0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314, + 0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309, + 0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC, + 0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA, + 0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD, + 0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712, + 0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794, + 0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F, + 0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927, + 0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC, + 0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3, + 0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9, + 0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6, + 0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33, + 0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C, + 0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93, + 0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95, + 0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17, + 0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29, + 0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10, + 0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86, + 0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5, + 0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D, + 0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124, + 0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693, + 0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684, + 0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F, + 0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF, + 0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32, + 0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26, + 0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1, + 0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A, + 0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5, + 0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5, + 0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF, + 0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4, + 0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6, + 0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96, + 0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F, + 0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87, + 0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83, + 0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F, + 0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C, + 0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09, + 0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4, + 0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7, + 0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD, + 0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1, + 0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0, + 0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F, + 0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490, + 0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5, + 0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512, + 0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648, + 0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9, + 0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7, + 0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8, + 0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902, + 0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905, + 0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB, + 0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56, + 0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE, + 0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F, + 0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB, + 0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3, + 0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01, + 0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0, + 0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8, + 0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33, + 0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49, + 0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C, + 0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44, + 0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E, + 0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C, + 0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA, + 0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9, + 0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583, + 0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595, + 0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B, + 0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577, + 0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A, + 0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596, + 0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D, + 0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588, + 0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598, + 0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE, + 0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0, + 0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC, + 0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2, + 0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4, + 0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF, + 0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2, + 0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E, + 0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942, + 0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2, + 0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16, + 0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22, + 0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07, + 0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C, + 0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70, + 0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95, + 0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E, + 0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C, + 0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085, + 0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2, + 0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1, + 0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383, + 0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347, + 0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376, + 0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360, + 0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A, + 0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352, + 0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B, + 0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367, + 0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7, + 0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5, + 0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC, + 0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D, + 0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C, + 0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4, + 0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A, + 0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925, + 0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933, + 0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931, + 0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1, + 0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7, + 0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB, + 0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03, + 0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01, + 0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8, + 0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1, + 0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2, + 0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41, + 0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F, + 0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45, + 0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37, + 0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D, + 0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0, + 0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF, + 0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54, + 0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E, + 0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A, + 0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C, + 0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D, + 0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED, + 0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0, + 0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF, + 0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501, + 0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB, + 0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5, + 0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6, + 0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7, + 0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9, + 0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D, + 0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E, + 0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026, + 0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201, + 0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD, + 0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5, + 0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB, + 0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C, + 0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653, + 0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD, + 0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF, + 0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909, + 0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD, + 0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29, + 0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D, + 0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22, + 0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50, + 0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62, + 0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57, + 0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7, + 0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2, + 0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4, + 0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2, + 0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7, + 0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE, + 0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6, + 0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7, + 0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6, + 0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA, + 0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4, + 0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED, + 0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7, + 0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8, + 0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F, + 0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951, + 0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23, + 0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47, + 0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31, + 0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36, + 0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D, + 0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99, + 0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04, + 0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62, + 0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E, + 0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A, + 0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54, + 0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B, + 0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E, + 0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF, + 0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392, + 0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389, + 0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E, + 0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399, + 0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391, + 0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4, + 0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3, + 0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA, + 0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD, + 0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC, + 0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4, + 0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7, + 0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA, + 0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8, + 0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F, + 0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04, + 0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07, + 0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08, + 0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35, + 0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7, + 0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1, + 0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6, + 0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C, + 0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B, + 0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C, + 0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F, + 0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C, + 0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16, + 0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29, + 0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134, + 0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4, + 0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7, + 0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD, + 0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E, + 0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF, + 0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D, + 0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584, + 0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7, + 0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9, + 0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0, + 0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE, + 0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019, + 0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B, + 0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029, + 0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A, + 0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202, + 0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4, + 0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5, + 0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660, + 0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1, + 0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C, + 0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67, + 0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39, + 0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA, + 0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70, + 0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72, + 0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A, + 0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD, + 0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5, + 0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB, + 0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1, + 0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC, + 0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF, + 0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0, + 0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2, + 0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6, + 0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B, + 0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF, + 0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A, + 0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C, + 0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988, + 0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50, + 0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53, + 0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55, + 0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57, + 0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A, + 0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC, + 0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D, + 0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F, + 0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51, + 0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4, + 0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD, + 0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2, + 0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC, + 0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6, + 0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3, + 0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0, + 0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA, + 0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B, + 0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3, + 0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE, + 0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D, + 0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB, + 0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943, + 0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15, + 0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B, + 0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23, + 0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2, + 0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C, + 0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0, + 0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2, + 0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC, + 0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5, + 0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81, + 0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71, + 0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B, + 0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74, + 0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85, + 0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F, + 0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68, + 0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC, + 0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D, + 0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337, + 0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3, + 0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE, + 0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9, + 0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513, + 0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4, + 0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8, + 0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF, + 0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037, + 0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038, + 0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040, + 0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213, + 0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C, + 0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE, + 0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF, + 0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923, + 0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929, + 0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D, + 0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A, + 0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B, + 0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA, + 0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9, + 0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622, + 0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B, + 0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609, + 0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819, + 0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813, + 0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9, + 0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D, + 0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67, + 0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88, + 0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57, + 0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D, + 0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5, + 0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413, + 0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414, + 0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428, + 0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400, + 0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416, + 0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8, + 0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C, + 0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE, + 0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F, + 0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE, + 0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F, + 0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E, + 0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953, + 0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C, + 0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E, + 0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA, + 0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11, + 0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05, + 0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07, + 0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14, + 0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4, + 0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90, + 0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C, + 0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A, + 0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3, + 0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6, + 0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A, + 0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6, + 0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60, + 0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91, + 0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297, + 0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48, + 0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1, + 0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC, + 0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043, + 0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049, + 0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A, + 0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A, + 0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F, + 0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A, + 0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86, + 0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030, + 0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626, + 0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619, + 0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620, + 0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829, + 0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824, + 0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D, + 0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA, + 0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A, + 0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF, + 0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B, + 0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145, + 0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436, + 0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430, + 0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C, + 0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4, + 0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF, + 0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6, + 0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39, + 0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42, + 0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD, + 0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16, + 0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D, + 0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28, + 0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7, + 0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7, + 0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5, + 0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE, + 0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8, + 0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3, + 0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C, + 0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B, + 0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E, + 0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9, + 0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971, + 0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1, + 0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526, + 0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09, + 0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057, + 0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9, + 0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9, + 0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935, + 0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57, + 0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A, + 0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F, + 0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634, + 0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632, + 0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826, + 0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF, + 0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84, + 0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F, + 0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A, + 0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97, + 0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C, + 0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F, + 0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449, + 0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A, + 0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B, + 0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C, + 0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49, + 0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19, + 0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55, + 0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44, + 0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C, + 0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D, + 0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE, + 0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC, + 0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9, + 0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5, + 0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35, + 0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B, + 0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299, + 0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D, + 0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201, + 0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525, + 0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12, + 0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A, + 0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383, + 0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66, + 0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640, + 0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B, + 0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E, + 0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973, + 0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B, + 0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98, + 0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462, + 0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E, + 0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56, + 0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20, + 0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A, + 0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59, + 0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7, + 0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8, + 0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE, + 0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2, + 0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8, + 0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2, + 0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38, + 0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F, + 0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F, + 0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D, + 0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13, + 0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060, + 0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5, + 0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A, + 0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643, + 0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B, + 0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F, + 0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD, + 0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469, + 0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747, + 0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5, + 0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66, + 0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02, + 0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06, + 0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09, + 0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0, + 0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75, + 0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8, + 0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A, + 0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8, + 0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B, + 0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B, + 0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646, + 0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A, + 0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98, + 0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3, + 0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471, + 0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F, + 0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B, + 0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12, + 0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09, + 0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A, + 0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F, + 0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3, + 0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475, + 0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71, + 0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6, + 0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065, + 0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D, + 0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9, + 0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874, + 0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64, + 0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15, + 0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E, + 0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482, + 0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68, + 0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B, + 0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7, + 0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D, + 0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E, + 0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9, + 0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7, + 0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557, + 0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A, + 0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564, + 0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561, + 0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553, + 0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B, + 0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C, + 0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E, + 0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (src < 0x80) { /* ASCII */ + c = src; + } else { + if (dir) { /* OEMCP to unicode */ + p = oem2uni; + hi = sizeof(oem2uni) / 4 - 1; + } else { /* Unicode to OEMCP */ + p = uni2oem; + hi = sizeof(uni2oem) / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (src == p[i * 2]) break; + if (src > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/Lib/Fat/src/option/ccsbcs.c b/Lib/Fat/src/option/ccsbcs.c new file mode 100644 index 0000000..37fd70d --- /dev/null +++ b/Lib/Fat/src/option/ccsbcs.c @@ -0,0 +1,540 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */ +/* (SBCS code pages) */ +/*------------------------------------------------------------------------*/ +/* 437 U.S. (OEM) +/ 720 Arabic (OEM) +/ 1256 Arabic (Windows) +/ 737 Greek (OEM) +/ 1253 Greek (Windows) +/ 1250 Central Europe (Windows) +/ 775 Baltic (OEM) +/ 1257 Baltic (Windows) +/ 850 Multilingual Latin 1 (OEM) +/ 852 Latin 2 (OEM) +/ 1252 Latin 1 (Windows) +/ 855 Cyrillic (OEM) +/ 1251 Cyrillic (Windows) +/ 866 Russian (OEM) +/ 857 Turkish (OEM) +/ 1254 Turkish (Windows) +/ 858 Multilingual Latin 1 + Euro (OEM) +/ 862 Hebrew (OEM) +/ 1255 Hebrew (Windows) +/ 874 Thai (OEM, Windows) +/ 1258 Vietnam (OEM, Windows) +*/ + +#include "../ff.h" + + +#if _CODE_PAGE == 437 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 720 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ + 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, + 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, + 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, + 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 737 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, + 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, + 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, + 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, + 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 775 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ + 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, + 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, + 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, + 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, + 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, + 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, + 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, + 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, + 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, + 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 850 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 852 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, + 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, + 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, + 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, + 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 855 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, + 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, + 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, + 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, + 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, + 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 857 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, + 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 858 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 862 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 866 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 874 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +#elif _CODE_PAGE == 1250 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +}; + +#elif _CODE_PAGE == 1251 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */ + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042D, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F +}; + +#elif _CODE_PAGE == 1252 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +}; + +#elif _CODE_PAGE == 1253 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000 +}; + +#elif _CODE_PAGE == 1254 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +}; + +#elif _CODE_PAGE == 1255 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, + 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, + 0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000 +}; + +#elif _CODE_PAGE == 1256 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, + 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, + 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2 +} + +#elif _CODE_PAGE == 1257 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9 +}; + +#elif _CODE_PAGE == 1258 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF +}; + +#endif + + +#if !_TBLDEF || !_USE_LFN +#error This file is not needed in current configuration. Remove from the project. +#endif + + +WCHAR ff_convert ( /* Converted character, Returns zero on error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + WCHAR c; + + + if (src < 0x80) { /* ASCII */ + c = src; + + } else { + if (dir) { /* OEMCP to Unicode */ + c = (src >= 0x100) ? 0 : Tbl[src - 0x80]; + + } else { /* Unicode to OEMCP */ + for (c = 0; c < 0x80; c++) { + if (src == Tbl[c]) break; + } + c = (c + 0x80) & 0xFF; + } + } + + return c; +} + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/Lib/Fat/src/option/syscall.c b/Lib/Fat/src/option/syscall.c new file mode 100644 index 0000000..beb7385 --- /dev/null +++ b/Lib/Fat/src/option/syscall.c @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------*/ +/* Sample code of OS dependent controls for FatFs R0.08 */ +/* (C)ChaN, 2010 */ +/*------------------------------------------------------------------------*/ + +#include /* ANSI memory controls */ +#include /* ANSI memory controls */ + +#include "../ff.h" + + +#if _FS_REENTRANT +/*------------------------------------------------------------------------*/ +/* Create a Synchronization Object +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount function to create a new +/ synchronization object, such as semaphore and mutex. When a FALSE is +/ returned, the f_mount function fails with FR_INT_ERR. +*/ + +BOOL ff_cre_syncobj ( /* TRUE:Function succeeded, FALSE:Could not create due to any error */ + BYTE vol, /* Corresponding logical drive being processed */ + _SYNC_t *sobj /* Pointer to return the created sync object */ +) +{ + BOOL ret; + + *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */ + ret = (*sobj != INVALID_HANDLE_VALUE) ? TRUE : FALSE; + +// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */ +// ret = TRUE; /* The initial value of the semaphore must be 1. */ + +// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */ +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; + +// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */ +// ret = (*sobj != NULL) ? TRUE : FALSE; + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Delete a Synchronization Object */ +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount function to delete a synchronization +/ object that created with ff_cre_syncobj function. When a FALSE is +/ returned, the f_mount function fails with FR_INT_ERR. +*/ + +BOOL ff_del_syncobj ( /* TRUE:Function succeeded, FALSE:Could not delete due to any error */ + _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ +) +{ + BOOL ret; + + ret = CloseHandle(sobj); /* Win32 * + +// ret = TRUE; /* uITRON (nothing to do) * + +// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */ +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; + +// ret = TRUE; /* FreeRTOS (nothing to do) */ + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Request Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on entering file functions to lock the volume. +/ When a FALSE is returned, the file function fails with FR_TIMEOUT. +*/ + +BOOL ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */ + _SYNC_t sobj /* Sync object to wait */ +) +{ + BOOL ret; + + ret = (WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0) ? TRUE : FALSE; /* Win32 */ + +// ret = (wai_sem(sobj) == E_OK) ? TRUE : FALSE; /* uITRON */ + +// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */ +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; + +// ret = (xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE) ? TRUE : FALSE; /* FreeRTOS */ + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Release Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on leaving file functions to unlock the volume. +*/ + +void ff_rel_grant ( + _SYNC_t sobj /* Sync object to be signaled */ +) +{ + ReleaseMutex(sobj); /* Win32 */ + +// sig_sem(sobj); /* uITRON */ + +// OSMutexPost(sobj); /* uC/OS-II */ + +// xSemaphoreGive(sobj); /* FreeRTOS */ + +} + +#endif + + + + +#if _USE_LFN == 3 /* LFN with a working buffer on the heap */ +/*------------------------------------------------------------------------*/ +/* Allocate a memory block */ +/*------------------------------------------------------------------------*/ +/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE. +*/ + +void* ff_memalloc ( /* Returns pointer to the allocated memory block */ + UINT size /* Number of bytes to allocate */ +) +{ + return malloc(size); +} + + +/*------------------------------------------------------------------------*/ +/* Free a memory block */ +/*------------------------------------------------------------------------*/ + +void ff_memfree( + void* mblock /* Pointer to the memory block to free */ +) +{ + free(mblock); +} + +#endif diff --git a/Lib/Rs485_prot.c b/Lib/Rs485_prot.c new file mode 100644 index 0000000..6bae92b --- /dev/null +++ b/Lib/Rs485_prot.c @@ -0,0 +1,677 @@ +#include "Rs485_prot.h" +#include +#include + +#if LANG_EN +#include "Rs485_prot_en.h" +#define PRINT_RS485_DEVICE 1 +#endif + +#if LANG_PL +#include "Rs485_prot_pl.h" +#define PRINT_RS485_DEVICE 1 +#endif + + +static void sendPing(uint8_t addr, uint8_t pingLen); +static uint8_t receivePong(uint8_t addr, uint8_t pingLen); +static void sendHello(uint8_t addr); +static uint8_t receiveHello(uint8_t* response, uint8_t maxSize); + +// ********************* Those function have to be implemented in your project ************* +void takeRs485(void) { } +void releaseRs485(void) { } +void uartRs485SendByte(uint8_t c) { (void) c; } +uint8_t rs485Receive(uint8_t *c, uint8_t timeout) { (void) c; (void) timeout; return 1; } +uint8_t flushRs485RecBuffer(void) { return 1;} + + +void rollersMemInit(void) +{ + rollers = xmalloc(MAX_NUMBER_OF_ROLLERS * sizeof(struct sterRolet)); + memset(rollers, 0, MAX_NUMBER_OF_ROLLERS * sizeof(struct sterRolet)); +} + + +// ********************* Hiden Functions *************************************************** + + + +void sendPing(uint8_t addr, uint8_t pingLen) +{ + uint16_t crc = _crc_xmodem_update(0, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, addr); + uartRs485SendByte(addr); + + crc = _crc_xmodem_update(crc, rPING); + uartRs485SendByte(rPING); + + crc = _crc_xmodem_update(crc, pingLen); + uartRs485SendByte(pingLen); + + for (uint8_t i=0; i < pingLen; i++) + { + crc = _crc_xmodem_update(crc, i); + uartRs485SendByte(i); + } + uartRs485SendByte((uint8_t)(crc >> 8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); +} + +uint8_t receivePong(uint8_t addr, uint8_t dataLen) +{ + (void)addr; + uint8_t data; + uint16_t crc; + + //SYNC + if(rs485Receive(&data, 20) == pdFALSE) + return 1; + + if (data != SYNC) + return 2; + crc = _crc_xmodem_update(0, data); + + //Adres ma być wartość 0 + if(rs485Receive(&data, 1) == 0) + return 3; + + if (data != 0) + return 4; + + crc = _crc_xmodem_update(crc, data); + + //Kod rozkazu. Ma być rPING + if(rs485Receive(&data, 1) == pdFALSE) + return 5; + if (data != rPING) + return 6; + crc = _crc_xmodem_update(crc, data); + + //Długość odpowiedzi + if(rs485Receive(&data, 1) == pdFALSE) + return 7; + if (data != dataLen) + return 8; + crc = _crc_xmodem_update(crc, data); + + + uint8_t temp; + for (temp=0; temp < dataLen; temp++) + { + if(rs485Receive(&data, 5) == pdFALSE) + return 2*temp+9; + crc = _crc_xmodem_update(crc, data); + if (data != temp) + return 2*temp+10; + } + + uint8_t crcHi; + uint8_t crcLo; + if(rs485Receive(&crcHi, 1) != pdTRUE) + return 2*temp+11; + + if(xQueueReceive(xRs485Rec, &crcLo, 1) != pdTRUE) + return 2*temp+12; + + if (crcHi != (uint8_t)(crc>>8)) + return 254; + if (crcLo != (uint8_t)(crc & 0xFF)) + return 255; + + return 0; +} + +static void sendHello(uint8_t addr) +{ + uint16_t crc = _crc_xmodem_update(0, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, addr); + uartRs485SendByte(addr); + + crc = _crc_xmodem_update(crc, rHELLO); + uartRs485SendByte(rHELLO); + + crc = _crc_xmodem_update(crc, 0); + uartRs485SendByte(0); + + uartRs485SendByte((uint8_t)(crc >> 8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); +} + +static uint8_t receiveHello(uint8_t* response, uint8_t maxSize) +{ + uint16_t crc; + uint8_t data; + //SYNC + if(rs485Receive(&data, 20) == pdFALSE) + return 8; + + if (data != SYNC) + return 2; + crc = _crc_xmodem_update(0, data); + + //Adres ma być wartość 0 + if(rs485Receive(&data, 1) == 0) + return 3; + + if (data != 0) + return 4; + + crc = _crc_xmodem_update(crc, data); + + //Kod rozkazu. Ma być rHELLO + if(rs485Receive(&data, 1) == pdFALSE) + return 5; + if (data != rHELLO) + return 6; + crc = _crc_xmodem_update(crc, data); + + //Długość odpowiedzi + if(rs485Receive(&data, 1) == pdFALSE) + return 7; + if (data > maxSize) + return 1; + + crc = _crc_xmodem_update(crc, data); + memset(response, 0, maxSize); + maxSize = data; + + for (data=0; data < maxSize; data++) + { + if(rs485Receive(response, 5) == pdFALSE) + return 20; + crc = _crc_xmodem_update(crc, *((uint8_t *)(response))); + response++; + } + + uint8_t crcHi; + uint8_t crcLo; + if(rs485Receive(&crcHi, 1) != pdTRUE) + return 21; + + if(xQueueReceive(xRs485Rec, &crcLo, 1) != pdTRUE) + return 22; + + if (crcHi != (uint8_t)(crc>>8)) + return 254; + if (crcLo != (uint8_t)(crc & 0xFF)) + return 255; + + return 0; +} + +// ************************ Rs485 API ************************************ + + + +#ifdef PRINT_RS485_DEVICE +uint8_t printRs485devices(FILE *stream) +{ + uint8_t result = 0; + struct sterRolet *rolTmp = rollers; + + //Print RollerDrivers + for (uint8_t i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + { + if (rolTmp->address != 0) + { + fprintf_P(stream, statusRollerDescStr, rolTmp->address, rolTmp->response.parsed.stateRoller1 & 0x3F, rolTmp->response.parsed.stateRoller2 & 0x3F); + // fprintf_P(stream, statusRollerDescStrConf, rolTmp->response.parsed.settings); + fprintf_P(stream, statusRollerDescStr2, rolTmp->response.parsed.firmware); + result++; + } + rolTmp++; + } + + + return result; +} +#endif /*PRINT_RS485_DEVICE*/ + +uint8_t rs485ping(uint8_t devAddr) +{ + takeRs485(); + const int len = 8; + sendPing(devAddr, len); + uint8_t result = receivePong(devAddr, len); + flushRs485RecBuffer(); + + releaseRs485(); + return result; +} + +uint8_t rs485rollerHello(uint8_t devAddr) +{ + struct sterRolet *tmp = NULL; + uint8_t i; + for (i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + if (rollers[i].address == devAddr) + tmp = &rollers[i]; + + if (rs485ping(devAddr)==0) + { + if (tmp == NULL) + { + for (i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + { + if (rollers[i].address == 0) + { + tmp = &rollers[i]; + tmp->address = devAddr; + break; + } + } + } + if (tmp != NULL) + { + tmp->state &= (~NOT_DETECTED); + tmp->address = devAddr; + } + else + return 1; + } + else + { + if (tmp != NULL) + { + if (tmp->state & NOT_DETECTED) + { + tmp->address = 0; + } + tmp->state |= NOT_DETECTED; + return 2; + } + } + + takeRs485(); + sendHello(devAddr); + uint8_t result = receiveHello((tmp->response.data), HELLO_RESP_LEN); + releaseRs485(); + return result; +} + + +uint8_t rs485xModemFlash(struct ramPlikFd *file, uint8_t devAddr, FILE *debugStr) +{ + uint16_t crc; + uint8_t blad = 0; + uint8_t data; + uint8_t nrBloku; + uint8_t lRetransmisji; + + takeRs485(); // Zajmowanie magistrali Rs485 + + // Wysyłanie polecenia restartu + crc = _crc_xmodem_update(0, SYNC); uartRs485SendByte(SYNC); + crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + crc = _crc_xmodem_update(crc, rFLASH); uartRs485SendByte(rFLASH); + crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + + // Odbieranie odpowiedzi po wysłaniu polecenia restartu + //Odbieranie SYNC lub C + if(rs485Receive(&data, 100) != pdTRUE) + { + blad = 1; // Timeout + if (debugStr != NULL) + fprintf_P(debugStr, PSTR("rFLASH timeout\r\n")); + } + crc = _crc_xmodem_update(0, data); + + if ((blad == 0) && (data == 'C')) + { + blad = 253; //Na urządzeniu jest wgrany tylko bootloader + if (debugStr != NULL) + fprintf_P(debugStr, PSTR("na urzadzeniu wgrany jest tylko bootloader\r\n")); + } + else + { + if (data != SYNC) + blad = 2; + } + + //Odbieranie odpowiedzi programu. Program zresetuje się by uruchomić bootloadera. + //Odbieranie adresu + if (blad == 0) //Odbieranie adresu (powinno być 0) + { + if(rs485Receive(&data, 1) != pdTRUE) + blad = 3; + else + { + if (data != 0) + blad = 4; + } + crc = _crc_xmodem_update(crc, data); + } + + //Odbieranie kodu rozkazu + if (blad == 0) + { + if(rs485Receive(&data, 1) != pdTRUE) + blad = 5; + else + { + if (data != rFLASH) + blad = 6; + } + crc = _crc_xmodem_update(crc, data); + } + + //Odbieranie długości danych w rozkazie + if (blad == 0) + { + if(rs485Receive(&data, 1) != pdTRUE) + blad = 7; + else + { + if (data != 1) + blad = 8; + } + crc = _crc_xmodem_update(crc, data); + } + + //Odbieranie danych w rozkazie + if (blad == 0) + { + if(rs485Receive(&data, 1) != pdTRUE) + blad = 9; + else + { + if (data != devAddr) + blad = 10; + } + crc = _crc_xmodem_update(crc, data); + } + + //Odbieranie CRC Hi + if (blad == 0) + { + if (rs485Receive(&nrBloku, 1) != pdTRUE) + blad = 11; + else + { + if ((uint8_t)(crc>>8) != nrBloku) + blad = 12; + } + } + + //Odbieranie CRC Lo + if (blad == 0) + { + if (rs485Receive(&nrBloku, 1) != pdTRUE) + blad = 13; + else + { + if ((uint8_t)(crc & 0xFF) != nrBloku) + blad = 14; + } + } + + if ((blad != 0) && (blad != 253)) + { + releaseRs485(); + flushRs485RecBuffer(); + return 1; + } + +// Wysyłanie polecenia do bootloadera + if (blad == 0) + { + vTaskDelay(100); + + crc = _crc_xmodem_update(0, SYNC); uartRs485SendByte(SYNC); + crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + crc = _crc_xmodem_update(crc, rFLASH); uartRs485SendByte(rFLASH); + crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + //Odbieranie odpowiedzi od Bootloadera + if(rs485Receive(&data, 150) != pdTRUE) + blad = 15; + + if (data != 'C') + blad = 16; + else + blad = 0; + } + else + blad = 0; + + + if (blad != 0) + { + releaseRs485(); + flushRs485RecBuffer(); + if (debugStr != NULL) + fprintf_P(debugStr, PSTR("bootloader nie rozpoczal odbioru danych\r\n")); + return 1; + } + + uint8_t liczbaBlokow = file->wpis->rozmiarHi * 2; + if (file->wpis->rozmiarLo == 128) + liczbaBlokow++; + + nrBloku = 1; + lRetransmisji = 0; + + while (nrBloku <= liczbaBlokow) + { + crc = 0; + uartRs485SendByte(SOH); + uartRs485SendByte(nrBloku); + data = (uint8_t)(~nrBloku); + uartRs485SendByte(data); + + for (blad = 0; blad < 128; blad++) //wysyłanie danych. Zmianna Blad jest tymczasowa + { + if (ramDyskCzytajBajtZPliku(file, &data) != 0) + data = 0; + crc = _crc_xmodem_update(crc, data); + uartRs485SendByte(data); + } + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + if(rs485Receive(&data, 100) != pdTRUE) + { + blad = 250; + if (debugStr != NULL) + fputc('#', debugStr); + data = 0; + } + + flushRs485RecBuffer(); + + if (data == ACK) + { + nrBloku ++; + lRetransmisji = 0; + blad = 0; + if (debugStr != NULL) + { + fputc('.', debugStr); + if ((nrBloku & 0x0F) == 0) + { + fputc('\r', debugStr); + fputc('\n', debugStr); + } + } + continue; + } + + if (data == CAN) + { + if (debugStr != NULL) + fputc('C', debugStr); + blad = 249; + break; + } + + if (debugStr != NULL) + { + if (data == NAK) + fputc('N', debugStr); + if (data != 0) + fprintf(debugStr, "data 0x%x ", data); + } + + lRetransmisji ++; + + if (lRetransmisji == 3) + { + blad = 248; + break; + } + } + + if (blad == 0) + { + uartRs485SendByte(EOT); + if(rs485Receive(&data, 25) == pdTRUE) + { + if (data == ACK) + { + uartRs485SendByte(EOT); + rs485Receive(&data, 25); + } + } + } + + flushRs485RecBuffer(); + releaseRs485(); + return blad; +} + +uint8_t rs485curtainUp(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos) +{ + uint16_t crc = 0; + + crc = _crc_xmodem_update(crc, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, deviceAddr); + uartRs485SendByte(deviceAddr); + if (curtainNo == 0) + { + crc = _crc_xmodem_update(crc, rPodniesRolete1); + uartRs485SendByte(rPodniesRolete1); + } + else + { + crc = _crc_xmodem_update(crc, rPodniesRolete2); + uartRs485SendByte(rPodniesRolete2); + } + + crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + crc = _crc_xmodem_update(crc, pos); uartRs485SendByte(pos); + + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + return 0; +} + +uint8_t rs485Led(uint8_t deviceAddr, uint8_t ledNo, uint8_t time) +{ + uint16_t crc = 0; + + crc = _crc_xmodem_update(crc, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, deviceAddr); + uartRs485SendByte(deviceAddr); + + crc = _crc_xmodem_update(crc, ledNo); + + crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + crc = _crc_xmodem_update(crc, time); uartRs485SendByte(time); + + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + return 0; +} + + +#ifdef PRINT_RS485_DEVICE +/** + * Prints list of Rs485 devices + * @param stream - outpuf stream + * @return number of printed devices + */ +uint8_t printRs485devices(FILE *stream); +#endif /*PRINT_RS485_DEVICE*/ + + +void sendSettings(uint8_t addr, uint8_t value) +{ + uint16_t crc = _crc_xmodem_update(0, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, addr); + uartRs485SendByte(addr); + + crc = _crc_xmodem_update(crc, rUstaw); + uartRs485SendByte(rUstaw); + + crc = _crc_xmodem_update(crc, 1); + uartRs485SendByte(1); + + crc = _crc_xmodem_update(crc, value); + uartRs485SendByte(value); + + uartRs485SendByte((uint8_t)(crc >> 8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); +} + +void saveSettings(uint8_t addr) +{ + uint16_t crc = _crc_xmodem_update(0, SYNC); + uartRs485SendByte(SYNC); + + crc = _crc_xmodem_update(crc, addr); + uartRs485SendByte(addr); + + crc = _crc_xmodem_update(crc, rZapiszUstawienia); + uartRs485SendByte(rZapiszUstawienia); + + crc = _crc_xmodem_update(crc, 0); + uartRs485SendByte(0); + + uartRs485SendByte((uint8_t)(crc >> 8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); +} + +uint8_t rs485curtainDown(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos) +{ + uint16_t crc = 0; + + crc = _crc_xmodem_update(crc, SYNC); uartRs485SendByte(SYNC); + crc = _crc_xmodem_update(crc, deviceAddr); uartRs485SendByte(deviceAddr); + if (curtainNo == 0) + { + crc = _crc_xmodem_update(crc, rOpuscRolete1); uartRs485SendByte(rOpuscRolete1); + } + else + { + crc = _crc_xmodem_update(crc, rOpuscRolete2); uartRs485SendByte(rOpuscRolete2); + } + + crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + crc = _crc_xmodem_update(crc, pos); uartRs485SendByte(pos); + + uartRs485SendByte((uint8_t)(crc>>8)); + uartRs485SendByte((uint8_t)(crc & 0xFF)); + + return 0; +} + diff --git a/Lib/Rs485_prot.lst b/Lib/Rs485_prot.lst new file mode 100644 index 0000000..9b10faf --- /dev/null +++ b/Lib/Rs485_prot.lst @@ -0,0 +1,3166 @@ + 1 .file "Rs485_prot.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 274 _crc_xmodem_update: + 275 .stabd 46,0,0 + 277 .Ltext1: + 1:/usr/lib/avr/include/util/crc16.h **** /* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz + 2:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2005, 2007 Joerg Wunsch + 3:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2013 Dave Hylands + 4:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2013 Frederic Nadeau + 5:/usr/lib/avr/include/util/crc16.h **** All rights reserved. + 6:/usr/lib/avr/include/util/crc16.h **** + 7:/usr/lib/avr/include/util/crc16.h **** Redistribution and use in source and binary forms, with or without + 8:/usr/lib/avr/include/util/crc16.h **** modification, are permitted provided that the following conditions are met: + 9:/usr/lib/avr/include/util/crc16.h **** + 10:/usr/lib/avr/include/util/crc16.h **** * Redistributions of source code must retain the above copyright + 11:/usr/lib/avr/include/util/crc16.h **** notice, this list of conditions and the following disclaimer. + 12:/usr/lib/avr/include/util/crc16.h **** + 13:/usr/lib/avr/include/util/crc16.h **** * Redistributions in binary form must reproduce the above copyright + 14:/usr/lib/avr/include/util/crc16.h **** notice, this list of conditions and the following disclaimer in + 15:/usr/lib/avr/include/util/crc16.h **** the documentation and/or other materials provided with the + 16:/usr/lib/avr/include/util/crc16.h **** distribution. + 17:/usr/lib/avr/include/util/crc16.h **** + 18:/usr/lib/avr/include/util/crc16.h **** * Neither the name of the copyright holders nor the names of + 19:/usr/lib/avr/include/util/crc16.h **** contributors may be used to endorse or promote products derived + 20:/usr/lib/avr/include/util/crc16.h **** from this software without specific prior written permission. + 21:/usr/lib/avr/include/util/crc16.h **** + 22:/usr/lib/avr/include/util/crc16.h **** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + 23:/usr/lib/avr/include/util/crc16.h **** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + 24:/usr/lib/avr/include/util/crc16.h **** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + 25:/usr/lib/avr/include/util/crc16.h **** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + 26:/usr/lib/avr/include/util/crc16.h **** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + 27:/usr/lib/avr/include/util/crc16.h **** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + 28:/usr/lib/avr/include/util/crc16.h **** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + 29:/usr/lib/avr/include/util/crc16.h **** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + 30:/usr/lib/avr/include/util/crc16.h **** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + 31:/usr/lib/avr/include/util/crc16.h **** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + 32:/usr/lib/avr/include/util/crc16.h **** POSSIBILITY OF SUCH DAMAGE. */ + 33:/usr/lib/avr/include/util/crc16.h **** + 34:/usr/lib/avr/include/util/crc16.h **** /* $Id$ */ + 35:/usr/lib/avr/include/util/crc16.h **** + 36:/usr/lib/avr/include/util/crc16.h **** #ifndef _UTIL_CRC16_H_ + 37:/usr/lib/avr/include/util/crc16.h **** #define _UTIL_CRC16_H_ + 38:/usr/lib/avr/include/util/crc16.h **** + 39:/usr/lib/avr/include/util/crc16.h **** #include + 40:/usr/lib/avr/include/util/crc16.h **** + 41:/usr/lib/avr/include/util/crc16.h **** /** \file */ + 42:/usr/lib/avr/include/util/crc16.h **** /** \defgroup util_crc : CRC Computations + 43:/usr/lib/avr/include/util/crc16.h **** \code#include \endcode + 44:/usr/lib/avr/include/util/crc16.h **** + 45:/usr/lib/avr/include/util/crc16.h **** This header file provides a optimized inline functions for calculating + 46:/usr/lib/avr/include/util/crc16.h **** cyclic redundancy checks (CRC) using common polynomials. + 47:/usr/lib/avr/include/util/crc16.h **** + 48:/usr/lib/avr/include/util/crc16.h **** \par References: + 49:/usr/lib/avr/include/util/crc16.h **** + 50:/usr/lib/avr/include/util/crc16.h **** \par + 51:/usr/lib/avr/include/util/crc16.h **** + 52:/usr/lib/avr/include/util/crc16.h **** See the Dallas Semiconductor app note 27 for 8051 assembler example and + 53:/usr/lib/avr/include/util/crc16.h **** general CRC optimization suggestions. The table on the last page of the + 54:/usr/lib/avr/include/util/crc16.h **** app note is the key to understanding these implementations. + 55:/usr/lib/avr/include/util/crc16.h **** + 56:/usr/lib/avr/include/util/crc16.h **** \par + 57:/usr/lib/avr/include/util/crc16.h **** + 58:/usr/lib/avr/include/util/crc16.h **** Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e + 59:/usr/lib/avr/include/util/crc16.h **** Embedded \e Systems \e Programming. This may be difficult to find, but it + 60:/usr/lib/avr/include/util/crc16.h **** explains CRC's in very clear and concise terms. Well worth the effort to + 61:/usr/lib/avr/include/util/crc16.h **** obtain a copy. + 62:/usr/lib/avr/include/util/crc16.h **** + 63:/usr/lib/avr/include/util/crc16.h **** A typical application would look like: + 64:/usr/lib/avr/include/util/crc16.h **** + 65:/usr/lib/avr/include/util/crc16.h **** \code + 66:/usr/lib/avr/include/util/crc16.h **** // Dallas iButton test vector. + 67:/usr/lib/avr/include/util/crc16.h **** uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + 68:/usr/lib/avr/include/util/crc16.h **** + 69:/usr/lib/avr/include/util/crc16.h **** int + 70:/usr/lib/avr/include/util/crc16.h **** checkcrc(void) + 71:/usr/lib/avr/include/util/crc16.h **** { + 72:/usr/lib/avr/include/util/crc16.h **** uint8_t crc = 0, i; + 73:/usr/lib/avr/include/util/crc16.h **** + 74:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + 75:/usr/lib/avr/include/util/crc16.h **** crc = _crc_ibutton_update(crc, serno[i]); + 76:/usr/lib/avr/include/util/crc16.h **** + 77:/usr/lib/avr/include/util/crc16.h **** return crc; // must be 0 + 78:/usr/lib/avr/include/util/crc16.h **** } + 79:/usr/lib/avr/include/util/crc16.h **** \endcode + 80:/usr/lib/avr/include/util/crc16.h **** */ + 81:/usr/lib/avr/include/util/crc16.h **** + 82:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 83:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-16 calculation. + 84:/usr/lib/avr/include/util/crc16.h **** + 85:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ 86:/usr/lib/avr/include/util/crc16.h **** Initial value: 0xffff + 87:/usr/lib/avr/include/util/crc16.h **** + 88:/usr/lib/avr/include/util/crc16.h **** This CRC is normally used in disk-drive controllers. + 89:/usr/lib/avr/include/util/crc16.h **** + 90:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 91:/usr/lib/avr/include/util/crc16.h **** + 92:/usr/lib/avr/include/util/crc16.h **** \code + 93:/usr/lib/avr/include/util/crc16.h **** uint16_t + 94:/usr/lib/avr/include/util/crc16.h **** crc16_update(uint16_t crc, uint8_t a) + 95:/usr/lib/avr/include/util/crc16.h **** { + 96:/usr/lib/avr/include/util/crc16.h **** int i; + 97:/usr/lib/avr/include/util/crc16.h **** + 98:/usr/lib/avr/include/util/crc16.h **** crc ^= a; + 99:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < 8; ++i) + 100:/usr/lib/avr/include/util/crc16.h **** { + 101:/usr/lib/avr/include/util/crc16.h **** if (crc & 1) + 102:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1) ^ 0xA001; + 103:/usr/lib/avr/include/util/crc16.h **** else + 104:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1); + 105:/usr/lib/avr/include/util/crc16.h **** } + 106:/usr/lib/avr/include/util/crc16.h **** + 107:/usr/lib/avr/include/util/crc16.h **** return crc; + 108:/usr/lib/avr/include/util/crc16.h **** } + 109:/usr/lib/avr/include/util/crc16.h **** + 110:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 111:/usr/lib/avr/include/util/crc16.h **** + 112:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 113:/usr/lib/avr/include/util/crc16.h **** _crc16_update(uint16_t __crc, uint8_t __data) + 114:/usr/lib/avr/include/util/crc16.h **** { + 115:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp; + 116:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; + 117:/usr/lib/avr/include/util/crc16.h **** + 118:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 119:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%2" "\n\t" + 120:/usr/lib/avr/include/util/crc16.h **** "mov %1,%A0" "\n\t" + 121:/usr/lib/avr/include/util/crc16.h **** "swap %1" "\n\t" + 122:/usr/lib/avr/include/util/crc16.h **** "eor %1,%A0" "\n\t" + 123:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 124:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 125:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 126:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 127:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 128:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 129:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 130:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x07" "\n\t" + 131:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%A0" "\n\t" + 132:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%B0" "\n\t" + 133:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 134:/usr/lib/avr/include/util/crc16.h **** "ror __tmp_reg__" "\n\t" + 135:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 136:/usr/lib/avr/include/util/crc16.h **** "mov %B0,__tmp_reg__" "\n\t" + 137:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" "\n\t" + 138:/usr/lib/avr/include/util/crc16.h **** "lsr __tmp_reg__" "\n\t" + 139:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 140:/usr/lib/avr/include/util/crc16.h **** "eor %B0,__tmp_reg__" "\n\t" + 141:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" + 142:/usr/lib/avr/include/util/crc16.h **** : "=r" (__ret), "=d" (__tmp) + 143:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 144:/usr/lib/avr/include/util/crc16.h **** : "r0" + 145:/usr/lib/avr/include/util/crc16.h **** ); + 146:/usr/lib/avr/include/util/crc16.h **** return __ret; + 147:/usr/lib/avr/include/util/crc16.h **** } + 148:/usr/lib/avr/include/util/crc16.h **** + 149:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 150:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-XMODEM calculation. + 151:/usr/lib/avr/include/util/crc16.h **** + 152:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ 153:/usr/lib/avr/include/util/crc16.h **** Initial value: 0x0 + 154:/usr/lib/avr/include/util/crc16.h **** + 155:/usr/lib/avr/include/util/crc16.h **** This is the CRC used by the Xmodem-CRC protocol. + 156:/usr/lib/avr/include/util/crc16.h **** + 157:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 158:/usr/lib/avr/include/util/crc16.h **** + 159:/usr/lib/avr/include/util/crc16.h **** \code + 160:/usr/lib/avr/include/util/crc16.h **** uint16_t + 161:/usr/lib/avr/include/util/crc16.h **** crc_xmodem_update (uint16_t crc, uint8_t data) + 162:/usr/lib/avr/include/util/crc16.h **** { + 163:/usr/lib/avr/include/util/crc16.h **** int i; + 164:/usr/lib/avr/include/util/crc16.h **** + 165:/usr/lib/avr/include/util/crc16.h **** crc = crc ^ ((uint16_t)data << 8); + 166:/usr/lib/avr/include/util/crc16.h **** for (i=0; i<8; i++) + 167:/usr/lib/avr/include/util/crc16.h **** { + 168:/usr/lib/avr/include/util/crc16.h **** if (crc & 0x8000) + 169:/usr/lib/avr/include/util/crc16.h **** crc = (crc << 1) ^ 0x1021; + 170:/usr/lib/avr/include/util/crc16.h **** else + 171:/usr/lib/avr/include/util/crc16.h **** crc <<= 1; + 172:/usr/lib/avr/include/util/crc16.h **** } + 173:/usr/lib/avr/include/util/crc16.h **** + 174:/usr/lib/avr/include/util/crc16.h **** return crc; + 175:/usr/lib/avr/include/util/crc16.h **** } + 176:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 177:/usr/lib/avr/include/util/crc16.h **** + 178:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 179:/usr/lib/avr/include/util/crc16.h **** _crc_xmodem_update(uint16_t __crc, uint8_t __data) + 180:/usr/lib/avr/include/util/crc16.h **** { + 279 .LM0: + 280 .LFBB1: + 281 /* prologue: function */ + 282 /* frame size = 0 */ + 283 /* stack size = 0 */ + 284 .L__stack_usage = 0 + 181:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + 182:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp1; /* %1 */ + 183:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp2; /* %2 */ + 184:/usr/lib/avr/include/util/crc16.h **** /* %3 __data */ + 185:/usr/lib/avr/include/util/crc16.h **** + 186:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 187:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%3" "\n\t" /* crc.hi ^ data */ + 188:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%B0" "\n\t" + 189:/usr/lib/avr/include/util/crc16.h **** "swap __tmp_reg__" "\n\t" /* swap(crc.hi ^ data) */ + 190:/usr/lib/avr/include/util/crc16.h **** + 191:/usr/lib/avr/include/util/crc16.h **** /* Calculate the ret.lo of the CRC. */ + 192:/usr/lib/avr/include/util/crc16.h **** "mov %1,__tmp_reg__" "\n\t" + 193:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x0f" "\n\t" + 194:/usr/lib/avr/include/util/crc16.h **** "eor %1,%B0" "\n\t" + 195:/usr/lib/avr/include/util/crc16.h **** "mov %2,%B0" "\n\t" + 196:/usr/lib/avr/include/util/crc16.h **** "eor %2,__tmp_reg__" "\n\t" + 197:/usr/lib/avr/include/util/crc16.h **** "lsl %2" "\n\t" + 198:/usr/lib/avr/include/util/crc16.h **** "andi %2,0xe0" "\n\t" + 199:/usr/lib/avr/include/util/crc16.h **** "eor %1,%2" "\n\t" /* __tmp1 is now ret.lo. */ + 200:/usr/lib/avr/include/util/crc16.h **** + 201:/usr/lib/avr/include/util/crc16.h **** /* Calculate the ret.hi of the CRC. */ + 202:/usr/lib/avr/include/util/crc16.h **** "mov %2,__tmp_reg__" "\n\t" + 203:/usr/lib/avr/include/util/crc16.h **** "eor %2,%B0" "\n\t" + 204:/usr/lib/avr/include/util/crc16.h **** "andi %2,0xf0" "\n\t" + 205:/usr/lib/avr/include/util/crc16.h **** "lsr %2" "\n\t" + 206:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%B0" "\n\t" + 207:/usr/lib/avr/include/util/crc16.h **** "lsl __tmp_reg__" "\n\t" + 208:/usr/lib/avr/include/util/crc16.h **** "rol %2" "\n\t" + 209:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 210:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 211:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 212:/usr/lib/avr/include/util/crc16.h **** "andi %B0,0x1f" "\n\t" + 213:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%2" "\n\t" + 214:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%A0" "\n\t" /* ret.hi is now ready. */ + 215:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%1" "\n\t" /* ret.lo is now ready. */ + 216:/usr/lib/avr/include/util/crc16.h **** : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + 217:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 218:/usr/lib/avr/include/util/crc16.h **** : "r0" + 219:/usr/lib/avr/include/util/crc16.h **** ); + 220:/usr/lib/avr/include/util/crc16.h **** return __ret; + 221:/usr/lib/avr/include/util/crc16.h **** } + 286 .LM1: + 287 /* #APP */ + 288 ; 186 "/usr/lib/avr/include/util/crc16.h" 1 + 289 0000 9627 eor r25,r22 + 290 0002 092E mov __tmp_reg__,r25 + 291 0004 0294 swap __tmp_reg__ + 292 0006 202D mov r18,__tmp_reg__ + 293 0008 2F70 andi r18,0x0f + 294 000a 2927 eor r18,r25 + 295 000c 692F mov r22,r25 + 296 000e 6025 eor r22,__tmp_reg__ + 297 0010 660F lsl r22 + 298 0012 607E andi r22,0xe0 + 299 0014 2627 eor r18,r22 + 300 0016 602D mov r22,__tmp_reg__ + 301 0018 6927 eor r22,r25 + 302 001a 607F andi r22,0xf0 + 303 001c 6695 lsr r22 + 304 001e 092E mov __tmp_reg__,r25 + 305 0020 000C lsl __tmp_reg__ + 306 0022 661F rol r22 + 307 0024 9695 lsr r25 + 308 0026 9695 lsr r25 + 309 0028 9695 lsr r25 + 310 002a 9F71 andi r25,0x1f + 311 002c 9627 eor r25,r22 + 312 002e 9827 eor r25,r24 + 313 0030 822F mov r24,r18 + 314 + 315 ; 0 "" 2 + 316 /* #NOAPP */ + 317 0032 0895 ret + 319 .Lscope1: + 321 .stabd 78,0,0 + 323 .weak takeRs485 + 325 takeRs485: + 326 .stabd 46,0,0 + 328 .Ltext2: + 1:../../../../Lib/Rs485_prot.c **** #include "Rs485_prot.h" + 2:../../../../Lib/Rs485_prot.c **** #include + 3:../../../../Lib/Rs485_prot.c **** #include + 4:../../../../Lib/Rs485_prot.c **** + 5:../../../../Lib/Rs485_prot.c **** #if LANG_EN + 6:../../../../Lib/Rs485_prot.c **** #include "Rs485_prot_en.h" + 7:../../../../Lib/Rs485_prot.c **** #define PRINT_RS485_DEVICE 1 + 8:../../../../Lib/Rs485_prot.c **** #endif + 9:../../../../Lib/Rs485_prot.c **** + 10:../../../../Lib/Rs485_prot.c **** #if LANG_PL + 11:../../../../Lib/Rs485_prot.c **** #include "Rs485_prot_pl.h" + 12:../../../../Lib/Rs485_prot.c **** #define PRINT_RS485_DEVICE 1 + 13:../../../../Lib/Rs485_prot.c **** #endif + 14:../../../../Lib/Rs485_prot.c **** + 15:../../../../Lib/Rs485_prot.c **** + 16:../../../../Lib/Rs485_prot.c **** static void sendPing(uint8_t addr, uint8_t pingLen); + 17:../../../../Lib/Rs485_prot.c **** static uint8_t receivePong(uint8_t addr, uint8_t pingLen); + 18:../../../../Lib/Rs485_prot.c **** static void sendHello(uint8_t addr); + 19:../../../../Lib/Rs485_prot.c **** static uint8_t receiveHello(uint8_t* response, uint8_t maxSize); + 20:../../../../Lib/Rs485_prot.c **** + 21:../../../../Lib/Rs485_prot.c **** // ********************* Those function have to be implemented in your project ************* + 22:../../../../Lib/Rs485_prot.c **** void takeRs485(void) { } + 330 .LM2: + 331 .LFBB2: + 332 /* prologue: function */ + 333 /* frame size = 0 */ + 334 /* stack size = 0 */ + 335 .L__stack_usage = 0 + 336 0034 0895 ret + 338 .Lscope2: + 340 .stabd 78,0,0 + 342 .weak releaseRs485 + 344 releaseRs485: + 345 .stabd 46,0,0 + 23:../../../../Lib/Rs485_prot.c **** void releaseRs485(void) { } + 347 .LM3: + 348 .LFBB3: + 349 /* prologue: function */ + 350 /* frame size = 0 */ + 351 /* stack size = 0 */ + 352 .L__stack_usage = 0 + 353 0036 0895 ret + 355 .Lscope3: + 357 .stabd 78,0,0 + 360 .weak uartRs485SendByte + 362 uartRs485SendByte: + 363 .stabd 46,0,0 + 24:../../../../Lib/Rs485_prot.c **** void uartRs485SendByte(uint8_t c) { (void) c; } + 365 .LM4: + 366 .LFBB4: + 367 /* prologue: function */ + 368 /* frame size = 0 */ + 369 /* stack size = 0 */ + 370 .L__stack_usage = 0 + 371 0038 0895 ret + 373 .Lscope4: + 375 .stabd 78,0,0 + 379 .weak rs485Receive + 381 rs485Receive: + 382 .stabd 46,0,0 + 25:../../../../Lib/Rs485_prot.c **** uint8_t rs485Receive(uint8_t *c, uint8_t timeout) { (void) c; (void) timeout; return 1; } + 384 .LM5: + 385 .LFBB5: + 386 /* prologue: function */ + 387 /* frame size = 0 */ + 388 /* stack size = 0 */ + 389 .L__stack_usage = 0 + 391 .LM6: + 392 003a 81E0 ldi r24,lo8(1) + 393 003c 0895 ret + 395 .Lscope5: + 397 .stabd 78,0,0 + 399 .weak flushRs485RecBuffer + 401 flushRs485RecBuffer: + 402 .stabd 46,0,0 + 26:../../../../Lib/Rs485_prot.c **** uint8_t flushRs485RecBuffer(void) { return 1;} + 404 .LM7: + 405 .LFBB6: + 406 /* prologue: function */ + 407 /* frame size = 0 */ + 408 /* stack size = 0 */ + 409 .L__stack_usage = 0 + 411 .LM8: + 412 003e 81E0 ldi r24,lo8(1) + 413 0040 0895 ret + 415 .Lscope6: + 417 .stabd 78,0,0 + 419 .global rollersMemInit + 421 rollersMemInit: + 422 .stabd 46,0,0 + 27:../../../../Lib/Rs485_prot.c **** + 28:../../../../Lib/Rs485_prot.c **** + 29:../../../../Lib/Rs485_prot.c **** void rollersMemInit(void) + 30:../../../../Lib/Rs485_prot.c **** { + 424 .LM9: + 425 .LFBB7: + 426 /* prologue: function */ + 427 /* frame size = 0 */ + 428 /* stack size = 0 */ + 429 .L__stack_usage = 0 + 31:../../../../Lib/Rs485_prot.c **** rollers = xmalloc(MAX_NUMBER_OF_ROLLERS * sizeof(struct sterRolet)); + 431 .LM10: + 432 0042 8EE6 ldi r24,lo8(110) + 433 0044 90E0 ldi r25,0 + 434 0046 0E94 0000 call xmalloc + 435 004a 9093 0000 sts rollers+1,r25 + 436 004e 8093 0000 sts rollers,r24 + 32:../../../../Lib/Rs485_prot.c **** memset(rollers, 0, MAX_NUMBER_OF_ROLLERS * sizeof(struct sterRolet)); + 438 .LM11: + 439 0052 2EE6 ldi r18,lo8(110) + 440 0054 FC01 movw r30,r24 + 441 0: + 442 0056 1192 st Z+,__zero_reg__ + 443 0058 2A95 dec r18 + 444 005a 01F4 brne 0b + 445 005c 0895 ret + 447 .Lscope7: + 449 .stabd 78,0,0 + 451 .global printRs485devices + 453 printRs485devices: + 454 .stabd 46,0,0 + 33:../../../../Lib/Rs485_prot.c **** } + 34:../../../../Lib/Rs485_prot.c **** + 35:../../../../Lib/Rs485_prot.c **** + 36:../../../../Lib/Rs485_prot.c **** // ********************* Hiden Functions *************************************************** + 37:../../../../Lib/Rs485_prot.c **** + 38:../../../../Lib/Rs485_prot.c **** + 39:../../../../Lib/Rs485_prot.c **** + 40:../../../../Lib/Rs485_prot.c **** void sendPing(uint8_t addr, uint8_t pingLen) + 41:../../../../Lib/Rs485_prot.c **** { + 42:../../../../Lib/Rs485_prot.c **** uint16_t crc = _crc_xmodem_update(0, SYNC); + 43:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 44:../../../../Lib/Rs485_prot.c **** + 45:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, addr); + 46:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 47:../../../../Lib/Rs485_prot.c **** + 48:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rPING); + 49:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rPING); + 50:../../../../Lib/Rs485_prot.c **** + 51:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, pingLen); + 52:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(pingLen); + 53:../../../../Lib/Rs485_prot.c **** + 54:../../../../Lib/Rs485_prot.c **** for (uint8_t i=0; i < pingLen; i++) + 55:../../../../Lib/Rs485_prot.c **** { + 56:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, i); + 57:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(i); + 58:../../../../Lib/Rs485_prot.c **** } + 59:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc >> 8)); + 60:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 61:../../../../Lib/Rs485_prot.c **** } + 62:../../../../Lib/Rs485_prot.c **** + 63:../../../../Lib/Rs485_prot.c **** uint8_t receivePong(uint8_t addr, uint8_t dataLen) + 64:../../../../Lib/Rs485_prot.c **** { + 65:../../../../Lib/Rs485_prot.c **** (void)addr; + 66:../../../../Lib/Rs485_prot.c **** uint8_t data; + 67:../../../../Lib/Rs485_prot.c **** uint16_t crc; + 68:../../../../Lib/Rs485_prot.c **** + 69:../../../../Lib/Rs485_prot.c **** //SYNC + 70:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 20) == pdFALSE) + 71:../../../../Lib/Rs485_prot.c **** return 1; + 72:../../../../Lib/Rs485_prot.c **** + 73:../../../../Lib/Rs485_prot.c **** if (data != SYNC) + 74:../../../../Lib/Rs485_prot.c **** return 2; + 75:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, data); + 76:../../../../Lib/Rs485_prot.c **** + 77:../../../../Lib/Rs485_prot.c **** //Adres ma być wartość 0 + 78:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == 0) + 79:../../../../Lib/Rs485_prot.c **** return 3; + 80:../../../../Lib/Rs485_prot.c **** + 81:../../../../Lib/Rs485_prot.c **** if (data != 0) + 82:../../../../Lib/Rs485_prot.c **** return 4; + 83:../../../../Lib/Rs485_prot.c **** + 84:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 85:../../../../Lib/Rs485_prot.c **** + 86:../../../../Lib/Rs485_prot.c **** //Kod rozkazu. Ma być rPING + 87:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == pdFALSE) + 88:../../../../Lib/Rs485_prot.c **** return 5; + 89:../../../../Lib/Rs485_prot.c **** if (data != rPING) + 90:../../../../Lib/Rs485_prot.c **** return 6; + 91:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 92:../../../../Lib/Rs485_prot.c **** + 93:../../../../Lib/Rs485_prot.c **** //DÅ‚ugość odpowiedzi + 94:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == pdFALSE) + 95:../../../../Lib/Rs485_prot.c **** return 7; + 96:../../../../Lib/Rs485_prot.c **** if (data != dataLen) + 97:../../../../Lib/Rs485_prot.c **** return 8; + 98:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 99:../../../../Lib/Rs485_prot.c **** + 100:../../../../Lib/Rs485_prot.c **** + 101:../../../../Lib/Rs485_prot.c **** uint8_t temp; + 102:../../../../Lib/Rs485_prot.c **** for (temp=0; temp < dataLen; temp++) + 103:../../../../Lib/Rs485_prot.c **** { + 104:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 5) == pdFALSE) + 105:../../../../Lib/Rs485_prot.c **** return 2*temp+9; + 106:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 107:../../../../Lib/Rs485_prot.c **** if (data != temp) + 108:../../../../Lib/Rs485_prot.c **** return 2*temp+10; + 109:../../../../Lib/Rs485_prot.c **** } + 110:../../../../Lib/Rs485_prot.c **** + 111:../../../../Lib/Rs485_prot.c **** uint8_t crcHi; + 112:../../../../Lib/Rs485_prot.c **** uint8_t crcLo; + 113:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&crcHi, 1) != pdTRUE) + 114:../../../../Lib/Rs485_prot.c **** return 2*temp+11; + 115:../../../../Lib/Rs485_prot.c **** + 116:../../../../Lib/Rs485_prot.c **** if(xQueueReceive(xRs485Rec, &crcLo, 1) != pdTRUE) + 117:../../../../Lib/Rs485_prot.c **** return 2*temp+12; + 118:../../../../Lib/Rs485_prot.c **** + 119:../../../../Lib/Rs485_prot.c **** if (crcHi != (uint8_t)(crc>>8)) + 120:../../../../Lib/Rs485_prot.c **** return 254; + 121:../../../../Lib/Rs485_prot.c **** if (crcLo != (uint8_t)(crc & 0xFF)) + 122:../../../../Lib/Rs485_prot.c **** return 255; + 123:../../../../Lib/Rs485_prot.c **** + 124:../../../../Lib/Rs485_prot.c **** return 0; + 125:../../../../Lib/Rs485_prot.c **** } + 126:../../../../Lib/Rs485_prot.c **** + 127:../../../../Lib/Rs485_prot.c **** static void sendHello(uint8_t addr) + 128:../../../../Lib/Rs485_prot.c **** { + 129:../../../../Lib/Rs485_prot.c **** uint16_t crc = _crc_xmodem_update(0, SYNC); + 130:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 131:../../../../Lib/Rs485_prot.c **** + 132:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, addr); + 133:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 134:../../../../Lib/Rs485_prot.c **** + 135:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rHELLO); + 136:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rHELLO); + 137:../../../../Lib/Rs485_prot.c **** + 138:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 0); + 139:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(0); + 140:../../../../Lib/Rs485_prot.c **** + 141:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc >> 8)); + 142:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 143:../../../../Lib/Rs485_prot.c **** } + 144:../../../../Lib/Rs485_prot.c **** + 145:../../../../Lib/Rs485_prot.c **** static uint8_t receiveHello(uint8_t* response, uint8_t maxSize) + 146:../../../../Lib/Rs485_prot.c **** { + 147:../../../../Lib/Rs485_prot.c **** uint16_t crc; + 148:../../../../Lib/Rs485_prot.c **** uint8_t data; + 149:../../../../Lib/Rs485_prot.c **** //SYNC + 150:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 20) == pdFALSE) + 151:../../../../Lib/Rs485_prot.c **** return 8; + 152:../../../../Lib/Rs485_prot.c **** + 153:../../../../Lib/Rs485_prot.c **** if (data != SYNC) + 154:../../../../Lib/Rs485_prot.c **** return 2; + 155:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, data); + 156:../../../../Lib/Rs485_prot.c **** + 157:../../../../Lib/Rs485_prot.c **** //Adres ma być wartość 0 + 158:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == 0) + 159:../../../../Lib/Rs485_prot.c **** return 3; + 160:../../../../Lib/Rs485_prot.c **** + 161:../../../../Lib/Rs485_prot.c **** if (data != 0) + 162:../../../../Lib/Rs485_prot.c **** return 4; + 163:../../../../Lib/Rs485_prot.c **** + 164:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 165:../../../../Lib/Rs485_prot.c **** + 166:../../../../Lib/Rs485_prot.c **** //Kod rozkazu. Ma być rHELLO + 167:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == pdFALSE) + 168:../../../../Lib/Rs485_prot.c **** return 5; + 169:../../../../Lib/Rs485_prot.c **** if (data != rHELLO) + 170:../../../../Lib/Rs485_prot.c **** return 6; + 171:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 172:../../../../Lib/Rs485_prot.c **** + 173:../../../../Lib/Rs485_prot.c **** //DÅ‚ugość odpowiedzi + 174:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) == pdFALSE) + 175:../../../../Lib/Rs485_prot.c **** return 7; + 176:../../../../Lib/Rs485_prot.c **** if (data > maxSize) + 177:../../../../Lib/Rs485_prot.c **** return 1; + 178:../../../../Lib/Rs485_prot.c **** + 179:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 180:../../../../Lib/Rs485_prot.c **** memset(response, 0, maxSize); + 181:../../../../Lib/Rs485_prot.c **** maxSize = data; + 182:../../../../Lib/Rs485_prot.c **** + 183:../../../../Lib/Rs485_prot.c **** for (data=0; data < maxSize; data++) + 184:../../../../Lib/Rs485_prot.c **** { + 185:../../../../Lib/Rs485_prot.c **** if(rs485Receive(response, 5) == pdFALSE) + 186:../../../../Lib/Rs485_prot.c **** return 20; + 187:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, *((uint8_t *)(response))); + 188:../../../../Lib/Rs485_prot.c **** response++; + 189:../../../../Lib/Rs485_prot.c **** } + 190:../../../../Lib/Rs485_prot.c **** + 191:../../../../Lib/Rs485_prot.c **** uint8_t crcHi; + 192:../../../../Lib/Rs485_prot.c **** uint8_t crcLo; + 193:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&crcHi, 1) != pdTRUE) + 194:../../../../Lib/Rs485_prot.c **** return 21; + 195:../../../../Lib/Rs485_prot.c **** + 196:../../../../Lib/Rs485_prot.c **** if(xQueueReceive(xRs485Rec, &crcLo, 1) != pdTRUE) + 197:../../../../Lib/Rs485_prot.c **** return 22; + 198:../../../../Lib/Rs485_prot.c **** + 199:../../../../Lib/Rs485_prot.c **** if (crcHi != (uint8_t)(crc>>8)) + 200:../../../../Lib/Rs485_prot.c **** return 254; + 201:../../../../Lib/Rs485_prot.c **** if (crcLo != (uint8_t)(crc & 0xFF)) + 202:../../../../Lib/Rs485_prot.c **** return 255; + 203:../../../../Lib/Rs485_prot.c **** + 204:../../../../Lib/Rs485_prot.c **** return 0; + 205:../../../../Lib/Rs485_prot.c **** } + 206:../../../../Lib/Rs485_prot.c **** + 207:../../../../Lib/Rs485_prot.c **** // ************************ Rs485 API ************************************ + 208:../../../../Lib/Rs485_prot.c **** + 209:../../../../Lib/Rs485_prot.c **** + 210:../../../../Lib/Rs485_prot.c **** + 211:../../../../Lib/Rs485_prot.c **** #ifdef PRINT_RS485_DEVICE + 212:../../../../Lib/Rs485_prot.c **** uint8_t printRs485devices(FILE *stream) + 213:../../../../Lib/Rs485_prot.c **** { + 456 .LM12: + 457 .LFBB8: + 458 005e 9F92 push r9 + 459 0060 AF92 push r10 + 460 0062 BF92 push r11 + 461 0064 CF92 push r12 + 462 0066 DF92 push r13 + 463 0068 EF92 push r14 + 464 006a FF92 push r15 + 465 006c 0F93 push r16 + 466 006e 1F93 push r17 + 467 0070 CF93 push r28 + 468 0072 DF93 push r29 + 469 /* prologue: function */ + 470 /* frame size = 0 */ + 471 /* stack size = 11 */ + 472 .L__stack_usage = 11 + 473 0074 E82E mov r14,r24 + 474 0076 992E mov r9,r25 + 214:../../../../Lib/Rs485_prot.c **** uint8_t result = 0; + 215:../../../../Lib/Rs485_prot.c **** struct sterRolet *rolTmp = rollers; + 476 .LM13: + 477 0078 0091 0000 lds r16,rollers + 478 007c 1091 0000 lds r17,rollers+1 + 479 0080 E801 movw r28,r16 + 480 0082 2596 adiw r28,5 + 481 0084 0D58 subi r16,-115 + 482 0086 1F4F sbci r17,-1 + 214:../../../../Lib/Rs485_prot.c **** uint8_t result = 0; + 484 .LM14: + 485 0088 F12C mov r15,__zero_reg__ + 486 .LBB3: + 216:../../../../Lib/Rs485_prot.c **** + 217:../../../../Lib/Rs485_prot.c **** //Print RollerDrivers + 218:../../../../Lib/Rs485_prot.c **** for (uint8_t i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + 219:../../../../Lib/Rs485_prot.c **** { + 220:../../../../Lib/Rs485_prot.c **** if (rolTmp->address != 0) + 221:../../../../Lib/Rs485_prot.c **** { + 222:../../../../Lib/Rs485_prot.c **** fprintf_P(stream, statusRollerDescStr, rolTmp->address, rolTmp->response.parsed.stateRoller1 + 488 .LM15: + 489 008a 80E0 ldi r24,lo8(statusRollerDescStr) + 490 008c A82E mov r10,r24 + 491 008e 80E0 ldi r24,hi8(statusRollerDescStr) + 492 0090 B82E mov r11,r24 + 223:../../../../Lib/Rs485_prot.c **** // fprintf_P(stream, statusRollerDescStrConf, rolTmp->response.parsed.settings); + 224:../../../../Lib/Rs485_prot.c **** fprintf_P(stream, statusRollerDescStr2, rolTmp->response.parsed.firmware); + 494 .LM16: + 495 0092 90E0 ldi r25,lo8(statusRollerDescStr2) + 496 0094 C92E mov r12,r25 + 497 0096 90E0 ldi r25,hi8(statusRollerDescStr2) + 498 0098 D92E mov r13,r25 + 499 .L10: + 500 009a FE01 movw r30,r28 + 501 009c 3497 sbiw r30,4 + 220:../../../../Lib/Rs485_prot.c **** { + 503 .LM17: + 504 009e 8081 ld r24,Z + 505 00a0 8823 tst r24 + 506 00a2 01F0 breq .L9 + 507 00a4 3296 adiw r30,2 + 222:../../../../Lib/Rs485_prot.c **** // fprintf_P(stream, statusRollerDescStrConf, rolTmp->response.parsed.settings); + 509 .LM18: + 510 00a6 2081 ld r18,Z + 511 00a8 2F73 andi r18,lo8(63) + 512 00aa 1F92 push __zero_reg__ + 513 00ac 2F93 push r18 + 514 00ae 3197 sbiw r30,1 + 515 00b0 2081 ld r18,Z + 516 00b2 2F73 andi r18,lo8(63) + 517 00b4 1F92 push __zero_reg__ + 518 00b6 2F93 push r18 + 519 00b8 1F92 push __zero_reg__ + 520 00ba 8F93 push r24 + 521 00bc BF92 push r11 + 522 00be AF92 push r10 + 523 00c0 9F92 push r9 + 524 00c2 EF92 push r14 + 525 00c4 0E94 0000 call fprintf_P + 527 .LM19: + 528 00c8 DF93 push r29 + 529 00ca CF93 push r28 + 530 00cc DF92 push r13 + 531 00ce CF92 push r12 + 532 00d0 9F92 push r9 + 533 00d2 EF92 push r14 + 534 00d4 0E94 0000 call fprintf_P + 225:../../../../Lib/Rs485_prot.c **** result++; + 536 .LM20: + 537 00d8 F394 inc r15 + 538 00da 8DB7 in r24,__SP_L__ + 539 00dc 9EB7 in r25,__SP_H__ + 540 00de 4096 adiw r24,16 + 541 00e0 0FB6 in __tmp_reg__,__SREG__ + 542 00e2 F894 cli + 543 00e4 9EBF out __SP_H__,r25 + 544 00e6 0FBE out __SREG__,__tmp_reg__ + 545 00e8 8DBF out __SP_L__,r24 + 546 .L9: + 547 00ea 2B96 adiw r28,11 + 218:../../../../Lib/Rs485_prot.c **** { + 549 .LM21: + 550 00ec C017 cp r28,r16 + 551 00ee D107 cpc r29,r17 + 552 00f0 01F4 brne .L10 + 553 .LBE3: + 226:../../../../Lib/Rs485_prot.c **** } + 227:../../../../Lib/Rs485_prot.c **** rolTmp++; + 228:../../../../Lib/Rs485_prot.c **** } + 229:../../../../Lib/Rs485_prot.c **** + 230:../../../../Lib/Rs485_prot.c **** + 231:../../../../Lib/Rs485_prot.c **** return result; + 232:../../../../Lib/Rs485_prot.c **** } + 555 .LM22: + 556 00f2 8F2D mov r24,r15 + 557 /* epilogue start */ + 558 00f4 DF91 pop r29 + 559 00f6 CF91 pop r28 + 560 00f8 1F91 pop r17 + 561 00fa 0F91 pop r16 + 562 00fc FF90 pop r15 + 563 00fe EF90 pop r14 + 564 0100 DF90 pop r13 + 565 0102 CF90 pop r12 + 566 0104 BF90 pop r11 + 567 0106 AF90 pop r10 + 568 0108 9F90 pop r9 + 569 010a 0895 ret + 575 .Lscope8: + 577 .stabd 78,0,0 + 580 .global rs485ping + 582 rs485ping: + 583 .stabd 46,0,0 + 233:../../../../Lib/Rs485_prot.c **** #endif /*PRINT_RS485_DEVICE*/ + 234:../../../../Lib/Rs485_prot.c **** + 235:../../../../Lib/Rs485_prot.c **** uint8_t rs485ping(uint8_t devAddr) + 236:../../../../Lib/Rs485_prot.c **** { + 585 .LM23: + 586 .LFBB9: + 587 010c EF92 push r14 + 588 010e FF92 push r15 + 589 0110 0F93 push r16 + 590 0112 1F93 push r17 + 591 0114 CF93 push r28 + 592 0116 DF93 push r29 + 593 0118 00D0 rcall . + 594 011a 00D0 rcall . + 595 011c CDB7 in r28,__SP_L__ + 596 011e DEB7 in r29,__SP_H__ + 597 /* prologue: function */ + 598 /* frame size = 4 */ + 599 /* stack size = 10 */ + 600 .L__stack_usage = 10 + 601 0120 182F mov r17,r24 + 237:../../../../Lib/Rs485_prot.c **** takeRs485(); + 603 .LM24: + 604 0122 0E94 0000 call takeRs485 + 605 .LBB9: + 606 .LBB10: + 42:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 608 .LM25: + 609 0126 6AE5 ldi r22,lo8(90) + 610 0128 80E0 ldi r24,0 + 611 012a 90E0 ldi r25,0 + 612 012c 0E94 0000 call _crc_xmodem_update + 613 0130 7C01 movw r14,r24 + 43:../../../../Lib/Rs485_prot.c **** + 615 .LM26: + 616 0132 8AE5 ldi r24,lo8(90) + 617 0134 0E94 0000 call uartRs485SendByte + 45:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 619 .LM27: + 620 0138 612F mov r22,r17 + 621 013a C701 movw r24,r14 + 622 013c 0E94 0000 call _crc_xmodem_update + 623 0140 7C01 movw r14,r24 + 46:../../../../Lib/Rs485_prot.c **** + 625 .LM28: + 626 0142 812F mov r24,r17 + 627 0144 0E94 0000 call uartRs485SendByte + 48:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rPING); + 629 .LM29: + 630 0148 60E8 ldi r22,lo8(-128) + 631 014a C701 movw r24,r14 + 632 014c 0E94 0000 call _crc_xmodem_update + 633 0150 8C01 movw r16,r24 + 49:../../../../Lib/Rs485_prot.c **** + 635 .LM30: + 636 0152 80E8 ldi r24,lo8(-128) + 637 0154 0E94 0000 call uartRs485SendByte + 51:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(pingLen); + 639 .LM31: + 640 0158 68E0 ldi r22,lo8(8) + 641 015a C801 movw r24,r16 + 642 015c 0E94 0000 call _crc_xmodem_update + 643 0160 082F mov r16,r24 + 52:../../../../Lib/Rs485_prot.c **** + 645 .LM32: + 646 0162 88E0 ldi r24,lo8(8) + 647 0164 9C83 std Y+4,r25 + 648 0166 0E94 0000 call uartRs485SendByte + 649 .LBB11: + 54:../../../../Lib/Rs485_prot.c **** { + 651 .LM33: + 652 016a 10E0 ldi r17,0 + 653 016c 9C81 ldd r25,Y+4 + 654 .L17: + 56:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(i); + 656 .LM34: + 657 016e 612F mov r22,r17 + 658 0170 802F mov r24,r16 + 659 0172 0E94 0000 call _crc_xmodem_update + 660 0176 082F mov r16,r24 + 57:../../../../Lib/Rs485_prot.c **** } + 662 .LM35: + 663 0178 812F mov r24,r17 + 664 017a 9C83 std Y+4,r25 + 665 017c 0E94 0000 call uartRs485SendByte + 54:../../../../Lib/Rs485_prot.c **** { + 667 .LM36: + 668 0180 1F5F subi r17,lo8(-(1)) + 669 0182 9C81 ldd r25,Y+4 + 670 0184 1830 cpi r17,lo8(8) + 671 0186 01F4 brne .L17 + 672 .LBE11: + 59:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 674 .LM37: + 675 0188 892F mov r24,r25 + 676 018a 0E94 0000 call uartRs485SendByte + 60:../../../../Lib/Rs485_prot.c **** } + 678 .LM38: + 679 018e 802F mov r24,r16 + 680 0190 0E94 0000 call uartRs485SendByte + 681 .LBE10: + 682 .LBE9: + 683 .LBB12: + 684 .LBB13: + 70:../../../../Lib/Rs485_prot.c **** return 1; + 686 .LM39: + 687 0194 64E1 ldi r22,lo8(20) + 688 0196 CE01 movw r24,r28 + 689 0198 0396 adiw r24,3 + 690 019a 0E94 0000 call rs485Receive + 691 019e 8823 tst r24 + 692 01a0 01F4 brne .+2 + 693 01a2 00C0 rjmp .L23 + 73:../../../../Lib/Rs485_prot.c **** return 2; + 695 .LM40: + 696 01a4 8B81 ldd r24,Y+3 + 697 01a6 8A35 cpi r24,lo8(90) + 698 01a8 01F0 breq .+2 + 699 01aa 00C0 rjmp .L24 + 75:../../../../Lib/Rs485_prot.c **** + 701 .LM41: + 702 01ac 6AE5 ldi r22,lo8(90) + 703 01ae 80E0 ldi r24,0 + 704 01b0 90E0 ldi r25,0 + 705 01b2 0E94 0000 call _crc_xmodem_update + 706 01b6 8C01 movw r16,r24 + 78:../../../../Lib/Rs485_prot.c **** return 3; + 708 .LM42: + 709 01b8 61E0 ldi r22,lo8(1) + 710 01ba CE01 movw r24,r28 + 711 01bc 0396 adiw r24,3 + 712 01be 0E94 0000 call rs485Receive + 713 01c2 8823 tst r24 + 714 01c4 01F4 brne .+2 + 715 01c6 00C0 rjmp .L25 + 81:../../../../Lib/Rs485_prot.c **** return 4; + 717 .LM43: + 718 01c8 8B81 ldd r24,Y+3 + 719 01ca 8111 cpse r24,__zero_reg__ + 720 01cc 00C0 rjmp .L26 + 84:../../../../Lib/Rs485_prot.c **** + 722 .LM44: + 723 01ce 60E0 ldi r22,0 + 724 01d0 C801 movw r24,r16 + 725 01d2 0E94 0000 call _crc_xmodem_update + 726 01d6 8C01 movw r16,r24 + 87:../../../../Lib/Rs485_prot.c **** return 5; + 728 .LM45: + 729 01d8 61E0 ldi r22,lo8(1) + 730 01da CE01 movw r24,r28 + 731 01dc 0396 adiw r24,3 + 732 01de 0E94 0000 call rs485Receive + 733 01e2 8823 tst r24 + 734 01e4 01F4 brne .+2 + 735 01e6 00C0 rjmp .L27 + 89:../../../../Lib/Rs485_prot.c **** return 6; + 737 .LM46: + 738 01e8 8B81 ldd r24,Y+3 + 739 01ea 8038 cpi r24,lo8(-128) + 740 01ec 01F0 breq .+2 + 741 01ee 00C0 rjmp .L28 + 91:../../../../Lib/Rs485_prot.c **** + 743 .LM47: + 744 01f0 60E8 ldi r22,lo8(-128) + 745 01f2 C801 movw r24,r16 + 746 01f4 0E94 0000 call _crc_xmodem_update + 747 01f8 8C01 movw r16,r24 + 94:../../../../Lib/Rs485_prot.c **** return 7; + 749 .LM48: + 750 01fa 61E0 ldi r22,lo8(1) + 751 01fc CE01 movw r24,r28 + 752 01fe 0396 adiw r24,3 + 753 0200 0E94 0000 call rs485Receive + 754 0204 8823 tst r24 + 755 0206 01F4 brne .+2 + 756 0208 00C0 rjmp .L29 + 96:../../../../Lib/Rs485_prot.c **** return 8; + 758 .LM49: + 759 020a 8B81 ldd r24,Y+3 + 760 020c 8830 cpi r24,lo8(8) + 761 020e 01F0 breq .+2 + 762 0210 00C0 rjmp .L30 + 98:../../../../Lib/Rs485_prot.c **** + 764 .LM50: + 765 0212 68E0 ldi r22,lo8(8) + 766 0214 C801 movw r24,r16 + 767 0216 0E94 0000 call _crc_xmodem_update + 768 021a 082F mov r16,r24 + 769 021c F92E mov r15,r25 + 102:../../../../Lib/Rs485_prot.c **** { + 771 .LM51: + 772 021e 10E0 ldi r17,0 + 773 .L21: + 104:../../../../Lib/Rs485_prot.c **** return 2*temp+9; + 775 .LM52: + 776 0220 65E0 ldi r22,lo8(5) + 777 0222 CE01 movw r24,r28 + 778 0224 0396 adiw r24,3 + 779 0226 0E94 0000 call rs485Receive + 780 022a 8111 cpse r24,__zero_reg__ + 781 022c 00C0 rjmp .L19 + 105:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 783 .LM53: + 784 022e 110F lsl r17 + 785 0230 175F subi r17,lo8(-(9)) + 786 0232 00C0 rjmp .L18 + 787 .L19: + 106:../../../../Lib/Rs485_prot.c **** if (data != temp) + 789 .LM54: + 790 0234 6B81 ldd r22,Y+3 + 791 0236 802F mov r24,r16 + 792 0238 9F2D mov r25,r15 + 793 023a 0E94 0000 call _crc_xmodem_update + 794 023e 082F mov r16,r24 + 795 0240 F92E mov r15,r25 + 107:../../../../Lib/Rs485_prot.c **** return 2*temp+10; + 797 .LM55: + 798 0242 8B81 ldd r24,Y+3 + 799 0244 8117 cp r24,r17 + 800 0246 01F0 breq .L20 + 108:../../../../Lib/Rs485_prot.c **** } + 802 .LM56: + 803 0248 110F lsl r17 + 804 024a 165F subi r17,lo8(-(10)) + 805 024c 00C0 rjmp .L18 + 806 .L20: + 102:../../../../Lib/Rs485_prot.c **** { + 808 .LM57: + 809 024e 1F5F subi r17,lo8(-(1)) + 810 0250 1830 cpi r17,lo8(8) + 811 0252 01F4 brne .L21 + 113:../../../../Lib/Rs485_prot.c **** return 2*temp+11; + 813 .LM58: + 814 0254 61E0 ldi r22,lo8(1) + 815 0256 CE01 movw r24,r28 + 816 0258 0296 adiw r24,2 + 817 025a 0E94 0000 call rs485Receive + 818 025e 8130 cpi r24,lo8(1) + 819 0260 01F4 brne .L31 + 116:../../../../Lib/Rs485_prot.c **** return 2*temp+12; + 821 .LM59: + 822 0262 20E0 ldi r18,0 + 823 0264 41E0 ldi r20,lo8(1) + 824 0266 50E0 ldi r21,0 + 825 0268 BE01 movw r22,r28 + 826 026a 6F5F subi r22,-1 + 827 026c 7F4F sbci r23,-1 + 828 026e 8091 0000 lds r24,xRs485Rec + 829 0272 9091 0000 lds r25,xRs485Rec+1 + 830 0276 0E94 0000 call xQueueGenericReceive + 831 027a 8130 cpi r24,lo8(1) + 832 027c 01F4 brne .L32 + 119:../../../../Lib/Rs485_prot.c **** return 254; + 834 .LM60: + 835 027e 8A81 ldd r24,Y+2 + 836 0280 8F11 cpse r24,r15 + 837 0282 00C0 rjmp .L33 + 121:../../../../Lib/Rs485_prot.c **** return 255; + 839 .LM61: + 840 0284 11E0 ldi r17,lo8(1) + 841 0286 8981 ldd r24,Y+1 + 842 0288 8013 cpse r24,r16 + 843 028a 00C0 rjmp .L22 + 844 028c 10E0 ldi r17,0 + 845 .L22: + 846 028e 1195 neg r17 + 847 0290 00C0 rjmp .L18 + 848 .L23: + 71:../../../../Lib/Rs485_prot.c **** + 850 .LM62: + 851 0292 11E0 ldi r17,lo8(1) + 852 0294 00C0 rjmp .L18 + 853 .L24: + 74:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, data); + 855 .LM63: + 856 0296 12E0 ldi r17,lo8(2) + 857 0298 00C0 rjmp .L18 + 858 .L25: + 79:../../../../Lib/Rs485_prot.c **** + 860 .LM64: + 861 029a 13E0 ldi r17,lo8(3) + 862 029c 00C0 rjmp .L18 + 863 .L26: + 82:../../../../Lib/Rs485_prot.c **** + 865 .LM65: + 866 029e 14E0 ldi r17,lo8(4) + 867 02a0 00C0 rjmp .L18 + 868 .L27: + 88:../../../../Lib/Rs485_prot.c **** if (data != rPING) + 870 .LM66: + 871 02a2 15E0 ldi r17,lo8(5) + 872 02a4 00C0 rjmp .L18 + 873 .L28: + 90:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 875 .LM67: + 876 02a6 16E0 ldi r17,lo8(6) + 877 02a8 00C0 rjmp .L18 + 878 .L29: + 95:../../../../Lib/Rs485_prot.c **** if (data != dataLen) + 880 .LM68: + 881 02aa 17E0 ldi r17,lo8(7) + 882 02ac 00C0 rjmp .L18 + 883 .L30: + 97:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 885 .LM69: + 886 02ae 18E0 ldi r17,lo8(8) + 887 02b0 00C0 rjmp .L18 + 888 .L31: + 114:../../../../Lib/Rs485_prot.c **** + 890 .LM70: + 891 02b2 1BE1 ldi r17,lo8(27) + 892 02b4 00C0 rjmp .L18 + 893 .L32: + 117:../../../../Lib/Rs485_prot.c **** + 895 .LM71: + 896 02b6 1CE1 ldi r17,lo8(28) + 897 02b8 00C0 rjmp .L18 + 898 .L33: + 120:../../../../Lib/Rs485_prot.c **** if (crcLo != (uint8_t)(crc & 0xFF)) + 900 .LM72: + 901 02ba 1EEF ldi r17,lo8(-2) + 902 .L18: + 903 .LBE13: + 904 .LBE12: + 238:../../../../Lib/Rs485_prot.c **** const int len = 8; + 239:../../../../Lib/Rs485_prot.c **** sendPing(devAddr, len); + 240:../../../../Lib/Rs485_prot.c **** uint8_t result = receivePong(devAddr, len); + 241:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 906 .LM73: + 907 02bc 0E94 0000 call flushRs485RecBuffer + 242:../../../../Lib/Rs485_prot.c **** + 243:../../../../Lib/Rs485_prot.c **** releaseRs485(); + 909 .LM74: + 910 02c0 0E94 0000 call releaseRs485 + 244:../../../../Lib/Rs485_prot.c **** return result; + 245:../../../../Lib/Rs485_prot.c **** } + 912 .LM75: + 913 02c4 812F mov r24,r17 + 914 /* epilogue start */ + 915 02c6 0F90 pop __tmp_reg__ + 916 02c8 0F90 pop __tmp_reg__ + 917 02ca 0F90 pop __tmp_reg__ + 918 02cc 0F90 pop __tmp_reg__ + 919 02ce DF91 pop r29 + 920 02d0 CF91 pop r28 + 921 02d2 1F91 pop r17 + 922 02d4 0F91 pop r16 + 923 02d6 FF90 pop r15 + 924 02d8 EF90 pop r14 + 925 02da 0895 ret + 936 .Lscope9: + 938 .stabd 78,0,0 + 941 .global rs485rollerHello + 943 rs485rollerHello: + 944 .stabd 46,0,0 + 246:../../../../Lib/Rs485_prot.c **** + 247:../../../../Lib/Rs485_prot.c **** uint8_t rs485rollerHello(uint8_t devAddr) + 248:../../../../Lib/Rs485_prot.c **** { + 946 .LM76: + 947 .LFBB10: + 948 02dc CF92 push r12 + 949 02de DF92 push r13 + 950 02e0 EF92 push r14 + 951 02e2 FF92 push r15 + 952 02e4 0F93 push r16 + 953 02e6 1F93 push r17 + 954 02e8 CF93 push r28 + 955 02ea DF93 push r29 + 956 02ec 00D0 rcall . + 957 02ee 00D0 rcall . + 958 02f0 CDB7 in r28,__SP_L__ + 959 02f2 DEB7 in r29,__SP_H__ + 960 /* prologue: function */ + 961 /* frame size = 4 */ + 962 /* stack size = 12 */ + 963 .L__stack_usage = 12 + 964 02f4 F82E mov r15,r24 + 249:../../../../Lib/Rs485_prot.c **** struct sterRolet *tmp = NULL; + 250:../../../../Lib/Rs485_prot.c **** uint8_t i; + 251:../../../../Lib/Rs485_prot.c **** for (i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + 252:../../../../Lib/Rs485_prot.c **** if (rollers[i].address == devAddr) + 966 .LM77: + 967 02f6 8091 0000 lds r24,rollers + 968 02fa 9091 0000 lds r25,rollers+1 + 969 02fe FC01 movw r30,r24 + 970 0300 3196 adiw r30,1 + 971 0302 8159 subi r24,-111 + 972 0304 9F4F sbci r25,-1 + 249:../../../../Lib/Rs485_prot.c **** struct sterRolet *tmp = NULL; + 974 .LM78: + 975 0306 00E0 ldi r16,0 + 976 0308 10E0 ldi r17,0 + 977 .L38: + 978 030a 9F01 movw r18,r30 + 979 030c 2150 subi r18,1 + 980 030e 3109 sbc r19,__zero_reg__ + 982 .LM79: + 983 0310 4081 ld r20,Z + 984 0312 4F11 cpse r20,r15 + 985 0314 00C0 rjmp .L37 + 253:../../../../Lib/Rs485_prot.c **** tmp = &rollers[i]; + 987 .LM80: + 988 0316 8901 movw r16,r18 + 989 .L37: + 990 0318 3B96 adiw r30,11 + 251:../../../../Lib/Rs485_prot.c **** if (rollers[i].address == devAddr) + 992 .LM81: + 993 031a E817 cp r30,r24 + 994 031c F907 cpc r31,r25 + 995 031e 01F4 brne .L38 + 254:../../../../Lib/Rs485_prot.c **** + 255:../../../../Lib/Rs485_prot.c **** if (rs485ping(devAddr)==0) + 997 .LM82: + 998 0320 8F2D mov r24,r15 + 999 0322 0E94 0000 call rs485ping + 1000 0326 8111 cpse r24,__zero_reg__ + 1001 0328 00C0 rjmp .L39 + 256:../../../../Lib/Rs485_prot.c **** { + 257:../../../../Lib/Rs485_prot.c **** if (tmp == NULL) + 1003 .LM83: + 1004 032a 0115 cp r16,__zero_reg__ + 1005 032c 1105 cpc r17,__zero_reg__ + 1006 032e 01F4 brne .L40 + 258:../../../../Lib/Rs485_prot.c **** { + 259:../../../../Lib/Rs485_prot.c **** for (i=0; i< MAX_NUMBER_OF_ROLLERS; i++) + 260:../../../../Lib/Rs485_prot.c **** { + 261:../../../../Lib/Rs485_prot.c **** if (rollers[i].address == 0) + 1008 .LM84: + 1009 0330 8091 0000 lds r24,rollers + 1010 0334 9091 0000 lds r25,rollers+1 + 1011 0338 FC01 movw r30,r24 + 1012 033a 3196 adiw r30,1 + 1013 033c 8159 subi r24,-111 + 1014 033e 9F4F sbci r25,-1 + 1015 .L43: + 1016 0340 8F01 movw r16,r30 + 1017 0342 0150 subi r16,1 + 1018 0344 1109 sbc r17,__zero_reg__ + 1019 0346 2081 ld r18,Z + 1020 0348 2111 cpse r18,__zero_reg__ + 1021 034a 00C0 rjmp .L41 + 262:../../../../Lib/Rs485_prot.c **** { + 263:../../../../Lib/Rs485_prot.c **** tmp = &rollers[i]; + 264:../../../../Lib/Rs485_prot.c **** tmp->address = devAddr; + 1023 .LM85: + 1024 034c F801 movw r30,r16 + 1025 034e F182 std Z+1,r15 + 265:../../../../Lib/Rs485_prot.c **** break; + 266:../../../../Lib/Rs485_prot.c **** } + 267:../../../../Lib/Rs485_prot.c **** } + 268:../../../../Lib/Rs485_prot.c **** } + 269:../../../../Lib/Rs485_prot.c **** if (tmp != NULL) + 1027 .LM86: + 1028 0350 0115 cp r16,__zero_reg__ + 1029 0352 1105 cpc r17,__zero_reg__ + 1030 0354 01F4 brne .L40 + 1031 .L44: + 270:../../../../Lib/Rs485_prot.c **** { + 271:../../../../Lib/Rs485_prot.c **** tmp->state &= (~NOT_DETECTED); + 272:../../../../Lib/Rs485_prot.c **** tmp->address = devAddr; + 273:../../../../Lib/Rs485_prot.c **** } + 274:../../../../Lib/Rs485_prot.c **** else + 275:../../../../Lib/Rs485_prot.c **** return 1; + 1033 .LM87: + 1034 0356 81E0 ldi r24,lo8(1) + 1035 0358 00C0 rjmp .L42 + 1036 .L41: + 1037 035a 3B96 adiw r30,11 + 259:../../../../Lib/Rs485_prot.c **** { + 1039 .LM88: + 1040 035c E817 cp r30,r24 + 1041 035e F907 cpc r31,r25 + 1042 0360 01F4 brne .L43 + 1043 0362 00C0 rjmp .L44 + 1044 .L40: + 271:../../../../Lib/Rs485_prot.c **** tmp->address = devAddr; + 1046 .LM89: + 1047 0364 F801 movw r30,r16 + 1048 0366 8081 ld r24,Z + 1049 0368 8E7F andi r24,lo8(-2) + 1050 036a 8083 st Z,r24 + 272:../../../../Lib/Rs485_prot.c **** } + 1052 .LM90: + 1053 036c F182 std Z+1,r15 + 1054 036e 00C0 rjmp .L45 + 1055 .L39: + 276:../../../../Lib/Rs485_prot.c **** } + 277:../../../../Lib/Rs485_prot.c **** else + 278:../../../../Lib/Rs485_prot.c **** { + 279:../../../../Lib/Rs485_prot.c **** if (tmp != NULL) + 1057 .LM91: + 1058 0370 0115 cp r16,__zero_reg__ + 1059 0372 1105 cpc r17,__zero_reg__ + 1060 0374 01F0 breq .L45 + 280:../../../../Lib/Rs485_prot.c **** { + 281:../../../../Lib/Rs485_prot.c **** if (tmp->state & NOT_DETECTED) + 1062 .LM92: + 1063 0376 F801 movw r30,r16 + 1064 0378 8081 ld r24,Z + 1065 037a 80FD sbrc r24,0 + 282:../../../../Lib/Rs485_prot.c **** { + 283:../../../../Lib/Rs485_prot.c **** tmp->address = 0; + 1067 .LM93: + 1068 037c 1182 std Z+1,__zero_reg__ + 1069 .L46: + 284:../../../../Lib/Rs485_prot.c **** } + 285:../../../../Lib/Rs485_prot.c **** tmp->state |= NOT_DETECTED; + 1071 .LM94: + 1072 037e 8160 ori r24,lo8(1) + 1073 0380 F801 movw r30,r16 + 1074 0382 8083 st Z,r24 + 286:../../../../Lib/Rs485_prot.c **** return 2; + 1076 .LM95: + 1077 0384 82E0 ldi r24,lo8(2) + 1078 0386 00C0 rjmp .L42 + 1079 .L45: + 287:../../../../Lib/Rs485_prot.c **** } + 288:../../../../Lib/Rs485_prot.c **** } + 289:../../../../Lib/Rs485_prot.c **** + 290:../../../../Lib/Rs485_prot.c **** takeRs485(); + 1081 .LM96: + 1082 0388 0E94 0000 call takeRs485 + 1083 .LBB18: + 1084 .LBB19: + 129:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 1086 .LM97: + 1087 038c 6AE5 ldi r22,lo8(90) + 1088 038e 80E0 ldi r24,0 + 1089 0390 90E0 ldi r25,0 + 1090 0392 0E94 0000 call _crc_xmodem_update + 1091 0396 6C01 movw r12,r24 + 130:../../../../Lib/Rs485_prot.c **** + 1093 .LM98: + 1094 0398 8AE5 ldi r24,lo8(90) + 1095 039a 0E94 0000 call uartRs485SendByte + 132:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 1097 .LM99: + 1098 039e 6F2D mov r22,r15 + 1099 03a0 C601 movw r24,r12 + 1100 03a2 0E94 0000 call _crc_xmodem_update + 1101 03a6 6C01 movw r12,r24 + 133:../../../../Lib/Rs485_prot.c **** + 1103 .LM100: + 1104 03a8 8F2D mov r24,r15 + 1105 03aa 0E94 0000 call uartRs485SendByte + 135:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rHELLO); + 1107 .LM101: + 1108 03ae 62E8 ldi r22,lo8(-126) + 1109 03b0 C601 movw r24,r12 + 1110 03b2 0E94 0000 call _crc_xmodem_update + 1111 03b6 7C01 movw r14,r24 + 136:../../../../Lib/Rs485_prot.c **** + 1113 .LM102: + 1114 03b8 82E8 ldi r24,lo8(-126) + 1115 03ba 0E94 0000 call uartRs485SendByte + 138:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(0); + 1117 .LM103: + 1118 03be 60E0 ldi r22,0 + 1119 03c0 C701 movw r24,r14 + 1120 03c2 0E94 0000 call _crc_xmodem_update + 1121 03c6 F82E mov r15,r24 + 139:../../../../Lib/Rs485_prot.c **** + 1123 .LM104: + 1124 03c8 80E0 ldi r24,0 + 1125 03ca 9C83 std Y+4,r25 + 1126 03cc 0E94 0000 call uartRs485SendByte + 141:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 1128 .LM105: + 1129 03d0 9C81 ldd r25,Y+4 + 1130 03d2 892F mov r24,r25 + 1131 03d4 0E94 0000 call uartRs485SendByte + 142:../../../../Lib/Rs485_prot.c **** } + 1133 .LM106: + 1134 03d8 8F2D mov r24,r15 + 1135 03da 0E94 0000 call uartRs485SendByte + 1136 .LBE19: + 1137 .LBE18: + 1138 .LBB20: + 1139 .LBB21: + 150:../../../../Lib/Rs485_prot.c **** return 8; + 1141 .LM107: + 1142 03de 64E1 ldi r22,lo8(20) + 1143 03e0 CE01 movw r24,r28 + 1144 03e2 0396 adiw r24,3 + 1145 03e4 0E94 0000 call rs485Receive + 1146 03e8 8823 tst r24 + 1147 03ea 01F4 brne .+2 + 1148 03ec 00C0 rjmp .L52 + 153:../../../../Lib/Rs485_prot.c **** return 2; + 1150 .LM108: + 1151 03ee 8B81 ldd r24,Y+3 + 1152 03f0 8A35 cpi r24,lo8(90) + 1153 03f2 01F0 breq .+2 + 1154 03f4 00C0 rjmp .L53 + 155:../../../../Lib/Rs485_prot.c **** + 1156 .LM109: + 1157 03f6 6AE5 ldi r22,lo8(90) + 1158 03f8 80E0 ldi r24,0 + 1159 03fa 90E0 ldi r25,0 + 1160 03fc 0E94 0000 call _crc_xmodem_update + 1161 0400 7C01 movw r14,r24 + 158:../../../../Lib/Rs485_prot.c **** return 3; + 1163 .LM110: + 1164 0402 61E0 ldi r22,lo8(1) + 1165 0404 CE01 movw r24,r28 + 1166 0406 0396 adiw r24,3 + 1167 0408 0E94 0000 call rs485Receive + 1168 040c 8823 tst r24 + 1169 040e 01F4 brne .+2 + 1170 0410 00C0 rjmp .L54 + 161:../../../../Lib/Rs485_prot.c **** return 4; + 1172 .LM111: + 1173 0412 8B81 ldd r24,Y+3 + 1174 0414 8111 cpse r24,__zero_reg__ + 1175 0416 00C0 rjmp .L55 + 164:../../../../Lib/Rs485_prot.c **** + 1177 .LM112: + 1178 0418 60E0 ldi r22,0 + 1179 041a C701 movw r24,r14 + 1180 041c 0E94 0000 call _crc_xmodem_update + 1181 0420 7C01 movw r14,r24 + 167:../../../../Lib/Rs485_prot.c **** return 5; + 1183 .LM113: + 1184 0422 61E0 ldi r22,lo8(1) + 1185 0424 CE01 movw r24,r28 + 1186 0426 0396 adiw r24,3 + 1187 0428 0E94 0000 call rs485Receive + 1188 042c 8823 tst r24 + 1189 042e 01F4 brne .+2 + 1190 0430 00C0 rjmp .L56 + 169:../../../../Lib/Rs485_prot.c **** return 6; + 1192 .LM114: + 1193 0432 8B81 ldd r24,Y+3 + 1194 0434 8238 cpi r24,lo8(-126) + 1195 0436 01F0 breq .+2 + 1196 0438 00C0 rjmp .L57 + 171:../../../../Lib/Rs485_prot.c **** + 1198 .LM115: + 1199 043a 62E8 ldi r22,lo8(-126) + 1200 043c C701 movw r24,r14 + 1201 043e 0E94 0000 call _crc_xmodem_update + 1202 0442 7C01 movw r14,r24 + 174:../../../../Lib/Rs485_prot.c **** return 7; + 1204 .LM116: + 1205 0444 61E0 ldi r22,lo8(1) + 1206 0446 CE01 movw r24,r28 + 1207 0448 0396 adiw r24,3 + 1208 044a 0E94 0000 call rs485Receive + 1209 044e 8823 tst r24 + 1210 0450 01F4 brne .+2 + 1211 0452 00C0 rjmp .L58 + 176:../../../../Lib/Rs485_prot.c **** return 1; + 1213 .LM117: + 1214 0454 6B81 ldd r22,Y+3 + 1215 0456 6930 cpi r22,lo8(9) + 1216 0458 00F0 brlo .+2 + 1217 045a 00C0 rjmp .L59 + 1218 .LBE21: + 1219 .LBE20: + 291:../../../../Lib/Rs485_prot.c **** sendHello(devAddr); + 292:../../../../Lib/Rs485_prot.c **** uint8_t result = receiveHello((tmp->response.data), HELLO_RESP_LEN); + 1221 .LM118: + 1222 045c 0E5F subi r16,-2 + 1223 045e 1F4F sbci r17,-1 + 1224 .LBB23: + 1225 .LBB22: + 179:../../../../Lib/Rs485_prot.c **** memset(response, 0, maxSize); + 1227 .LM119: + 1228 0460 C701 movw r24,r14 + 1229 0462 0E94 0000 call _crc_xmodem_update + 1230 0466 F82E mov r15,r24 + 1231 0468 E92E mov r14,r25 + 180:../../../../Lib/Rs485_prot.c **** maxSize = data; + 1233 .LM120: + 1234 046a 88E0 ldi r24,lo8(8) + 1235 046c F801 movw r30,r16 + 1236 0: + 1237 046e 1192 st Z+,__zero_reg__ + 1238 0470 8A95 dec r24 + 1239 0472 01F4 brne 0b + 181:../../../../Lib/Rs485_prot.c **** + 1241 .LM121: + 1242 0474 DB80 ldd r13,Y+3 + 183:../../../../Lib/Rs485_prot.c **** { + 1244 .LM122: + 1245 0476 1B82 std Y+3,__zero_reg__ + 1246 .L48: + 1247 0478 8B81 ldd r24,Y+3 + 1248 047a 8D15 cp r24,r13 + 1249 047c 00F4 brsh .L72 + 185:../../../../Lib/Rs485_prot.c **** return 20; + 1251 .LM123: + 1252 047e 65E0 ldi r22,lo8(5) + 1253 0480 C801 movw r24,r16 + 1254 0482 0E94 0000 call rs485Receive + 1255 0486 8823 tst r24 + 1256 0488 01F0 breq .L60 + 187:../../../../Lib/Rs485_prot.c **** response++; + 1258 .LM124: + 1259 048a F801 movw r30,r16 + 1260 048c 6191 ld r22,Z+ + 1261 048e 8F01 movw r16,r30 + 1262 0490 8F2D mov r24,r15 + 1263 0492 9E2D mov r25,r14 + 1264 0494 0E94 0000 call _crc_xmodem_update + 1265 0498 F82E mov r15,r24 + 1266 049a E92E mov r14,r25 + 183:../../../../Lib/Rs485_prot.c **** { + 1268 .LM125: + 1269 049c 8B81 ldd r24,Y+3 + 1270 049e 8F5F subi r24,lo8(-(1)) + 1271 04a0 8B83 std Y+3,r24 + 1272 04a2 00C0 rjmp .L48 + 1273 .L72: + 193:../../../../Lib/Rs485_prot.c **** return 21; + 1275 .LM126: + 1276 04a4 61E0 ldi r22,lo8(1) + 1277 04a6 CE01 movw r24,r28 + 1278 04a8 0296 adiw r24,2 + 1279 04aa 0E94 0000 call rs485Receive + 1280 04ae 8130 cpi r24,lo8(1) + 1281 04b0 01F4 brne .L61 + 196:../../../../Lib/Rs485_prot.c **** return 22; + 1283 .LM127: + 1284 04b2 20E0 ldi r18,0 + 1285 04b4 41E0 ldi r20,lo8(1) + 1286 04b6 50E0 ldi r21,0 + 1287 04b8 BE01 movw r22,r28 + 1288 04ba 6F5F subi r22,-1 + 1289 04bc 7F4F sbci r23,-1 + 1290 04be 8091 0000 lds r24,xRs485Rec + 1291 04c2 9091 0000 lds r25,xRs485Rec+1 + 1292 04c6 0E94 0000 call xQueueGenericReceive + 1293 04ca 8130 cpi r24,lo8(1) + 1294 04cc 01F4 brne .L62 + 199:../../../../Lib/Rs485_prot.c **** return 254; + 1296 .LM128: + 1297 04ce 8A81 ldd r24,Y+2 + 1298 04d0 8E11 cpse r24,r14 + 1299 04d2 00C0 rjmp .L63 + 201:../../../../Lib/Rs485_prot.c **** return 255; + 1301 .LM129: + 1302 04d4 91E0 ldi r25,lo8(1) + 1303 04d6 8981 ldd r24,Y+1 + 1304 04d8 8F11 cpse r24,r15 + 1305 04da 00C0 rjmp .L50 + 1306 04dc 90E0 ldi r25,0 + 1307 .L50: + 1308 04de 892F mov r24,r25 + 1309 04e0 8195 neg r24 + 1310 04e2 00C0 rjmp .L47 + 1311 .L52: + 151:../../../../Lib/Rs485_prot.c **** + 1313 .LM130: + 1314 04e4 88E0 ldi r24,lo8(8) + 1315 04e6 00C0 rjmp .L47 + 1316 .L53: + 154:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, data); + 1318 .LM131: + 1319 04e8 82E0 ldi r24,lo8(2) + 1320 04ea 00C0 rjmp .L47 + 1321 .L54: + 159:../../../../Lib/Rs485_prot.c **** + 1323 .LM132: + 1324 04ec 83E0 ldi r24,lo8(3) + 1325 04ee 00C0 rjmp .L47 + 1326 .L55: + 162:../../../../Lib/Rs485_prot.c **** + 1328 .LM133: + 1329 04f0 84E0 ldi r24,lo8(4) + 1330 04f2 00C0 rjmp .L47 + 1331 .L56: + 168:../../../../Lib/Rs485_prot.c **** if (data != rHELLO) + 1333 .LM134: + 1334 04f4 85E0 ldi r24,lo8(5) + 1335 04f6 00C0 rjmp .L47 + 1336 .L57: + 170:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1338 .LM135: + 1339 04f8 86E0 ldi r24,lo8(6) + 1340 04fa 00C0 rjmp .L47 + 1341 .L58: + 175:../../../../Lib/Rs485_prot.c **** if (data > maxSize) + 1343 .LM136: + 1344 04fc 87E0 ldi r24,lo8(7) + 1345 04fe 00C0 rjmp .L47 + 1346 .L59: + 177:../../../../Lib/Rs485_prot.c **** + 1348 .LM137: + 1349 0500 81E0 ldi r24,lo8(1) + 1350 0502 00C0 rjmp .L47 + 1351 .L60: + 186:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, *((uint8_t *)(response))); + 1353 .LM138: + 1354 0504 84E1 ldi r24,lo8(20) + 1355 0506 00C0 rjmp .L47 + 1356 .L61: + 194:../../../../Lib/Rs485_prot.c **** + 1358 .LM139: + 1359 0508 85E1 ldi r24,lo8(21) + 1360 050a 00C0 rjmp .L47 + 1361 .L62: + 197:../../../../Lib/Rs485_prot.c **** + 1363 .LM140: + 1364 050c 86E1 ldi r24,lo8(22) + 1365 050e 00C0 rjmp .L47 + 1366 .L63: + 200:../../../../Lib/Rs485_prot.c **** if (crcLo != (uint8_t)(crc & 0xFF)) + 1368 .LM141: + 1369 0510 8EEF ldi r24,lo8(-2) + 1370 .L47: + 1371 .LBE22: + 1372 .LBE23: + 293:../../../../Lib/Rs485_prot.c **** releaseRs485(); + 1374 .LM142: + 1375 0512 8C83 std Y+4,r24 + 1376 0514 0E94 0000 call releaseRs485 + 1377 0518 8C81 ldd r24,Y+4 + 1378 .L42: + 1379 /* epilogue start */ + 294:../../../../Lib/Rs485_prot.c **** return result; + 295:../../../../Lib/Rs485_prot.c **** } + 1381 .LM143: + 1382 051a 0F90 pop __tmp_reg__ + 1383 051c 0F90 pop __tmp_reg__ + 1384 051e 0F90 pop __tmp_reg__ + 1385 0520 0F90 pop __tmp_reg__ + 1386 0522 DF91 pop r29 + 1387 0524 CF91 pop r28 + 1388 0526 1F91 pop r17 + 1389 0528 0F91 pop r16 + 1390 052a FF90 pop r15 + 1391 052c EF90 pop r14 + 1392 052e DF90 pop r13 + 1393 0530 CF90 pop r12 + 1394 0532 0895 ret + 1414 .Lscope10: + 1416 .stabd 78,0,0 + 1417 .section .rodata.str1.1,"aMS",@progbits,1 + 1418 .LC0: + 1419 0000 6461 7461 .string "data 0x%x " + 1419 2030 7825 + 1419 7820 00 + 1420 .text + 1425 .global rs485xModemFlash + 1427 rs485xModemFlash: + 1428 .stabd 46,0,0 + 296:../../../../Lib/Rs485_prot.c **** + 297:../../../../Lib/Rs485_prot.c **** + 298:../../../../Lib/Rs485_prot.c **** uint8_t rs485xModemFlash(struct ramPlikFd *file, uint8_t devAddr, FILE *debugStr) + 299:../../../../Lib/Rs485_prot.c **** { + 1430 .LM144: + 1431 .LFBB11: + 1432 0534 7F92 push r7 + 1433 0536 8F92 push r8 + 1434 0538 9F92 push r9 + 1435 053a AF92 push r10 + 1436 053c BF92 push r11 + 1437 053e CF92 push r12 + 1438 0540 DF92 push r13 + 1439 0542 EF92 push r14 + 1440 0544 FF92 push r15 + 1441 0546 0F93 push r16 + 1442 0548 1F93 push r17 + 1443 054a CF93 push r28 + 1444 054c DF93 push r29 + 1445 054e 00D0 rcall . + 1446 0550 1F92 push __zero_reg__ + 1447 0552 CDB7 in r28,__SP_L__ + 1448 0554 DEB7 in r29,__SP_H__ + 1449 /* prologue: function */ + 1450 /* frame size = 3 */ + 1451 /* stack size = 16 */ + 1452 .L__stack_usage = 16 + 1453 0556 6C01 movw r12,r24 + 1454 0558 E62E mov r14,r22 + 1455 055a 8A01 movw r16,r20 + 300:../../../../Lib/Rs485_prot.c **** uint16_t crc; + 301:../../../../Lib/Rs485_prot.c **** uint8_t blad = 0; + 302:../../../../Lib/Rs485_prot.c **** uint8_t data; + 303:../../../../Lib/Rs485_prot.c **** uint8_t nrBloku; + 304:../../../../Lib/Rs485_prot.c **** uint8_t lRetransmisji; + 305:../../../../Lib/Rs485_prot.c **** + 306:../../../../Lib/Rs485_prot.c **** takeRs485(); // Zajmowanie magistrali Rs485 + 1457 .LM145: + 1458 055c 0E94 0000 call takeRs485 + 307:../../../../Lib/Rs485_prot.c **** + 308:../../../../Lib/Rs485_prot.c **** // WysyÅ‚anie polecenia restartu + 309:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, SYNC); uartRs485SendByte(SYNC); + 1460 .LM146: + 1461 0560 6AE5 ldi r22,lo8(90) + 1462 0562 80E0 ldi r24,0 + 1463 0564 90E0 ldi r25,0 + 1464 0566 0E94 0000 call _crc_xmodem_update + 1465 056a 5C01 movw r10,r24 + 1466 056c 8AE5 ldi r24,lo8(90) + 1467 056e 0E94 0000 call uartRs485SendByte + 310:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + 1469 .LM147: + 1470 0572 6E2D mov r22,r14 + 1471 0574 C501 movw r24,r10 + 1472 0576 0E94 0000 call _crc_xmodem_update + 1473 057a 5C01 movw r10,r24 + 1474 057c 8E2D mov r24,r14 + 1475 057e 0E94 0000 call uartRs485SendByte + 311:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rFLASH); uartRs485SendByte(rFLASH); + 1477 .LM148: + 1478 0582 61E8 ldi r22,lo8(-127) + 1479 0584 C501 movw r24,r10 + 1480 0586 0E94 0000 call _crc_xmodem_update + 1481 058a 5C01 movw r10,r24 + 1482 058c 81E8 ldi r24,lo8(-127) + 1483 058e 0E94 0000 call uartRs485SendByte + 312:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + 1485 .LM149: + 1486 0592 61E0 ldi r22,lo8(1) + 1487 0594 C501 movw r24,r10 + 1488 0596 0E94 0000 call _crc_xmodem_update + 1489 059a 5C01 movw r10,r24 + 1490 059c 81E0 ldi r24,lo8(1) + 1491 059e 0E94 0000 call uartRs485SendByte + 313:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + 1493 .LM150: + 1494 05a2 6E2D mov r22,r14 + 1495 05a4 C501 movw r24,r10 + 1496 05a6 0E94 0000 call _crc_xmodem_update + 1497 05aa F82E mov r15,r24 + 1498 05ac 8E2D mov r24,r14 + 1499 05ae 9B83 std Y+3,r25 + 1500 05b0 0E94 0000 call uartRs485SendByte + 314:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 1502 .LM151: + 1503 05b4 9B81 ldd r25,Y+3 + 1504 05b6 892F mov r24,r25 + 1505 05b8 0E94 0000 call uartRs485SendByte + 315:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 1507 .LM152: + 1508 05bc 8F2D mov r24,r15 + 1509 05be 0E94 0000 call uartRs485SendByte + 316:../../../../Lib/Rs485_prot.c **** + 317:../../../../Lib/Rs485_prot.c **** + 318:../../../../Lib/Rs485_prot.c **** // Odbieranie odpowiedzi po wysÅ‚aniu polecenia restartu + 319:../../../../Lib/Rs485_prot.c **** //Odbieranie SYNC lub C + 320:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 100) != pdTRUE) + 1511 .LM153: + 1512 05c2 64E6 ldi r22,lo8(100) + 1513 05c4 CE01 movw r24,r28 + 1514 05c6 0296 adiw r24,2 + 1515 05c8 0E94 0000 call rs485Receive + 1516 05cc 8130 cpi r24,lo8(1) + 1517 05ce 01F0 breq .L110 + 321:../../../../Lib/Rs485_prot.c **** { + 322:../../../../Lib/Rs485_prot.c **** blad = 1; // Timeout + 323:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 1519 .LM154: + 1520 05d0 0115 cp r16,__zero_reg__ + 1521 05d2 1105 cpc r17,__zero_reg__ + 1522 05d4 01F0 breq .L111 + 324:../../../../Lib/Rs485_prot.c **** fprintf_P(debugStr, PSTR("rFLASH timeout\r\n")); + 1524 .LM155: + 1525 05d6 80E0 ldi r24,lo8(__c.3526) + 1526 05d8 90E0 ldi r25,hi8(__c.3526) + 1527 05da 9F93 push r25 + 1528 05dc 8F93 push r24 + 1529 05de 1F93 push r17 + 1530 05e0 0F93 push r16 + 1531 05e2 0E94 0000 call fprintf_P + 1532 05e6 0F90 pop __tmp_reg__ + 1533 05e8 0F90 pop __tmp_reg__ + 1534 05ea 0F90 pop __tmp_reg__ + 1535 05ec 0F90 pop __tmp_reg__ + 1536 05ee 00C0 rjmp .L111 + 1537 .L110: + 301:../../../../Lib/Rs485_prot.c **** uint8_t data; + 1539 .LM156: + 1540 05f0 F12C mov r15,__zero_reg__ + 1541 05f2 00C0 rjmp .L74 + 1542 .L111: + 322:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 1544 .LM157: + 1545 05f4 FF24 clr r15 + 1546 05f6 F394 inc r15 + 1547 .L74: + 325:../../../../Lib/Rs485_prot.c **** } + 326:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, data); + 1549 .LM158: + 1550 05f8 6A81 ldd r22,Y+2 + 1551 05fa 80E0 ldi r24,0 + 1552 05fc 90E0 ldi r25,0 + 1553 05fe 0E94 0000 call _crc_xmodem_update + 1554 0602 5C01 movw r10,r24 + 1555 0604 9A81 ldd r25,Y+2 + 327:../../../../Lib/Rs485_prot.c **** + 328:../../../../Lib/Rs485_prot.c **** if ((blad == 0) && (data == 'C')) + 1557 .LM159: + 1558 0606 F110 cpse r15,__zero_reg__ + 1559 0608 00C0 rjmp .L75 + 1561 .LM160: + 1562 060a 9334 cpi r25,lo8(67) + 1563 060c 01F4 brne .L75 + 329:../../../../Lib/Rs485_prot.c **** { + 330:../../../../Lib/Rs485_prot.c **** blad = 253; //Na urzÄ…dzeniu jest wgrany tylko bootloader + 331:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 1565 .LM161: + 1566 060e 0115 cp r16,__zero_reg__ + 1567 0610 1105 cpc r17,__zero_reg__ + 1568 0612 01F4 brne .+2 + 1569 0614 00C0 rjmp .L107 + 332:../../../../Lib/Rs485_prot.c **** fprintf_P(debugStr, PSTR("na urzadzeniu wgrany jest tylko bootloader\r\n")); + 1571 .LM162: + 1572 0616 80E0 ldi r24,lo8(__c.3528) + 1573 0618 90E0 ldi r25,hi8(__c.3528) + 1574 061a 9F93 push r25 + 1575 061c 8F93 push r24 + 1576 061e 1F93 push r17 + 1577 0620 0F93 push r16 + 1578 0622 0E94 0000 call fprintf_P + 1579 0626 0F90 pop __tmp_reg__ + 1580 0628 0F90 pop __tmp_reg__ + 1581 062a 0F90 pop __tmp_reg__ + 1582 062c 0F90 pop __tmp_reg__ + 1583 062e 00C0 rjmp .L107 + 1584 .L75: + 333:../../../../Lib/Rs485_prot.c **** } + 334:../../../../Lib/Rs485_prot.c **** else + 335:../../../../Lib/Rs485_prot.c **** { + 336:../../../../Lib/Rs485_prot.c **** if (data != SYNC) + 1586 .LM163: + 1587 0630 9A35 cpi r25,lo8(90) + 1588 0632 01F0 breq .+2 + 1589 0634 00C0 rjmp .L85 + 337:../../../../Lib/Rs485_prot.c **** blad = 2; + 338:../../../../Lib/Rs485_prot.c **** } + 339:../../../../Lib/Rs485_prot.c **** + 340:../../../../Lib/Rs485_prot.c **** //Odbieranie odpowiedzi programu. Program zresetuje siÄ™ by uruchomić bootloadera. + 341:../../../../Lib/Rs485_prot.c **** //Odbieranie adresu + 342:../../../../Lib/Rs485_prot.c **** if (blad == 0) //Odbieranie adresu (powinno być 0) + 1591 .LM164: + 1592 0636 F110 cpse r15,__zero_reg__ + 1593 0638 00C0 rjmp .L85 + 343:../../../../Lib/Rs485_prot.c **** { + 344:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) != pdTRUE) + 1595 .LM165: + 1596 063a 61E0 ldi r22,lo8(1) + 1597 063c CE01 movw r24,r28 + 1598 063e 0296 adiw r24,2 + 1599 0640 0E94 0000 call rs485Receive + 1600 0644 8130 cpi r24,lo8(1) + 1601 0646 01F4 brne .L115 + 345:../../../../Lib/Rs485_prot.c **** blad = 3; + 346:../../../../Lib/Rs485_prot.c **** else + 347:../../../../Lib/Rs485_prot.c **** { + 348:../../../../Lib/Rs485_prot.c **** if (data != 0) + 1603 .LM166: + 1604 0648 8A81 ldd r24,Y+2 + 1605 064a 8823 tst r24 + 1606 064c 01F0 breq .L78 + 349:../../../../Lib/Rs485_prot.c **** blad = 4; + 1608 .LM167: + 1609 064e B4E0 ldi r27,lo8(4) + 1610 0650 FB2E mov r15,r27 + 1611 0652 00C0 rjmp .L78 + 1612 .L115: + 345:../../../../Lib/Rs485_prot.c **** blad = 3; + 1614 .LM168: + 1615 0654 A3E0 ldi r26,lo8(3) + 1616 0656 FA2E mov r15,r26 + 1617 .L78: + 350:../../../../Lib/Rs485_prot.c **** } + 351:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1619 .LM169: + 1620 0658 6A81 ldd r22,Y+2 + 1621 065a C501 movw r24,r10 + 1622 065c 0E94 0000 call _crc_xmodem_update + 1623 0660 5C01 movw r10,r24 + 352:../../../../Lib/Rs485_prot.c **** } + 353:../../../../Lib/Rs485_prot.c **** + 354:../../../../Lib/Rs485_prot.c **** //Odbieranie kodu rozkazu + 355:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 1625 .LM170: + 1626 0662 F110 cpse r15,__zero_reg__ + 1627 0664 00C0 rjmp .L85 + 356:../../../../Lib/Rs485_prot.c **** { + 357:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) != pdTRUE) + 1629 .LM171: + 1630 0666 61E0 ldi r22,lo8(1) + 1631 0668 CE01 movw r24,r28 + 1632 066a 0296 adiw r24,2 + 1633 066c 0E94 0000 call rs485Receive + 1634 0670 8130 cpi r24,lo8(1) + 1635 0672 01F4 brne .L116 + 358:../../../../Lib/Rs485_prot.c **** blad = 5; + 359:../../../../Lib/Rs485_prot.c **** else + 360:../../../../Lib/Rs485_prot.c **** { + 361:../../../../Lib/Rs485_prot.c **** if (data != rFLASH) + 1637 .LM172: + 1638 0674 8A81 ldd r24,Y+2 + 1639 0676 8138 cpi r24,lo8(-127) + 1640 0678 01F0 breq .L80 + 362:../../../../Lib/Rs485_prot.c **** blad = 6; + 1642 .LM173: + 1643 067a F6E0 ldi r31,lo8(6) + 1644 067c FF2E mov r15,r31 + 1645 067e 00C0 rjmp .L80 + 1646 .L116: + 358:../../../../Lib/Rs485_prot.c **** blad = 5; + 1648 .LM174: + 1649 0680 E5E0 ldi r30,lo8(5) + 1650 0682 FE2E mov r15,r30 + 1651 .L80: + 363:../../../../Lib/Rs485_prot.c **** } + 364:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1653 .LM175: + 1654 0684 6A81 ldd r22,Y+2 + 1655 0686 C501 movw r24,r10 + 1656 0688 0E94 0000 call _crc_xmodem_update + 1657 068c 5C01 movw r10,r24 + 365:../../../../Lib/Rs485_prot.c **** } + 366:../../../../Lib/Rs485_prot.c **** + 367:../../../../Lib/Rs485_prot.c **** //Odbieranie dÅ‚ugoÅ›ci danych w rozkazie + 368:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 1659 .LM176: + 1660 068e F110 cpse r15,__zero_reg__ + 1661 0690 00C0 rjmp .L85 + 369:../../../../Lib/Rs485_prot.c **** { + 370:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) != pdTRUE) + 1663 .LM177: + 1664 0692 61E0 ldi r22,lo8(1) + 1665 0694 CE01 movw r24,r28 + 1666 0696 0296 adiw r24,2 + 1667 0698 0E94 0000 call rs485Receive + 1668 069c 8130 cpi r24,lo8(1) + 1669 069e 01F4 brne .L117 + 371:../../../../Lib/Rs485_prot.c **** blad = 7; + 372:../../../../Lib/Rs485_prot.c **** else + 373:../../../../Lib/Rs485_prot.c **** { + 374:../../../../Lib/Rs485_prot.c **** if (data != 1) + 1671 .LM178: + 1672 06a0 8A81 ldd r24,Y+2 + 1673 06a2 8130 cpi r24,lo8(1) + 1674 06a4 01F0 breq .L82 + 375:../../../../Lib/Rs485_prot.c **** blad = 8; + 1676 .LM179: + 1677 06a6 78E0 ldi r23,lo8(8) + 1678 06a8 F72E mov r15,r23 + 1679 06aa 00C0 rjmp .L82 + 1680 .L117: + 371:../../../../Lib/Rs485_prot.c **** blad = 7; + 1682 .LM180: + 1683 06ac 67E0 ldi r22,lo8(7) + 1684 06ae F62E mov r15,r22 + 1685 .L82: + 376:../../../../Lib/Rs485_prot.c **** } + 377:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1687 .LM181: + 1688 06b0 6A81 ldd r22,Y+2 + 1689 06b2 C501 movw r24,r10 + 1690 06b4 0E94 0000 call _crc_xmodem_update + 1691 06b8 5C01 movw r10,r24 + 378:../../../../Lib/Rs485_prot.c **** } + 379:../../../../Lib/Rs485_prot.c **** + 380:../../../../Lib/Rs485_prot.c **** //Odbieranie danych w rozkazie + 381:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 1693 .LM182: + 1694 06ba F110 cpse r15,__zero_reg__ + 1695 06bc 00C0 rjmp .L85 + 382:../../../../Lib/Rs485_prot.c **** { + 383:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 1) != pdTRUE) + 1697 .LM183: + 1698 06be 61E0 ldi r22,lo8(1) + 1699 06c0 CE01 movw r24,r28 + 1700 06c2 0296 adiw r24,2 + 1701 06c4 0E94 0000 call rs485Receive + 1702 06c8 8130 cpi r24,lo8(1) + 1703 06ca 01F4 brne .L118 + 384:../../../../Lib/Rs485_prot.c **** blad = 9; + 385:../../../../Lib/Rs485_prot.c **** else + 386:../../../../Lib/Rs485_prot.c **** { + 387:../../../../Lib/Rs485_prot.c **** if (data != devAddr) + 1705 .LM184: + 1706 06cc 8A81 ldd r24,Y+2 + 1707 06ce 8E15 cp r24,r14 + 1708 06d0 01F0 breq .L84 + 388:../../../../Lib/Rs485_prot.c **** blad = 10; + 1710 .LM185: + 1711 06d2 5AE0 ldi r21,lo8(10) + 1712 06d4 F52E mov r15,r21 + 1713 06d6 00C0 rjmp .L84 + 1714 .L118: + 384:../../../../Lib/Rs485_prot.c **** blad = 9; + 1716 .LM186: + 1717 06d8 49E0 ldi r20,lo8(9) + 1718 06da F42E mov r15,r20 + 1719 .L84: + 389:../../../../Lib/Rs485_prot.c **** } + 390:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1721 .LM187: + 1722 06dc 6A81 ldd r22,Y+2 + 1723 06de C501 movw r24,r10 + 1724 06e0 0E94 0000 call _crc_xmodem_update + 1725 06e4 B82E mov r11,r24 + 1726 06e6 A92E mov r10,r25 + 391:../../../../Lib/Rs485_prot.c **** } + 392:../../../../Lib/Rs485_prot.c **** + 393:../../../../Lib/Rs485_prot.c **** //Odbieranie CRC Hi + 394:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 1728 .LM188: + 1729 06e8 F110 cpse r15,__zero_reg__ + 1730 06ea 00C0 rjmp .L85 + 395:../../../../Lib/Rs485_prot.c **** { + 396:../../../../Lib/Rs485_prot.c **** if (rs485Receive(&nrBloku, 1) != pdTRUE) + 1732 .LM189: + 1733 06ec 61E0 ldi r22,lo8(1) + 1734 06ee CE01 movw r24,r28 + 1735 06f0 0196 adiw r24,1 + 1736 06f2 0E94 0000 call rs485Receive + 1737 06f6 8130 cpi r24,lo8(1) + 1738 06f8 01F4 brne .L85 + 397:../../../../Lib/Rs485_prot.c **** blad = 11; + 398:../../../../Lib/Rs485_prot.c **** else + 399:../../../../Lib/Rs485_prot.c **** { + 400:../../../../Lib/Rs485_prot.c **** if ((uint8_t)(crc>>8) != nrBloku) + 1740 .LM190: + 1741 06fa 8981 ldd r24,Y+1 + 1742 06fc 8A11 cpse r24,r10 + 1743 06fe 00C0 rjmp .L85 + 401:../../../../Lib/Rs485_prot.c **** blad = 12; + 402:../../../../Lib/Rs485_prot.c **** } + 403:../../../../Lib/Rs485_prot.c **** } + 404:../../../../Lib/Rs485_prot.c **** + 405:../../../../Lib/Rs485_prot.c **** //Odbieranie CRC Lo + 406:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 407:../../../../Lib/Rs485_prot.c **** { + 408:../../../../Lib/Rs485_prot.c **** if (rs485Receive(&nrBloku, 1) != pdTRUE) + 1745 .LM191: + 1746 0700 61E0 ldi r22,lo8(1) + 1747 0702 CE01 movw r24,r28 + 1748 0704 0196 adiw r24,1 + 1749 0706 0E94 0000 call rs485Receive + 1750 070a F82E mov r15,r24 + 1751 070c A1E0 ldi r26,lo8(1) + 1752 070e 8A13 cpse r24,r26 + 1753 0710 00C0 rjmp .L85 + 409:../../../../Lib/Rs485_prot.c **** blad = 13; + 410:../../../../Lib/Rs485_prot.c **** else + 411:../../../../Lib/Rs485_prot.c **** { + 412:../../../../Lib/Rs485_prot.c **** if ((uint8_t)(crc & 0xFF) != nrBloku) + 1755 .LM192: + 1756 0712 8981 ldd r24,Y+1 + 1757 0714 8B15 cp r24,r11 + 1758 0716 01F0 breq .L87 + 1759 .L85: + 413:../../../../Lib/Rs485_prot.c **** blad = 14; + 414:../../../../Lib/Rs485_prot.c **** } + 415:../../../../Lib/Rs485_prot.c **** } + 416:../../../../Lib/Rs485_prot.c **** + 417:../../../../Lib/Rs485_prot.c **** if ((blad != 0) && (blad != 253)) + 418:../../../../Lib/Rs485_prot.c **** { + 419:../../../../Lib/Rs485_prot.c **** releaseRs485(); + 1761 .LM193: + 1762 0718 0E94 0000 call releaseRs485 + 420:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 1764 .LM194: + 1765 071c 0E94 0000 call flushRs485RecBuffer + 421:../../../../Lib/Rs485_prot.c **** return 1; + 1767 .LM195: + 1768 0720 FF24 clr r15 + 1769 0722 F394 inc r15 + 1770 0724 00C0 rjmp .L130 + 1771 .L87: + 422:../../../../Lib/Rs485_prot.c **** } + 423:../../../../Lib/Rs485_prot.c **** + 424:../../../../Lib/Rs485_prot.c **** // WysyÅ‚anie polecenia do bootloadera + 425:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 426:../../../../Lib/Rs485_prot.c **** { + 427:../../../../Lib/Rs485_prot.c **** vTaskDelay(100); + 1773 .LM196: + 1774 0726 84E6 ldi r24,lo8(100) + 1775 0728 90E0 ldi r25,0 + 1776 072a 0E94 0000 call vTaskDelay + 428:../../../../Lib/Rs485_prot.c **** + 429:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(0, SYNC); uartRs485SendByte(SYNC); + 1778 .LM197: + 1779 072e 6AE5 ldi r22,lo8(90) + 1780 0730 80E0 ldi r24,0 + 1781 0732 90E0 ldi r25,0 + 1782 0734 0E94 0000 call _crc_xmodem_update + 1783 0738 5C01 movw r10,r24 + 1784 073a 8AE5 ldi r24,lo8(90) + 1785 073c 0E94 0000 call uartRs485SendByte + 430:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + 1787 .LM198: + 1788 0740 6E2D mov r22,r14 + 1789 0742 C501 movw r24,r10 + 1790 0744 0E94 0000 call _crc_xmodem_update + 1791 0748 5C01 movw r10,r24 + 1792 074a 8E2D mov r24,r14 + 1793 074c 0E94 0000 call uartRs485SendByte + 431:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rFLASH); uartRs485SendByte(rFLASH); + 1795 .LM199: + 1796 0750 61E8 ldi r22,lo8(-127) + 1797 0752 C501 movw r24,r10 + 1798 0754 0E94 0000 call _crc_xmodem_update + 1799 0758 5C01 movw r10,r24 + 1800 075a 81E8 ldi r24,lo8(-127) + 1801 075c 0E94 0000 call uartRs485SendByte + 432:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + 1803 .LM200: + 1804 0760 61E0 ldi r22,lo8(1) + 1805 0762 C501 movw r24,r10 + 1806 0764 0E94 0000 call _crc_xmodem_update + 1807 0768 5C01 movw r10,r24 + 1808 076a 81E0 ldi r24,lo8(1) + 1809 076c 0E94 0000 call uartRs485SendByte + 433:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, devAddr); uartRs485SendByte(devAddr); + 1811 .LM201: + 1812 0770 6E2D mov r22,r14 + 1813 0772 C501 movw r24,r10 + 1814 0774 0E94 0000 call _crc_xmodem_update + 1815 0778 B82E mov r11,r24 + 1816 077a 8E2D mov r24,r14 + 1817 077c 9B83 std Y+3,r25 + 1818 077e 0E94 0000 call uartRs485SendByte + 434:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 1820 .LM202: + 1821 0782 9B81 ldd r25,Y+3 + 1822 0784 892F mov r24,r25 + 1823 0786 0E94 0000 call uartRs485SendByte + 435:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 1825 .LM203: + 1826 078a 8B2D mov r24,r11 + 1827 078c 0E94 0000 call uartRs485SendByte + 436:../../../../Lib/Rs485_prot.c **** + 437:../../../../Lib/Rs485_prot.c **** //Odbieranie odpowiedzi od Bootloadera + 438:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 150) != pdTRUE) + 1829 .LM204: + 1830 0790 66E9 ldi r22,lo8(-106) + 1831 0792 CE01 movw r24,r28 + 1832 0794 0296 adiw r24,2 + 1833 0796 0E94 0000 call rs485Receive + 439:../../../../Lib/Rs485_prot.c **** blad = 15; + 440:../../../../Lib/Rs485_prot.c **** + 441:../../../../Lib/Rs485_prot.c **** if (data != 'C') + 1835 .LM205: + 1836 079a 8A81 ldd r24,Y+2 + 1837 079c 8334 cpi r24,lo8(67) + 1838 079e 01F0 breq .+2 + 1839 07a0 00C0 rjmp .L109 + 1840 .L107: + 442:../../../../Lib/Rs485_prot.c **** blad = 16; + 443:../../../../Lib/Rs485_prot.c **** else + 444:../../../../Lib/Rs485_prot.c **** blad = 0; + 445:../../../../Lib/Rs485_prot.c **** } + 446:../../../../Lib/Rs485_prot.c **** else + 447:../../../../Lib/Rs485_prot.c **** blad = 0; + 448:../../../../Lib/Rs485_prot.c **** + 449:../../../../Lib/Rs485_prot.c **** + 450:../../../../Lib/Rs485_prot.c **** if (blad != 0) + 451:../../../../Lib/Rs485_prot.c **** { + 452:../../../../Lib/Rs485_prot.c **** releaseRs485(); + 453:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 454:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 455:../../../../Lib/Rs485_prot.c **** fprintf_P(debugStr, PSTR("bootloader nie rozpoczal odbioru danych\r\n")); + 456:../../../../Lib/Rs485_prot.c **** return 1; + 457:../../../../Lib/Rs485_prot.c **** } + 458:../../../../Lib/Rs485_prot.c **** + 459:../../../../Lib/Rs485_prot.c **** uint8_t liczbaBlokow = file->wpis->rozmiarHi * 2; + 1842 .LM206: + 1843 07a2 D601 movw r26,r12 + 1844 07a4 1496 adiw r26,4 + 1845 07a6 ED91 ld r30,X+ + 1846 07a8 FC91 ld r31,X + 1847 07aa 1597 sbiw r26,4+1 + 1848 07ac E280 ldd r14,Z+2 + 1849 07ae EE0C lsl r14 + 460:../../../../Lib/Rs485_prot.c **** if (file->wpis->rozmiarLo == 128) + 1851 .LM207: + 1852 07b0 8181 ldd r24,Z+1 + 1853 07b2 8038 cpi r24,lo8(-128) + 1854 07b4 01F4 brne .L89 + 461:../../../../Lib/Rs485_prot.c **** liczbaBlokow++; + 1856 .LM208: + 1857 07b6 E394 inc r14 + 1858 .L89: + 462:../../../../Lib/Rs485_prot.c **** + 463:../../../../Lib/Rs485_prot.c **** nrBloku = 1; + 1860 .LM209: + 1861 07b8 81E0 ldi r24,lo8(1) + 1862 07ba 8983 std Y+1,r24 + 464:../../../../Lib/Rs485_prot.c **** lRetransmisji = 0; + 1864 .LM210: + 1865 07bc B12C mov r11,__zero_reg__ + 465:../../../../Lib/Rs485_prot.c **** + 466:../../../../Lib/Rs485_prot.c **** while (nrBloku <= liczbaBlokow) + 1867 .LM211: + 1868 07be F12C mov r15,__zero_reg__ + 467:../../../../Lib/Rs485_prot.c **** { + 468:../../../../Lib/Rs485_prot.c **** crc = 0; + 469:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SOH); + 470:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(nrBloku); + 471:../../../../Lib/Rs485_prot.c **** data = (uint8_t)(~nrBloku); + 472:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(data); + 473:../../../../Lib/Rs485_prot.c **** + 474:../../../../Lib/Rs485_prot.c **** for (blad = 0; blad < 128; blad++) //wysyÅ‚anie danych. Zmianna Blad jest tymczasowa + 475:../../../../Lib/Rs485_prot.c **** { + 476:../../../../Lib/Rs485_prot.c **** if (ramDyskCzytajBajtZPliku(file, &data) != 0) + 477:../../../../Lib/Rs485_prot.c **** data = 0; + 478:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 479:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(data); + 480:../../../../Lib/Rs485_prot.c **** } + 481:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 482:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 483:../../../../Lib/Rs485_prot.c **** + 484:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 100) != pdTRUE) + 485:../../../../Lib/Rs485_prot.c **** { + 486:../../../../Lib/Rs485_prot.c **** blad = 250; + 487:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 488:../../../../Lib/Rs485_prot.c **** fputc('#', debugStr); + 489:../../../../Lib/Rs485_prot.c **** data = 0; + 490:../../../../Lib/Rs485_prot.c **** } + 491:../../../../Lib/Rs485_prot.c **** + 492:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 493:../../../../Lib/Rs485_prot.c **** + 494:../../../../Lib/Rs485_prot.c **** if (data == ACK) + 495:../../../../Lib/Rs485_prot.c **** { + 496:../../../../Lib/Rs485_prot.c **** nrBloku ++; + 497:../../../../Lib/Rs485_prot.c **** lRetransmisji = 0; + 498:../../../../Lib/Rs485_prot.c **** blad = 0; + 499:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 500:../../../../Lib/Rs485_prot.c **** { + 501:../../../../Lib/Rs485_prot.c **** fputc('.', debugStr); + 502:../../../../Lib/Rs485_prot.c **** if ((nrBloku & 0x0F) == 0) + 503:../../../../Lib/Rs485_prot.c **** { + 504:../../../../Lib/Rs485_prot.c **** fputc('\r', debugStr); + 505:../../../../Lib/Rs485_prot.c **** fputc('\n', debugStr); + 506:../../../../Lib/Rs485_prot.c **** } + 507:../../../../Lib/Rs485_prot.c **** } + 508:../../../../Lib/Rs485_prot.c **** continue; + 509:../../../../Lib/Rs485_prot.c **** } + 510:../../../../Lib/Rs485_prot.c **** + 511:../../../../Lib/Rs485_prot.c **** if (data == CAN) + 512:../../../../Lib/Rs485_prot.c **** { + 513:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 514:../../../../Lib/Rs485_prot.c **** fputc('C', debugStr); + 515:../../../../Lib/Rs485_prot.c **** blad = 249; + 516:../../../../Lib/Rs485_prot.c **** break; + 517:../../../../Lib/Rs485_prot.c **** } + 518:../../../../Lib/Rs485_prot.c **** + 519:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 520:../../../../Lib/Rs485_prot.c **** { + 521:../../../../Lib/Rs485_prot.c **** if (data == NAK) + 522:../../../../Lib/Rs485_prot.c **** fputc('N', debugStr); + 523:../../../../Lib/Rs485_prot.c **** if (data != 0) + 524:../../../../Lib/Rs485_prot.c **** fprintf(debugStr, "data 0x%x ", data); + 1870 .LM212: + 1871 07c0 30E0 ldi r19,lo8(.LC0) + 1872 07c2 832E mov r8,r19 + 1873 07c4 30E0 ldi r19,hi8(.LC0) + 1874 07c6 932E mov r9,r19 + 1875 .L90: + 466:../../../../Lib/Rs485_prot.c **** { + 1877 .LM213: + 1878 07c8 8981 ldd r24,Y+1 + 1879 07ca E816 cp r14,r24 + 1880 07cc 00F4 brsh .+2 + 1881 07ce 00C0 rjmp .L152 + 469:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(nrBloku); + 1883 .LM214: + 1884 07d0 81E0 ldi r24,lo8(1) + 1885 07d2 0E94 0000 call uartRs485SendByte + 470:../../../../Lib/Rs485_prot.c **** data = (uint8_t)(~nrBloku); + 1887 .LM215: + 1888 07d6 8981 ldd r24,Y+1 + 1889 07d8 0E94 0000 call uartRs485SendByte + 471:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(data); + 1891 .LM216: + 1892 07dc 8981 ldd r24,Y+1 + 1893 07de 8095 com r24 + 1894 07e0 8A83 std Y+2,r24 + 472:../../../../Lib/Rs485_prot.c **** + 1896 .LM217: + 1897 07e2 0E94 0000 call uartRs485SendByte + 474:../../../../Lib/Rs485_prot.c **** { + 1899 .LM218: + 1900 07e6 F12C mov r15,__zero_reg__ + 468:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SOH); + 1902 .LM219: + 1903 07e8 A12C mov r10,__zero_reg__ + 1904 07ea 712C mov r7,__zero_reg__ + 1905 .L92: + 476:../../../../Lib/Rs485_prot.c **** data = 0; + 1907 .LM220: + 1908 07ec BE01 movw r22,r28 + 1909 07ee 6E5F subi r22,-2 + 1910 07f0 7F4F sbci r23,-1 + 1911 07f2 C601 movw r24,r12 + 1912 07f4 0E94 0000 call ramDyskCzytajBajtZPliku + 1913 07f8 8111 cpse r24,__zero_reg__ + 477:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, data); + 1915 .LM221: + 1916 07fa 1A82 std Y+2,__zero_reg__ + 1917 .L91: + 478:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(data); + 1919 .LM222: + 1920 07fc 6A81 ldd r22,Y+2 + 1921 07fe 8A2D mov r24,r10 + 1922 0800 972D mov r25,r7 + 1923 0802 0E94 0000 call _crc_xmodem_update + 1924 0806 A82E mov r10,r24 + 1925 0808 792E mov r7,r25 + 479:../../../../Lib/Rs485_prot.c **** } + 1927 .LM223: + 1928 080a 8A81 ldd r24,Y+2 + 1929 080c 0E94 0000 call uartRs485SendByte + 474:../../../../Lib/Rs485_prot.c **** { + 1931 .LM224: + 1932 0810 F394 inc r15 + 1933 0812 B0E8 ldi r27,lo8(-128) + 1934 0814 FB12 cpse r15,r27 + 1935 0816 00C0 rjmp .L92 + 481:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 1937 .LM225: + 1938 0818 872D mov r24,r7 + 1939 081a 0E94 0000 call uartRs485SendByte + 482:../../../../Lib/Rs485_prot.c **** + 1941 .LM226: + 1942 081e 8A2D mov r24,r10 + 1943 0820 0E94 0000 call uartRs485SendByte + 484:../../../../Lib/Rs485_prot.c **** { + 1945 .LM227: + 1946 0824 64E6 ldi r22,lo8(100) + 1947 0826 CE01 movw r24,r28 + 1948 0828 0296 adiw r24,2 + 1949 082a 0E94 0000 call rs485Receive + 1950 082e 8130 cpi r24,lo8(1) + 1951 0830 01F0 breq .L93 + 487:../../../../Lib/Rs485_prot.c **** fputc('#', debugStr); + 1953 .LM228: + 1954 0832 0115 cp r16,__zero_reg__ + 1955 0834 1105 cpc r17,__zero_reg__ + 1956 0836 01F0 breq .L94 + 488:../../../../Lib/Rs485_prot.c **** data = 0; + 1958 .LM229: + 1959 0838 B801 movw r22,r16 + 1960 083a 83E2 ldi r24,lo8(35) + 1961 083c 90E0 ldi r25,0 + 1962 083e 0E94 0000 call fputc + 1963 .L94: + 489:../../../../Lib/Rs485_prot.c **** } + 1965 .LM230: + 1966 0842 1A82 std Y+2,__zero_reg__ + 486:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 1968 .LM231: + 1969 0844 2AEF ldi r18,lo8(-6) + 1970 0846 F22E mov r15,r18 + 1971 .L93: + 492:../../../../Lib/Rs485_prot.c **** + 1973 .LM232: + 1974 0848 0E94 0000 call flushRs485RecBuffer + 494:../../../../Lib/Rs485_prot.c **** { + 1976 .LM233: + 1977 084c 8A81 ldd r24,Y+2 + 1978 084e 8630 cpi r24,lo8(6) + 1979 0850 01F4 brne .L95 + 496:../../../../Lib/Rs485_prot.c **** lRetransmisji = 0; + 1981 .LM234: + 1982 0852 8981 ldd r24,Y+1 + 1983 0854 8F5F subi r24,lo8(-(1)) + 1984 0856 8983 std Y+1,r24 + 499:../../../../Lib/Rs485_prot.c **** { + 1986 .LM235: + 1987 0858 0115 cp r16,__zero_reg__ + 1988 085a 1105 cpc r17,__zero_reg__ + 1989 085c 01F0 breq .L151 + 501:../../../../Lib/Rs485_prot.c **** if ((nrBloku & 0x0F) == 0) + 1991 .LM236: + 1992 085e B801 movw r22,r16 + 1993 0860 8EE2 ldi r24,lo8(46) + 1994 0862 90E0 ldi r25,0 + 1995 0864 0E94 0000 call fputc + 502:../../../../Lib/Rs485_prot.c **** { + 1997 .LM237: + 1998 0868 8981 ldd r24,Y+1 + 1999 086a 8F70 andi r24,lo8(15) + 2000 086c 01F4 brne .L151 + 504:../../../../Lib/Rs485_prot.c **** fputc('\n', debugStr); + 2002 .LM238: + 2003 086e B801 movw r22,r16 + 2004 0870 8DE0 ldi r24,lo8(13) + 2005 0872 90E0 ldi r25,0 + 2006 0874 0E94 0000 call fputc + 505:../../../../Lib/Rs485_prot.c **** } + 2008 .LM239: + 2009 0878 B801 movw r22,r16 + 2010 087a 8AE0 ldi r24,lo8(10) + 2011 087c 90E0 ldi r25,0 + 2012 087e 0E94 0000 call fputc + 2013 .L151: + 497:../../../../Lib/Rs485_prot.c **** blad = 0; + 2015 .LM240: + 2016 0882 B12C mov r11,__zero_reg__ + 498:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 2018 .LM241: + 2019 0884 F12C mov r15,__zero_reg__ + 2020 0886 00C0 rjmp .L90 + 2021 .L95: + 511:../../../../Lib/Rs485_prot.c **** { + 2023 .LM242: + 2024 0888 8831 cpi r24,lo8(24) + 2025 088a 01F4 brne .L99 + 513:../../../../Lib/Rs485_prot.c **** fputc('C', debugStr); + 2027 .LM243: + 2028 088c 0115 cp r16,__zero_reg__ + 2029 088e 1105 cpc r17,__zero_reg__ + 2030 0890 01F4 brne .+2 + 2031 0892 00C0 rjmp .L119 + 514:../../../../Lib/Rs485_prot.c **** blad = 249; + 2033 .LM244: + 2034 0894 B801 movw r22,r16 + 2035 0896 83E4 ldi r24,lo8(67) + 2036 0898 90E0 ldi r25,0 + 2037 089a 0E94 0000 call fputc + 2038 089e 00C0 rjmp .L119 + 2039 .L99: + 519:../../../../Lib/Rs485_prot.c **** { + 2041 .LM245: + 2042 08a0 0115 cp r16,__zero_reg__ + 2043 08a2 1105 cpc r17,__zero_reg__ + 2044 08a4 01F0 breq .L102 + 521:../../../../Lib/Rs485_prot.c **** fputc('N', debugStr); + 2046 .LM246: + 2047 08a6 8531 cpi r24,lo8(21) + 2048 08a8 01F4 brne .L103 + 522:../../../../Lib/Rs485_prot.c **** if (data != 0) + 2050 .LM247: + 2051 08aa B801 movw r22,r16 + 2052 08ac 8EE4 ldi r24,lo8(78) + 2053 08ae 90E0 ldi r25,0 + 2054 08b0 0E94 0000 call fputc + 2055 .L103: + 523:../../../../Lib/Rs485_prot.c **** fprintf(debugStr, "data 0x%x ", data); + 2057 .LM248: + 2058 08b4 8A81 ldd r24,Y+2 + 2059 08b6 8823 tst r24 + 2060 08b8 01F0 breq .L102 + 2062 .LM249: + 2063 08ba 1F92 push __zero_reg__ + 2064 08bc 8F93 push r24 + 2065 08be 9F92 push r9 + 2066 08c0 8F92 push r8 + 2067 08c2 1F93 push r17 + 2068 08c4 0F93 push r16 + 2069 08c6 0E94 0000 call fprintf + 2070 08ca 0F90 pop __tmp_reg__ + 2071 08cc 0F90 pop __tmp_reg__ + 2072 08ce 0F90 pop __tmp_reg__ + 2073 08d0 0F90 pop __tmp_reg__ + 2074 08d2 0F90 pop __tmp_reg__ + 2075 08d4 0F90 pop __tmp_reg__ + 2076 .L102: + 525:../../../../Lib/Rs485_prot.c **** } + 526:../../../../Lib/Rs485_prot.c **** + 527:../../../../Lib/Rs485_prot.c **** lRetransmisji ++; + 2078 .LM250: + 2079 08d6 B394 inc r11 + 528:../../../../Lib/Rs485_prot.c **** + 529:../../../../Lib/Rs485_prot.c **** if (lRetransmisji == 3) + 2081 .LM251: + 2082 08d8 83E0 ldi r24,lo8(3) + 2083 08da B812 cpse r11,r24 + 2084 08dc 00C0 rjmp .L90 + 530:../../../../Lib/Rs485_prot.c **** { + 531:../../../../Lib/Rs485_prot.c **** blad = 248; + 2086 .LM252: + 2087 08de 88EF ldi r24,lo8(-8) + 2088 08e0 F82E mov r15,r24 + 2089 08e2 00C0 rjmp .L106 + 2090 .L152: + 532:../../../../Lib/Rs485_prot.c **** break; + 533:../../../../Lib/Rs485_prot.c **** } + 534:../../../../Lib/Rs485_prot.c **** } + 535:../../../../Lib/Rs485_prot.c **** + 536:../../../../Lib/Rs485_prot.c **** if (blad == 0) + 2092 .LM253: + 2093 08e4 F110 cpse r15,__zero_reg__ + 2094 08e6 00C0 rjmp .L106 + 537:../../../../Lib/Rs485_prot.c **** { + 538:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(EOT); + 2096 .LM254: + 2097 08e8 84E0 ldi r24,lo8(4) + 2098 08ea 0E94 0000 call uartRs485SendByte + 539:../../../../Lib/Rs485_prot.c **** if(rs485Receive(&data, 25) == pdTRUE) + 2100 .LM255: + 2101 08ee 69E1 ldi r22,lo8(25) + 2102 08f0 CE01 movw r24,r28 + 2103 08f2 0296 adiw r24,2 + 2104 08f4 0E94 0000 call rs485Receive + 2105 08f8 8130 cpi r24,lo8(1) + 2106 08fa 01F4 brne .L106 + 540:../../../../Lib/Rs485_prot.c **** { + 541:../../../../Lib/Rs485_prot.c **** if (data == ACK) + 2108 .LM256: + 2109 08fc 8A81 ldd r24,Y+2 + 2110 08fe 8630 cpi r24,lo8(6) + 2111 0900 01F4 brne .L106 + 542:../../../../Lib/Rs485_prot.c **** { + 543:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(EOT); + 2113 .LM257: + 2114 0902 84E0 ldi r24,lo8(4) + 2115 0904 0E94 0000 call uartRs485SendByte + 544:../../../../Lib/Rs485_prot.c **** rs485Receive(&data, 25); + 2117 .LM258: + 2118 0908 69E1 ldi r22,lo8(25) + 2119 090a CE01 movw r24,r28 + 2120 090c 0296 adiw r24,2 + 2121 090e 0E94 0000 call rs485Receive + 2122 .L106: + 545:../../../../Lib/Rs485_prot.c **** } + 546:../../../../Lib/Rs485_prot.c **** } + 547:../../../../Lib/Rs485_prot.c **** } + 548:../../../../Lib/Rs485_prot.c **** + 549:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 2124 .LM259: + 2125 0912 0E94 0000 call flushRs485RecBuffer + 550:../../../../Lib/Rs485_prot.c **** releaseRs485(); + 2127 .LM260: + 2128 0916 0E94 0000 call releaseRs485 + 551:../../../../Lib/Rs485_prot.c **** return blad; + 2130 .LM261: + 2131 091a 00C0 rjmp .L130 + 2132 .L109: + 452:../../../../Lib/Rs485_prot.c **** flushRs485RecBuffer(); + 2134 .LM262: + 2135 091c 0E94 0000 call releaseRs485 + 453:../../../../Lib/Rs485_prot.c **** if (debugStr != NULL) + 2137 .LM263: + 2138 0920 0E94 0000 call flushRs485RecBuffer + 454:../../../../Lib/Rs485_prot.c **** fprintf_P(debugStr, PSTR("bootloader nie rozpoczal odbioru danych\r\n")); + 2140 .LM264: + 2141 0924 0115 cp r16,__zero_reg__ + 2142 0926 1105 cpc r17,__zero_reg__ + 2143 0928 01F0 breq .L130 + 455:../../../../Lib/Rs485_prot.c **** return 1; + 2145 .LM265: + 2146 092a 80E0 ldi r24,lo8(__c.3530) + 2147 092c 90E0 ldi r25,hi8(__c.3530) + 2148 092e 9F93 push r25 + 2149 0930 8F93 push r24 + 2150 0932 1F93 push r17 + 2151 0934 0F93 push r16 + 2152 0936 0E94 0000 call fprintf_P + 2153 093a 0F90 pop __tmp_reg__ + 2154 093c 0F90 pop __tmp_reg__ + 2155 093e 0F90 pop __tmp_reg__ + 2156 0940 0F90 pop __tmp_reg__ + 2157 0942 00C0 rjmp .L130 + 2158 .L119: + 515:../../../../Lib/Rs485_prot.c **** break; + 2160 .LM266: + 2161 0944 99EF ldi r25,lo8(-7) + 2162 0946 F92E mov r15,r25 + 2163 0948 00C0 rjmp .L106 + 2164 .L130: + 552:../../../../Lib/Rs485_prot.c **** } + 2166 .LM267: + 2167 094a 8F2D mov r24,r15 + 2168 /* epilogue start */ + 2169 094c 0F90 pop __tmp_reg__ + 2170 094e 0F90 pop __tmp_reg__ + 2171 0950 0F90 pop __tmp_reg__ + 2172 0952 DF91 pop r29 + 2173 0954 CF91 pop r28 + 2174 0956 1F91 pop r17 + 2175 0958 0F91 pop r16 + 2176 095a FF90 pop r15 + 2177 095c EF90 pop r14 + 2178 095e DF90 pop r13 + 2179 0960 CF90 pop r12 + 2180 0962 BF90 pop r11 + 2181 0964 AF90 pop r10 + 2182 0966 9F90 pop r9 + 2183 0968 8F90 pop r8 + 2184 096a 7F90 pop r7 + 2185 096c 0895 ret + 2193 .Lscope11: + 2195 .stabd 78,0,0 + 2200 .global rs485curtainUp + 2202 rs485curtainUp: + 2203 .stabd 46,0,0 + 553:../../../../Lib/Rs485_prot.c **** + 554:../../../../Lib/Rs485_prot.c **** uint8_t rs485curtainUp(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos) + 555:../../../../Lib/Rs485_prot.c **** { + 2205 .LM268: + 2206 .LFBB12: + 2207 096e DF92 push r13 + 2208 0970 EF92 push r14 + 2209 0972 FF92 push r15 + 2210 0974 0F93 push r16 + 2211 0976 1F93 push r17 + 2212 0978 CF93 push r28 + 2213 097a DF93 push r29 + 2214 097c 1F92 push __zero_reg__ + 2215 097e CDB7 in r28,__SP_L__ + 2216 0980 DEB7 in r29,__SP_H__ + 2217 /* prologue: function */ + 2218 /* frame size = 1 */ + 2219 /* stack size = 8 */ + 2220 .L__stack_usage = 8 + 2221 0982 E82E mov r14,r24 + 2222 0984 F62E mov r15,r22 + 2223 0986 D42E mov r13,r20 + 556:../../../../Lib/Rs485_prot.c **** uint16_t crc = 0; + 557:../../../../Lib/Rs485_prot.c **** + 558:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, SYNC); + 2225 .LM269: + 2226 0988 6AE5 ldi r22,lo8(90) + 2227 098a 80E0 ldi r24,0 + 2228 098c 90E0 ldi r25,0 + 2229 098e 0E94 0000 call _crc_xmodem_update + 2230 0992 8C01 movw r16,r24 + 559:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 2232 .LM270: + 2233 0994 8AE5 ldi r24,lo8(90) + 2234 0996 0E94 0000 call uartRs485SendByte + 560:../../../../Lib/Rs485_prot.c **** + 561:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, deviceAddr); + 2236 .LM271: + 2237 099a 6E2D mov r22,r14 + 2238 099c C801 movw r24,r16 + 2239 099e 0E94 0000 call _crc_xmodem_update + 2240 09a2 8C01 movw r16,r24 + 562:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(deviceAddr); + 2242 .LM272: + 2243 09a4 8E2D mov r24,r14 + 2244 09a6 0E94 0000 call uartRs485SendByte + 563:../../../../Lib/Rs485_prot.c **** if (curtainNo == 0) + 2246 .LM273: + 2247 09aa F110 cpse r15,__zero_reg__ + 2248 09ac 00C0 rjmp .L154 + 564:../../../../Lib/Rs485_prot.c **** { + 565:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rPodniesRolete1); + 2250 .LM274: + 2251 09ae 60E2 ldi r22,lo8(32) + 2252 09b0 C801 movw r24,r16 + 2253 09b2 0E94 0000 call _crc_xmodem_update + 2254 09b6 8C01 movw r16,r24 + 566:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rPodniesRolete1); + 2256 .LM275: + 2257 09b8 80E2 ldi r24,lo8(32) + 2258 09ba 00C0 rjmp .L156 + 2259 .L154: + 567:../../../../Lib/Rs485_prot.c **** } + 568:../../../../Lib/Rs485_prot.c **** else + 569:../../../../Lib/Rs485_prot.c **** { + 570:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rPodniesRolete2); + 2261 .LM276: + 2262 09bc 61E2 ldi r22,lo8(33) + 2263 09be C801 movw r24,r16 + 2264 09c0 0E94 0000 call _crc_xmodem_update + 2265 09c4 8C01 movw r16,r24 + 571:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rPodniesRolete2); + 2267 .LM277: + 2268 09c6 81E2 ldi r24,lo8(33) + 2269 .L156: + 2270 09c8 0E94 0000 call uartRs485SendByte + 572:../../../../Lib/Rs485_prot.c **** } + 573:../../../../Lib/Rs485_prot.c **** + 574:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + 2272 .LM278: + 2273 09cc 61E0 ldi r22,lo8(1) + 2274 09ce C801 movw r24,r16 + 2275 09d0 0E94 0000 call _crc_xmodem_update + 2276 09d4 8C01 movw r16,r24 + 2277 09d6 81E0 ldi r24,lo8(1) + 2278 09d8 0E94 0000 call uartRs485SendByte + 575:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, pos); uartRs485SendByte(pos); + 2280 .LM279: + 2281 09dc 6D2D mov r22,r13 + 2282 09de C801 movw r24,r16 + 2283 09e0 0E94 0000 call _crc_xmodem_update + 2284 09e4 182F mov r17,r24 + 2285 09e6 8D2D mov r24,r13 + 2286 09e8 9983 std Y+1,r25 + 2287 09ea 0E94 0000 call uartRs485SendByte + 576:../../../../Lib/Rs485_prot.c **** + 577:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 2289 .LM280: + 2290 09ee 9981 ldd r25,Y+1 + 2291 09f0 892F mov r24,r25 + 2292 09f2 0E94 0000 call uartRs485SendByte + 578:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2294 .LM281: + 2295 09f6 812F mov r24,r17 + 2296 09f8 0E94 0000 call uartRs485SendByte + 579:../../../../Lib/Rs485_prot.c **** + 580:../../../../Lib/Rs485_prot.c **** return 0; + 581:../../../../Lib/Rs485_prot.c **** } + 2298 .LM282: + 2299 09fc 80E0 ldi r24,0 + 2300 /* epilogue start */ + 2301 09fe 0F90 pop __tmp_reg__ + 2302 0a00 DF91 pop r29 + 2303 0a02 CF91 pop r28 + 2304 0a04 1F91 pop r17 + 2305 0a06 0F91 pop r16 + 2306 0a08 FF90 pop r15 + 2307 0a0a EF90 pop r14 + 2308 0a0c DF90 pop r13 + 2309 0a0e 0895 ret + 2311 .Lscope12: + 2313 .stabd 78,0,0 + 2318 .global rs485Led + 2320 rs485Led: + 2321 .stabd 46,0,0 + 582:../../../../Lib/Rs485_prot.c **** + 583:../../../../Lib/Rs485_prot.c **** uint8_t rs485Led(uint8_t deviceAddr, uint8_t ledNo, uint8_t time) + 584:../../../../Lib/Rs485_prot.c **** { + 2323 .LM283: + 2324 .LFBB13: + 2325 0a10 DF92 push r13 + 2326 0a12 EF92 push r14 + 2327 0a14 FF92 push r15 + 2328 0a16 0F93 push r16 + 2329 0a18 1F93 push r17 + 2330 0a1a CF93 push r28 + 2331 0a1c DF93 push r29 + 2332 0a1e 1F92 push __zero_reg__ + 2333 0a20 CDB7 in r28,__SP_L__ + 2334 0a22 DEB7 in r29,__SP_H__ + 2335 /* prologue: function */ + 2336 /* frame size = 1 */ + 2337 /* stack size = 8 */ + 2338 .L__stack_usage = 8 + 2339 0a24 E82E mov r14,r24 + 2340 0a26 F62E mov r15,r22 + 2341 0a28 D42E mov r13,r20 + 585:../../../../Lib/Rs485_prot.c **** uint16_t crc = 0; + 586:../../../../Lib/Rs485_prot.c **** + 587:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, SYNC); + 2343 .LM284: + 2344 0a2a 6AE5 ldi r22,lo8(90) + 2345 0a2c 80E0 ldi r24,0 + 2346 0a2e 90E0 ldi r25,0 + 2347 0a30 0E94 0000 call _crc_xmodem_update + 2348 0a34 8C01 movw r16,r24 + 588:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 2350 .LM285: + 2351 0a36 8AE5 ldi r24,lo8(90) + 2352 0a38 0E94 0000 call uartRs485SendByte + 589:../../../../Lib/Rs485_prot.c **** + 590:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, deviceAddr); + 2354 .LM286: + 2355 0a3c 6E2D mov r22,r14 + 2356 0a3e C801 movw r24,r16 + 2357 0a40 0E94 0000 call _crc_xmodem_update + 2358 0a44 8C01 movw r16,r24 + 591:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(deviceAddr); + 2360 .LM287: + 2361 0a46 8E2D mov r24,r14 + 2362 0a48 0E94 0000 call uartRs485SendByte + 592:../../../../Lib/Rs485_prot.c **** + 593:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, ledNo); + 2364 .LM288: + 2365 0a4c 6F2D mov r22,r15 + 2366 0a4e C801 movw r24,r16 + 2367 0a50 0E94 0000 call _crc_xmodem_update + 594:../../../../Lib/Rs485_prot.c **** + 595:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + 2369 .LM289: + 2370 0a54 61E0 ldi r22,lo8(1) + 2371 0a56 0E94 0000 call _crc_xmodem_update + 2372 0a5a 8C01 movw r16,r24 + 2373 0a5c 81E0 ldi r24,lo8(1) + 2374 0a5e 0E94 0000 call uartRs485SendByte + 596:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, time); uartRs485SendByte(time); + 2376 .LM290: + 2377 0a62 6D2D mov r22,r13 + 2378 0a64 C801 movw r24,r16 + 2379 0a66 0E94 0000 call _crc_xmodem_update + 2380 0a6a 182F mov r17,r24 + 2381 0a6c 8D2D mov r24,r13 + 2382 0a6e 9983 std Y+1,r25 + 2383 0a70 0E94 0000 call uartRs485SendByte + 597:../../../../Lib/Rs485_prot.c **** + 598:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 2385 .LM291: + 2386 0a74 9981 ldd r25,Y+1 + 2387 0a76 892F mov r24,r25 + 2388 0a78 0E94 0000 call uartRs485SendByte + 599:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2390 .LM292: + 2391 0a7c 812F mov r24,r17 + 2392 0a7e 0E94 0000 call uartRs485SendByte + 600:../../../../Lib/Rs485_prot.c **** + 601:../../../../Lib/Rs485_prot.c **** return 0; + 602:../../../../Lib/Rs485_prot.c **** } + 2394 .LM293: + 2395 0a82 80E0 ldi r24,0 + 2396 /* epilogue start */ + 2397 0a84 0F90 pop __tmp_reg__ + 2398 0a86 DF91 pop r29 + 2399 0a88 CF91 pop r28 + 2400 0a8a 1F91 pop r17 + 2401 0a8c 0F91 pop r16 + 2402 0a8e FF90 pop r15 + 2403 0a90 EF90 pop r14 + 2404 0a92 DF90 pop r13 + 2405 0a94 0895 ret + 2407 .Lscope13: + 2409 .stabd 78,0,0 + 2413 .global sendSettings + 2415 sendSettings: + 2416 .stabd 46,0,0 + 603:../../../../Lib/Rs485_prot.c **** + 604:../../../../Lib/Rs485_prot.c **** + 605:../../../../Lib/Rs485_prot.c **** #ifdef PRINT_RS485_DEVICE + 606:../../../../Lib/Rs485_prot.c **** /** + 607:../../../../Lib/Rs485_prot.c **** * Prints list of Rs485 devices + 608:../../../../Lib/Rs485_prot.c **** * @param stream - outpuf stream + 609:../../../../Lib/Rs485_prot.c **** * @return number of printed devices + 610:../../../../Lib/Rs485_prot.c **** */ + 611:../../../../Lib/Rs485_prot.c **** uint8_t printRs485devices(FILE *stream); + 612:../../../../Lib/Rs485_prot.c **** #endif /*PRINT_RS485_DEVICE*/ + 613:../../../../Lib/Rs485_prot.c **** + 614:../../../../Lib/Rs485_prot.c **** + 615:../../../../Lib/Rs485_prot.c **** void sendSettings(uint8_t addr, uint8_t value) + 616:../../../../Lib/Rs485_prot.c **** { + 2418 .LM294: + 2419 .LFBB14: + 2420 0a96 EF92 push r14 + 2421 0a98 FF92 push r15 + 2422 0a9a 0F93 push r16 + 2423 0a9c 1F93 push r17 + 2424 0a9e CF93 push r28 + 2425 0aa0 DF93 push r29 + 2426 0aa2 1F92 push __zero_reg__ + 2427 0aa4 CDB7 in r28,__SP_L__ + 2428 0aa6 DEB7 in r29,__SP_H__ + 2429 /* prologue: function */ + 2430 /* frame size = 1 */ + 2431 /* stack size = 7 */ + 2432 .L__stack_usage = 7 + 2433 0aa8 F82E mov r15,r24 + 2434 0aaa E62E mov r14,r22 + 617:../../../../Lib/Rs485_prot.c **** uint16_t crc = _crc_xmodem_update(0, SYNC); + 2436 .LM295: + 2437 0aac 6AE5 ldi r22,lo8(90) + 2438 0aae 80E0 ldi r24,0 + 2439 0ab0 90E0 ldi r25,0 + 2440 0ab2 0E94 0000 call _crc_xmodem_update + 2441 0ab6 8C01 movw r16,r24 + 618:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 2443 .LM296: + 2444 0ab8 8AE5 ldi r24,lo8(90) + 2445 0aba 0E94 0000 call uartRs485SendByte + 619:../../../../Lib/Rs485_prot.c **** + 620:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, addr); + 2447 .LM297: + 2448 0abe 6F2D mov r22,r15 + 2449 0ac0 C801 movw r24,r16 + 2450 0ac2 0E94 0000 call _crc_xmodem_update + 2451 0ac6 8C01 movw r16,r24 + 621:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 2453 .LM298: + 2454 0ac8 8F2D mov r24,r15 + 2455 0aca 0E94 0000 call uartRs485SendByte + 622:../../../../Lib/Rs485_prot.c **** + 623:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rUstaw); + 2457 .LM299: + 2458 0ace 60E4 ldi r22,lo8(64) + 2459 0ad0 C801 movw r24,r16 + 2460 0ad2 0E94 0000 call _crc_xmodem_update + 2461 0ad6 8C01 movw r16,r24 + 624:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rUstaw); + 2463 .LM300: + 2464 0ad8 80E4 ldi r24,lo8(64) + 2465 0ada 0E94 0000 call uartRs485SendByte + 625:../../../../Lib/Rs485_prot.c **** + 626:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); + 2467 .LM301: + 2468 0ade 61E0 ldi r22,lo8(1) + 2469 0ae0 C801 movw r24,r16 + 2470 0ae2 0E94 0000 call _crc_xmodem_update + 2471 0ae6 8C01 movw r16,r24 + 627:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(1); + 2473 .LM302: + 2474 0ae8 81E0 ldi r24,lo8(1) + 2475 0aea 0E94 0000 call uartRs485SendByte + 628:../../../../Lib/Rs485_prot.c **** + 629:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, value); + 2477 .LM303: + 2478 0aee 6E2D mov r22,r14 + 2479 0af0 C801 movw r24,r16 + 2480 0af2 0E94 0000 call _crc_xmodem_update + 2481 0af6 182F mov r17,r24 + 630:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(value); + 2483 .LM304: + 2484 0af8 8E2D mov r24,r14 + 2485 0afa 9983 std Y+1,r25 + 2486 0afc 0E94 0000 call uartRs485SendByte + 631:../../../../Lib/Rs485_prot.c **** + 632:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc >> 8)); + 2488 .LM305: + 2489 0b00 9981 ldd r25,Y+1 + 2490 0b02 892F mov r24,r25 + 2491 0b04 0E94 0000 call uartRs485SendByte + 633:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2493 .LM306: + 2494 0b08 812F mov r24,r17 + 2495 /* epilogue start */ + 634:../../../../Lib/Rs485_prot.c **** } + 2497 .LM307: + 2498 0b0a 0F90 pop __tmp_reg__ + 2499 0b0c DF91 pop r29 + 2500 0b0e CF91 pop r28 + 2501 0b10 1F91 pop r17 + 2502 0b12 0F91 pop r16 + 2503 0b14 FF90 pop r15 + 2504 0b16 EF90 pop r14 + 633:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2506 .LM308: + 2507 0b18 0C94 0000 jmp uartRs485SendByte + 2509 .Lscope14: + 2511 .stabd 78,0,0 + 2514 .global saveSettings + 2516 saveSettings: + 2517 .stabd 46,0,0 + 635:../../../../Lib/Rs485_prot.c **** + 636:../../../../Lib/Rs485_prot.c **** void saveSettings(uint8_t addr) + 637:../../../../Lib/Rs485_prot.c **** { + 2519 .LM309: + 2520 .LFBB15: + 2521 0b1c FF92 push r15 + 2522 0b1e 0F93 push r16 + 2523 0b20 1F93 push r17 + 2524 0b22 CF93 push r28 + 2525 0b24 DF93 push r29 + 2526 0b26 1F92 push __zero_reg__ + 2527 0b28 CDB7 in r28,__SP_L__ + 2528 0b2a DEB7 in r29,__SP_H__ + 2529 /* prologue: function */ + 2530 /* frame size = 1 */ + 2531 /* stack size = 6 */ + 2532 .L__stack_usage = 6 + 2533 0b2c F82E mov r15,r24 + 638:../../../../Lib/Rs485_prot.c **** uint16_t crc = _crc_xmodem_update(0, SYNC); + 2535 .LM310: + 2536 0b2e 6AE5 ldi r22,lo8(90) + 2537 0b30 80E0 ldi r24,0 + 2538 0b32 90E0 ldi r25,0 + 2539 0b34 0E94 0000 call _crc_xmodem_update + 2540 0b38 8C01 movw r16,r24 + 639:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(SYNC); + 2542 .LM311: + 2543 0b3a 8AE5 ldi r24,lo8(90) + 2544 0b3c 0E94 0000 call uartRs485SendByte + 640:../../../../Lib/Rs485_prot.c **** + 641:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, addr); + 2546 .LM312: + 2547 0b40 6F2D mov r22,r15 + 2548 0b42 C801 movw r24,r16 + 2549 0b44 0E94 0000 call _crc_xmodem_update + 2550 0b48 8C01 movw r16,r24 + 642:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(addr); + 2552 .LM313: + 2553 0b4a 8F2D mov r24,r15 + 2554 0b4c 0E94 0000 call uartRs485SendByte + 643:../../../../Lib/Rs485_prot.c **** + 644:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rZapiszUstawienia); + 2556 .LM314: + 2557 0b50 61E4 ldi r22,lo8(65) + 2558 0b52 C801 movw r24,r16 + 2559 0b54 0E94 0000 call _crc_xmodem_update + 2560 0b58 8C01 movw r16,r24 + 645:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(rZapiszUstawienia); + 2562 .LM315: + 2563 0b5a 81E4 ldi r24,lo8(65) + 2564 0b5c 0E94 0000 call uartRs485SendByte + 646:../../../../Lib/Rs485_prot.c **** + 647:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 0); + 2566 .LM316: + 2567 0b60 60E0 ldi r22,0 + 2568 0b62 C801 movw r24,r16 + 2569 0b64 0E94 0000 call _crc_xmodem_update + 2570 0b68 182F mov r17,r24 + 648:../../../../Lib/Rs485_prot.c **** uartRs485SendByte(0); + 2572 .LM317: + 2573 0b6a 80E0 ldi r24,0 + 2574 0b6c 9983 std Y+1,r25 + 2575 0b6e 0E94 0000 call uartRs485SendByte + 649:../../../../Lib/Rs485_prot.c **** + 650:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc >> 8)); + 2577 .LM318: + 2578 0b72 9981 ldd r25,Y+1 + 2579 0b74 892F mov r24,r25 + 2580 0b76 0E94 0000 call uartRs485SendByte + 651:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2582 .LM319: + 2583 0b7a 812F mov r24,r17 + 2584 /* epilogue start */ + 652:../../../../Lib/Rs485_prot.c **** } + 2586 .LM320: + 2587 0b7c 0F90 pop __tmp_reg__ + 2588 0b7e DF91 pop r29 + 2589 0b80 CF91 pop r28 + 2590 0b82 1F91 pop r17 + 2591 0b84 0F91 pop r16 + 2592 0b86 FF90 pop r15 + 651:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2594 .LM321: + 2595 0b88 0C94 0000 jmp uartRs485SendByte + 2597 .Lscope15: + 2599 .stabd 78,0,0 + 2604 .global rs485curtainDown + 2606 rs485curtainDown: + 2607 .stabd 46,0,0 + 653:../../../../Lib/Rs485_prot.c **** + 654:../../../../Lib/Rs485_prot.c **** uint8_t rs485curtainDown(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos) + 655:../../../../Lib/Rs485_prot.c **** { + 2609 .LM322: + 2610 .LFBB16: + 2611 0b8c DF92 push r13 + 2612 0b8e EF92 push r14 + 2613 0b90 FF92 push r15 + 2614 0b92 0F93 push r16 + 2615 0b94 1F93 push r17 + 2616 0b96 CF93 push r28 + 2617 0b98 DF93 push r29 + 2618 0b9a 1F92 push __zero_reg__ + 2619 0b9c CDB7 in r28,__SP_L__ + 2620 0b9e DEB7 in r29,__SP_H__ + 2621 /* prologue: function */ + 2622 /* frame size = 1 */ + 2623 /* stack size = 8 */ + 2624 .L__stack_usage = 8 + 2625 0ba0 E82E mov r14,r24 + 2626 0ba2 F62E mov r15,r22 + 2627 0ba4 D42E mov r13,r20 + 656:../../../../Lib/Rs485_prot.c **** uint16_t crc = 0; + 657:../../../../Lib/Rs485_prot.c **** + 658:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, SYNC); uartRs485SendByte(SYNC); + 2629 .LM323: + 2630 0ba6 6AE5 ldi r22,lo8(90) + 2631 0ba8 80E0 ldi r24,0 + 2632 0baa 90E0 ldi r25,0 + 2633 0bac 0E94 0000 call _crc_xmodem_update + 2634 0bb0 8C01 movw r16,r24 + 2635 0bb2 8AE5 ldi r24,lo8(90) + 2636 0bb4 0E94 0000 call uartRs485SendByte + 659:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, deviceAddr); uartRs485SendByte(deviceAddr); + 2638 .LM324: + 2639 0bb8 6E2D mov r22,r14 + 2640 0bba C801 movw r24,r16 + 2641 0bbc 0E94 0000 call _crc_xmodem_update + 2642 0bc0 8C01 movw r16,r24 + 2643 0bc2 8E2D mov r24,r14 + 2644 0bc4 0E94 0000 call uartRs485SendByte + 660:../../../../Lib/Rs485_prot.c **** if (curtainNo == 0) + 2646 .LM325: + 2647 0bc8 F110 cpse r15,__zero_reg__ + 2648 0bca 00C0 rjmp .L161 + 661:../../../../Lib/Rs485_prot.c **** { + 662:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rOpuscRolete1); uartRs485SendByte(rOpuscRolete1); + 2650 .LM326: + 2651 0bcc 60E1 ldi r22,lo8(16) + 2652 0bce C801 movw r24,r16 + 2653 0bd0 0E94 0000 call _crc_xmodem_update + 2654 0bd4 8C01 movw r16,r24 + 2655 0bd6 80E1 ldi r24,lo8(16) + 2656 0bd8 00C0 rjmp .L163 + 2657 .L161: + 663:../../../../Lib/Rs485_prot.c **** } + 664:../../../../Lib/Rs485_prot.c **** else + 665:../../../../Lib/Rs485_prot.c **** { + 666:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, rOpuscRolete2); uartRs485SendByte(rOpuscRolete2); + 2659 .LM327: + 2660 0bda 61E1 ldi r22,lo8(17) + 2661 0bdc C801 movw r24,r16 + 2662 0bde 0E94 0000 call _crc_xmodem_update + 2663 0be2 8C01 movw r16,r24 + 2664 0be4 81E1 ldi r24,lo8(17) + 2665 .L163: + 2666 0be6 0E94 0000 call uartRs485SendByte + 667:../../../../Lib/Rs485_prot.c **** } + 668:../../../../Lib/Rs485_prot.c **** + 669:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, 1); uartRs485SendByte(1); + 2668 .LM328: + 2669 0bea 61E0 ldi r22,lo8(1) + 2670 0bec C801 movw r24,r16 + 2671 0bee 0E94 0000 call _crc_xmodem_update + 2672 0bf2 8C01 movw r16,r24 + 2673 0bf4 81E0 ldi r24,lo8(1) + 2674 0bf6 0E94 0000 call uartRs485SendByte + 670:../../../../Lib/Rs485_prot.c **** crc = _crc_xmodem_update(crc, pos); uartRs485SendByte(pos); + 2676 .LM329: + 2677 0bfa 6D2D mov r22,r13 + 2678 0bfc C801 movw r24,r16 + 2679 0bfe 0E94 0000 call _crc_xmodem_update + 2680 0c02 182F mov r17,r24 + 2681 0c04 8D2D mov r24,r13 + 2682 0c06 9983 std Y+1,r25 + 2683 0c08 0E94 0000 call uartRs485SendByte + 671:../../../../Lib/Rs485_prot.c **** + 672:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc>>8)); + 2685 .LM330: + 2686 0c0c 9981 ldd r25,Y+1 + 2687 0c0e 892F mov r24,r25 + 2688 0c10 0E94 0000 call uartRs485SendByte + 673:../../../../Lib/Rs485_prot.c **** uartRs485SendByte((uint8_t)(crc & 0xFF)); + 2690 .LM331: + 2691 0c14 812F mov r24,r17 + 2692 0c16 0E94 0000 call uartRs485SendByte + 674:../../../../Lib/Rs485_prot.c **** + 675:../../../../Lib/Rs485_prot.c **** return 0; + 676:../../../../Lib/Rs485_prot.c **** } + 2694 .LM332: + 2695 0c1a 80E0 ldi r24,0 + 2696 /* epilogue start */ + 2697 0c1c 0F90 pop __tmp_reg__ + 2698 0c1e DF91 pop r29 + 2699 0c20 CF91 pop r28 + 2700 0c22 1F91 pop r17 + 2701 0c24 0F91 pop r16 + 2702 0c26 FF90 pop r15 + 2703 0c28 EF90 pop r14 + 2704 0c2a DF90 pop r13 + 2705 0c2c 0895 ret + 2707 .Lscope16: + 2709 .stabd 78,0,0 + 2710 .section .progmem.data,"a",@progbits + 2713 __c.3530: + 2714 0000 626F 6F74 .string "bootloader nie rozpoczal odbioru danych\r\n" + 2714 6C6F 6164 + 2714 6572 206E + 2714 6965 2072 + 2714 6F7A 706F + 2717 __c.3528: + 2718 002a 6E61 2075 .string "na urzadzeniu wgrany jest tylko bootloader\r\n" + 2718 727A 6164 + 2718 7A65 6E69 + 2718 7520 7767 + 2718 7261 6E79 + 2721 __c.3526: + 2722 0057 7246 4C41 .string "rFLASH timeout\r\n" + 2722 5348 2074 + 2722 696D 656F + 2722 7574 0D0A + 2722 00 + 2723 .global statusRollerDescStr2 + 2726 statusRollerDescStr2: + 2727 0068 2C20 6669 .string ", firmware %s\r\n" + 2727 726D 7761 + 2727 7265 2025 + 2727 730D 0A00 + 2728 .global statusRollerDescStrConf + 2731 statusRollerDescStrConf: + 2732 0078 2063 6F6E .string " config %x" + 2732 6669 6720 + 2732 2578 00 + 2733 .global statusRollerDescStr + 2736 statusRollerDescStr: + 2737 0083 2025 6420 .string " %d roller driver: roller 1 position %d, roller 2 position %d" + 2737 726F 6C6C + 2737 6572 2064 + 2737 7269 7665 + 2737 723A 2072 + 2738 .comm rollers,2,1 + 2739 .comm klastry,128,1 + 2740 .comm czasRtc,7,1 + 2741 .comm sockets,2,1 + 2742 .comm tcpDebugLevel,1,1 + 2743 .comm tcpDebugStream,2,1 + 2744 .comm IpMyConfig,15,1 + 2745 .comm udpDbgLevel,1,1 + 2746 .comm udpDbgStream,2,1 + 2747 .comm udpSocket,2,1 + 2748 .comm icmpDebugLevel,1,1 + 2749 .comm icmpDebug,2,1 + 2750 .comm arpDebugLevel,1,1 + 2751 .comm arpDebug,2,1 + 2752 .comm nicState,14,1 + 2753 .comm xSemaphoreRs485,2,1 + 2754 .comm lockSensors,2,1 + 2755 .comm portB,1,1 + 2756 .comm portA,1,1 + 2757 .comm xSemaphoreSpiSS,2,1 + 2758 .comm wwwport,1,1 + 2783 .text + 2785 .Letext0: + 2786 .ident "GCC: (GNU) 4.9.2" + 2787 .global __do_copy_data + 2788 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 Rs485_prot.c + /tmp/cc8cp7qm.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cc8cp7qm.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cc8cp7qm.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cc8cp7qm.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cc8cp7qm.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cc8cp7qm.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cc8cp7qm.s:274 .text:0000000000000000 _crc_xmodem_update + /tmp/cc8cp7qm.s:325 .text:0000000000000034 takeRs485 + /tmp/cc8cp7qm.s:344 .text:0000000000000036 releaseRs485 + /tmp/cc8cp7qm.s:362 .text:0000000000000038 uartRs485SendByte + /tmp/cc8cp7qm.s:381 .text:000000000000003a rs485Receive + /tmp/cc8cp7qm.s:401 .text:000000000000003e flushRs485RecBuffer + /tmp/cc8cp7qm.s:421 .text:0000000000000042 rollersMemInit + *COM*:0000000000000002 rollers + /tmp/cc8cp7qm.s:453 .text:000000000000005e printRs485devices + /tmp/cc8cp7qm.s:2736 .progmem.data:0000000000000083 statusRollerDescStr + /tmp/cc8cp7qm.s:2726 .progmem.data:0000000000000068 statusRollerDescStr2 + /tmp/cc8cp7qm.s:582 .text:000000000000010c rs485ping + /tmp/cc8cp7qm.s:943 .text:00000000000002dc rs485rollerHello + /tmp/cc8cp7qm.s:1427 .text:0000000000000534 rs485xModemFlash + /tmp/cc8cp7qm.s:2721 .progmem.data:0000000000000057 __c.3526 + /tmp/cc8cp7qm.s:2717 .progmem.data:000000000000002a __c.3528 + /tmp/cc8cp7qm.s:2713 .progmem.data:0000000000000000 __c.3530 + /tmp/cc8cp7qm.s:2202 .text:000000000000096e rs485curtainUp + /tmp/cc8cp7qm.s:2320 .text:0000000000000a10 rs485Led + /tmp/cc8cp7qm.s:2415 .text:0000000000000a96 sendSettings + /tmp/cc8cp7qm.s:2516 .text:0000000000000b1c saveSettings + /tmp/cc8cp7qm.s:2606 .text:0000000000000b8c rs485curtainDown + /tmp/cc8cp7qm.s:2731 .progmem.data:0000000000000078 statusRollerDescStrConf + *COM*:0000000000000080 klastry + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +xmalloc +fprintf_P +xRs485Rec +xQueueGenericReceive +vTaskDelay +ramDyskCzytajBajtZPliku +fputc +fprintf +__do_copy_data +__do_clear_bss diff --git a/Lib/cmdline.c b/Lib/cmdline.c new file mode 100644 index 0000000..eabd770 --- /dev/null +++ b/Lib/cmdline.c @@ -0,0 +1,594 @@ +/** + * @file cmdline.h + * @author Pascal Stang, Adam Kaliszan + * @brief Command-Line Interface Library + * @ingroup protocols + * @version 0.6 + * Created 2003.07.16 + * Revised 2010.04.23 + * Editor Tabs 2 + * Target MCU Atmel AVR Series + * + * @par Description + * This library provides cammand lineinterpreter, that works on many instances. + * Each instance requires: separate input/output stream, and separate instance of cmdState struct + * The library was optimised under memory consumption. + * + * @note: This code is currently below version 1.0, and therefore is considered + * to be lacking in some functionality or documentation, or may not be fully + * tested. Nonetheless, you can expect most functions to work. + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt +*/ +//----- Include Files --------------------------------------------------------- + +#include "main.h" + +#include // fprint() support +#include // include I/O definitions (port names, pin names, etc) +#include // include interrupt support +#include // include AVR program memory support +#include // include standard C string functions +#include // include stdlib for string conversion functions + +#include "cmdline.h" // Configuration +#include "vt100.h" // vty100 constans + + +// Constans Strings +const char CmdlinePromptNormal[] PROGMEM = "DomOs>"; +const char CmdlinePromptEnable[] PROGMEM = "DomOs#"; +const char CmdlinePromptConfigure[] PROGMEM = "DomOs@"; +const char CmdlineNotice[] PROGMEM = "cmdline: "; +const char CmdlineCmdNotFound[] PROGMEM = "# nk"; + + +// internal commands +static void cmdlineRepaint (cmdState_t *state, char *buf); +static void cmdlineDoHistory (enum cliHistoryAction action, cmdState_t *state); +static void cmdlineProcessInputString (cmdState_t *state); +static void cmdlinePrintPrompt (cmdState_t *state); +static void cmdlinePrintError (cmdState_t *state); +//static void cmdStateClear (cmdState_t *state); +static void cmdHistoryCopy (cmdState_t *state); +static void cmdHistoryMove (cmdState_t *state); + + +void cmdStateConfigure(cmdState_t * state, char *buffPtr, uint16_t bufferTotalSize, FILE *stream, const command_t *commands, enum cliModeState mode) +{ + memset(state, 0, sizeof(cmdState_t)); + memset(buffPtr, 0, bufferTotalSize); + + state->CmdlineBuffer = buffPtr; + state->bufferMaxSize = (uint8_t)(bufferTotalSize / CMD_STATE_HISTORY); + + state->cliMode = mode; + state->cmdList = commands; + + uint8_t i; + char *tmpPtr = buffPtr; + for (i=0; i < CMD_STATE_HISTORY; i++) + { + state->CmdlineHistory[i] = tmpPtr; + tmpPtr += state->bufferMaxSize; + } + state->myStdInOut = stream; +} + +/*void cmdStateClear(cmdState_t *state) +{ + // reset vt100 processing state + state->CmdlineInputVT100State = 0; + + // initialize input buffer + state->CmdlineBufferLength = 0; + state->CmdlineBufferEditPos = 0; + + // initialize executing function + state->CmdlineExecFunction = 0; +}*/ + +void cmdlineInputFunc(char c, cmdState_t *state) +{ + uint8_t i; + // process the received character + + // VT100 handling + // are we processing a VT100 command? + if(state->CmdlineInputVT100State == 2) + { + // we have already received ESC and [ + // now process the vt100 codeCmdlineExcBuffer + switch(c) + { + case VT100_ARROWUP: + cmdlineDoHistory(CMDLINE_HISTORY_PREV, state); + break; + case VT100_ARROWDOWN: + cmdlineDoHistory(CMDLINE_HISTORY_NEXT, state); + break; + case VT100_ARROWRIGHT: + if (state->bufferHistoryState == NOT_COPIED) + cmdHistoryCopy(state); + // if the edit position less than current string length + if(state->CmdlineBufferEditPos < state->CmdlineBufferLength) + { + // increment the edit position + state->CmdlineBufferEditPos++; + // move cursor forward one space (no erase) + fputc(ASCII_ESC , state->myStdInOut); + fputc('[' , state->myStdInOut); + fputc(VT100_ARROWRIGHT , state->myStdInOut); + } + else + { + // else, ring the bell + fputc(ASCII_BEL , state->myStdInOut); + } + break; + case VT100_ARROWLEFT: + // if the edit position is non-zero + if (state->bufferHistoryState == NOT_COPIED) + cmdHistoryCopy(state); + + if(state->CmdlineBufferEditPos) + { + // decrement the edit position + state->CmdlineBufferEditPos--; + // move cursor back one space (no erase) + fputc(ASCII_BS , state->myStdInOut); + } + else + { + // else, ring the bell + fputc(ASCII_BEL , state->myStdInOut); + } + break; + default: + break; + } + // done, reset state + state->CmdlineInputVT100State = 0; + return; + } + else if(state->CmdlineInputVT100State == 1) + { + // we last received [ESC] + if(c == '[') + { + state->CmdlineInputVT100State = 2; + return; + } + else + state->CmdlineInputVT100State = 0; + } + else + { + // anything else, reset state + state->CmdlineInputVT100State = 0; + } + + // Regular handling + //Protection against buffer Overflow + if (state->CmdlineBufferLength == state->bufferMaxSize) + { + state->CmdlineBufferLength--; + for (i=1; i < state->bufferMaxSize; i++) + { + state->CmdlineBuffer[i-1] = state->CmdlineBuffer[i]; + } + } + + if( (c >= 0x20) && (c < 0x7F) ) + { + if (state->bufferHistoryState == NOT_COPIED) + cmdHistoryCopy(state); + // character is printable + // is this a simple append + if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + { + // echo character to the output + fputc(c , state->myStdInOut); + // add it to the command line buffer + state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + // update buffer length + state->CmdlineBufferLength++; + } + else + { + // edit/cursor position != end of buffer + // we're inserting characters at a mid-line edit position + // make room at the insert point + state->CmdlineBufferLength++; + for(i=state->CmdlineBufferLength; i>state->CmdlineBufferEditPos; i--) + state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + // insert character + state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + // reposition cursor + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + fputc(ASCII_BS , state->myStdInOut); + } + } + // handle special characters + else if(c == ASCII_CR) + { + if (state->bufferHistoryState == NOT_COPIED) + cmdHistoryMove(state); + + // user pressed [ENTER] + // echo CR and LF to terminal + fputc(ASCII_CR , state->myStdInOut); + fputc(ASCII_LF , state->myStdInOut); + // add null termination to command + state->CmdlineBuffer[state->CmdlineBufferLength++] = 0; + state->CmdlineBufferEditPos++; + // command is complete, process it + cmdlineProcessInputString(state); + // reset buffer + state->CmdlineBufferLength = 0; + state->CmdlineBufferEditPos = 0; + } + else if(c == ASCII_BS) + { + if(state->CmdlineBufferEditPos) + { + // is this a simple delete (off the end of the line) + if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + { + // destructive backspace + // echo backspace-space-backspace + fputc(ASCII_BS , state->myStdInOut); + fputc(' ' , state->myStdInOut); + fputc(ASCII_BS , state->myStdInOut); + // decrement our buffer length and edit position + state->CmdlineBufferLength--; + state->CmdlineBufferEditPos--; + } + else + { + // edit/cursor position != end of buffer + // we're deleting characters at a mid-line edit position + // shift characters down, effectively deleting + state->CmdlineBufferLength--; + state->CmdlineBufferEditPos--; + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + // add space to clear leftover characters + fputc(' ' , state->myStdInOut); + // reposition cursor + for(i=state->CmdlineBufferEditPos; i<(state->CmdlineBufferLength+1); i++) + fputc(ASCII_BS , state->myStdInOut); + } + } + else + { + // else, ring the bell + fputc(ASCII_BEL , state->myStdInOut); + } + } + else if(c == ASCII_DEL) + { + // not yet handled + } + else if(c == ASCII_ESC) + { + state->CmdlineInputVT100State = 1; + } +} + +void cmdlineRepaint(cmdState_t *state, char *buf) +{ + uint8_t i; + + // carriage return + fputc(ASCII_CR , state->myStdInOut); + // print fresh prompt + cmdlinePrintPrompt(state); + // print the new command line buffer + i = state->CmdlineBufferLength; + while(i--) + fputc(*buf++ , state->myStdInOut); + i = state->bufferMaxSize - state->CmdlineBufferLength; + while (i--) + fputc(' ', state->myStdInOut); + i = state->bufferMaxSize - state->CmdlineBufferLength; + while (i--) + fputc(ASCII_BS, state->myStdInOut); +} + +void cmdHistoryCopy(cmdState_t *state) +{ + if (state->historyDepthIdx != 0) + { + uint8_t historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + memset(state->CmdlineBuffer, 0, state->bufferMaxSize); + strcpy(state->CmdlineBuffer, state->CmdlineHistory[historyReadIdx]); + } + + state->historyDepthIdx = 0; + state->bufferHistoryState = COPIED; +} + +void cmdHistoryMove(cmdState_t *state) +{ + uint8_t i=state->historyDepthIdx; + + if (state->historyDepthIdx != 0) + { + state->CmdlineBuffer = state->CmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK]; + for ( ; iCmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK] = state->CmdlineHistory[(state->historyWrIdx-i-1) & CMD_STATE_HISTORY_MASK]; + } + } + state->CmdlineHistory[state->historyWrIdx] = state->CmdlineBuffer; + + state->historyDepthIdx = 0; + state->bufferHistoryState = COPIED; +} + +void cmdlineDoHistory(enum cliHistoryAction action, cmdState_t *state) +{ + uint8_t historyReadIdx; + switch(action) + { + case CMDLINE_HISTORY_SAVE: + // copy CmdlineBuffer to history if not null string + state->CmdlineBufferLength = 0; + state->CmdlineBufferEditPos = 0; + state->bufferHistoryState = NOT_COPIED; + + if( strlen(state->CmdlineBuffer) ) + { + state->historyWrIdx++; + state->historyWrIdx &= CMD_STATE_HISTORY_MASK; + + state->CmdlineBuffer = state->CmdlineHistory[state->historyWrIdx]; + } + break; + case CMDLINE_HISTORY_PREV: + if (state->historyDepthIdx == CMD_STATE_HISTORY - 1) + break; //We are on the end of the history list + + historyReadIdx = (state->historyWrIdx - state->historyDepthIdx - 1) & CMD_STATE_HISTORY_MASK; + + if (state->CmdlineHistory[historyReadIdx][0] == 0) + break; + + state->historyDepthIdx++; + state->historyDepthIdx &= CMD_STATE_HISTORY_MASK; + + // set the buffer position to the end of the line + state->CmdlineBufferLength = strlen(state->CmdlineHistory[historyReadIdx]); + state->CmdlineBufferEditPos = state->CmdlineBufferLength; + + state->bufferHistoryState = NOT_COPIED; + + // "re-paint" line + cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + + break; + case CMDLINE_HISTORY_NEXT: + if (state->historyDepthIdx == 0) + break; //We are on the begining of the history list + + state->historyDepthIdx --; + historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + + // set the buffer position to the end of the line + state->CmdlineBufferLength = strlen(state->CmdlineHistory[historyReadIdx]); + state->CmdlineBufferEditPos = state->CmdlineBufferLength; + + state->bufferHistoryState = NOT_COPIED; + + // "re-paint" line + cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + break; + } +} + +void cmdlineProcessInputString(cmdState_t *state) +{ + uint8_t i=0; + state->CmdlineExcBuffer = state->CmdlineBuffer; // We will use exec buffer later to read the arguments + + while( !((state->CmdlineExcBuffer[i] == ' ') // find the end of the command (excluding arguments) + || (state->CmdlineExcBuffer[i] == 0)) ) // find first whitespace character in CmdlineBuffer + i++; // i determines the cammand length + + if(!i) // command was null or empty + { + cmdlinePrintPrompt(state); // output a new prompt + return; + } + + const command_t *tmpPtr = state->cmdList; // Set list of commands. The list depends of the cli mode + command_t tmp; // We need to create this object. We can't directly + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // read from flash. We need to copy it before. + + do // search command list for match with entered command + { + if( !strncmp_P(state->CmdlineExcBuffer, tmp.commandStr, i) ) // user-entered command matched a command in the list + { // + state->CmdlineExecFunction = tmp.commandFun; // set function pointer + state->command_str = tmp.commandStr; + state->command_help_str = tmp.commandHelpStr; + cmdlineDoHistory(CMDLINE_HISTORY_SAVE, state); // save command in history + return; + } + tmpPtr++; // Next command + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // Copy this command from flash to ram + } + while (tmp.commandStr != NULL); // Last command on the list is NULL. It is required !!! + + // if we did not get a match + cmdlinePrintError(state); // output an error message + cmdlinePrintPrompt(state); // output a new prompt +} + +void cmdlineMainLoop(cmdState_t *state) +{ + cliExRes_t result; + if(state->CmdlineExecFunction) // do we have a command/function to be executed + { + state->argc = cmdLineGetLastArgIdx(state); // get number of arguments + result = state->CmdlineExecFunction(state); // run it + + switch(result) + { + case OK_INFORM: + fprintf_P(state->myStdInOut, PSTR("OK\r\n")); + break; + case SYNTAX_ERROR: + fprintf_P(state->myStdInOut, PSTR("Syntax Error. Use: ")); + fprintf_P(state->myStdInOut, state->command_str); + fprintf_P(state->myStdInOut, PSTR(" ")); + fprintf_P(state->myStdInOut, state->command_help_str); + fprintf_P(state->myStdInOut, PSTR("\r\n")); + break; + case ERROR_INFORM: + fprintf_P(state->myStdInOut, PSTR("Operation failed\r\n")); + break; + case ERROR_OPERATION_NOT_ALLOWED: + fprintf_P(state->myStdInOut, PSTR("Operation not allowed\r\n")); + break; + default: + break; + } + state->CmdlineExecFunction = NULL; // reset + state->command_str = NULL; + state->command_help_str = NULL; + cmdlinePrintPrompt(state); // output new prompt + } +} + +void cmdlinePrintPrompt(cmdState_t *state) +{ + const char* ptr; + // print a new command prompt + switch (state->cliMode) + { + case NR_NORMAL: + ptr = CmdlinePromptNormal; + break; + case NR_ENABLE: + ptr = CmdlinePromptEnable; + break; + case NR_CONFIGURE: + ptr = CmdlinePromptConfigure; + break; + default: + ptr = CmdlinePromptNormal; + break; + } + while(pgm_read_byte(ptr)) + fputc(pgm_read_byte(ptr++) , state->myStdInOut); +} + +void cmdlinePrintError(cmdState_t *state) +{ + char * ptr; + + // print a notice header + // (uint8_t*) cast used to avoid compiler warning + ptr = (char*)CmdlineNotice; + while(pgm_read_byte(ptr)) + fputc(pgm_read_byte(ptr++) , state->myStdInOut); + + // print the offending command + ptr = state->CmdlineBuffer; + while((*ptr) && (*ptr != ' ')) + fputc(*ptr++ , state->myStdInOut); + + fputc(':' , state->myStdInOut); + fputc(' ' , state->myStdInOut); + + // print the not-found message + // (uint8_t*) cast used to avoid compiler warning + ptr = (char*)CmdlineCmdNotFound; + while(pgm_read_byte(ptr)) + fputc(pgm_read_byte(ptr++) , state->myStdInOut); + + fputc('\r' , state->myStdInOut); + fputc('\n' , state->myStdInOut); +} + + +uint8_t cmdLineGetLastArgIdx(cmdState_t *state) +{ + uint8_t result = 0; + uint8_t lastWhite = 1; + char *str = state->CmdlineExcBuffer; + while(*str != 0) + { + if (*str == ' ') + { + if (lastWhite == 0) + result++; + lastWhite = 1; + } + else + lastWhite = 0; + str++; + } + return result; +} + +char* cmdlineGetArgStr(uint8_t argnum, cmdState_t *state) +{ + // find the offset of argument number [argnum] + uint8_t idx=0; + uint8_t arg; + + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + + // we are at the first argument + for(arg=0; argCmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] != ' ')) idx++; + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + } + // we are at the requested argument or the end of the buffer + return &state->CmdlineExcBuffer[idx]; +} + +// return argument [argnum] interpreted as a decimal integer +long cmdlineGetArgInt(uint8_t argnum, cmdState_t *state) +{ + char* endptr; + return strtol(cmdlineGetArgStr(argnum, state), &endptr, 10); +} + +// return argument [argnum] interpreted as a hex integer +long cmdlineGetArgHex(uint8_t argnum, cmdState_t *state) +{ + char* endptr; + return strtol(cmdlineGetArgStr(argnum, state), &endptr, 16); +} + +void cmdPrintHelp(cmdState_t *state) +{ + command_t tmp; + const command_t *tmpPtr = state->cmdList; + + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + do + { + fprintf_P(state->myStdInOut, tmp.commandStr); + fprintf_P(state->myStdInOut, PSTR("\t")); + fprintf_P(state->myStdInOut, tmp.commandHelpStr); + fprintf_P(state->myStdInOut, PSTR("\r\n")); + + tmpPtr++; + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + } + while (tmp.commandFun != NULL); +} diff --git a/Lib/cmdline.lst b/Lib/cmdline.lst new file mode 100644 index 0000000..b722b67 --- /dev/null +++ b/Lib/cmdline.lst @@ -0,0 +1,2624 @@ + 1 .file "cmdline.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 193 cmdlinePrintPrompt: + 194 .stabd 46,0,0 + 1:../../../../Lib/cmdline.c **** /** + 2:../../../../Lib/cmdline.c **** * @file cmdline.h + 3:../../../../Lib/cmdline.c **** * @author Pascal Stang, Adam Kaliszan + 4:../../../../Lib/cmdline.c **** * @brief Command-Line Interface Library + 5:../../../../Lib/cmdline.c **** * @ingroup protocols + 6:../../../../Lib/cmdline.c **** * @version 0.6 + 7:../../../../Lib/cmdline.c **** * Created 2003.07.16 + 8:../../../../Lib/cmdline.c **** * Revised 2010.04.23 + 9:../../../../Lib/cmdline.c **** * Editor Tabs 2 + 10:../../../../Lib/cmdline.c **** * Target MCU Atmel AVR Series + 11:../../../../Lib/cmdline.c **** * + 12:../../../../Lib/cmdline.c **** * @par Description + 13:../../../../Lib/cmdline.c **** * This library provides cammand lineinterpreter, that works on many instances. + 14:../../../../Lib/cmdline.c **** * Each instance requires: separate input/output stream, and separate instance of cmdState struct + 15:../../../../Lib/cmdline.c **** * The library was optimised under memory consumption. + 16:../../../../Lib/cmdline.c **** * + 17:../../../../Lib/cmdline.c **** * @note: This code is currently below version 1.0, and therefore is considered + 18:../../../../Lib/cmdline.c **** * to be lacking in some functionality or documentation, or may not be fully + 19:../../../../Lib/cmdline.c **** * tested. Nonetheless, you can expect most functions to work. + 20:../../../../Lib/cmdline.c **** * + 21:../../../../Lib/cmdline.c **** * This code is distributed under the GNU Public License + 22:../../../../Lib/cmdline.c **** * which can be found at http://www.gnu.org/licenses/gpl.txt + 23:../../../../Lib/cmdline.c **** */ + 24:../../../../Lib/cmdline.c **** //----- Include Files --------------------------------------------------------- + 25:../../../../Lib/cmdline.c **** + 26:../../../../Lib/cmdline.c **** #include "main.h" + 27:../../../../Lib/cmdline.c **** + 28:../../../../Lib/cmdline.c **** #include // fprint() support + 29:../../../../Lib/cmdline.c **** #include // include I/O definitions (port names, pin names, etc) + 30:../../../../Lib/cmdline.c **** #include // include interrupt support + 31:../../../../Lib/cmdline.c **** #include // include AVR program memory support + 32:../../../../Lib/cmdline.c **** #include // include standard C string functions + 33:../../../../Lib/cmdline.c **** #include // include stdlib for string conversion functions + 34:../../../../Lib/cmdline.c **** + 35:../../../../Lib/cmdline.c **** #include "cmdline.h" // Configuration + 36:../../../../Lib/cmdline.c **** #include "vt100.h" // vty100 constans + 37:../../../../Lib/cmdline.c **** + 38:../../../../Lib/cmdline.c **** + 39:../../../../Lib/cmdline.c **** // Constans Strings + 40:../../../../Lib/cmdline.c **** const char CmdlinePromptNormal[] PROGMEM = "DomOs>"; + 41:../../../../Lib/cmdline.c **** const char CmdlinePromptEnable[] PROGMEM = "DomOs#"; + 42:../../../../Lib/cmdline.c **** const char CmdlinePromptConfigure[] PROGMEM = "DomOs@"; + 43:../../../../Lib/cmdline.c **** const char CmdlineNotice[] PROGMEM = "cmdline: "; + 44:../../../../Lib/cmdline.c **** const char CmdlineCmdNotFound[] PROGMEM = "# nk"; + 45:../../../../Lib/cmdline.c **** + 46:../../../../Lib/cmdline.c **** + 47:../../../../Lib/cmdline.c **** // internal commands + 48:../../../../Lib/cmdline.c **** static void cmdlineRepaint (cmdState_t *state, char *buf); + 49:../../../../Lib/cmdline.c **** static void cmdlineDoHistory (enum cliHistoryAction action, cmdState_t *state); + 50:../../../../Lib/cmdline.c **** static void cmdlineProcessInputString (cmdState_t *state); + 51:../../../../Lib/cmdline.c **** static void cmdlinePrintPrompt (cmdState_t *state); + 52:../../../../Lib/cmdline.c **** static void cmdlinePrintError (cmdState_t *state); + 53:../../../../Lib/cmdline.c **** //static void cmdStateClear (cmdState_t *state); + 54:../../../../Lib/cmdline.c **** static void cmdHistoryCopy (cmdState_t *state); + 55:../../../../Lib/cmdline.c **** static void cmdHistoryMove (cmdState_t *state); + 56:../../../../Lib/cmdline.c **** + 57:../../../../Lib/cmdline.c **** + 58:../../../../Lib/cmdline.c **** void cmdStateConfigure(cmdState_t * state, char *buffPtr, uint16_t bufferTotalSize, FILE *stream, c + 59:../../../../Lib/cmdline.c **** { + 60:../../../../Lib/cmdline.c **** memset(state, 0, sizeof(cmdState_t)); + 61:../../../../Lib/cmdline.c **** memset(buffPtr, 0, bufferTotalSize); + 62:../../../../Lib/cmdline.c **** + 63:../../../../Lib/cmdline.c **** state->CmdlineBuffer = buffPtr; + 64:../../../../Lib/cmdline.c **** state->bufferMaxSize = (uint8_t)(bufferTotalSize / CMD_STATE_HISTORY); + 65:../../../../Lib/cmdline.c **** + 66:../../../../Lib/cmdline.c **** state->cliMode = mode; + 67:../../../../Lib/cmdline.c **** state->cmdList = commands; + 68:../../../../Lib/cmdline.c **** + 69:../../../../Lib/cmdline.c **** uint8_t i; + 70:../../../../Lib/cmdline.c **** char *tmpPtr = buffPtr; + 71:../../../../Lib/cmdline.c **** for (i=0; i < CMD_STATE_HISTORY; i++) + 72:../../../../Lib/cmdline.c **** { + 73:../../../../Lib/cmdline.c **** state->CmdlineHistory[i] = tmpPtr; + 74:../../../../Lib/cmdline.c **** tmpPtr += state->bufferMaxSize; + 75:../../../../Lib/cmdline.c **** } + 76:../../../../Lib/cmdline.c **** state->myStdInOut = stream; + 77:../../../../Lib/cmdline.c **** } + 78:../../../../Lib/cmdline.c **** + 79:../../../../Lib/cmdline.c **** /*void cmdStateClear(cmdState_t *state) + 80:../../../../Lib/cmdline.c **** { + 81:../../../../Lib/cmdline.c **** // reset vt100 processing state + 82:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 0; + 83:../../../../Lib/cmdline.c **** + 84:../../../../Lib/cmdline.c **** // initialize input buffer + 85:../../../../Lib/cmdline.c **** state->CmdlineBufferLength = 0; + 86:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = 0; + 87:../../../../Lib/cmdline.c **** + 88:../../../../Lib/cmdline.c **** // initialize executing function + 89:../../../../Lib/cmdline.c **** state->CmdlineExecFunction = 0; + 90:../../../../Lib/cmdline.c **** }*/ + 91:../../../../Lib/cmdline.c **** + 92:../../../../Lib/cmdline.c **** void cmdlineInputFunc(char c, cmdState_t *state) + 93:../../../../Lib/cmdline.c **** { + 94:../../../../Lib/cmdline.c **** uint8_t i; + 95:../../../../Lib/cmdline.c **** // process the received character + 96:../../../../Lib/cmdline.c **** + 97:../../../../Lib/cmdline.c **** // VT100 handling + 98:../../../../Lib/cmdline.c **** // are we processing a VT100 command? + 99:../../../../Lib/cmdline.c **** if(state->CmdlineInputVT100State == 2) + 100:../../../../Lib/cmdline.c **** { + 101:../../../../Lib/cmdline.c **** // we have already received ESC and [ + 102:../../../../Lib/cmdline.c **** // now process the vt100 codeCmdlineExcBuffer + 103:../../../../Lib/cmdline.c **** switch(c) + 104:../../../../Lib/cmdline.c **** { + 105:../../../../Lib/cmdline.c **** case VT100_ARROWUP: + 106:../../../../Lib/cmdline.c **** cmdlineDoHistory(CMDLINE_HISTORY_PREV, state); + 107:../../../../Lib/cmdline.c **** break; + 108:../../../../Lib/cmdline.c **** case VT100_ARROWDOWN: + 109:../../../../Lib/cmdline.c **** cmdlineDoHistory(CMDLINE_HISTORY_NEXT, state); + 110:../../../../Lib/cmdline.c **** break; + 111:../../../../Lib/cmdline.c **** case VT100_ARROWRIGHT: + 112:../../../../Lib/cmdline.c **** if (state->bufferHistoryState == NOT_COPIED) + 113:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 114:../../../../Lib/cmdline.c **** // if the edit position less than current string length + 115:../../../../Lib/cmdline.c **** if(state->CmdlineBufferEditPos < state->CmdlineBufferLength) + 116:../../../../Lib/cmdline.c **** { + 117:../../../../Lib/cmdline.c **** // increment the edit position + 118:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos++; + 119:../../../../Lib/cmdline.c **** // move cursor forward one space (no erase) + 120:../../../../Lib/cmdline.c **** fputc(ASCII_ESC , state->myStdInOut); + 121:../../../../Lib/cmdline.c **** fputc('[' , state->myStdInOut); + 122:../../../../Lib/cmdline.c **** fputc(VT100_ARROWRIGHT , state->myStdInOut); + 123:../../../../Lib/cmdline.c **** } + 124:../../../../Lib/cmdline.c **** else + 125:../../../../Lib/cmdline.c **** { + 126:../../../../Lib/cmdline.c **** // else, ring the bell + 127:../../../../Lib/cmdline.c **** fputc(ASCII_BEL , state->myStdInOut); + 128:../../../../Lib/cmdline.c **** } + 129:../../../../Lib/cmdline.c **** break; + 130:../../../../Lib/cmdline.c **** case VT100_ARROWLEFT: + 131:../../../../Lib/cmdline.c **** // if the edit position is non-zero + 132:../../../../Lib/cmdline.c **** if (state->bufferHistoryState == NOT_COPIED) + 133:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 134:../../../../Lib/cmdline.c **** + 135:../../../../Lib/cmdline.c **** if(state->CmdlineBufferEditPos) + 136:../../../../Lib/cmdline.c **** { + 137:../../../../Lib/cmdline.c **** // decrement the edit position + 138:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos--; + 139:../../../../Lib/cmdline.c **** // move cursor back one space (no erase) + 140:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 141:../../../../Lib/cmdline.c **** } + 142:../../../../Lib/cmdline.c **** else + 143:../../../../Lib/cmdline.c **** { + 144:../../../../Lib/cmdline.c **** // else, ring the bell + 145:../../../../Lib/cmdline.c **** fputc(ASCII_BEL , state->myStdInOut); + 146:../../../../Lib/cmdline.c **** } + 147:../../../../Lib/cmdline.c **** break; + 148:../../../../Lib/cmdline.c **** default: + 149:../../../../Lib/cmdline.c **** break; + 150:../../../../Lib/cmdline.c **** } + 151:../../../../Lib/cmdline.c **** // done, reset state + 152:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 0; + 153:../../../../Lib/cmdline.c **** return; + 154:../../../../Lib/cmdline.c **** } + 155:../../../../Lib/cmdline.c **** else if(state->CmdlineInputVT100State == 1) + 156:../../../../Lib/cmdline.c **** { + 157:../../../../Lib/cmdline.c **** // we last received [ESC] + 158:../../../../Lib/cmdline.c **** if(c == '[') + 159:../../../../Lib/cmdline.c **** { + 160:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 2; + 161:../../../../Lib/cmdline.c **** return; + 162:../../../../Lib/cmdline.c **** } + 163:../../../../Lib/cmdline.c **** else + 164:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 0; + 165:../../../../Lib/cmdline.c **** } + 166:../../../../Lib/cmdline.c **** else + 167:../../../../Lib/cmdline.c **** { + 168:../../../../Lib/cmdline.c **** // anything else, reset state + 169:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 0; + 170:../../../../Lib/cmdline.c **** } + 171:../../../../Lib/cmdline.c **** + 172:../../../../Lib/cmdline.c **** // Regular handling + 173:../../../../Lib/cmdline.c **** //Protection against buffer Overflow + 174:../../../../Lib/cmdline.c **** if (state->CmdlineBufferLength == state->bufferMaxSize) + 175:../../../../Lib/cmdline.c **** { + 176:../../../../Lib/cmdline.c **** state->CmdlineBufferLength--; + 177:../../../../Lib/cmdline.c **** for (i=1; i < state->bufferMaxSize; i++) + 178:../../../../Lib/cmdline.c **** { + 179:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i-1] = state->CmdlineBuffer[i]; + 180:../../../../Lib/cmdline.c **** } + 181:../../../../Lib/cmdline.c **** } + 182:../../../../Lib/cmdline.c **** + 183:../../../../Lib/cmdline.c **** if( (c >= 0x20) && (c < 0x7F) ) + 184:../../../../Lib/cmdline.c **** { + 185:../../../../Lib/cmdline.c **** if (state->bufferHistoryState == NOT_COPIED) + 186:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 187:../../../../Lib/cmdline.c **** // character is printable + 188:../../../../Lib/cmdline.c **** // is this a simple append + 189:../../../../Lib/cmdline.c **** if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + 190:../../../../Lib/cmdline.c **** { + 191:../../../../Lib/cmdline.c **** // echo character to the output + 192:../../../../Lib/cmdline.c **** fputc(c , state->myStdInOut); + 193:../../../../Lib/cmdline.c **** // add it to the command line buffer + 194:../../../../Lib/cmdline.c **** state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + 195:../../../../Lib/cmdline.c **** // update buffer length + 196:../../../../Lib/cmdline.c **** state->CmdlineBufferLength++; + 197:../../../../Lib/cmdline.c **** } + 198:../../../../Lib/cmdline.c **** else + 199:../../../../Lib/cmdline.c **** { + 200:../../../../Lib/cmdline.c **** // edit/cursor position != end of buffer + 201:../../../../Lib/cmdline.c **** // we're inserting characters at a mid-line edit position + 202:../../../../Lib/cmdline.c **** // make room at the insert point + 203:../../../../Lib/cmdline.c **** state->CmdlineBufferLength++; + 204:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferLength; i>state->CmdlineBufferEditPos; i--) + 205:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + 206:../../../../Lib/cmdline.c **** // insert character + 207:../../../../Lib/cmdline.c **** state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + 208:../../../../Lib/cmdline.c **** // repaint + 209:../../../../Lib/cmdline.c **** cmdlineRepaint(state, state->CmdlineBuffer); + 210:../../../../Lib/cmdline.c **** // reposition cursor + 211:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 212:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 213:../../../../Lib/cmdline.c **** } + 214:../../../../Lib/cmdline.c **** } + 215:../../../../Lib/cmdline.c **** // handle special characters + 216:../../../../Lib/cmdline.c **** else if(c == ASCII_CR) + 217:../../../../Lib/cmdline.c **** { + 218:../../../../Lib/cmdline.c **** if (state->bufferHistoryState == NOT_COPIED) + 219:../../../../Lib/cmdline.c **** cmdHistoryMove(state); + 220:../../../../Lib/cmdline.c **** + 221:../../../../Lib/cmdline.c **** // user pressed [ENTER] + 222:../../../../Lib/cmdline.c **** // echo CR and LF to terminal + 223:../../../../Lib/cmdline.c **** fputc(ASCII_CR , state->myStdInOut); + 224:../../../../Lib/cmdline.c **** fputc(ASCII_LF , state->myStdInOut); + 225:../../../../Lib/cmdline.c **** // add null termination to command + 226:../../../../Lib/cmdline.c **** state->CmdlineBuffer[state->CmdlineBufferLength++] = 0; + 227:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos++; + 228:../../../../Lib/cmdline.c **** // command is complete, process it + 229:../../../../Lib/cmdline.c **** cmdlineProcessInputString(state); + 230:../../../../Lib/cmdline.c **** // reset buffer + 231:../../../../Lib/cmdline.c **** state->CmdlineBufferLength = 0; + 232:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = 0; + 233:../../../../Lib/cmdline.c **** } + 234:../../../../Lib/cmdline.c **** else if(c == ASCII_BS) + 235:../../../../Lib/cmdline.c **** { + 236:../../../../Lib/cmdline.c **** if(state->CmdlineBufferEditPos) + 237:../../../../Lib/cmdline.c **** { + 238:../../../../Lib/cmdline.c **** // is this a simple delete (off the end of the line) + 239:../../../../Lib/cmdline.c **** if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + 240:../../../../Lib/cmdline.c **** { + 241:../../../../Lib/cmdline.c **** // destructive backspace + 242:../../../../Lib/cmdline.c **** // echo backspace-space-backspace + 243:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 244:../../../../Lib/cmdline.c **** fputc(' ' , state->myStdInOut); + 245:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 246:../../../../Lib/cmdline.c **** // decrement our buffer length and edit position + 247:../../../../Lib/cmdline.c **** state->CmdlineBufferLength--; + 248:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos--; + 249:../../../../Lib/cmdline.c **** } + 250:../../../../Lib/cmdline.c **** else + 251:../../../../Lib/cmdline.c **** { + 252:../../../../Lib/cmdline.c **** // edit/cursor position != end of buffer + 253:../../../../Lib/cmdline.c **** // we're deleting characters at a mid-line edit position + 254:../../../../Lib/cmdline.c **** // shift characters down, effectively deleting + 255:../../../../Lib/cmdline.c **** state->CmdlineBufferLength--; + 256:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos--; + 257:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 258:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + 259:../../../../Lib/cmdline.c **** // repaint + 260:../../../../Lib/cmdline.c **** cmdlineRepaint(state, state->CmdlineBuffer); + 261:../../../../Lib/cmdline.c **** // add space to clear leftover characters + 262:../../../../Lib/cmdline.c **** fputc(' ' , state->myStdInOut); + 263:../../../../Lib/cmdline.c **** // reposition cursor + 264:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferEditPos; i<(state->CmdlineBufferLength+1); i++) + 265:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 266:../../../../Lib/cmdline.c **** } + 267:../../../../Lib/cmdline.c **** } + 268:../../../../Lib/cmdline.c **** else + 269:../../../../Lib/cmdline.c **** { + 270:../../../../Lib/cmdline.c **** // else, ring the bell + 271:../../../../Lib/cmdline.c **** fputc(ASCII_BEL , state->myStdInOut); + 272:../../../../Lib/cmdline.c **** } + 273:../../../../Lib/cmdline.c **** } + 274:../../../../Lib/cmdline.c **** else if(c == ASCII_DEL) + 275:../../../../Lib/cmdline.c **** { + 276:../../../../Lib/cmdline.c **** // not yet handled + 277:../../../../Lib/cmdline.c **** } + 278:../../../../Lib/cmdline.c **** else if(c == ASCII_ESC) + 279:../../../../Lib/cmdline.c **** { + 280:../../../../Lib/cmdline.c **** state->CmdlineInputVT100State = 1; + 281:../../../../Lib/cmdline.c **** } + 282:../../../../Lib/cmdline.c **** } + 283:../../../../Lib/cmdline.c **** + 284:../../../../Lib/cmdline.c **** void cmdlineRepaint(cmdState_t *state, char *buf) + 285:../../../../Lib/cmdline.c **** { + 286:../../../../Lib/cmdline.c **** uint8_t i; + 287:../../../../Lib/cmdline.c **** + 288:../../../../Lib/cmdline.c **** // carriage return + 289:../../../../Lib/cmdline.c **** fputc(ASCII_CR , state->myStdInOut); + 290:../../../../Lib/cmdline.c **** // print fresh prompt + 291:../../../../Lib/cmdline.c **** cmdlinePrintPrompt(state); + 292:../../../../Lib/cmdline.c **** // print the new command line buffer + 293:../../../../Lib/cmdline.c **** i = state->CmdlineBufferLength; + 294:../../../../Lib/cmdline.c **** while(i--) + 295:../../../../Lib/cmdline.c **** fputc(*buf++ , state->myStdInOut); + 296:../../../../Lib/cmdline.c **** i = state->bufferMaxSize - state->CmdlineBufferLength; + 297:../../../../Lib/cmdline.c **** while (i--) + 298:../../../../Lib/cmdline.c **** fputc(' ', state->myStdInOut); + 299:../../../../Lib/cmdline.c **** i = state->bufferMaxSize - state->CmdlineBufferLength; + 300:../../../../Lib/cmdline.c **** while (i--) + 301:../../../../Lib/cmdline.c **** fputc(ASCII_BS, state->myStdInOut); + 302:../../../../Lib/cmdline.c **** } + 303:../../../../Lib/cmdline.c **** + 304:../../../../Lib/cmdline.c **** void cmdHistoryCopy(cmdState_t *state) + 305:../../../../Lib/cmdline.c **** { + 306:../../../../Lib/cmdline.c **** if (state->historyDepthIdx != 0) + 307:../../../../Lib/cmdline.c **** { + 308:../../../../Lib/cmdline.c **** uint8_t historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MAS + 309:../../../../Lib/cmdline.c **** memset(state->CmdlineBuffer, 0, state->bufferMaxSize); + 310:../../../../Lib/cmdline.c **** strcpy(state->CmdlineBuffer, state->CmdlineHistory[historyReadIdx]); + 311:../../../../Lib/cmdline.c **** } + 312:../../../../Lib/cmdline.c **** + 313:../../../../Lib/cmdline.c **** state->historyDepthIdx = 0; + 314:../../../../Lib/cmdline.c **** state->bufferHistoryState = COPIED; + 315:../../../../Lib/cmdline.c **** } + 316:../../../../Lib/cmdline.c **** + 317:../../../../Lib/cmdline.c **** void cmdHistoryMove(cmdState_t *state) + 318:../../../../Lib/cmdline.c **** { + 319:../../../../Lib/cmdline.c **** uint8_t i=state->historyDepthIdx; + 320:../../../../Lib/cmdline.c **** + 321:../../../../Lib/cmdline.c **** if (state->historyDepthIdx != 0) + 322:../../../../Lib/cmdline.c **** { + 323:../../../../Lib/cmdline.c **** state->CmdlineBuffer = state->CmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK]; + 324:../../../../Lib/cmdline.c **** for ( ; iCmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK] = state->CmdlineHisto + 327:../../../../Lib/cmdline.c **** } + 328:../../../../Lib/cmdline.c **** } + 329:../../../../Lib/cmdline.c **** state->CmdlineHistory[state->historyWrIdx] = state->CmdlineBuffer; + 330:../../../../Lib/cmdline.c **** + 331:../../../../Lib/cmdline.c **** state->historyDepthIdx = 0; + 332:../../../../Lib/cmdline.c **** state->bufferHistoryState = COPIED; + 333:../../../../Lib/cmdline.c **** } + 334:../../../../Lib/cmdline.c **** + 335:../../../../Lib/cmdline.c **** void cmdlineDoHistory(enum cliHistoryAction action, cmdState_t *state) + 336:../../../../Lib/cmdline.c **** { + 337:../../../../Lib/cmdline.c **** uint8_t historyReadIdx; + 338:../../../../Lib/cmdline.c **** switch(action) + 339:../../../../Lib/cmdline.c **** { + 340:../../../../Lib/cmdline.c **** case CMDLINE_HISTORY_SAVE: + 341:../../../../Lib/cmdline.c **** // copy CmdlineBuffer to history if not null string + 342:../../../../Lib/cmdline.c **** state->CmdlineBufferLength = 0; + 343:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = 0; + 344:../../../../Lib/cmdline.c **** state->bufferHistoryState = NOT_COPIED; + 345:../../../../Lib/cmdline.c **** + 346:../../../../Lib/cmdline.c **** if( strlen(state->CmdlineBuffer) ) + 347:../../../../Lib/cmdline.c **** { + 348:../../../../Lib/cmdline.c **** state->historyWrIdx++; + 349:../../../../Lib/cmdline.c **** state->historyWrIdx &= CMD_STATE_HISTORY_MASK; + 350:../../../../Lib/cmdline.c **** + 351:../../../../Lib/cmdline.c **** state->CmdlineBuffer = state->CmdlineHistory[state->historyWrIdx]; + 352:../../../../Lib/cmdline.c **** } + 353:../../../../Lib/cmdline.c **** break; + 354:../../../../Lib/cmdline.c **** case CMDLINE_HISTORY_PREV: + 355:../../../../Lib/cmdline.c **** if (state->historyDepthIdx == CMD_STATE_HISTORY - 1) + 356:../../../../Lib/cmdline.c **** break; //We are on the end of the history list + 357:../../../../Lib/cmdline.c **** + 358:../../../../Lib/cmdline.c **** historyReadIdx = (state->historyWrIdx - state->historyDepthIdx - 1) & CMD_STATE_HISTORY_MASK; + 359:../../../../Lib/cmdline.c **** + 360:../../../../Lib/cmdline.c **** if (state->CmdlineHistory[historyReadIdx][0] == 0) + 361:../../../../Lib/cmdline.c **** break; + 362:../../../../Lib/cmdline.c **** + 363:../../../../Lib/cmdline.c **** state->historyDepthIdx++; + 364:../../../../Lib/cmdline.c **** state->historyDepthIdx &= CMD_STATE_HISTORY_MASK; + 365:../../../../Lib/cmdline.c **** + 366:../../../../Lib/cmdline.c **** // set the buffer position to the end of the line + 367:../../../../Lib/cmdline.c **** state->CmdlineBufferLength = strlen(state->CmdlineHistory[historyReadIdx]); + 368:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = state->CmdlineBufferLength; + 369:../../../../Lib/cmdline.c **** + 370:../../../../Lib/cmdline.c **** state->bufferHistoryState = NOT_COPIED; + 371:../../../../Lib/cmdline.c **** + 372:../../../../Lib/cmdline.c **** // "re-paint" line + 373:../../../../Lib/cmdline.c **** cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + 374:../../../../Lib/cmdline.c **** + 375:../../../../Lib/cmdline.c **** break; + 376:../../../../Lib/cmdline.c **** case CMDLINE_HISTORY_NEXT: + 377:../../../../Lib/cmdline.c **** if (state->historyDepthIdx == 0) + 378:../../../../Lib/cmdline.c **** break; //We are on the begining of the history + 379:../../../../Lib/cmdline.c **** + 380:../../../../Lib/cmdline.c **** state->historyDepthIdx --; + 381:../../../../Lib/cmdline.c **** historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + 382:../../../../Lib/cmdline.c **** + 383:../../../../Lib/cmdline.c **** // set the buffer position to the end of the line + 384:../../../../Lib/cmdline.c **** state->CmdlineBufferLength = strlen(state->CmdlineHistory[historyReadIdx]); + 385:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = state->CmdlineBufferLength; + 386:../../../../Lib/cmdline.c **** + 387:../../../../Lib/cmdline.c **** state->bufferHistoryState = NOT_COPIED; + 388:../../../../Lib/cmdline.c **** + 389:../../../../Lib/cmdline.c **** // "re-paint" line + 390:../../../../Lib/cmdline.c **** cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + 391:../../../../Lib/cmdline.c **** break; + 392:../../../../Lib/cmdline.c **** } + 393:../../../../Lib/cmdline.c **** } + 394:../../../../Lib/cmdline.c **** + 395:../../../../Lib/cmdline.c **** void cmdlineProcessInputString(cmdState_t *state) + 396:../../../../Lib/cmdline.c **** { + 397:../../../../Lib/cmdline.c **** uint8_t i=0; + 398:../../../../Lib/cmdline.c **** state->CmdlineExcBuffer = state->CmdlineBuffer; // We will use exec buffer la + 399:../../../../Lib/cmdline.c **** + 400:../../../../Lib/cmdline.c **** while( !((state->CmdlineExcBuffer[i] == ' ') // find the end of the comman + 401:../../../../Lib/cmdline.c **** || (state->CmdlineExcBuffer[i] == 0)) ) // find first whitespace char + 402:../../../../Lib/cmdline.c **** i++; // i determines the cammand l + 403:../../../../Lib/cmdline.c **** + 404:../../../../Lib/cmdline.c **** if(!i) // command was null or empty + 405:../../../../Lib/cmdline.c **** { + 406:../../../../Lib/cmdline.c **** cmdlinePrintPrompt(state); // output a new prompt + 407:../../../../Lib/cmdline.c **** return; + 408:../../../../Lib/cmdline.c **** } + 409:../../../../Lib/cmdline.c **** + 410:../../../../Lib/cmdline.c **** const command_t *tmpPtr = state->cmdList; // Set list of commands. The + 411:../../../../Lib/cmdline.c **** command_t tmp; // We need to create this obj + 412:../../../../Lib/cmdline.c **** memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // read from flash. We need t + 413:../../../../Lib/cmdline.c **** + 414:../../../../Lib/cmdline.c **** do // search command list for ma + 415:../../../../Lib/cmdline.c **** { + 416:../../../../Lib/cmdline.c **** if( !strncmp_P(state->CmdlineExcBuffer, tmp.commandStr, i) ) // user-entered command match + 417:../../../../Lib/cmdline.c **** { // + 418:../../../../Lib/cmdline.c **** state->CmdlineExecFunction = tmp.commandFun; // set function pointer + 419:../../../../Lib/cmdline.c **** state->command_str = tmp.commandStr; + 420:../../../../Lib/cmdline.c **** state->command_help_str = tmp.commandHelpStr; + 421:../../../../Lib/cmdline.c **** cmdlineDoHistory(CMDLINE_HISTORY_SAVE, state); // save command in history + 422:../../../../Lib/cmdline.c **** return; + 423:../../../../Lib/cmdline.c **** } + 424:../../../../Lib/cmdline.c **** tmpPtr++; // Next command + 425:../../../../Lib/cmdline.c **** memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // Copy this command from fla + 426:../../../../Lib/cmdline.c **** } + 427:../../../../Lib/cmdline.c **** while (tmp.commandStr != NULL); // Last command on the list i + 428:../../../../Lib/cmdline.c **** + 429:../../../../Lib/cmdline.c **** // if we did not get a match + 430:../../../../Lib/cmdline.c **** cmdlinePrintError(state); // output an error message + 431:../../../../Lib/cmdline.c **** cmdlinePrintPrompt(state); // output a new prompt + 432:../../../../Lib/cmdline.c **** } + 433:../../../../Lib/cmdline.c **** + 434:../../../../Lib/cmdline.c **** void cmdlineMainLoop(cmdState_t *state) + 435:../../../../Lib/cmdline.c **** { + 436:../../../../Lib/cmdline.c **** cliExRes_t result; + 437:../../../../Lib/cmdline.c **** if(state->CmdlineExecFunction) // do we have a command/function to be executed + 438:../../../../Lib/cmdline.c **** { + 439:../../../../Lib/cmdline.c **** state->argc = cmdLineGetLastArgIdx(state); // get number of arguments + 440:../../../../Lib/cmdline.c **** result = state->CmdlineExecFunction(state); // run it + 441:../../../../Lib/cmdline.c **** + 442:../../../../Lib/cmdline.c **** switch(result) + 443:../../../../Lib/cmdline.c **** { + 444:../../../../Lib/cmdline.c **** case OK_INFORM: + 445:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("OK\r\n")); + 446:../../../../Lib/cmdline.c **** break; + 447:../../../../Lib/cmdline.c **** case SYNTAX_ERROR: + 448:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("Syntax Error. Use: ")); + 449:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, state->command_str); + 450:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR(" ")); + 451:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, state->command_help_str); + 452:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("\r\n")); + 453:../../../../Lib/cmdline.c **** break; + 454:../../../../Lib/cmdline.c **** case ERROR_INFORM: + 455:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("Operation failed\r\n")); + 456:../../../../Lib/cmdline.c **** break; + 457:../../../../Lib/cmdline.c **** case ERROR_OPERATION_NOT_ALLOWED: + 458:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("Operation not allowed\r\n")); + 459:../../../../Lib/cmdline.c **** break; + 460:../../../../Lib/cmdline.c **** default: + 461:../../../../Lib/cmdline.c **** break; + 462:../../../../Lib/cmdline.c **** } + 463:../../../../Lib/cmdline.c **** state->CmdlineExecFunction = NULL; // reset + 464:../../../../Lib/cmdline.c **** state->command_str = NULL; + 465:../../../../Lib/cmdline.c **** state->command_help_str = NULL; + 466:../../../../Lib/cmdline.c **** cmdlinePrintPrompt(state); // output new prompt + 467:../../../../Lib/cmdline.c **** } + 468:../../../../Lib/cmdline.c **** } + 469:../../../../Lib/cmdline.c **** + 470:../../../../Lib/cmdline.c **** void cmdlinePrintPrompt(cmdState_t *state) + 471:../../../../Lib/cmdline.c **** { + 196 .LM0: + 197 .LFBB1: + 198 0000 0F93 push r16 + 199 0002 1F93 push r17 + 200 0004 CF93 push r28 + 201 0006 DF93 push r29 + 202 /* prologue: function */ + 203 /* frame size = 0 */ + 204 /* stack size = 4 */ + 205 .L__stack_usage = 4 + 206 0008 8C01 movw r16,r24 + 472:../../../../Lib/cmdline.c **** const char* ptr; + 473:../../../../Lib/cmdline.c **** // print a new command prompt + 474:../../../../Lib/cmdline.c **** switch (state->cliMode) + 208 .LM1: + 209 000a FC01 movw r30,r24 + 210 000c 80A1 ldd r24,Z+32 + 211 000e 8130 cpi r24,lo8(1) + 212 0010 01F0 breq .L3 + 213 0012 8230 cpi r24,lo8(2) + 214 0014 01F0 breq .L4 + 475:../../../../Lib/cmdline.c **** { + 476:../../../../Lib/cmdline.c **** case NR_NORMAL: + 477:../../../../Lib/cmdline.c **** ptr = CmdlinePromptNormal; + 216 .LM2: + 217 0016 C0E0 ldi r28,lo8(CmdlinePromptNormal) + 218 0018 D0E0 ldi r29,hi8(CmdlinePromptNormal) + 219 001a 00C0 rjmp .L5 + 220 .L3: + 478:../../../../Lib/cmdline.c **** break; + 479:../../../../Lib/cmdline.c **** case NR_ENABLE: + 480:../../../../Lib/cmdline.c **** ptr = CmdlinePromptEnable; + 222 .LM3: + 223 001c C0E0 ldi r28,lo8(CmdlinePromptEnable) + 224 001e D0E0 ldi r29,hi8(CmdlinePromptEnable) + 225 0020 00C0 rjmp .L5 + 226 .L4: + 481:../../../../Lib/cmdline.c **** break; + 482:../../../../Lib/cmdline.c **** case NR_CONFIGURE: + 483:../../../../Lib/cmdline.c **** ptr = CmdlinePromptConfigure; + 228 .LM4: + 229 0022 C0E0 ldi r28,lo8(CmdlinePromptConfigure) + 230 0024 D0E0 ldi r29,hi8(CmdlinePromptConfigure) + 231 .L5: + 232 .LBB2: + 484:../../../../Lib/cmdline.c **** break; + 485:../../../../Lib/cmdline.c **** default: + 486:../../../../Lib/cmdline.c **** ptr = CmdlinePromptNormal; + 487:../../../../Lib/cmdline.c **** break; + 488:../../../../Lib/cmdline.c **** } + 489:../../../../Lib/cmdline.c **** while(pgm_read_byte(ptr)) + 234 .LM5: + 235 0026 9E01 movw r18,r28 + 236 0028 FE01 movw r30,r28 + 237 /* #APP */ + 238 ; 489 "../../../../Lib/cmdline.c" 1 + 239 002a 8491 lpm r24, Z + 240 + 241 ; 0 "" 2 + 242 /* #NOAPP */ + 243 .LBE2: + 244 002c 8823 tst r24 + 245 002e 01F0 breq .L10 + 246 .LBB3: + 490:../../../../Lib/cmdline.c **** fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 248 .LM6: + 249 0030 2196 adiw r28,1 + 250 0032 F901 movw r30,r18 + 251 /* #APP */ + 252 ; 490 "../../../../Lib/cmdline.c" 1 + 253 0034 8491 lpm r24, Z + 254 + 255 ; 0 "" 2 + 256 /* #NOAPP */ + 257 .LBE3: + 258 0036 F801 movw r30,r16 + 259 0038 628D ldd r22,Z+26 + 260 003a 738D ldd r23,Z+27 + 261 003c 90E0 ldi r25,0 + 262 003e 0E94 0000 call fputc + 263 0042 00C0 rjmp .L5 + 264 .L10: + 265 /* epilogue start */ + 491:../../../../Lib/cmdline.c **** } + 267 .LM7: + 268 0044 DF91 pop r29 + 269 0046 CF91 pop r28 + 270 0048 1F91 pop r17 + 271 004a 0F91 pop r16 + 272 004c 0895 ret + 280 .Lscope1: + 282 .stabd 78,0,0 + 286 cmdlineRepaint: + 287 .stabd 46,0,0 + 285:../../../../Lib/cmdline.c **** uint8_t i; + 289 .LM8: + 290 .LFBB2: + 291 004e EF92 push r14 + 292 0050 FF92 push r15 + 293 0052 0F93 push r16 + 294 0054 1F93 push r17 + 295 0056 CF93 push r28 + 296 0058 DF93 push r29 + 297 /* prologue: function */ + 298 /* frame size = 0 */ + 299 /* stack size = 6 */ + 300 .L__stack_usage = 6 + 301 005a EC01 movw r28,r24 + 302 005c F62E mov r15,r22 + 303 005e E72E mov r14,r23 + 289:../../../../Lib/cmdline.c **** // print fresh prompt + 305 .LM9: + 306 0060 6A8D ldd r22,Y+26 + 307 0062 7B8D ldd r23,Y+27 + 308 0064 8DE0 ldi r24,lo8(13) + 309 0066 90E0 ldi r25,0 + 310 0068 0E94 0000 call fputc + 291:../../../../Lib/cmdline.c **** // print the new command line buffer + 312 .LM10: + 313 006c CE01 movw r24,r28 + 314 006e 0E94 0000 call cmdlinePrintPrompt + 293:../../../../Lib/cmdline.c **** while(i--) + 316 .LM11: + 317 0072 8D85 ldd r24,Y+13 + 294:../../../../Lib/cmdline.c **** fputc(*buf++ , state->myStdInOut); + 319 .LM12: + 320 0074 0F2D mov r16,r15 + 321 0076 1E2D mov r17,r14 + 322 0078 F80E add r15,r24 + 323 .L12: + 324 007a F016 cp r15,r16 + 325 007c 01F0 breq .L18 + 295:../../../../Lib/cmdline.c **** i = state->bufferMaxSize - state->CmdlineBufferLength; + 327 .LM13: + 328 007e F801 movw r30,r16 + 329 0080 8191 ld r24,Z+ + 330 0082 8F01 movw r16,r30 + 331 0084 6A8D ldd r22,Y+26 + 332 0086 7B8D ldd r23,Y+27 + 333 0088 082E mov __tmp_reg__,r24 + 334 008a 000C lsl r0 + 335 008c 990B sbc r25,r25 + 336 008e 0E94 0000 call fputc + 337 0092 00C0 rjmp .L12 + 338 .L18: + 296:../../../../Lib/cmdline.c **** while (i--) + 340 .LM14: + 341 0094 1C85 ldd r17,Y+12 + 342 0096 8D85 ldd r24,Y+13 + 343 0098 181B sub r17,r24 + 344 .L14: + 297:../../../../Lib/cmdline.c **** fputc(' ', state->myStdInOut); + 346 .LM15: + 347 009a 1123 tst r17 + 348 009c 01F0 breq .L19 + 298:../../../../Lib/cmdline.c **** i = state->bufferMaxSize - state->CmdlineBufferLength; + 350 .LM16: + 351 009e 6A8D ldd r22,Y+26 + 352 00a0 7B8D ldd r23,Y+27 + 353 00a2 80E2 ldi r24,lo8(32) + 354 00a4 90E0 ldi r25,0 + 355 00a6 0E94 0000 call fputc + 356 00aa 1150 subi r17,lo8(-(-1)) + 357 00ac 00C0 rjmp .L14 + 358 .L19: + 299:../../../../Lib/cmdline.c **** while (i--) + 360 .LM17: + 361 00ae 1C85 ldd r17,Y+12 + 362 00b0 8D85 ldd r24,Y+13 + 363 00b2 181B sub r17,r24 + 364 .L16: + 300:../../../../Lib/cmdline.c **** fputc(ASCII_BS, state->myStdInOut); + 366 .LM18: + 367 00b4 1123 tst r17 + 368 00b6 01F0 breq .L20 + 301:../../../../Lib/cmdline.c **** } + 370 .LM19: + 371 00b8 6A8D ldd r22,Y+26 + 372 00ba 7B8D ldd r23,Y+27 + 373 00bc 88E0 ldi r24,lo8(8) + 374 00be 90E0 ldi r25,0 + 375 00c0 0E94 0000 call fputc + 376 00c4 1150 subi r17,lo8(-(-1)) + 377 00c6 00C0 rjmp .L16 + 378 .L20: + 379 /* epilogue start */ + 302:../../../../Lib/cmdline.c **** + 381 .LM20: + 382 00c8 DF91 pop r29 + 383 00ca CF91 pop r28 + 384 00cc 1F91 pop r17 + 385 00ce 0F91 pop r16 + 386 00d0 FF90 pop r15 + 387 00d2 EF90 pop r14 + 388 00d4 0895 ret + 390 .Lscope2: + 392 .stabd 78,0,0 + 396 cmdHistoryCopy: + 397 .stabd 46,0,0 + 305:../../../../Lib/cmdline.c **** if (state->historyDepthIdx != 0) + 399 .LM21: + 400 .LFBB3: + 401 00d6 1F93 push r17 + 402 00d8 CF93 push r28 + 403 00da DF93 push r29 + 404 /* prologue: function */ + 405 /* frame size = 0 */ + 406 /* stack size = 3 */ + 407 .L__stack_usage = 3 + 408 00dc EC01 movw r28,r24 + 306:../../../../Lib/cmdline.c **** { + 410 .LM22: + 411 00de 8889 ldd r24,Y+16 + 412 00e0 8823 tst r24 + 413 00e2 01F0 breq .L22 + 414 .LBB4: + 308:../../../../Lib/cmdline.c **** memset(state->CmdlineBuffer, 0, state->bufferMaxSize); + 416 .LM23: + 417 00e4 1F85 ldd r17,Y+15 + 418 00e6 181B sub r17,r24 + 419 00e8 1370 andi r17,lo8(3) + 309:../../../../Lib/cmdline.c **** strcpy(state->CmdlineBuffer, state->CmdlineHistory[historyReadIdx]); + 421 .LM24: + 422 00ea 4C85 ldd r20,Y+12 + 423 00ec 50E0 ldi r21,0 + 424 00ee 60E0 ldi r22,0 + 425 00f0 70E0 ldi r23,0 + 426 00f2 8881 ld r24,Y + 427 00f4 9981 ldd r25,Y+1 + 428 00f6 0E94 0000 call memset + 310:../../../../Lib/cmdline.c **** } + 430 .LM25: + 431 00fa FE01 movw r30,r28 + 432 00fc E10F add r30,r17 + 433 00fe F11D adc r31,__zero_reg__ + 434 0100 E10F add r30,r17 + 435 0102 F11D adc r31,__zero_reg__ + 436 0104 6481 ldd r22,Z+4 + 437 0106 7581 ldd r23,Z+5 + 438 0108 8881 ld r24,Y + 439 010a 9981 ldd r25,Y+1 + 440 010c 0E94 0000 call strcpy + 441 .L22: + 442 .LBE4: + 313:../../../../Lib/cmdline.c **** state->bufferHistoryState = COPIED; + 444 .LM26: + 445 0110 188A std Y+16,__zero_reg__ + 314:../../../../Lib/cmdline.c **** } + 447 .LM27: + 448 0112 81E0 ldi r24,lo8(1) + 449 0114 898B std Y+17,r24 + 450 /* epilogue start */ + 315:../../../../Lib/cmdline.c **** + 452 .LM28: + 453 0116 DF91 pop r29 + 454 0118 CF91 pop r28 + 455 011a 1F91 pop r17 + 456 011c 0895 ret + 461 .Lscope3: + 463 .stabd 78,0,0 + 471 .global cmdStateConfigure + 473 cmdStateConfigure: + 474 .stabd 46,0,0 + 59:../../../../Lib/cmdline.c **** memset(state, 0, sizeof(cmdState_t)); + 476 .LM29: + 477 .LFBB4: + 478 011e 8F92 push r8 + 479 0120 9F92 push r9 + 480 0122 AF92 push r10 + 481 0124 BF92 push r11 + 482 0126 CF92 push r12 + 483 0128 DF92 push r13 + 484 012a EF92 push r14 + 485 012c 0F93 push r16 + 486 012e 1F93 push r17 + 487 0130 CF93 push r28 + 488 0132 DF93 push r29 + 489 /* prologue: function */ + 490 /* frame size = 0 */ + 491 /* stack size = 11 */ + 492 .L__stack_usage = 11 + 493 0134 EC01 movw r28,r24 + 494 0136 5B01 movw r10,r22 + 495 0138 6A01 movw r12,r20 + 496 013a 4901 movw r8,r18 + 60:../../../../Lib/cmdline.c **** memset(buffPtr, 0, bufferTotalSize); + 498 .LM30: + 499 013c 83E2 ldi r24,lo8(35) + 500 013e FE01 movw r30,r28 + 501 0: + 502 0140 1192 st Z+,__zero_reg__ + 503 0142 8A95 dec r24 + 504 0144 01F4 brne 0b + 61:../../../../Lib/cmdline.c **** + 506 .LM31: + 507 0146 60E0 ldi r22,0 + 508 0148 70E0 ldi r23,0 + 509 014a C501 movw r24,r10 + 510 014c 0E94 0000 call memset + 63:../../../../Lib/cmdline.c **** state->bufferMaxSize = (uint8_t)(bufferTotalSize / CMD_STATE_HISTORY); + 512 .LM32: + 513 0150 B982 std Y+1,r11 + 514 0152 A882 st Y,r10 + 64:../../../../Lib/cmdline.c **** + 516 .LM33: + 517 0154 D694 lsr r13 + 518 0156 C794 ror r12 + 519 0158 D694 lsr r13 + 520 015a C794 ror r12 + 521 015c CC86 std Y+12,r12 + 66:../../../../Lib/cmdline.c **** state->cmdList = commands; + 523 .LM34: + 524 015e E8A2 std Y+32,r14 + 67:../../../../Lib/cmdline.c **** + 526 .LM35: + 527 0160 1AA3 std Y+34,r17 + 528 0162 09A3 std Y+33,r16 + 529 0164 FE01 movw r30,r28 + 530 0166 3496 adiw r30,4 + 531 0168 CE01 movw r24,r28 + 532 016a 0C96 adiw r24,12 + 74:../../../../Lib/cmdline.c **** } + 534 .LM36: + 535 016c DD24 clr r13 + 536 .L27: + 73:../../../../Lib/cmdline.c **** tmpPtr += state->bufferMaxSize; + 538 .LM37: + 539 016e A192 st Z+,r10 + 540 0170 B192 st Z+,r11 + 74:../../../../Lib/cmdline.c **** } + 542 .LM38: + 543 0172 AC0C add r10,r12 + 544 0174 BD1C adc r11,r13 + 71:../../../../Lib/cmdline.c **** { + 546 .LM39: + 547 0176 E817 cp r30,r24 + 548 0178 F907 cpc r31,r25 + 549 017a 01F4 brne .L27 + 76:../../../../Lib/cmdline.c **** } + 551 .LM40: + 552 017c 9B8E std Y+27,r9 + 553 017e 8A8E std Y+26,r8 + 554 /* epilogue start */ + 77:../../../../Lib/cmdline.c **** + 556 .LM41: + 557 0180 DF91 pop r29 + 558 0182 CF91 pop r28 + 559 0184 1F91 pop r17 + 560 0186 0F91 pop r16 + 561 0188 EF90 pop r14 + 562 018a DF90 pop r13 + 563 018c CF90 pop r12 + 564 018e BF90 pop r11 + 565 0190 AF90 pop r10 + 566 0192 9F90 pop r9 + 567 0194 8F90 pop r8 + 568 0196 0895 ret + 570 .Lscope4: + 572 .stabd 78,0,0 + 576 .global cmdlineInputFunc + 578 cmdlineInputFunc: + 579 .stabd 46,0,0 + 93:../../../../Lib/cmdline.c **** uint8_t i; + 581 .LM42: + 582 .LFBB5: + 583 0198 AF92 push r10 + 584 019a BF92 push r11 + 585 019c CF92 push r12 + 586 019e DF92 push r13 + 587 01a0 EF92 push r14 + 588 01a2 FF92 push r15 + 589 01a4 0F93 push r16 + 590 01a6 1F93 push r17 + 591 01a8 CF93 push r28 + 592 01aa DF93 push r29 + 593 01ac CDB7 in r28,__SP_L__ + 594 01ae DEB7 in r29,__SP_H__ + 595 01b0 2797 sbiw r28,7 + 596 01b2 0FB6 in __tmp_reg__,__SREG__ + 597 01b4 F894 cli + 598 01b6 DEBF out __SP_H__,r29 + 599 01b8 0FBE out __SREG__,__tmp_reg__ + 600 01ba CDBF out __SP_L__,r28 + 601 /* prologue: function */ + 602 /* frame size = 7 */ + 603 /* stack size = 17 */ + 604 .L__stack_usage = 17 + 605 01bc 282F mov r18,r24 + 606 01be 8B01 movw r16,r22 + 99:../../../../Lib/cmdline.c **** { + 608 .LM43: + 609 01c0 DB01 movw r26,r22 + 610 01c2 5296 adiw r26,18 + 611 01c4 8C91 ld r24,X + 612 01c6 8230 cpi r24,lo8(2) + 613 01c8 01F0 breq .+2 + 614 01ca 00C0 rjmp .L30 + 103:../../../../Lib/cmdline.c **** { + 616 .LM44: + 617 01cc 2234 cpi r18,lo8(66) + 618 01ce 01F0 breq .L32 + 619 01d0 04F4 brge .L33 + 620 01d2 2134 cpi r18,lo8(65) + 621 01d4 01F0 breq .L34 + 622 01d6 00C0 rjmp .L31 + 623 .L33: + 624 01d8 2334 cpi r18,lo8(67) + 625 01da 01F4 brne .+2 + 626 01dc 00C0 rjmp .L35 + 627 01de 2434 cpi r18,lo8(68) + 628 01e0 01F4 brne .+2 + 629 01e2 00C0 rjmp .L36 + 630 01e4 00C0 rjmp .L31 + 631 .L34: + 632 .LBB21: + 633 .LBB22: + 355:../../../../Lib/cmdline.c **** break; //We are on the end of the history list + 635 .LM45: + 636 01e6 FB01 movw r30,r22 + 637 01e8 9089 ldd r25,Z+16 + 638 01ea 9330 cpi r25,lo8(3) + 639 01ec 01F4 brne .+2 + 640 01ee 00C0 rjmp .L31 + 641 01f0 8785 ldd r24,Z+15 + 642 01f2 8150 subi r24,lo8(-(-1)) + 358:../../../../Lib/cmdline.c **** + 644 .LM46: + 645 01f4 891B sub r24,r25 + 646 01f6 8370 andi r24,lo8(3) + 360:../../../../Lib/cmdline.c **** break; + 648 .LM47: + 649 01f8 E80F add r30,r24 + 650 01fa F11D adc r31,__zero_reg__ + 651 01fc E80F add r30,r24 + 652 01fe F11D adc r31,__zero_reg__ + 653 0200 6481 ldd r22,Z+4 + 654 0202 7581 ldd r23,Z+5 + 655 0204 DB01 movw r26,r22 + 656 0206 8C91 ld r24,X + 657 0208 8823 tst r24 + 658 020a 01F4 brne .+2 + 659 020c 00C0 rjmp .L31 + 363:../../../../Lib/cmdline.c **** state->historyDepthIdx &= CMD_STATE_HISTORY_MASK; + 661 .LM48: + 662 020e 9F5F subi r25,lo8(-(1)) + 364:../../../../Lib/cmdline.c **** + 664 .LM49: + 665 0210 9370 andi r25,lo8(3) + 666 0212 F801 movw r30,r16 + 667 0214 908B std Z+16,r25 + 668 0216 00C0 rjmp .L96 + 669 .L32: + 670 .LBE22: + 671 .LBE21: + 672 .LBB23: + 673 .LBB24: + 377:../../../../Lib/cmdline.c **** break; //We are on the begining of the history + 675 .LM50: + 676 0218 FB01 movw r30,r22 + 677 021a 9089 ldd r25,Z+16 + 678 021c 9923 tst r25 + 679 021e 01F4 brne .+2 + 680 0220 00C0 rjmp .L31 + 380:../../../../Lib/cmdline.c **** historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + 682 .LM51: + 683 0222 9150 subi r25,lo8(-(-1)) + 684 0224 908B std Z+16,r25 + 381:../../../../Lib/cmdline.c **** + 686 .LM52: + 687 0226 8785 ldd r24,Z+15 + 688 0228 891B sub r24,r25 + 689 022a 8370 andi r24,lo8(3) + 384:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = state->CmdlineBufferLength; + 691 .LM53: + 692 022c E80F add r30,r24 + 693 022e F11D adc r31,__zero_reg__ + 694 0230 E80F add r30,r24 + 695 0232 F11D adc r31,__zero_reg__ + 696 0234 6481 ldd r22,Z+4 + 697 0236 7581 ldd r23,Z+5 + 698 .L96: + 699 0238 FB01 movw r30,r22 + 700 0: + 701 023a 0190 ld __tmp_reg__,Z+ + 702 023c 0020 tst __tmp_reg__ + 703 023e 01F4 brne 0b + 704 0240 3197 sbiw r30,1 + 705 0242 E61B sub r30,r22 + 706 0244 F70B sbc r31,r23 + 707 0246 D801 movw r26,r16 + 708 0248 1D96 adiw r26,13 + 709 024a EC93 st X,r30 + 710 024c 1D97 sbiw r26,13 + 385:../../../../Lib/cmdline.c **** + 712 .LM54: + 713 024e 1E96 adiw r26,14 + 714 0250 EC93 st X,r30 + 715 0252 1E97 sbiw r26,14 + 387:../../../../Lib/cmdline.c **** + 717 .LM55: + 718 0254 5196 adiw r26,17 + 719 0256 1C92 st X,__zero_reg__ + 390:../../../../Lib/cmdline.c **** break; + 721 .LM56: + 722 0258 C801 movw r24,r16 + 723 025a 0E94 0000 call cmdlineRepaint + 724 025e 00C0 rjmp .L31 + 725 .L35: + 726 .LBE24: + 727 .LBE23: + 112:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 729 .LM57: + 730 0260 FB01 movw r30,r22 + 731 0262 8189 ldd r24,Z+17 + 732 0264 8111 cpse r24,__zero_reg__ + 733 0266 00C0 rjmp .L37 + 113:../../../../Lib/cmdline.c **** // if the edit position less than current string length + 735 .LM58: + 736 0268 CB01 movw r24,r22 + 737 026a 0E94 0000 call cmdHistoryCopy + 738 .L37: + 115:../../../../Lib/cmdline.c **** { + 740 .LM59: + 741 026e D801 movw r26,r16 + 742 0270 1E96 adiw r26,14 + 743 0272 8C91 ld r24,X + 744 0274 1E97 sbiw r26,14 + 745 0276 1D96 adiw r26,13 + 746 0278 9C91 ld r25,X + 747 027a 1D97 sbiw r26,13 + 748 027c 5A96 adiw r26,26 + 749 027e 6D91 ld r22,X+ + 750 0280 7C91 ld r23,X + 751 0282 5B97 sbiw r26,26+1 + 752 0284 8917 cp r24,r25 + 753 0286 00F4 brsh .L40 + 118:../../../../Lib/cmdline.c **** // move cursor forward one space (no erase) + 755 .LM60: + 756 0288 8F5F subi r24,lo8(-(1)) + 757 028a 1E96 adiw r26,14 + 758 028c 8C93 st X,r24 + 120:../../../../Lib/cmdline.c **** fputc('[' , state->myStdInOut); + 760 .LM61: + 761 028e 8BE1 ldi r24,lo8(27) + 762 0290 90E0 ldi r25,0 + 763 0292 0E94 0000 call fputc + 121:../../../../Lib/cmdline.c **** fputc(VT100_ARROWRIGHT , state->myStdInOut); + 765 .LM62: + 766 0296 F801 movw r30,r16 + 767 0298 628D ldd r22,Z+26 + 768 029a 738D ldd r23,Z+27 + 769 029c 8BE5 ldi r24,lo8(91) + 770 029e 90E0 ldi r25,0 + 771 02a0 0E94 0000 call fputc + 122:../../../../Lib/cmdline.c **** } + 773 .LM63: + 774 02a4 D801 movw r26,r16 + 775 02a6 5A96 adiw r26,26 + 776 02a8 6D91 ld r22,X+ + 777 02aa 7C91 ld r23,X + 778 02ac 5B97 sbiw r26,26+1 + 779 02ae 83E4 ldi r24,lo8(67) + 780 02b0 90E0 ldi r25,0 + 781 02b2 00C0 rjmp .L97 + 782 .L36: + 132:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 784 .LM64: + 785 02b4 FB01 movw r30,r22 + 786 02b6 8189 ldd r24,Z+17 + 787 02b8 8111 cpse r24,__zero_reg__ + 788 02ba 00C0 rjmp .L39 + 133:../../../../Lib/cmdline.c **** + 790 .LM65: + 791 02bc CB01 movw r24,r22 + 792 02be 0E94 0000 call cmdHistoryCopy + 793 .L39: + 135:../../../../Lib/cmdline.c **** { + 795 .LM66: + 796 02c2 D801 movw r26,r16 + 797 02c4 1E96 adiw r26,14 + 798 02c6 8C91 ld r24,X + 799 02c8 1E97 sbiw r26,14 + 800 02ca 5A96 adiw r26,26 + 801 02cc 6D91 ld r22,X+ + 802 02ce 7C91 ld r23,X + 803 02d0 5B97 sbiw r26,26+1 + 804 02d2 8823 tst r24 + 805 02d4 01F0 breq .L40 + 138:../../../../Lib/cmdline.c **** // move cursor back one space (no erase) + 807 .LM67: + 808 02d6 8150 subi r24,lo8(-(-1)) + 809 02d8 1E96 adiw r26,14 + 810 02da 8C93 st X,r24 + 140:../../../../Lib/cmdline.c **** } + 812 .LM68: + 813 02dc 88E0 ldi r24,lo8(8) + 814 02de 90E0 ldi r25,0 + 815 02e0 00C0 rjmp .L97 + 816 .L40: + 145:../../../../Lib/cmdline.c **** } + 818 .LM69: + 819 02e2 87E0 ldi r24,lo8(7) + 820 02e4 90E0 ldi r25,0 + 821 .L97: + 822 02e6 0E94 0000 call fputc + 823 .L31: + 152:../../../../Lib/cmdline.c **** return; + 825 .LM70: + 826 02ea F801 movw r30,r16 + 827 02ec 128A std Z+18,__zero_reg__ + 153:../../../../Lib/cmdline.c **** } + 829 .LM71: + 830 02ee 00C0 rjmp .L29 + 831 .L30: + 155:../../../../Lib/cmdline.c **** { + 833 .LM72: + 834 02f0 8130 cpi r24,lo8(1) + 835 02f2 01F4 brne .L42 + 158:../../../../Lib/cmdline.c **** { + 837 .LM73: + 838 02f4 2B35 cpi r18,lo8(91) + 839 02f6 01F4 brne .L42 + 160:../../../../Lib/cmdline.c **** return; + 841 .LM74: + 842 02f8 82E0 ldi r24,lo8(2) + 843 02fa 00C0 rjmp .L99 + 844 .L42: + 164:../../../../Lib/cmdline.c **** } + 846 .LM75: + 847 02fc F801 movw r30,r16 + 848 02fe 128A std Z+18,__zero_reg__ + 174:../../../../Lib/cmdline.c **** { + 850 .LM76: + 851 0300 8585 ldd r24,Z+13 + 852 0302 9485 ldd r25,Z+12 + 853 0304 8917 cp r24,r25 + 854 0306 01F0 breq .L43 + 855 .L48: + 183:../../../../Lib/cmdline.c **** { + 857 .LM77: + 858 0308 80EE ldi r24,lo8(-32) + 859 030a 820F add r24,r18 + 860 030c 8F35 cpi r24,lo8(95) + 861 030e 00F0 brlo .L44 + 862 0310 00C0 rjmp .L100 + 863 .L43: + 176:../../../../Lib/cmdline.c **** for (i=1; i < state->bufferMaxSize; i++) + 865 .LM78: + 866 0312 8150 subi r24,lo8(-(-1)) + 867 0314 8587 std Z+13,r24 + 177:../../../../Lib/cmdline.c **** { + 869 .LM79: + 870 0316 81E0 ldi r24,lo8(1) + 871 .L46: + 177:../../../../Lib/cmdline.c **** { + 873 .LM80: + 874 0318 F801 movw r30,r16 + 875 031a 9485 ldd r25,Z+12 + 876 031c 8917 cp r24,r25 + 877 031e 00F4 brsh .L48 + 179:../../../../Lib/cmdline.c **** } + 879 .LM81: + 880 0320 D801 movw r26,r16 + 881 0322 ED91 ld r30,X+ + 882 0324 FC91 ld r31,X + 883 0326 E80F add r30,r24 + 884 0328 F11D adc r31,__zero_reg__ + 885 032a 9081 ld r25,Z + 886 032c 3197 sbiw r30,1 + 887 032e 9083 st Z,r25 + 177:../../../../Lib/cmdline.c **** { + 889 .LM82: + 890 0330 8F5F subi r24,lo8(-(1)) + 891 0332 00C0 rjmp .L46 + 892 .L44: + 185:../../../../Lib/cmdline.c **** cmdHistoryCopy(state); + 894 .LM83: + 895 0334 D801 movw r26,r16 + 896 0336 5196 adiw r26,17 + 897 0338 8C91 ld r24,X + 898 033a 8111 cpse r24,__zero_reg__ + 899 033c 00C0 rjmp .L49 + 186:../../../../Lib/cmdline.c **** // character is printable + 901 .LM84: + 902 033e C801 movw r24,r16 + 903 0340 2F83 std Y+7,r18 + 904 0342 0E94 0000 call cmdHistoryCopy + 905 0346 2F81 ldd r18,Y+7 + 906 .L49: + 189:../../../../Lib/cmdline.c **** { + 908 .LM85: + 909 0348 F801 movw r30,r16 + 910 034a 8585 ldd r24,Z+13 + 911 034c 9685 ldd r25,Z+14 + 912 034e 9813 cpse r25,r24 + 913 0350 00C0 rjmp .L50 + 192:../../../../Lib/cmdline.c **** // add it to the command line buffer + 915 .LM86: + 916 0352 628D ldd r22,Z+26 + 917 0354 738D ldd r23,Z+27 + 918 0356 822F mov r24,r18 + 919 0358 022E mov __tmp_reg__,r18 + 920 035a 000C lsl r0 + 921 035c 990B sbc r25,r25 + 922 035e 2F83 std Y+7,r18 + 923 0360 0E94 0000 call fputc + 194:../../../../Lib/cmdline.c **** // update buffer length + 925 .LM87: + 926 0364 D801 movw r26,r16 + 927 0366 ED91 ld r30,X+ + 928 0368 FC91 ld r31,X + 929 036a 1197 sbiw r26,1 + 930 036c 1E96 adiw r26,14 + 931 036e 8C91 ld r24,X + 932 0370 1E97 sbiw r26,14 + 933 0372 91E0 ldi r25,lo8(1) + 934 0374 980F add r25,r24 + 935 0376 1E96 adiw r26,14 + 936 0378 9C93 st X,r25 + 937 037a 1E97 sbiw r26,14 + 938 037c E80F add r30,r24 + 939 037e F11D adc r31,__zero_reg__ + 940 0380 2F81 ldd r18,Y+7 + 941 0382 2083 st Z,r18 + 196:../../../../Lib/cmdline.c **** } + 943 .LM88: + 944 0384 1D96 adiw r26,13 + 945 0386 8C91 ld r24,X + 946 0388 1D97 sbiw r26,13 + 947 038a 8F5F subi r24,lo8(-(1)) + 948 038c 1D96 adiw r26,13 + 949 038e 8C93 st X,r24 + 950 0390 00C0 rjmp .L29 + 951 .L50: + 203:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferLength; i>state->CmdlineBufferEditPos; i--) + 953 .LM89: + 954 0392 8F5F subi r24,lo8(-(1)) + 955 0394 F801 movw r30,r16 + 956 0396 8587 std Z+13,r24 + 957 .L51: + 204:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + 959 .LM90: + 960 0398 D801 movw r26,r16 + 961 039a 1E96 adiw r26,14 + 962 039c 9C91 ld r25,X + 963 039e 1E97 sbiw r26,14 + 964 03a0 4D91 ld r20,X+ + 965 03a2 5C91 ld r21,X + 966 03a4 1197 sbiw r26,1 + 967 03a6 9817 cp r25,r24 + 968 03a8 00F4 brsh .L101 + 205:../../../../Lib/cmdline.c **** // insert character + 970 .LM91: + 971 03aa DA01 movw r26,r20 + 972 03ac A80F add r26,r24 + 973 03ae B11D adc r27,__zero_reg__ + 974 03b0 FD01 movw r30,r26 + 975 03b2 3197 sbiw r30,1 + 976 03b4 9081 ld r25,Z + 977 03b6 9C93 st X,r25 + 204:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + 979 .LM92: + 980 03b8 8150 subi r24,lo8(-(-1)) + 981 03ba 00C0 rjmp .L51 + 982 .L101: + 207:../../../../Lib/cmdline.c **** // repaint + 984 .LM93: + 985 03bc 81E0 ldi r24,lo8(1) + 986 03be 890F add r24,r25 + 987 03c0 1E96 adiw r26,14 + 988 03c2 8C93 st X,r24 + 989 03c4 1E97 sbiw r26,14 + 990 03c6 FA01 movw r30,r20 + 991 03c8 E90F add r30,r25 + 992 03ca F11D adc r31,__zero_reg__ + 993 03cc 2083 st Z,r18 + 209:../../../../Lib/cmdline.c **** // reposition cursor + 995 .LM94: + 996 03ce 6D91 ld r22,X+ + 997 03d0 7C91 ld r23,X + 998 03d2 C801 movw r24,r16 + 999 03d4 0E94 0000 call cmdlineRepaint + 211:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1001 .LM95: + 1002 03d8 F801 movw r30,r16 + 1003 03da F684 ldd r15,Z+14 + 1004 .L53: + 211:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1006 .LM96: + 1007 03dc F801 movw r30,r16 + 1008 03de 8585 ldd r24,Z+13 + 1009 03e0 F816 cp r15,r24 + 1010 03e2 00F0 brlo .+2 + 1011 03e4 00C0 rjmp .L29 + 212:../../../../Lib/cmdline.c **** } + 1013 .LM97: + 1014 03e6 D801 movw r26,r16 + 1015 03e8 5A96 adiw r26,26 + 1016 03ea 6D91 ld r22,X+ + 1017 03ec 7C91 ld r23,X + 1018 03ee 5B97 sbiw r26,26+1 + 1019 03f0 88E0 ldi r24,lo8(8) + 1020 03f2 90E0 ldi r25,0 + 1021 03f4 0E94 0000 call fputc + 211:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1023 .LM98: + 1024 03f8 F394 inc r15 + 1025 03fa 00C0 rjmp .L53 + 1026 .L100: + 216:../../../../Lib/cmdline.c **** { + 1028 .LM99: + 1029 03fc 2D30 cpi r18,lo8(13) + 1030 03fe 01F0 breq .+2 + 1031 0400 00C0 rjmp .L55 + 218:../../../../Lib/cmdline.c **** cmdHistoryMove(state); + 1033 .LM100: + 1034 0402 D801 movw r26,r16 + 1035 0404 5196 adiw r26,17 + 1036 0406 8C91 ld r24,X + 1037 0408 5197 sbiw r26,17 + 1038 040a 8111 cpse r24,__zero_reg__ + 1039 040c 00C0 rjmp .L56 + 1040 .LBB25: + 1041 .LBB26: + 319:../../../../Lib/cmdline.c **** + 1043 .LM101: + 1044 040e 5096 adiw r26,16 + 1045 0410 4C91 ld r20,X + 1046 0412 5097 sbiw r26,16 + 1047 0414 1F96 adiw r26,15 + 1048 0416 5C91 ld r21,X + 321:../../../../Lib/cmdline.c **** { + 1050 .LM102: + 1051 0418 4111 cpse r20,__zero_reg__ + 1052 041a 00C0 rjmp .L57 + 1053 .L60: + 329:../../../../Lib/cmdline.c **** + 1055 .LM103: + 1056 041c F801 movw r30,r16 + 1057 041e E50F add r30,r21 + 1058 0420 F11D adc r31,__zero_reg__ + 1059 0422 E50F add r30,r21 + 1060 0424 F11D adc r31,__zero_reg__ + 1061 0426 D801 movw r26,r16 + 1062 0428 8D91 ld r24,X+ + 1063 042a 9C91 ld r25,X + 1064 042c 1197 sbiw r26,1 + 1065 042e 9583 std Z+5,r25 + 1066 0430 8483 std Z+4,r24 + 331:../../../../Lib/cmdline.c **** state->bufferHistoryState = COPIED; + 1068 .LM104: + 1069 0432 5096 adiw r26,16 + 1070 0434 1C92 st X,__zero_reg__ + 1071 0436 5097 sbiw r26,16 + 332:../../../../Lib/cmdline.c **** } + 1073 .LM105: + 1074 0438 81E0 ldi r24,lo8(1) + 1075 043a 5196 adiw r26,17 + 1076 043c 8C93 st X,r24 + 1077 043e 00C0 rjmp .L56 + 1078 .L57: + 323:../../../../Lib/cmdline.c **** for ( ; imyStdInOut); + 1137 .LM110: + 1138 049a D801 movw r26,r16 + 1139 049c 5A96 adiw r26,26 + 1140 049e 6D91 ld r22,X+ + 1141 04a0 7C91 ld r23,X + 1142 04a2 5B97 sbiw r26,26+1 + 1143 04a4 8DE0 ldi r24,lo8(13) + 1144 04a6 90E0 ldi r25,0 + 1145 04a8 0E94 0000 call fputc + 224:../../../../Lib/cmdline.c **** // add null termination to command + 1147 .LM111: + 1148 04ac F801 movw r30,r16 + 1149 04ae 628D ldd r22,Z+26 + 1150 04b0 738D ldd r23,Z+27 + 1151 04b2 8AE0 ldi r24,lo8(10) + 1152 04b4 90E0 ldi r25,0 + 1153 04b6 0E94 0000 call fputc + 226:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos++; + 1155 .LM112: + 1156 04ba D801 movw r26,r16 + 1157 04bc ED91 ld r30,X+ + 1158 04be FC91 ld r31,X + 1159 04c0 1197 sbiw r26,1 + 1160 04c2 1D96 adiw r26,13 + 1161 04c4 8C91 ld r24,X + 1162 04c6 1D97 sbiw r26,13 + 1163 04c8 91E0 ldi r25,lo8(1) + 1164 04ca 980F add r25,r24 + 1165 04cc 1D96 adiw r26,13 + 1166 04ce 9C93 st X,r25 + 1167 04d0 1D97 sbiw r26,13 + 1168 04d2 E80F add r30,r24 + 1169 04d4 F11D adc r31,__zero_reg__ + 1170 04d6 1082 st Z,__zero_reg__ + 227:../../../../Lib/cmdline.c **** // command is complete, process it + 1172 .LM113: + 1173 04d8 1E96 adiw r26,14 + 1174 04da 8C91 ld r24,X + 1175 04dc 1E97 sbiw r26,14 + 1176 04de 8F5F subi r24,lo8(-(1)) + 1177 04e0 1E96 adiw r26,14 + 1178 04e2 8C93 st X,r24 + 1179 04e4 1E97 sbiw r26,14 + 1180 .LBB27: + 1181 .LBB28: + 398:../../../../Lib/cmdline.c **** + 1183 .LM114: + 1184 04e6 2D91 ld r18,X+ + 1185 04e8 3C91 ld r19,X + 1186 04ea 1197 sbiw r26,1 + 1187 04ec 1396 adiw r26,2+1 + 1188 04ee 3C93 st X,r19 + 1189 04f0 2E93 st -X,r18 + 1190 04f2 1297 sbiw r26,2 + 397:../../../../Lib/cmdline.c **** state->CmdlineExcBuffer = state->CmdlineBuffer; // We will use exec buffer la + 1192 .LM115: + 1193 04f4 80E0 ldi r24,0 + 1194 .L61: + 400:../../../../Lib/cmdline.c **** || (state->CmdlineExcBuffer[i] == 0)) ) // find first whitespace char + 1196 .LM116: + 1197 04f6 C82E mov r12,r24 + 1198 04f8 D12C mov r13,__zero_reg__ + 1199 04fa F901 movw r30,r18 + 1200 04fc EC0D add r30,r12 + 1201 04fe FD1D adc r31,r13 + 1202 0500 9081 ld r25,Z + 1203 0502 9F7D andi r25,lo8(-33) + 1204 0504 01F0 breq .L102 + 402:../../../../Lib/cmdline.c **** + 1206 .LM117: + 1207 0506 8F5F subi r24,lo8(-(1)) + 1208 0508 00C0 rjmp .L61 + 1209 .L102: + 404:../../../../Lib/cmdline.c **** { + 1211 .LM118: + 1212 050a 8823 tst r24 + 1213 050c 01F4 brne .+2 + 1214 050e 00C0 rjmp .L98 + 410:../../../../Lib/cmdline.c **** command_t tmp; // We need to create this obj + 1216 .LM119: + 1217 0510 F801 movw r30,r16 + 1218 0512 E1A0 ldd r14,Z+33 + 1219 0514 F2A0 ldd r15,Z+34 + 412:../../../../Lib/cmdline.c **** + 1221 .LM120: + 1222 0516 46E0 ldi r20,lo8(6) + 1223 0518 50E0 ldi r21,0 + 1224 051a B701 movw r22,r14 + 1225 051c CE01 movw r24,r28 + 1226 051e 0196 adiw r24,1 + 1227 0520 0E94 0000 call memcpy_P + 1228 .L66: + 416:../../../../Lib/cmdline.c **** { // + 1230 .LM121: + 1231 0524 A980 ldd r10,Y+1 + 1232 0526 BA80 ldd r11,Y+2 + 1233 0528 A601 movw r20,r12 + 1234 052a B501 movw r22,r10 + 1235 052c D801 movw r26,r16 + 1236 052e 1296 adiw r26,2 + 1237 0530 8D91 ld r24,X+ + 1238 0532 9C91 ld r25,X + 1239 0534 1397 sbiw r26,2+1 + 1240 0536 0E94 0000 call strncmp_P + 1241 053a 892B or r24,r25 + 1242 053c 01F4 brne .L65 + 418:../../../../Lib/cmdline.c **** state->command_str = tmp.commandStr; + 1244 .LM122: + 1245 053e 8D81 ldd r24,Y+5 + 1246 0540 9E81 ldd r25,Y+6 + 1247 0542 F801 movw r30,r16 + 1248 0544 908F std Z+24,r25 + 1249 0546 878B std Z+23,r24 + 419:../../../../Lib/cmdline.c **** state->command_help_str = tmp.commandHelpStr; + 1251 .LM123: + 1252 0548 B48A std Z+20,r11 + 1253 054a A38A std Z+19,r10 + 420:../../../../Lib/cmdline.c **** cmdlineDoHistory(CMDLINE_HISTORY_SAVE, state); // save command in history + 1255 .LM124: + 1256 054c 8B81 ldd r24,Y+3 + 1257 054e 9C81 ldd r25,Y+4 + 1258 0550 968B std Z+22,r25 + 1259 0552 858B std Z+21,r24 + 1260 .LBB29: + 1261 .LBB30: + 342:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = 0; + 1263 .LM125: + 1264 0554 1586 std Z+13,__zero_reg__ + 343:../../../../Lib/cmdline.c **** state->bufferHistoryState = NOT_COPIED; + 1266 .LM126: + 1267 0556 1686 std Z+14,__zero_reg__ + 344:../../../../Lib/cmdline.c **** + 1269 .LM127: + 1270 0558 118A std Z+17,__zero_reg__ + 346:../../../../Lib/cmdline.c **** { + 1272 .LM128: + 1273 055a 0190 ld __tmp_reg__,Z+ + 1274 055c F081 ld r31,Z + 1275 055e E02D mov r30,__tmp_reg__ + 1276 0560 8081 ld r24,Z + 1277 0562 8823 tst r24 + 1278 0564 01F4 brne .+2 + 1279 0566 00C0 rjmp .L73 + 348:../../../../Lib/cmdline.c **** state->historyWrIdx &= CMD_STATE_HISTORY_MASK; + 1281 .LM129: + 1282 0568 D801 movw r26,r16 + 1283 056a 1F96 adiw r26,15 + 1284 056c 8C91 ld r24,X + 1285 056e 1F97 sbiw r26,15 + 1286 0570 8F5F subi r24,lo8(-(1)) + 349:../../../../Lib/cmdline.c **** + 1288 .LM130: + 1289 0572 8370 andi r24,lo8(3) + 1290 0574 1F96 adiw r26,15 + 1291 0576 8C93 st X,r24 + 351:../../../../Lib/cmdline.c **** } + 1293 .LM131: + 1294 0578 F801 movw r30,r16 + 1295 057a E80F add r30,r24 + 1296 057c F11D adc r31,__zero_reg__ + 1297 057e E80F add r30,r24 + 1298 0580 F11D adc r31,__zero_reg__ + 1299 0582 8481 ldd r24,Z+4 + 1300 0584 9581 ldd r25,Z+5 + 1301 0586 F801 movw r30,r16 + 1302 0588 9183 std Z+1,r25 + 1303 058a 8083 st Z,r24 + 1304 058c 00C0 rjmp .L73 + 1305 .L65: + 1306 .LBE30: + 1307 .LBE29: + 424:../../../../Lib/cmdline.c **** memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // Copy this command from fla + 1309 .LM132: + 1310 058e F6E0 ldi r31,6 + 1311 0590 EF0E add r14,r31 + 1312 0592 F11C adc r15,__zero_reg__ + 425:../../../../Lib/cmdline.c **** } + 1314 .LM133: + 1315 0594 46E0 ldi r20,lo8(6) + 1316 0596 50E0 ldi r21,0 + 1317 0598 B701 movw r22,r14 + 1318 059a CE01 movw r24,r28 + 1319 059c 0196 adiw r24,1 + 1320 059e 0E94 0000 call memcpy_P + 427:../../../../Lib/cmdline.c **** + 1322 .LM134: + 1323 05a2 8981 ldd r24,Y+1 + 1324 05a4 9A81 ldd r25,Y+2 + 1325 05a6 892B or r24,r25 + 1326 05a8 01F0 breq .+2 + 1327 05aa 00C0 rjmp .L66 + 1328 05ac 90E0 ldi r25,lo8(CmdlineNotice) + 1329 05ae E92E mov r14,r25 + 1330 05b0 90E0 ldi r25,hi8(CmdlineNotice) + 1331 05b2 F92E mov r15,r25 + 1332 .L67: + 1333 .LBB31: + 1334 .LBB32: + 1335 .LBB33: + 492:../../../../Lib/cmdline.c **** + 493:../../../../Lib/cmdline.c **** void cmdlinePrintError(cmdState_t *state) + 494:../../../../Lib/cmdline.c **** { + 495:../../../../Lib/cmdline.c **** char * ptr; + 496:../../../../Lib/cmdline.c **** + 497:../../../../Lib/cmdline.c **** // print a notice header + 498:../../../../Lib/cmdline.c **** // (uint8_t*) cast used to avoid compiler warning + 499:../../../../Lib/cmdline.c **** ptr = (char*)CmdlineNotice; + 500:../../../../Lib/cmdline.c **** while(pgm_read_byte(ptr)) + 1337 .LM135: + 1338 05b4 C701 movw r24,r14 + 1339 05b6 F701 movw r30,r14 + 1340 /* #APP */ + 1341 ; 500 "../../../../Lib/cmdline.c" 1 + 1342 05b8 2491 lpm r18, Z + 1343 + 1344 ; 0 "" 2 + 1345 /* #NOAPP */ + 1346 .LBE33: + 1347 05ba 2223 tst r18 + 1348 05bc 01F0 breq .L103 + 1349 .LBB34: + 501:../../../../Lib/cmdline.c **** fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 1351 .LM136: + 1352 05be 2FEF ldi r18,-1 + 1353 05c0 E21A sub r14,r18 + 1354 05c2 F20A sbc r15,r18 + 1355 05c4 FC01 movw r30,r24 + 1356 /* #APP */ + 1357 ; 501 "../../../../Lib/cmdline.c" 1 + 1358 05c6 8491 lpm r24, Z + 1359 + 1360 ; 0 "" 2 + 1361 /* #NOAPP */ + 1362 .LBE34: + 1363 05c8 D801 movw r26,r16 + 1364 05ca 5A96 adiw r26,26 + 1365 05cc 6D91 ld r22,X+ + 1366 05ce 7C91 ld r23,X + 1367 05d0 5B97 sbiw r26,26+1 + 1368 05d2 90E0 ldi r25,0 + 1369 05d4 0E94 0000 call fputc + 1370 05d8 00C0 rjmp .L67 + 1371 .L103: + 1372 05da D801 movw r26,r16 + 1373 05dc ED90 ld r14,X+ + 1374 05de FC90 ld r15,X + 1375 .L69: + 502:../../../../Lib/cmdline.c **** + 503:../../../../Lib/cmdline.c **** // print the offending command + 504:../../../../Lib/cmdline.c **** ptr = state->CmdlineBuffer; + 505:../../../../Lib/cmdline.c **** while((*ptr) && (*ptr != ' ')) + 1377 .LM137: + 1378 05e0 F701 movw r30,r14 + 1379 05e2 8191 ld r24,Z+ + 1380 05e4 7F01 movw r14,r30 + 1381 05e6 982F mov r25,r24 + 1382 05e8 9F7D andi r25,lo8(-33) + 1383 05ea D801 movw r26,r16 + 1384 05ec 5A96 adiw r26,26 + 1385 05ee 6D91 ld r22,X+ + 1386 05f0 7C91 ld r23,X + 1387 05f2 5B97 sbiw r26,26+1 + 1388 05f4 9923 tst r25 + 1389 05f6 01F0 breq .L104 + 506:../../../../Lib/cmdline.c **** fputc(*ptr++ , state->myStdInOut); + 1391 .LM138: + 1392 05f8 082E mov __tmp_reg__,r24 + 1393 05fa 000C lsl r0 + 1394 05fc 990B sbc r25,r25 + 1395 05fe 0E94 0000 call fputc + 1396 0602 00C0 rjmp .L69 + 1397 .L104: + 507:../../../../Lib/cmdline.c **** + 508:../../../../Lib/cmdline.c **** fputc(':' , state->myStdInOut); + 1399 .LM139: + 1400 0604 8AE3 ldi r24,lo8(58) + 1401 0606 90E0 ldi r25,0 + 1402 0608 0E94 0000 call fputc + 509:../../../../Lib/cmdline.c **** fputc(' ' , state->myStdInOut); + 1404 .LM140: + 1405 060c F801 movw r30,r16 + 1406 060e 628D ldd r22,Z+26 + 1407 0610 738D ldd r23,Z+27 + 1408 0612 80E2 ldi r24,lo8(32) + 1409 0614 90E0 ldi r25,0 + 1410 0616 0E94 0000 call fputc + 510:../../../../Lib/cmdline.c **** + 511:../../../../Lib/cmdline.c **** // print the not-found message + 512:../../../../Lib/cmdline.c **** // (uint8_t*) cast used to avoid compiler warning + 513:../../../../Lib/cmdline.c **** ptr = (char*)CmdlineCmdNotFound; + 1412 .LM141: + 1413 061a 80E0 ldi r24,lo8(CmdlineCmdNotFound) + 1414 061c E82E mov r14,r24 + 1415 061e 80E0 ldi r24,hi8(CmdlineCmdNotFound) + 1416 0620 F82E mov r15,r24 + 1417 .L71: + 1418 .LBB35: + 514:../../../../Lib/cmdline.c **** while(pgm_read_byte(ptr)) + 1420 .LM142: + 1421 0622 9701 movw r18,r14 + 1422 0624 F701 movw r30,r14 + 1423 /* #APP */ + 1424 ; 514 "../../../../Lib/cmdline.c" 1 + 1425 0626 9491 lpm r25, Z + 1426 + 1427 ; 0 "" 2 + 1428 /* #NOAPP */ + 1429 0628 D801 movw r26,r16 + 1430 062a 5A96 adiw r26,26 + 1431 062c 6D91 ld r22,X+ + 1432 062e 7C91 ld r23,X + 1433 0630 5B97 sbiw r26,26+1 + 1434 .LBE35: + 1435 0632 9923 tst r25 + 1436 0634 01F0 breq .L105 + 1437 .LBB36: + 515:../../../../Lib/cmdline.c **** fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 1439 .LM143: + 1440 0636 FFEF ldi r31,-1 + 1441 0638 EF1A sub r14,r31 + 1442 063a FF0A sbc r15,r31 + 1443 063c F901 movw r30,r18 + 1444 /* #APP */ + 1445 ; 515 "../../../../Lib/cmdline.c" 1 + 1446 063e 8491 lpm r24, Z + 1447 + 1448 ; 0 "" 2 + 1449 /* #NOAPP */ + 1450 .LBE36: + 1451 0640 90E0 ldi r25,0 + 1452 0642 0E94 0000 call fputc + 1453 0646 00C0 rjmp .L71 + 1454 .L105: + 516:../../../../Lib/cmdline.c **** + 517:../../../../Lib/cmdline.c **** fputc('\r' , state->myStdInOut); + 1456 .LM144: + 1457 0648 8DE0 ldi r24,lo8(13) + 1458 064a 90E0 ldi r25,0 + 1459 064c 0E94 0000 call fputc + 518:../../../../Lib/cmdline.c **** fputc('\n' , state->myStdInOut); + 1461 .LM145: + 1462 0650 F801 movw r30,r16 + 1463 0652 628D ldd r22,Z+26 + 1464 0654 738D ldd r23,Z+27 + 1465 0656 8AE0 ldi r24,lo8(10) + 1466 0658 90E0 ldi r25,0 + 1467 065a 0E94 0000 call fputc + 1468 .L98: + 1469 .LBE32: + 1470 .LBE31: + 431:../../../../Lib/cmdline.c **** } + 1472 .LM146: + 1473 065e C801 movw r24,r16 + 1474 0660 0E94 0000 call cmdlinePrintPrompt + 1475 .L73: + 1476 .LBE28: + 1477 .LBE27: + 231:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos = 0; + 1479 .LM147: + 1480 0664 D801 movw r26,r16 + 1481 0666 1D96 adiw r26,13 + 1482 0668 1C92 st X,__zero_reg__ + 1483 066a 1D97 sbiw r26,13 + 232:../../../../Lib/cmdline.c **** } + 1485 .LM148: + 1486 066c 1E96 adiw r26,14 + 1487 066e 1C92 st X,__zero_reg__ + 1488 0670 00C0 rjmp .L29 + 1489 .L55: + 234:../../../../Lib/cmdline.c **** { + 1491 .LM149: + 1492 0672 2830 cpi r18,lo8(8) + 1493 0674 01F0 breq .+2 + 1494 0676 00C0 rjmp .L74 + 236:../../../../Lib/cmdline.c **** { + 1496 .LM150: + 1497 0678 F801 movw r30,r16 + 1498 067a 8685 ldd r24,Z+14 + 1499 067c 8823 tst r24 + 1500 067e 01F4 brne .+2 + 1501 0680 00C0 rjmp .L75 + 239:../../../../Lib/cmdline.c **** { + 1503 .LM151: + 1504 0682 9585 ldd r25,Z+13 + 1505 0684 8913 cpse r24,r25 + 1506 0686 00C0 rjmp .L76 + 243:../../../../Lib/cmdline.c **** fputc(' ' , state->myStdInOut); + 1508 .LM152: + 1509 0688 628D ldd r22,Z+26 + 1510 068a 738D ldd r23,Z+27 + 1511 068c 88E0 ldi r24,lo8(8) + 1512 068e 90E0 ldi r25,0 + 1513 0690 0E94 0000 call fputc + 244:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1515 .LM153: + 1516 0694 D801 movw r26,r16 + 1517 0696 5A96 adiw r26,26 + 1518 0698 6D91 ld r22,X+ + 1519 069a 7C91 ld r23,X + 1520 069c 5B97 sbiw r26,26+1 + 1521 069e 80E2 ldi r24,lo8(32) + 1522 06a0 90E0 ldi r25,0 + 1523 06a2 0E94 0000 call fputc + 245:../../../../Lib/cmdline.c **** // decrement our buffer length and edit position + 1525 .LM154: + 1526 06a6 F801 movw r30,r16 + 1527 06a8 628D ldd r22,Z+26 + 1528 06aa 738D ldd r23,Z+27 + 1529 06ac 88E0 ldi r24,lo8(8) + 1530 06ae 90E0 ldi r25,0 + 1531 06b0 0E94 0000 call fputc + 247:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos--; + 1533 .LM155: + 1534 06b4 D801 movw r26,r16 + 1535 06b6 1D96 adiw r26,13 + 1536 06b8 8C91 ld r24,X + 1537 06ba 1D97 sbiw r26,13 + 1538 06bc 8150 subi r24,lo8(-(-1)) + 1539 06be 1D96 adiw r26,13 + 1540 06c0 8C93 st X,r24 + 1541 06c2 1D97 sbiw r26,13 + 248:../../../../Lib/cmdline.c **** } + 1543 .LM156: + 1544 06c4 1E96 adiw r26,14 + 1545 06c6 8C91 ld r24,X + 1546 06c8 1E97 sbiw r26,14 + 1547 06ca 8150 subi r24,lo8(-(-1)) + 1548 06cc 1E96 adiw r26,14 + 1549 06ce 8C93 st X,r24 + 1550 06d0 00C0 rjmp .L29 + 1551 .L76: + 255:../../../../Lib/cmdline.c **** state->CmdlineBufferEditPos--; + 1553 .LM157: + 1554 06d2 9150 subi r25,lo8(-(-1)) + 1555 06d4 F801 movw r30,r16 + 1556 06d6 9587 std Z+13,r25 + 256:../../../../Lib/cmdline.c **** for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 1558 .LM158: + 1559 06d8 8150 subi r24,lo8(-(-1)) + 1560 06da 8687 std Z+14,r24 + 1561 .L77: + 257:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + 1563 .LM159: + 1564 06dc D801 movw r26,r16 + 1565 06de 1D96 adiw r26,13 + 1566 06e0 9C91 ld r25,X + 1567 06e2 1D97 sbiw r26,13 + 1568 06e4 6D91 ld r22,X+ + 1569 06e6 7C91 ld r23,X + 1570 06e8 8917 cp r24,r25 + 1571 06ea 00F4 brsh .L106 + 258:../../../../Lib/cmdline.c **** // repaint + 1573 .LM160: + 1574 06ec FB01 movw r30,r22 + 1575 06ee E80F add r30,r24 + 1576 06f0 F11D adc r31,__zero_reg__ + 1577 06f2 9181 ldd r25,Z+1 + 1578 06f4 9083 st Z,r25 + 257:../../../../Lib/cmdline.c **** state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + 1580 .LM161: + 1581 06f6 8F5F subi r24,lo8(-(1)) + 1582 06f8 00C0 rjmp .L77 + 1583 .L106: + 260:../../../../Lib/cmdline.c **** // add space to clear leftover characters + 1585 .LM162: + 1586 06fa C801 movw r24,r16 + 1587 06fc 0E94 0000 call cmdlineRepaint + 262:../../../../Lib/cmdline.c **** // reposition cursor + 1589 .LM163: + 1590 0700 F801 movw r30,r16 + 1591 0702 628D ldd r22,Z+26 + 1592 0704 738D ldd r23,Z+27 + 1593 0706 80E2 ldi r24,lo8(32) + 1594 0708 90E0 ldi r25,0 + 1595 070a 0E94 0000 call fputc + 264:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1597 .LM164: + 1598 070e D801 movw r26,r16 + 1599 0710 1E96 adiw r26,14 + 1600 0712 FC90 ld r15,X + 1601 .L79: + 264:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1603 .LM165: + 1604 0714 D801 movw r26,r16 + 1605 0716 1D96 adiw r26,13 + 1606 0718 8C91 ld r24,X + 1607 071a 90E0 ldi r25,0 + 1608 071c 2F2D mov r18,r15 + 1609 071e 30E0 ldi r19,0 + 1610 0720 8217 cp r24,r18 + 1611 0722 9307 cpc r25,r19 + 1612 0724 04F0 brlt .L29 + 265:../../../../Lib/cmdline.c **** } + 1614 .LM166: + 1615 0726 F801 movw r30,r16 + 1616 0728 628D ldd r22,Z+26 + 1617 072a 738D ldd r23,Z+27 + 1618 072c 88E0 ldi r24,lo8(8) + 1619 072e 90E0 ldi r25,0 + 1620 0730 0E94 0000 call fputc + 264:../../../../Lib/cmdline.c **** fputc(ASCII_BS , state->myStdInOut); + 1622 .LM167: + 1623 0734 F394 inc r15 + 1624 0736 00C0 rjmp .L79 + 1625 .L75: + 271:../../../../Lib/cmdline.c **** } + 1627 .LM168: + 1628 0738 F801 movw r30,r16 + 1629 073a 628D ldd r22,Z+26 + 1630 073c 738D ldd r23,Z+27 + 1631 073e 87E0 ldi r24,lo8(7) + 1632 0740 90E0 ldi r25,0 + 1633 0742 0E94 0000 call fputc + 1634 0746 00C0 rjmp .L29 + 1635 .L74: + 278:../../../../Lib/cmdline.c **** { + 1637 .LM169: + 1638 0748 2B31 cpi r18,lo8(27) + 1639 074a 01F4 brne .L29 + 280:../../../../Lib/cmdline.c **** } + 1641 .LM170: + 1642 074c 81E0 ldi r24,lo8(1) + 1643 .L99: + 1644 074e D801 movw r26,r16 + 1645 0750 5296 adiw r26,18 + 1646 0752 8C93 st X,r24 + 1647 .L29: + 1648 /* epilogue start */ + 282:../../../../Lib/cmdline.c **** + 1650 .LM171: + 1651 0754 2796 adiw r28,7 + 1652 0756 0FB6 in __tmp_reg__,__SREG__ + 1653 0758 F894 cli + 1654 075a DEBF out __SP_H__,r29 + 1655 075c 0FBE out __SREG__,__tmp_reg__ + 1656 075e CDBF out __SP_L__,r28 + 1657 0760 DF91 pop r29 + 1658 0762 CF91 pop r28 + 1659 0764 1F91 pop r17 + 1660 0766 0F91 pop r16 + 1661 0768 FF90 pop r15 + 1662 076a EF90 pop r14 + 1663 076c DF90 pop r13 + 1664 076e CF90 pop r12 + 1665 0770 BF90 pop r11 + 1666 0772 AF90 pop r10 + 1667 0774 0895 ret + 1683 .Lscope5: + 1685 .stabd 78,0,0 + 1688 .global cmdLineGetLastArgIdx + 1690 cmdLineGetLastArgIdx: + 1691 .stabd 46,0,0 + 519:../../../../Lib/cmdline.c **** } + 520:../../../../Lib/cmdline.c **** + 521:../../../../Lib/cmdline.c **** + 522:../../../../Lib/cmdline.c **** uint8_t cmdLineGetLastArgIdx(cmdState_t *state) + 523:../../../../Lib/cmdline.c **** { + 1693 .LM172: + 1694 .LFBB6: + 1695 /* prologue: function */ + 1696 /* frame size = 0 */ + 1697 /* stack size = 0 */ + 1698 .L__stack_usage = 0 + 1699 0776 DC01 movw r26,r24 + 1700 0778 1296 adiw r26,2 + 1701 077a ED91 ld r30,X+ + 1702 077c FC91 ld r31,X + 1703 077e 1397 sbiw r26,2+1 + 524:../../../../Lib/cmdline.c **** uint8_t result = 0; + 525:../../../../Lib/cmdline.c **** uint8_t lastWhite = 1; + 1705 .LM173: + 1706 0780 91E0 ldi r25,lo8(1) + 524:../../../../Lib/cmdline.c **** uint8_t result = 0; + 1708 .LM174: + 1709 0782 80E0 ldi r24,0 + 1710 .L108: + 526:../../../../Lib/cmdline.c **** char *str = state->CmdlineExcBuffer; + 527:../../../../Lib/cmdline.c **** while(*str != 0) + 1712 .LM175: + 1713 0784 2191 ld r18,Z+ + 1714 0786 2223 tst r18 + 1715 0788 01F0 breq .L113 + 528:../../../../Lib/cmdline.c **** { + 529:../../../../Lib/cmdline.c **** if (*str == ' ') + 1717 .LM176: + 1718 078a 2032 cpi r18,lo8(32) + 1719 078c 01F4 brne .L111 + 530:../../../../Lib/cmdline.c **** { + 531:../../../../Lib/cmdline.c **** if (lastWhite == 0) + 1721 .LM177: + 1722 078e 9111 cpse r25,__zero_reg__ + 1723 0790 00C0 rjmp .L112 + 532:../../../../Lib/cmdline.c **** result++; + 1725 .LM178: + 1726 0792 8F5F subi r24,lo8(-(1)) + 1727 0794 00C0 rjmp .L112 + 1728 .L111: + 533:../../../../Lib/cmdline.c **** lastWhite = 1; + 534:../../../../Lib/cmdline.c **** } + 535:../../../../Lib/cmdline.c **** else + 536:../../../../Lib/cmdline.c **** lastWhite = 0; + 1730 .LM179: + 1731 0796 90E0 ldi r25,0 + 1732 0798 00C0 rjmp .L108 + 1733 .L112: + 533:../../../../Lib/cmdline.c **** lastWhite = 1; + 1735 .LM180: + 1736 079a 91E0 ldi r25,lo8(1) + 1737 079c 00C0 rjmp .L108 + 1738 .L113: + 1739 /* epilogue start */ + 537:../../../../Lib/cmdline.c **** str++; + 538:../../../../Lib/cmdline.c **** } + 539:../../../../Lib/cmdline.c **** return result; + 540:../../../../Lib/cmdline.c **** } + 1741 .LM181: + 1742 079e 0895 ret + 1748 .Lscope6: + 1750 .stabd 78,0,0 + 1753 .global cmdlineMainLoop + 1755 cmdlineMainLoop: + 1756 .stabd 46,0,0 + 435:../../../../Lib/cmdline.c **** cliExRes_t result; + 1758 .LM182: + 1759 .LFBB7: + 1760 07a0 0F93 push r16 + 1761 07a2 1F93 push r17 + 1762 07a4 CF93 push r28 + 1763 07a6 DF93 push r29 + 1764 /* prologue: function */ + 1765 /* frame size = 0 */ + 1766 /* stack size = 4 */ + 1767 .L__stack_usage = 4 + 437:../../../../Lib/cmdline.c **** { + 1769 .LM183: + 1770 07a8 FC01 movw r30,r24 + 1771 07aa 0789 ldd r16,Z+23 + 1772 07ac 108D ldd r17,Z+24 + 1773 07ae 0115 cp r16,__zero_reg__ + 1774 07b0 1105 cpc r17,__zero_reg__ + 1775 07b2 01F4 brne .+2 + 1776 07b4 00C0 rjmp .L114 + 1777 07b6 EC01 movw r28,r24 + 439:../../../../Lib/cmdline.c **** result = state->CmdlineExecFunction(state); // run it + 1779 .LM184: + 1780 07b8 0E94 0000 call cmdLineGetLastArgIdx + 1781 07bc 898F std Y+25,r24 + 440:../../../../Lib/cmdline.c **** + 1783 .LM185: + 1784 07be CE01 movw r24,r28 + 1785 07c0 F801 movw r30,r16 + 1786 07c2 0995 icall + 442:../../../../Lib/cmdline.c **** { + 1788 .LM186: + 1789 07c4 8230 cpi r24,2 + 1790 07c6 9105 cpc r25,__zero_reg__ + 1791 07c8 01F0 breq .L117 + 1792 07ca 00F4 brsh .L118 + 1793 07cc 0197 sbiw r24,1 + 1794 07ce 01F0 breq .+2 + 1795 07d0 00C0 rjmp .L116 + 445:../../../../Lib/cmdline.c **** break; + 1797 .LM187: + 1798 07d2 80E0 ldi r24,lo8(__c.2705) + 1799 07d4 90E0 ldi r25,hi8(__c.2705) + 1800 07d6 00C0 rjmp .L122 + 1801 .L118: + 442:../../../../Lib/cmdline.c **** { + 1803 .LM188: + 1804 07d8 8430 cpi r24,4 + 1805 07da 9105 cpc r25,__zero_reg__ + 1806 07dc 01F4 brne .+2 + 1807 07de 00C0 rjmp .L120 + 1808 07e0 0597 sbiw r24,5 + 1809 07e2 01F0 breq .+2 + 1810 07e4 00C0 rjmp .L116 + 458:../../../../Lib/cmdline.c **** break; + 1812 .LM189: + 1813 07e6 80E0 ldi r24,lo8(__c.2719) + 1814 07e8 90E0 ldi r25,hi8(__c.2719) + 1815 07ea 00C0 rjmp .L122 + 1816 .L117: + 448:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, state->command_str); + 1818 .LM190: + 1819 07ec 80E0 ldi r24,lo8(__c.2709) + 1820 07ee 90E0 ldi r25,hi8(__c.2709) + 1821 07f0 9F93 push r25 + 1822 07f2 8F93 push r24 + 1823 07f4 8B8D ldd r24,Y+27 + 1824 07f6 8F93 push r24 + 1825 07f8 8A8D ldd r24,Y+26 + 1826 07fa 8F93 push r24 + 1827 07fc 0E94 0000 call fprintf_P + 449:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR(" ")); + 1829 .LM191: + 1830 0800 8C89 ldd r24,Y+20 + 1831 0802 8F93 push r24 + 1832 0804 8B89 ldd r24,Y+19 + 1833 0806 8F93 push r24 + 1834 0808 8B8D ldd r24,Y+27 + 1835 080a 8F93 push r24 + 1836 080c 8A8D ldd r24,Y+26 + 1837 080e 8F93 push r24 + 1838 0810 0E94 0000 call fprintf_P + 450:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, state->command_help_str); + 1840 .LM192: + 1841 0814 80E0 ldi r24,lo8(__c.2711) + 1842 0816 90E0 ldi r25,hi8(__c.2711) + 1843 0818 9F93 push r25 + 1844 081a 8F93 push r24 + 1845 081c 8B8D ldd r24,Y+27 + 1846 081e 8F93 push r24 + 1847 0820 8A8D ldd r24,Y+26 + 1848 0822 8F93 push r24 + 1849 0824 0E94 0000 call fprintf_P + 451:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("\r\n")); + 1851 .LM193: + 1852 0828 8E89 ldd r24,Y+22 + 1853 082a 8F93 push r24 + 1854 082c 8D89 ldd r24,Y+21 + 1855 082e 8F93 push r24 + 1856 0830 8B8D ldd r24,Y+27 + 1857 0832 8F93 push r24 + 1858 0834 8A8D ldd r24,Y+26 + 1859 0836 8F93 push r24 + 1860 0838 0E94 0000 call fprintf_P + 452:../../../../Lib/cmdline.c **** break; + 1862 .LM194: + 1863 083c 80E0 ldi r24,lo8(__c.2713) + 1864 083e 90E0 ldi r25,hi8(__c.2713) + 1865 0840 9F93 push r25 + 1866 0842 8F93 push r24 + 1867 0844 8B8D ldd r24,Y+27 + 1868 0846 8F93 push r24 + 1869 0848 8A8D ldd r24,Y+26 + 1870 084a 8F93 push r24 + 1871 084c 0E94 0000 call fprintf_P + 453:../../../../Lib/cmdline.c **** case ERROR_INFORM: + 1873 .LM195: + 1874 0850 8DB7 in r24,__SP_L__ + 1875 0852 9EB7 in r25,__SP_H__ + 1876 0854 4496 adiw r24,20 + 1877 0856 0FB6 in __tmp_reg__,__SREG__ + 1878 0858 F894 cli + 1879 085a 9EBF out __SP_H__,r25 + 1880 085c 0FBE out __SREG__,__tmp_reg__ + 1881 085e 8DBF out __SP_L__,r24 + 1882 0860 00C0 rjmp .L116 + 1883 .L120: + 455:../../../../Lib/cmdline.c **** break; + 1885 .LM196: + 1886 0862 80E0 ldi r24,lo8(__c.2716) + 1887 0864 90E0 ldi r25,hi8(__c.2716) + 1888 .L122: + 458:../../../../Lib/cmdline.c **** break; + 1890 .LM197: + 1891 0866 9F93 push r25 + 1892 0868 8F93 push r24 + 1893 086a 8B8D ldd r24,Y+27 + 1894 086c 8F93 push r24 + 1895 086e 8A8D ldd r24,Y+26 + 1896 0870 8F93 push r24 + 1897 0872 0E94 0000 call fprintf_P + 459:../../../../Lib/cmdline.c **** default: + 1899 .LM198: + 1900 0876 0F90 pop __tmp_reg__ + 1901 0878 0F90 pop __tmp_reg__ + 1902 087a 0F90 pop __tmp_reg__ + 1903 087c 0F90 pop __tmp_reg__ + 1904 .L116: + 463:../../../../Lib/cmdline.c **** state->command_str = NULL; + 1906 .LM199: + 1907 087e 188E std Y+24,__zero_reg__ + 1908 0880 1F8A std Y+23,__zero_reg__ + 464:../../../../Lib/cmdline.c **** state->command_help_str = NULL; + 1910 .LM200: + 1911 0882 1C8A std Y+20,__zero_reg__ + 1912 0884 1B8A std Y+19,__zero_reg__ + 465:../../../../Lib/cmdline.c **** cmdlinePrintPrompt(state); // output new prompt + 1914 .LM201: + 1915 0886 1E8A std Y+22,__zero_reg__ + 1916 0888 1D8A std Y+21,__zero_reg__ + 466:../../../../Lib/cmdline.c **** } + 1918 .LM202: + 1919 088a CE01 movw r24,r28 + 1920 /* epilogue start */ + 468:../../../../Lib/cmdline.c **** + 1922 .LM203: + 1923 088c DF91 pop r29 + 1924 088e CF91 pop r28 + 1925 0890 1F91 pop r17 + 1926 0892 0F91 pop r16 + 466:../../../../Lib/cmdline.c **** } + 1928 .LM204: + 1929 0894 0C94 0000 jmp cmdlinePrintPrompt + 1930 .L114: + 1931 /* epilogue start */ + 468:../../../../Lib/cmdline.c **** + 1933 .LM205: + 1934 0898 DF91 pop r29 + 1935 089a CF91 pop r28 + 1936 089c 1F91 pop r17 + 1937 089e 0F91 pop r16 + 1938 08a0 0895 ret + 1943 .Lscope7: + 1945 .stabd 78,0,0 + 1949 .global cmdlineGetArgStr + 1951 cmdlineGetArgStr: + 1952 .stabd 46,0,0 + 541:../../../../Lib/cmdline.c **** + 542:../../../../Lib/cmdline.c **** char* cmdlineGetArgStr(uint8_t argnum, cmdState_t *state) + 543:../../../../Lib/cmdline.c **** { + 1954 .LM206: + 1955 .LFBB8: + 1956 /* prologue: function */ + 1957 /* frame size = 0 */ + 1958 /* stack size = 0 */ + 1959 .L__stack_usage = 0 + 544:../../../../Lib/cmdline.c **** // find the offset of argument number [argnum] + 545:../../../../Lib/cmdline.c **** uint8_t idx=0; + 546:../../../../Lib/cmdline.c **** uint8_t arg; + 547:../../../../Lib/cmdline.c **** + 548:../../../../Lib/cmdline.c **** // find the first non-whitespace character + 549:../../../../Lib/cmdline.c **** while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + 1961 .LM207: + 1962 08a2 FB01 movw r30,r22 + 1963 08a4 2281 ldd r18,Z+2 + 1964 08a6 3381 ldd r19,Z+3 + 545:../../../../Lib/cmdline.c **** uint8_t arg; + 1966 .LM208: + 1967 08a8 90E0 ldi r25,0 + 1968 .L124: + 1970 .LM209: + 1971 08aa F901 movw r30,r18 + 1972 08ac E90F add r30,r25 + 1973 08ae F11D adc r31,__zero_reg__ + 1974 08b0 4081 ld r20,Z + 1975 08b2 4032 cpi r20,lo8(32) + 1976 08b4 01F4 brne .L132 + 1978 .LM210: + 1979 08b6 9F5F subi r25,lo8(-(1)) + 1980 08b8 00C0 rjmp .L124 + 1981 .L132: + 1983 .LM211: + 1984 08ba 40E0 ldi r20,0 + 1985 .L126: + 550:../../../../Lib/cmdline.c **** + 551:../../../../Lib/cmdline.c **** // we are at the first argument + 552:../../../../Lib/cmdline.c **** for(arg=0; argCmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] != ' ')) idx++; + 1992 .LM213: + 1993 08c0 F901 movw r30,r18 + 1994 08c2 E90F add r30,r25 + 1995 08c4 F11D adc r31,__zero_reg__ + 1996 08c6 5081 ld r21,Z + 1997 08c8 5F7D andi r21,lo8(-33) + 1998 08ca 01F0 breq .L128 + 2000 .LM214: + 2001 08cc 9F5F subi r25,lo8(-(1)) + 2002 08ce 00C0 rjmp .L131 + 2003 .L128: + 556:../../../../Lib/cmdline.c **** // find the first non-whitespace character + 557:../../../../Lib/cmdline.c **** while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + 2005 .LM215: + 2006 08d0 F901 movw r30,r18 + 2007 08d2 E90F add r30,r25 + 2008 08d4 F11D adc r31,__zero_reg__ + 2009 08d6 5081 ld r21,Z + 2010 08d8 5032 cpi r21,lo8(32) + 2011 08da 01F4 brne .L134 + 2013 .LM216: + 2014 08dc 9F5F subi r25,lo8(-(1)) + 2015 08de 00C0 rjmp .L128 + 2016 .L134: + 552:../../../../Lib/cmdline.c **** { + 2018 .LM217: + 2019 08e0 4F5F subi r20,lo8(-(1)) + 2020 08e2 00C0 rjmp .L126 + 2021 .L133: + 558:../../../../Lib/cmdline.c **** } + 559:../../../../Lib/cmdline.c **** // we are at the requested argument or the end of the buffer + 560:../../../../Lib/cmdline.c **** return &state->CmdlineExcBuffer[idx]; + 561:../../../../Lib/cmdline.c **** } + 2023 .LM218: + 2024 08e4 A901 movw r20,r18 + 2025 08e6 490F add r20,r25 + 2026 08e8 511D adc r21,__zero_reg__ + 2027 08ea CA01 movw r24,r20 + 2028 08ec 0895 ret + 2034 .Lscope8: + 2036 .stabd 78,0,0 + 2040 .global cmdlineGetArgInt + 2042 cmdlineGetArgInt: + 2043 .stabd 46,0,0 + 562:../../../../Lib/cmdline.c **** + 563:../../../../Lib/cmdline.c **** // return argument [argnum] interpreted as a decimal integer + 564:../../../../Lib/cmdline.c **** long cmdlineGetArgInt(uint8_t argnum, cmdState_t *state) + 565:../../../../Lib/cmdline.c **** { + 2045 .LM219: + 2046 .LFBB9: + 2047 08ee CF93 push r28 + 2048 08f0 DF93 push r29 + 2049 08f2 00D0 rcall . + 2050 08f4 CDB7 in r28,__SP_L__ + 2051 08f6 DEB7 in r29,__SP_H__ + 2052 /* prologue: function */ + 2053 /* frame size = 2 */ + 2054 /* stack size = 4 */ + 2055 .L__stack_usage = 4 + 566:../../../../Lib/cmdline.c **** char* endptr; + 567:../../../../Lib/cmdline.c **** return strtol(cmdlineGetArgStr(argnum, state), &endptr, 10); + 2057 .LM220: + 2058 08f8 0E94 0000 call cmdlineGetArgStr + 2059 08fc 4AE0 ldi r20,lo8(10) + 2060 08fe 50E0 ldi r21,0 + 2061 0900 BE01 movw r22,r28 + 2062 0902 6F5F subi r22,-1 + 2063 0904 7F4F sbci r23,-1 + 2064 0906 0E94 0000 call strtol + 2065 /* epilogue start */ + 568:../../../../Lib/cmdline.c **** } + 2067 .LM221: + 2068 090a 0F90 pop __tmp_reg__ + 2069 090c 0F90 pop __tmp_reg__ + 2070 090e DF91 pop r29 + 2071 0910 CF91 pop r28 + 2072 0912 0895 ret + 2077 .Lscope9: + 2079 .stabd 78,0,0 + 2083 .global cmdlineGetArgHex + 2085 cmdlineGetArgHex: + 2086 .stabd 46,0,0 + 569:../../../../Lib/cmdline.c **** + 570:../../../../Lib/cmdline.c **** // return argument [argnum] interpreted as a hex integer + 571:../../../../Lib/cmdline.c **** long cmdlineGetArgHex(uint8_t argnum, cmdState_t *state) + 572:../../../../Lib/cmdline.c **** { + 2088 .LM222: + 2089 .LFBB10: + 2090 0914 CF93 push r28 + 2091 0916 DF93 push r29 + 2092 0918 00D0 rcall . + 2093 091a CDB7 in r28,__SP_L__ + 2094 091c DEB7 in r29,__SP_H__ + 2095 /* prologue: function */ + 2096 /* frame size = 2 */ + 2097 /* stack size = 4 */ + 2098 .L__stack_usage = 4 + 573:../../../../Lib/cmdline.c **** char* endptr; + 574:../../../../Lib/cmdline.c **** return strtol(cmdlineGetArgStr(argnum, state), &endptr, 16); + 2100 .LM223: + 2101 091e 0E94 0000 call cmdlineGetArgStr + 2102 0922 40E1 ldi r20,lo8(16) + 2103 0924 50E0 ldi r21,0 + 2104 0926 BE01 movw r22,r28 + 2105 0928 6F5F subi r22,-1 + 2106 092a 7F4F sbci r23,-1 + 2107 092c 0E94 0000 call strtol + 2108 /* epilogue start */ + 575:../../../../Lib/cmdline.c **** } + 2110 .LM224: + 2111 0930 0F90 pop __tmp_reg__ + 2112 0932 0F90 pop __tmp_reg__ + 2113 0934 DF91 pop r29 + 2114 0936 CF91 pop r28 + 2115 0938 0895 ret + 2120 .Lscope10: + 2122 .stabd 78,0,0 + 2125 .global cmdPrintHelp + 2127 cmdPrintHelp: + 2128 .stabd 46,0,0 + 576:../../../../Lib/cmdline.c **** + 577:../../../../Lib/cmdline.c **** void cmdPrintHelp(cmdState_t *state) + 578:../../../../Lib/cmdline.c **** { + 2130 .LM225: + 2131 .LFBB11: + 2132 093a AF92 push r10 + 2133 093c BF92 push r11 + 2134 093e CF92 push r12 + 2135 0940 DF92 push r13 + 2136 0942 EF92 push r14 + 2137 0944 FF92 push r15 + 2138 0946 0F93 push r16 + 2139 0948 1F93 push r17 + 2140 094a CF93 push r28 + 2141 094c DF93 push r29 + 2142 094e 00D0 rcall . + 2143 0950 00D0 rcall . + 2144 0952 00D0 rcall . + 2145 0954 CDB7 in r28,__SP_L__ + 2146 0956 DEB7 in r29,__SP_H__ + 2147 /* prologue: function */ + 2148 /* frame size = 6 */ + 2149 /* stack size = 16 */ + 2150 .L__stack_usage = 16 + 2151 0958 8C01 movw r16,r24 + 579:../../../../Lib/cmdline.c **** command_t tmp; + 580:../../../../Lib/cmdline.c **** const command_t *tmpPtr = state->cmdList; + 2153 .LM226: + 2154 095a FC01 movw r30,r24 + 2155 095c E1A0 ldd r14,Z+33 + 2156 095e F2A0 ldd r15,Z+34 + 581:../../../../Lib/cmdline.c **** + 582:../../../../Lib/cmdline.c **** memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + 2158 .LM227: + 2159 0960 46E0 ldi r20,lo8(6) + 2160 0962 50E0 ldi r21,0 + 2161 0964 B701 movw r22,r14 + 2162 0966 CE01 movw r24,r28 + 2163 0968 0196 adiw r24,1 + 2164 096a 0E94 0000 call memcpy_P + 583:../../../../Lib/cmdline.c **** do + 584:../../../../Lib/cmdline.c **** { + 585:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, tmp.commandStr); + 586:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("\t")); + 2166 .LM228: + 2167 096e 80E0 ldi r24,lo8(__c.2807) + 2168 0970 A82E mov r10,r24 + 2169 0972 80E0 ldi r24,hi8(__c.2807) + 2170 0974 B82E mov r11,r24 + 587:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, tmp.commandHelpStr); + 588:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("\r\n")); + 2172 .LM229: + 2173 0976 90E0 ldi r25,lo8(__c.2809) + 2174 0978 C92E mov r12,r25 + 2175 097a 90E0 ldi r25,hi8(__c.2809) + 2176 097c D92E mov r13,r25 + 2177 .L138: + 585:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, PSTR("\t")); + 2179 .LM230: + 2180 097e 8A81 ldd r24,Y+2 + 2181 0980 8F93 push r24 + 2182 0982 8981 ldd r24,Y+1 + 2183 0984 8F93 push r24 + 2184 0986 F801 movw r30,r16 + 2185 0988 838D ldd r24,Z+27 + 2186 098a 8F93 push r24 + 2187 098c 828D ldd r24,Z+26 + 2188 098e 8F93 push r24 + 2189 0990 0E94 0000 call fprintf_P + 586:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, tmp.commandHelpStr); + 2191 .LM231: + 2192 0994 BF92 push r11 + 2193 0996 AF92 push r10 + 2194 0998 F801 movw r30,r16 + 2195 099a 838D ldd r24,Z+27 + 2196 099c 8F93 push r24 + 2197 099e 828D ldd r24,Z+26 + 2198 09a0 8F93 push r24 + 2199 09a2 0E94 0000 call fprintf_P + 587:../../../../Lib/cmdline.c **** fprintf_P(state->myStdInOut, tmp.commandHelpStr); + 2201 .LM232: + 2202 09a6 8C81 ldd r24,Y+4 + 2203 09a8 8F93 push r24 + 2204 09aa 8B81 ldd r24,Y+3 + 2205 09ac 8F93 push r24 + 2206 09ae F801 movw r30,r16 + 2207 09b0 838D ldd r24,Z+27 + 2208 09b2 8F93 push r24 + 2209 09b4 828D ldd r24,Z+26 + 2210 09b6 8F93 push r24 + 2211 09b8 0E94 0000 call fprintf_P + 2213 .LM233: + 2214 09bc DF92 push r13 + 2215 09be CF92 push r12 + 2216 09c0 F801 movw r30,r16 + 2217 09c2 838D ldd r24,Z+27 + 2218 09c4 8F93 push r24 + 2219 09c6 828D ldd r24,Z+26 + 2220 09c8 8F93 push r24 + 2221 09ca 0E94 0000 call fprintf_P + 589:../../../../Lib/cmdline.c **** + 590:../../../../Lib/cmdline.c **** tmpPtr++; + 2223 .LM234: + 2224 09ce F6E0 ldi r31,6 + 2225 09d0 EF0E add r14,r31 + 2226 09d2 F11C adc r15,__zero_reg__ + 591:../../../../Lib/cmdline.c **** memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + 2228 .LM235: + 2229 09d4 46E0 ldi r20,lo8(6) + 2230 09d6 50E0 ldi r21,0 + 2231 09d8 B701 movw r22,r14 + 2232 09da CE01 movw r24,r28 + 2233 09dc 0196 adiw r24,1 + 2234 09de 0E94 0000 call memcpy_P + 592:../../../../Lib/cmdline.c **** } + 593:../../../../Lib/cmdline.c **** while (tmp.commandFun != NULL); + 2236 .LM236: + 2237 09e2 0FB6 in __tmp_reg__,__SREG__ + 2238 09e4 F894 cli + 2239 09e6 DEBF out __SP_H__,r29 + 2240 09e8 0FBE out __SREG__,__tmp_reg__ + 2241 09ea CDBF out __SP_L__,r28 + 2242 09ec 8D81 ldd r24,Y+5 + 2243 09ee 9E81 ldd r25,Y+6 + 2244 09f0 892B or r24,r25 + 2245 09f2 01F4 brne .L138 + 2246 /* epilogue start */ + 594:../../../../Lib/cmdline.c **** } + 2248 .LM237: + 2249 09f4 2696 adiw r28,6 + 2250 09f6 0FB6 in __tmp_reg__,__SREG__ + 2251 09f8 F894 cli + 2252 09fa DEBF out __SP_H__,r29 + 2253 09fc 0FBE out __SREG__,__tmp_reg__ + 2254 09fe CDBF out __SP_L__,r28 + 2255 0a00 DF91 pop r29 + 2256 0a02 CF91 pop r28 + 2257 0a04 1F91 pop r17 + 2258 0a06 0F91 pop r16 + 2259 0a08 FF90 pop r15 + 2260 0a0a EF90 pop r14 + 2261 0a0c DF90 pop r13 + 2262 0a0e CF90 pop r12 + 2263 0a10 BF90 pop r11 + 2264 0a12 AF90 pop r10 + 2265 0a14 0895 ret + 2271 .Lscope11: + 2273 .stabd 78,0,0 + 2274 .section .progmem.data,"a",@progbits + 2277 __c.2809: + 2278 0000 0D0A 00 .string "\r\n" + 2281 __c.2807: + 2282 0003 0900 .string "\t" + 2285 __c.2719: + 2286 0005 4F70 6572 .string "Operation not allowed\r\n" + 2286 6174 696F + 2286 6E20 6E6F + 2286 7420 616C + 2286 6C6F 7765 + 2289 __c.2716: + 2290 001d 4F70 6572 .string "Operation failed\r\n" + 2290 6174 696F + 2290 6E20 6661 + 2290 696C 6564 + 2290 0D0A 00 + 2293 __c.2713: + 2294 0030 0D0A 00 .string "\r\n" + 2297 __c.2711: + 2298 0033 2000 .string " " + 2301 __c.2709: + 2302 0035 5379 6E74 .string "Syntax Error. Use: " + 2302 6178 2045 + 2302 7272 6F72 + 2302 2E20 5573 + 2302 653A 2000 + 2305 __c.2705: + 2306 0049 4F4B 0D0A .string "OK\r\n" + 2306 00 + 2307 .global CmdlineCmdNotFound + 2310 CmdlineCmdNotFound: + 2311 004e 2320 6E6B .string "# nk" + 2311 00 + 2312 .global CmdlineNotice + 2315 CmdlineNotice: + 2316 0053 636D 646C .string "cmdline: " + 2316 696E 653A + 2316 2000 + 2317 .global CmdlinePromptConfigure + 2320 CmdlinePromptConfigure: + 2321 005d 446F 6D4F .string "DomOs@" + 2321 7340 00 + 2322 .global CmdlinePromptEnable + 2325 CmdlinePromptEnable: + 2326 0064 446F 6D4F .string "DomOs#" + 2326 7323 00 + 2327 .global CmdlinePromptNormal + 2330 CmdlinePromptNormal: + 2331 006b 446F 6D4F .string "DomOs>" + 2331 733E 00 + 2332 .comm xSemaphoreRs485,2,1 + 2333 .comm cliBuffer,128,1 + 2341 .text + 2343 .Letext0: + 2344 .ident "GCC: (GNU) 4.9.2" + 2345 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 cmdline.c + /tmp/ccLZI2y8.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccLZI2y8.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccLZI2y8.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccLZI2y8.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccLZI2y8.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccLZI2y8.s:193 .text:0000000000000000 cmdlinePrintPrompt + /tmp/ccLZI2y8.s:2330 .progmem.data:000000000000006b CmdlinePromptNormal + /tmp/ccLZI2y8.s:2325 .progmem.data:0000000000000064 CmdlinePromptEnable + /tmp/ccLZI2y8.s:2320 .progmem.data:000000000000005d CmdlinePromptConfigure + /tmp/ccLZI2y8.s:286 .text:000000000000004e cmdlineRepaint + /tmp/ccLZI2y8.s:396 .text:00000000000000d6 cmdHistoryCopy + /tmp/ccLZI2y8.s:473 .text:000000000000011e cmdStateConfigure + /tmp/ccLZI2y8.s:578 .text:0000000000000198 cmdlineInputFunc + /tmp/ccLZI2y8.s:2315 .progmem.data:0000000000000053 CmdlineNotice + /tmp/ccLZI2y8.s:2310 .progmem.data:000000000000004e CmdlineCmdNotFound + /tmp/ccLZI2y8.s:1690 .text:0000000000000776 cmdLineGetLastArgIdx + /tmp/ccLZI2y8.s:1755 .text:00000000000007a0 cmdlineMainLoop + /tmp/ccLZI2y8.s:2305 .progmem.data:0000000000000049 __c.2705 + /tmp/ccLZI2y8.s:2285 .progmem.data:0000000000000005 __c.2719 + /tmp/ccLZI2y8.s:2301 .progmem.data:0000000000000035 __c.2709 + /tmp/ccLZI2y8.s:2297 .progmem.data:0000000000000033 __c.2711 + /tmp/ccLZI2y8.s:2293 .progmem.data:0000000000000030 __c.2713 + /tmp/ccLZI2y8.s:2289 .progmem.data:000000000000001d __c.2716 + /tmp/ccLZI2y8.s:1951 .text:00000000000008a2 cmdlineGetArgStr + /tmp/ccLZI2y8.s:2042 .text:00000000000008ee cmdlineGetArgInt + /tmp/ccLZI2y8.s:2085 .text:0000000000000914 cmdlineGetArgHex + /tmp/ccLZI2y8.s:2127 .text:000000000000093a cmdPrintHelp + /tmp/ccLZI2y8.s:2281 .progmem.data:0000000000000003 __c.2807 + /tmp/ccLZI2y8.s:2277 .progmem.data:0000000000000000 __c.2809 + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000080 cliBuffer + +UNDEFINED SYMBOLS +fputc +memset +strcpy +memcpy_P +strncmp_P +fprintf_P +strtol +__do_clear_bss diff --git a/Lib/ds1305.c b/Lib/ds1305.c new file mode 100644 index 0000000..9705a39 --- /dev/null +++ b/Lib/ds1305.c @@ -0,0 +1,146 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * http://www.gnu.org/licenses/gpl.html + * + * Based on the enc28j60.c file from the AVRlib library by Pascal Stang. + * For AVRlib See http://www.procyonengineering.com/ + * Used with explicit permission of Pascal Stang. + * + * Title: Microchip ENC28J60 Ethernet Interface Driver + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ +#include +#include +#include "ds1305.h" +#include "spiXmega.h" + +void spiEnableDS1305(void) {}; +void spiDisableDS1305(void) {}; + + +void readTimeBCD(timeBCD_t *time) +{ + spiTake(); + spiEnableDS1305(); + + uint8_t *ptr = (uint8_t *)(time); + uint8_t i; + + spiSend(0x00); + + for (i=0; i 95) + return 1; + if (addr + length > 95) + return 2; + + addr += 0xA0; + + spiTake(); + spiEnableDS1305(); + + spiSend(addr); + while (length > 0) + { + spiSend(*data); + data++; + length--; + } + + spiDisableDS1305(); + spiGive(); + return 0; +} +uint8_t ds1305readMem (uint8_t addr, uint8_t length, uint8_t *data) +{ + if (addr >95) + return 1; + if (addr + length > 95) + return 2; + + addr += 0x20; + + spiTake(); + spiEnableDS1305(); + + spiSend(addr); + while (length > 0) + { + *data = spiSend(0); + data++; + length--; + } + + spiDisableDS1305(); + spiGive(); + return 0; +} diff --git a/Lib/ds1305.lst b/Lib/ds1305.lst new file mode 100644 index 0000000..fada866 --- /dev/null +++ b/Lib/ds1305.lst @@ -0,0 +1,541 @@ + 1 .file "ds1305.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 153 .weak spiEnableDS1305 + 155 spiEnableDS1305: + 156 .stabd 46,0,0 + 1:../../../../Lib/ds1305.c **** /********************************************* + 2:../../../../Lib/ds1305.c **** * vim:sw=8:ts=8:si:et + 3:../../../../Lib/ds1305.c **** * To use the above modeline in vim you must have "set modeline" in your .vimrc + 4:../../../../Lib/ds1305.c **** * Author: Guido Socher + 5:../../../../Lib/ds1305.c **** * Copyright: GPL V2 + 6:../../../../Lib/ds1305.c **** * http://www.gnu.org/licenses/gpl.html + 7:../../../../Lib/ds1305.c **** * + 8:../../../../Lib/ds1305.c **** * Based on the enc28j60.c file from the AVRlib library by Pascal Stang. + 9:../../../../Lib/ds1305.c **** * For AVRlib See http://www.procyonengineering.com/ + 10:../../../../Lib/ds1305.c **** * Used with explicit permission of Pascal Stang. + 11:../../../../Lib/ds1305.c **** * + 12:../../../../Lib/ds1305.c **** * Title: Microchip ENC28J60 Ethernet Interface Driver + 13:../../../../Lib/ds1305.c **** * Chip type : ATMEGA88 with ENC28J60 + 14:../../../../Lib/ds1305.c **** *********************************************/ + 15:../../../../Lib/ds1305.c **** #include + 16:../../../../Lib/ds1305.c **** #include + 17:../../../../Lib/ds1305.c **** #include "ds1305.h" + 18:../../../../Lib/ds1305.c **** #include "spiXmega.h" + 19:../../../../Lib/ds1305.c **** + 20:../../../../Lib/ds1305.c **** void spiEnableDS1305(void) {}; + 158 .LM0: + 159 .LFBB1: + 160 /* prologue: function */ + 161 /* frame size = 0 */ + 162 /* stack size = 0 */ + 163 .L__stack_usage = 0 + 164 0000 0895 ret + 166 .Lscope1: + 168 .stabd 78,0,0 + 170 .weak spiDisableDS1305 + 172 spiDisableDS1305: + 173 .stabd 46,0,0 + 21:../../../../Lib/ds1305.c **** void spiDisableDS1305(void) {}; + 175 .LM1: + 176 .LFBB2: + 177 /* prologue: function */ + 178 /* frame size = 0 */ + 179 /* stack size = 0 */ + 180 .L__stack_usage = 0 + 181 0002 0895 ret + 183 .Lscope2: + 185 .stabd 78,0,0 + 188 .global readTimeBCD + 190 readTimeBCD: + 191 .stabd 46,0,0 + 22:../../../../Lib/ds1305.c **** + 23:../../../../Lib/ds1305.c **** + 24:../../../../Lib/ds1305.c **** void readTimeBCD(timeBCD_t *time) + 25:../../../../Lib/ds1305.c **** { + 193 .LM2: + 194 .LFBB3: + 196 .LM3: + 197 0004 0F93 push r16 + 198 0006 1F93 push r17 + 199 0008 CF93 push r28 + 200 /* prologue: function */ + 201 /* frame size = 0 */ + 202 /* stack size = 3 */ + 203 .L__stack_usage = 3 + 204 000a 8C01 movw r16,r24 + 26:../../../../Lib/ds1305.c **** spiTake(); + 206 .LM4: + 207 000c 0E94 0000 call spiTake + 27:../../../../Lib/ds1305.c **** spiEnableDS1305(); + 209 .LM5: + 210 0010 0E94 0000 call spiEnableDS1305 + 28:../../../../Lib/ds1305.c **** + 29:../../../../Lib/ds1305.c **** uint8_t *ptr = (uint8_t *)(time); + 30:../../../../Lib/ds1305.c **** uint8_t i; + 31:../../../../Lib/ds1305.c **** + 32:../../../../Lib/ds1305.c **** spiSend(0x00); + 212 .LM6: + 213 0014 80E0 ldi r24,0 + 214 0016 0E94 0000 call spiSend + 33:../../../../Lib/ds1305.c **** + 34:../../../../Lib/ds1305.c **** for (i=0; i 95) + 450 .LM38: + 451 00b6 8036 cpi r24,lo8(96) + 452 00b8 00F4 brsh .L19 + 102:../../../../Lib/ds1305.c **** return 1; + 103:../../../../Lib/ds1305.c **** if (addr + length > 95) + 454 .LM39: + 455 00ba 262F mov r18,r22 + 456 00bc 30E0 ldi r19,0 + 457 00be 280F add r18,r24 + 458 00c0 311D adc r19,__zero_reg__ + 459 00c2 2036 cpi r18,96 + 460 00c4 3105 cpc r19,__zero_reg__ + 461 00c6 04F4 brge .L20 + 104:../../../../Lib/ds1305.c **** return 2; + 105:../../../../Lib/ds1305.c **** + 106:../../../../Lib/ds1305.c **** addr += 0xA0; + 107:../../../../Lib/ds1305.c **** + 108:../../../../Lib/ds1305.c **** spiTake(); + 463 .LM40: + 464 00c8 8983 std Y+1,r24 + 465 00ca 0E94 0000 call spiTake + 109:../../../../Lib/ds1305.c **** spiEnableDS1305(); + 467 .LM41: + 468 00ce 0E94 0000 call spiEnableDS1305 + 110:../../../../Lib/ds1305.c **** + 111:../../../../Lib/ds1305.c **** spiSend(addr); + 470 .LM42: + 471 00d2 8981 ldd r24,Y+1 + 472 00d4 8056 subi r24,lo8(-(-96)) + 473 00d6 0E94 0000 call spiSend + 474 .L17: + 112:../../../../Lib/ds1305.c **** while (length > 0) + 476 .LM43: + 477 00da FF20 tst r15 + 478 00dc 01F0 breq .L21 + 113:../../../../Lib/ds1305.c **** { + 114:../../../../Lib/ds1305.c **** spiSend(*data); + 480 .LM44: + 481 00de F801 movw r30,r16 + 482 00e0 8191 ld r24,Z+ + 483 00e2 8F01 movw r16,r30 + 484 00e4 0E94 0000 call spiSend + 115:../../../../Lib/ds1305.c **** data++; + 116:../../../../Lib/ds1305.c **** length--; + 486 .LM45: + 487 00e8 FA94 dec r15 + 488 00ea 00C0 rjmp .L17 + 489 .L21: + 117:../../../../Lib/ds1305.c **** } + 118:../../../../Lib/ds1305.c **** + 119:../../../../Lib/ds1305.c **** spiDisableDS1305(); + 491 .LM46: + 492 00ec 0E94 0000 call spiDisableDS1305 + 120:../../../../Lib/ds1305.c **** spiGive(); + 494 .LM47: + 495 00f0 0E94 0000 call spiGive + 121:../../../../Lib/ds1305.c **** return 0; + 497 .LM48: + 498 00f4 80E0 ldi r24,0 + 499 00f6 00C0 rjmp .L16 + 500 .L19: + 102:../../../../Lib/ds1305.c **** if (addr + length > 95) + 502 .LM49: + 503 00f8 81E0 ldi r24,lo8(1) + 504 00fa 00C0 rjmp .L16 + 505 .L20: + 104:../../../../Lib/ds1305.c **** + 507 .LM50: + 508 00fc 82E0 ldi r24,lo8(2) + 509 .L16: + 510 /* epilogue start */ + 122:../../../../Lib/ds1305.c **** } + 512 .LM51: + 513 00fe 0F90 pop __tmp_reg__ + 514 0100 DF91 pop r29 + 515 0102 CF91 pop r28 + 516 0104 1F91 pop r17 + 517 0106 0F91 pop r16 + 518 0108 FF90 pop r15 + 519 010a 0895 ret + 521 .Lscope10: + 523 .stabd 78,0,0 + 528 .global ds1305readMem + 530 ds1305readMem: + 531 .stabd 46,0,0 + 123:../../../../Lib/ds1305.c **** uint8_t ds1305readMem (uint8_t addr, uint8_t length, uint8_t *data) + 124:../../../../Lib/ds1305.c **** { + 533 .LM52: + 534 .LFBB11: + 535 010c FF92 push r15 + 536 010e 0F93 push r16 + 537 0110 1F93 push r17 + 538 0112 CF93 push r28 + 539 0114 DF93 push r29 + 540 0116 1F92 push __zero_reg__ + 541 0118 CDB7 in r28,__SP_L__ + 542 011a DEB7 in r29,__SP_H__ + 543 /* prologue: function */ + 544 /* frame size = 1 */ + 545 /* stack size = 6 */ + 546 .L__stack_usage = 6 + 547 011c F62E mov r15,r22 + 548 011e 8A01 movw r16,r20 + 125:../../../../Lib/ds1305.c **** if (addr >95) + 550 .LM53: + 551 0120 8036 cpi r24,lo8(96) + 552 0122 00F4 brsh .L26 + 126:../../../../Lib/ds1305.c **** return 1; + 127:../../../../Lib/ds1305.c **** if (addr + length > 95) + 554 .LM54: + 555 0124 262F mov r18,r22 + 556 0126 30E0 ldi r19,0 + 557 0128 280F add r18,r24 + 558 012a 311D adc r19,__zero_reg__ + 559 012c 2036 cpi r18,96 + 560 012e 3105 cpc r19,__zero_reg__ + 561 0130 04F4 brge .L27 + 128:../../../../Lib/ds1305.c **** return 2; + 129:../../../../Lib/ds1305.c **** + 130:../../../../Lib/ds1305.c **** addr += 0x20; + 131:../../../../Lib/ds1305.c **** + 132:../../../../Lib/ds1305.c **** spiTake(); + 563 .LM55: + 564 0132 8983 std Y+1,r24 + 565 0134 0E94 0000 call spiTake + 133:../../../../Lib/ds1305.c **** spiEnableDS1305(); + 567 .LM56: + 568 0138 0E94 0000 call spiEnableDS1305 + 134:../../../../Lib/ds1305.c **** + 135:../../../../Lib/ds1305.c **** spiSend(addr); + 570 .LM57: + 571 013c 8981 ldd r24,Y+1 + 572 013e 805E subi r24,lo8(-(32)) + 573 0140 0E94 0000 call spiSend + 574 .L24: + 136:../../../../Lib/ds1305.c **** while (length > 0) + 576 .LM58: + 577 0144 FF20 tst r15 + 578 0146 01F0 breq .L28 + 137:../../../../Lib/ds1305.c **** { + 138:../../../../Lib/ds1305.c **** *data = spiSend(0); + 580 .LM59: + 581 0148 80E0 ldi r24,0 + 582 014a 0E94 0000 call spiSend + 583 014e F801 movw r30,r16 + 584 0150 8193 st Z+,r24 + 585 0152 8F01 movw r16,r30 + 139:../../../../Lib/ds1305.c **** data++; + 140:../../../../Lib/ds1305.c **** length--; + 587 .LM60: + 588 0154 FA94 dec r15 + 589 0156 00C0 rjmp .L24 + 590 .L28: + 141:../../../../Lib/ds1305.c **** } + 142:../../../../Lib/ds1305.c **** + 143:../../../../Lib/ds1305.c **** spiDisableDS1305(); + 592 .LM61: + 593 0158 0E94 0000 call spiDisableDS1305 + 144:../../../../Lib/ds1305.c **** spiGive(); + 595 .LM62: + 596 015c 0E94 0000 call spiGive + 145:../../../../Lib/ds1305.c **** return 0; + 598 .LM63: + 599 0160 80E0 ldi r24,0 + 600 0162 00C0 rjmp .L23 + 601 .L26: + 126:../../../../Lib/ds1305.c **** if (addr + length > 95) + 603 .LM64: + 604 0164 81E0 ldi r24,lo8(1) + 605 0166 00C0 rjmp .L23 + 606 .L27: + 128:../../../../Lib/ds1305.c **** + 608 .LM65: + 609 0168 82E0 ldi r24,lo8(2) + 610 .L23: + 611 /* epilogue start */ + 146:../../../../Lib/ds1305.c **** } + 613 .LM66: + 614 016a 0F90 pop __tmp_reg__ + 615 016c DF91 pop r29 + 616 016e CF91 pop r28 + 617 0170 1F91 pop r17 + 618 0172 0F91 pop r16 + 619 0174 FF90 pop r15 + 620 0176 0895 ret + 622 .Lscope11: + 624 .stabd 78,0,0 + 625 .comm xSemaphoreSpiSS,2,1 + 627 .weak spiSend + 629 .Letext0: + 630 .ident "GCC: (GNU) 4.9.2" + 631 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 ds1305.c + /tmp/ccryRLWS.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccryRLWS.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccryRLWS.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccryRLWS.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccryRLWS.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccryRLWS.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccryRLWS.s:155 .text:0000000000000000 spiEnableDS1305 + /tmp/ccryRLWS.s:172 .text:0000000000000002 spiDisableDS1305 + /tmp/ccryRLWS.s:190 .text:0000000000000004 readTimeBCD + /tmp/ccryRLWS.s:254 .text:000000000000003c readTimeDecoded + /tmp/ccryRLWS.s:274 .text:0000000000000040 readTime + /tmp/ccryRLWS.s:294 .text:0000000000000044 setTimeBCD + /tmp/ccryRLWS.s:352 .text:000000000000007e setTimeDecoded + /tmp/ccryRLWS.s:372 .text:0000000000000082 setTime + /tmp/ccryRLWS.s:391 .text:0000000000000086 ds1305start + /tmp/ccryRLWS.s:430 .text:00000000000000a2 ds1305writeMem + /tmp/ccryRLWS.s:530 .text:000000000000010c ds1305readMem + *COM*:0000000000000002 xSemaphoreSpiSS + +UNDEFINED SYMBOLS +spiTake +spiSend +spiGive +__do_clear_bss diff --git a/Lib/enc28j60.c b/Lib/enc28j60.c new file mode 100644 index 0000000..fb869a9 --- /dev/null +++ b/Lib/enc28j60.c @@ -0,0 +1,482 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * http://www.gnu.org/licenses/gpl.html + * + * Based on the enc28j60.c file from the AVRlib library by Pascal Stang + * For AVRlib See http://www.procyonengineering.com/ + * Used with explicit permission of Pascal Stang. + * + * Title: Microchip ENC28J60 Ethernet Interface Driver + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ + +#include "enc28j60.h" + + +static uint8_t Enc28j60Bank; +static uint16_t gNextPacketPtr; + + +/** + * Initialize enc28j60 + * @param *macaddr - pointer to the mac address (6 bytes) + */ +static void enc28j60Init(uint8_t* macaddr); + +/** + * Read register value (without changing the bank) + * @param op - operation type + * @param address - register address + * @return register value + */ +static uint8_t enc28j60ReadOp (uint8_t op, uint8_t address); +static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data); +static void enc28j60SetBank(uint8_t address); +static void enc28j60ReadBuffer(uint16_t len, uint8_t* data); +static void enc28j60WriteBuffer(uint16_t len, uint8_t* data); + +/** + * Reads Enc28j60 control register + * @param address - register address. Banks are changed automatically + * @return control register value + */ +static uint8_t enc28j60Read(uint8_t address); + +/** + * Writes Enc28j60 control register + * @param address - register address. Banks are changed automatically + * @param data - control register value to be writen + */ +static void enc28j60Write(uint8_t address, uint8_t data); + +/** + * Reads Enc28j60 phy register + * @param address - register address. Banks are changed automatically + * @return phy register value + */ +static uint16_t enc28j60PhyReadH(uint8_t address); + +/** + * Writes Enc28j60 phy register + * @param address - register address. Banks are changed automatically + * @param data - phy register value to be writen + */ +static void enc28j60PhyWrite(uint8_t address, uint16_t data); + + +//void enc28j60BufferSend(uint16_t len, roundBuffer* buffer); + +uint8_t enc28j60hasRxPkt(void); +uint8_t enc28j60getrev(void); +uint8_t enc28j60linkup(void); + +void nicMacInit(void) +{ + vTaskDelay (5); + enc28j60Init (nicState.mac.addr); +// enc28j60clkout (2); // change clkout from 6.25MHz to 12.5MHz + vTaskDelay (5); + enc28j60PhyWrite (PHLCON, 0x476); + vTaskDelay (2); +} + +uint8_t enc28j60ReadOp(uint8_t op, uint8_t address) +{ + uint8_t result; + //spiTake(); + spiEnableEnc28j60(); + + // issue read command + spiSendENC(op | (address & ADDR_MASK)); + + // read data + result = spiSendENC(0x00); + + // do dummy read if needed (for mac and mii, see datasheet page 29) + if(address & 0x80) + { + result = spiSendENC(0x00); + } + + spiDisableEnc28j60(); + // spiGive(); + return result; +} + +void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data) +{ + // spiTake(); + spiEnableEnc28j60(); + // issue write command + //spiSend(op | (address & ADDR_MASK)); + spiSendENC(op | (address & ADDR_MASK)); + spiSendENC(data); + spiDisableEnc28j60(); + // spiGive(); +} + +void enc28j60ReadBuffer(uint16_t len, uint8_t* data) +{ + // spiTake(); + spiEnableEnc28j60(); + spiSendENC(ENC28J60_READ_BUF_MEM); + while(len) + { + len--; + *data = spiSendENC(0x00); + data++; + } + *data='\0'; + spiDisableEnc28j60(); + // spiGive(); +} + +void enc28j60WriteBuffer(uint16_t len, uint8_t* data) +{ + //spiTake(); + spiEnableEnc28j60(); + // issue write command + //spiSend(ENC28J60_WRITE_BUF_MEM); // + spiSendENC(ENC28J60_WRITE_BUF_MEM); + while(len) + { + len--; + spiSendENC(*data); // write data + data++; + } + spiDisableEnc28j60(); + //spiGive(); +} + +// void enc28j60WriteRoundBuffer(uint8_t len, roundBuffer *buffer) +// { +// spiTake(); +// spiEnableEnc28j60(); +// // issue write command +// //spiSend(ENC28J60_WRITE_BUF_MEM); // +// spiSend(ENC28J60_WRITE_BUF_MEM); +// uint8_t data; +// while(len) +// { +// len--; +// data = *buffer->readIdx.ptr16; +// buffer->readIdx.ptr.L++; +// +// spiSend(*data); // write data +// } +// spiDisableEnc28j60(); +// spiGive(); +// } + + +void enc28j60SetBank(uint8_t address) +{ + // set the bank (if needed) + if((address & BANK_MASK) != Enc28j60Bank) + { + // set the bank + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); + Enc28j60Bank = (address & BANK_MASK); + } +} + +uint8_t enc28j60Read(uint8_t address) +{ + // set the bank + enc28j60SetBank(address); + // do the read + uint8_t result = enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); + return result; +} + +// read upper 8 bits +uint16_t enc28j60PhyReadH(uint8_t address) +{ + // Set the right address and start the register read operation + enc28j60Write(MIREGADR, address); + enc28j60Write(MICMD, MICMD_MIIRD); + + vTaskDelay(0); + + // wait until the PHY read completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY) + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zawieszenie + + // reset reading bit + enc28j60Write(MICMD, 0x00); + + return (enc28j60Read(MIRDH)); +} + +void enc28j60Write(uint8_t address, uint8_t data) +{ + // set the bank + enc28j60SetBank(address); + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +} + +void enc28j60PhyWrite(uint8_t address, uint16_t data) +{ + // set the PHY register address + enc28j60Write(MIREGADR, address); + // write the PHY data + enc28j60Write(MIWRL, data); + enc28j60Write(MIWRH, data>>8); + // wait until the PHY write completes + + while(enc28j60Read(MISTAT) & MISTAT_BUSY) + { + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + } +} + +void enc28j60Init(uint8_t* macaddr) +{ + // perform system reset + + //ENC28j60 reset is on PE2 TODO add in hardware.c macros for that. + ENC_RST_ON; // PORTE &= ~0x04; + vTaskDelay(5); // 50ms + ENC_RST_OFF; //PORTE |= 0x04; + vTaskDelay(5); // 50ms + + // check CLKRDY bit to see if reset is complete + // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait. + //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); + // do bank 0 stuff + // initialize receive buffer + // 16-bit transfers, must write low byte first + // set receive buffer start address + gNextPacketPtr = RXSTART_INIT; + // Rx start + enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXSTH, RXSTART_INIT>>8); + // set receive pointer address + enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + // RX end + enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + // TX start + enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + enc28j60Write(ETXSTH, TXSTART_INIT>>8); + // TX end + enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF); + enc28j60Write(ETXNDH, TXSTOP_INIT>>8); + + // do bank 1 stuff, packet filter: + // For broadcast packets we allow only ARP packtets + // All other packets should be unicast only for our mac (MAADR) + // + // The pattern to match on is therefore + // Type ETH.DST + // ARP BROADCAST + // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 + // in binary these poitions are:11 0000 0011 1111 + // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 + //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); //Bez wejsca dla broadcastu (jak opis powyzej, wpusci tylko arp - na zasadzie checksumy zgodnej z pakietem) + enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_MCEN); //Z wejsciem dla calego broadcastu + enc28j60Write(EPMM0, 0x3f); + enc28j60Write(EPMM1, 0x30); + enc28j60Write(EPMCSL, 0xf9); + enc28j60Write(EPMCSH, 0xf7); + // + // + // do bank 2 stuff + // enable MAC receive + enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + // bring MAC out of reset + enc28j60Write(MACON2, 0x00); + // enable automatic padding to 60bytes and CRC operations + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + // set inter-frame gap (non-back-to-back) + enc28j60Write(MAIPGL, 0x12); + enc28j60Write(MAIPGH, 0x0C); + // set inter-frame gap (back-to-back) + enc28j60Write(MABBIPG, 0x12); + // Set the maximum packet size which the controller will accept + // Do not send packets longer than MAX_FRAMELEN: + enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + + // do bank 3 stuff + // write MAC address + + nicSetMacAddress(macaddr); + + // no loopback of transmitted frames + enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + + enc28j60SetBank(ECON1); // switch to bank 0 + // enable interrutps + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + // enable packet reception + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +} + +// read the revision of the chip: +uint8_t enc28j60getrev(void) +{ + return(enc28j60Read(EREVID)); +} + +// link status +uint8_t enc28j60linkup(void) +{ + // bit 10 (= bit 3 in upper reg) + return(enc28j60PhyReadH(PHSTAT2) && 4); +} + +void nicSend(uint16_t len) +{ + // Check no transmit in progress + while (enc28j60ReadOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS) + { + // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. + if( (enc28j60Read(EIR) & EIR_TXERIF) ) + { + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); + } + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + } + // Set the write pointer to start of transmit buffer area + enc28j60Write(EWRPTL, TXSTART_INIT&0xFF); + enc28j60Write(EWRPTH, TXSTART_INIT>>8); + // Set the TXND pointer to correspond to the packet size given + enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF); + enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + // write per-packet control byte (0x00 means use macon3 settings) + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, nicState.layer2.buf); + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); +} + +// just probe if there might be a packet +uint8_t enc28j60hasRxPkt(void) +{ + if( enc28j60Read(EPKTCNT) ==0 ) + { + return(0); + } + return(1); +} + +uint16_t nicPoll(void) +{ + uint16_t rxstat; + uint16_t len; + // check if a packet has been received and buffered + //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ + // The above does not work. See Rev. B4 Silicon Errata point 6. + if( enc28j60Read(EPKTCNT) == 0 ) + { + return(0); + } + + // Set the read pointer to the start of the received packet + enc28j60Write(ERDPTL, (gNextPacketPtr &0xFF)); + enc28j60Write(ERDPTH, (gNextPacketPtr)>>8); + // read the next packet pointer + gNextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the packet length (see datasheet page 43) + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + len-=4; //remove the CRC count + // read the receive status (see datasheet page 43) + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8; + // limit retrieve length + if (len> nicState.bufferSize -1) + { + len= nicState.bufferSize-1; + } + // check CRC and symbol errors (see datasheet page 44, table 7-3): + // The ERXFCON.CRCEN is set by default. Normally we should not + // need to check this. + + if ((rxstat & 0x80)==0) + { + // invalid + len=0; + } + else + { + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, nicState.layer2.buf); + } + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out + enc28j60Write(ERXRDPTL, (gNextPacketPtr &0xFF)); + enc28j60Write(ERXRDPTH, (gNextPacketPtr)>>8); + +#if RXSTART_INIT > 0 + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out. + // However, compensate for the errata point 13, rev B4: enver write an even address! + //FIXME remove this warning + if ((gNextPacketPtr - 1 < RXSTART_INIT) || (gNextPacketPtr -1 > RXSTOP_INIT)) + { + enc28j60Write(ERXRDPTL, (RXSTOP_INIT)&0xFF); + enc28j60Write(ERXRDPTH, (RXSTOP_INIT)>>8); + } + else + { +#endif + enc28j60Write(ERXRDPTL, (gNextPacketPtr-1)&0xFF); + enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8); +#if RXSTART_INIT > 0 + } +#endif + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + return(len); +} + +void spiEnableEnc28j60(void) {}; +void spiDisableEnc28j60(void) {}; + +void nicSetMacAddress(uint8_t* macaddr) +{ +//NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, macaddr[0]); + enc28j60Write(MAADR4, macaddr[1]); + enc28j60Write(MAADR3, macaddr[2]); + enc28j60Write(MAADR2, macaddr[3]); + enc28j60Write(MAADR1, macaddr[4]); + enc28j60Write(MAADR0, macaddr[5]); + //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); +} + +void nicGetMacAddress(uint8_t* macaddr) +{ + macaddr[5] = enc28j60Read(MAADR0); + macaddr[4] = enc28j60Read(MAADR1); + macaddr[3] = enc28j60Read(MAADR2); + macaddr[2] = enc28j60Read(MAADR3); + macaddr[1] = enc28j60Read(MAADR4); + macaddr[0] = enc28j60Read(MAADR5); + //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); +} + +void nicRegDump(FILE *stream) +{ + uint8_t temp; + fprintf_P(stream, PSTR("ENC28j60 stan rejestrow:\r\n")); + + temp = enc28j60Read(MAADR0); fprintf_P(stream, PSTR("\tMAADR0 0x%x\r\n"), temp); + temp = enc28j60Read(MAADR1); fprintf_P(stream, PSTR("\tMAADR1 0x%x\r\n"), temp); + temp = enc28j60Read(MAADR2); fprintf_P(stream, PSTR("\tMAADR2 0x%x\r\n"), temp); + temp = enc28j60Read(MAADR3); fprintf_P(stream, PSTR("\tMAADR3 0x%x\r\n"), temp); + temp = enc28j60Read(MAADR4); fprintf_P(stream, PSTR("\tMAADR4 0x%x\r\n"), temp); + temp = enc28j60Read(MAADR5); fprintf_P(stream, PSTR("\tMAADR5 0x%x\r\n"), temp); +} + diff --git a/Lib/enc28j60.lst b/Lib/enc28j60.lst new file mode 100644 index 0000000..503c5dd --- /dev/null +++ b/Lib/enc28j60.lst @@ -0,0 +1,1750 @@ + 1 .file "enc28j60.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 269 .weak spiEnableEnc28j60 + 271 spiEnableEnc28j60: + 272 .stabd 46,0,0 + 1:../../../../Lib/enc28j60.c **** /********************************************* + 2:../../../../Lib/enc28j60.c **** * vim:sw=8:ts=8:si:et + 3:../../../../Lib/enc28j60.c **** * To use the above modeline in vim you must have "set modeline" in your .vimrc + 4:../../../../Lib/enc28j60.c **** * Author: Guido Socher + 5:../../../../Lib/enc28j60.c **** * Copyright: GPL V2 + 6:../../../../Lib/enc28j60.c **** * http://www.gnu.org/licenses/gpl.html + 7:../../../../Lib/enc28j60.c **** * + 8:../../../../Lib/enc28j60.c **** * Based on the enc28j60.c file from the AVRlib library by Pascal Stang + 9:../../../../Lib/enc28j60.c **** * For AVRlib See http://www.procyonengineering.com/ + 10:../../../../Lib/enc28j60.c **** * Used with explicit permission of Pascal Stang. + 11:../../../../Lib/enc28j60.c **** * + 12:../../../../Lib/enc28j60.c **** * Title: Microchip ENC28J60 Ethernet Interface Driver + 13:../../../../Lib/enc28j60.c **** * Chip type : ATMEGA88 with ENC28J60 + 14:../../../../Lib/enc28j60.c **** *********************************************/ + 15:../../../../Lib/enc28j60.c **** + 16:../../../../Lib/enc28j60.c **** #include "enc28j60.h" + 17:../../../../Lib/enc28j60.c **** + 18:../../../../Lib/enc28j60.c **** + 19:../../../../Lib/enc28j60.c **** static uint8_t Enc28j60Bank; + 20:../../../../Lib/enc28j60.c **** static uint16_t gNextPacketPtr; + 21:../../../../Lib/enc28j60.c **** + 22:../../../../Lib/enc28j60.c **** + 23:../../../../Lib/enc28j60.c **** /** + 24:../../../../Lib/enc28j60.c **** * Initialize enc28j60 + 25:../../../../Lib/enc28j60.c **** * @param *macaddr - pointer to the mac address (6 bytes) + 26:../../../../Lib/enc28j60.c **** */ + 27:../../../../Lib/enc28j60.c **** static void enc28j60Init(uint8_t* macaddr); + 28:../../../../Lib/enc28j60.c **** + 29:../../../../Lib/enc28j60.c **** /** + 30:../../../../Lib/enc28j60.c **** * Read register value (without changing the bank) + 31:../../../../Lib/enc28j60.c **** * @param op - operation type + 32:../../../../Lib/enc28j60.c **** * @param address - register address + 33:../../../../Lib/enc28j60.c **** * @return register value + 34:../../../../Lib/enc28j60.c **** */ + 35:../../../../Lib/enc28j60.c **** static uint8_t enc28j60ReadOp (uint8_t op, uint8_t address); + 36:../../../../Lib/enc28j60.c **** static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data); + 37:../../../../Lib/enc28j60.c **** static void enc28j60SetBank(uint8_t address); + 38:../../../../Lib/enc28j60.c **** static void enc28j60ReadBuffer(uint16_t len, uint8_t* data); + 39:../../../../Lib/enc28j60.c **** static void enc28j60WriteBuffer(uint16_t len, uint8_t* data); + 40:../../../../Lib/enc28j60.c **** + 41:../../../../Lib/enc28j60.c **** /** + 42:../../../../Lib/enc28j60.c **** * Reads Enc28j60 control register + 43:../../../../Lib/enc28j60.c **** * @param address - register address. Banks are changed automatically + 44:../../../../Lib/enc28j60.c **** * @return control register value + 45:../../../../Lib/enc28j60.c **** */ + 46:../../../../Lib/enc28j60.c **** static uint8_t enc28j60Read(uint8_t address); + 47:../../../../Lib/enc28j60.c **** + 48:../../../../Lib/enc28j60.c **** /** + 49:../../../../Lib/enc28j60.c **** * Writes Enc28j60 control register + 50:../../../../Lib/enc28j60.c **** * @param address - register address. Banks are changed automatically + 51:../../../../Lib/enc28j60.c **** * @param data - control register value to be writen + 52:../../../../Lib/enc28j60.c **** */ + 53:../../../../Lib/enc28j60.c **** static void enc28j60Write(uint8_t address, uint8_t data); + 54:../../../../Lib/enc28j60.c **** + 55:../../../../Lib/enc28j60.c **** /** + 56:../../../../Lib/enc28j60.c **** * Reads Enc28j60 phy register + 57:../../../../Lib/enc28j60.c **** * @param address - register address. Banks are changed automatically + 58:../../../../Lib/enc28j60.c **** * @return phy register value + 59:../../../../Lib/enc28j60.c **** */ + 60:../../../../Lib/enc28j60.c **** static uint16_t enc28j60PhyReadH(uint8_t address); + 61:../../../../Lib/enc28j60.c **** + 62:../../../../Lib/enc28j60.c **** /** + 63:../../../../Lib/enc28j60.c **** * Writes Enc28j60 phy register + 64:../../../../Lib/enc28j60.c **** * @param address - register address. Banks are changed automatically + 65:../../../../Lib/enc28j60.c **** * @param data - phy register value to be writen + 66:../../../../Lib/enc28j60.c **** */ + 67:../../../../Lib/enc28j60.c **** static void enc28j60PhyWrite(uint8_t address, uint16_t data); + 68:../../../../Lib/enc28j60.c **** + 69:../../../../Lib/enc28j60.c **** + 70:../../../../Lib/enc28j60.c **** //void enc28j60BufferSend(uint16_t len, roundBuffer* buffer); + 71:../../../../Lib/enc28j60.c **** + 72:../../../../Lib/enc28j60.c **** uint8_t enc28j60hasRxPkt(void); + 73:../../../../Lib/enc28j60.c **** uint8_t enc28j60getrev(void); + 74:../../../../Lib/enc28j60.c **** uint8_t enc28j60linkup(void); + 75:../../../../Lib/enc28j60.c **** + 76:../../../../Lib/enc28j60.c **** void nicMacInit(void) + 77:../../../../Lib/enc28j60.c **** { + 78:../../../../Lib/enc28j60.c **** vTaskDelay (5); + 79:../../../../Lib/enc28j60.c **** enc28j60Init (nicState.mac.addr); + 80:../../../../Lib/enc28j60.c **** // enc28j60clkout (2); // change clkout from 6.25MHz to 12.5MHz + 81:../../../../Lib/enc28j60.c **** vTaskDelay (5); + 82:../../../../Lib/enc28j60.c **** enc28j60PhyWrite (PHLCON, 0x476); + 83:../../../../Lib/enc28j60.c **** vTaskDelay (2); + 84:../../../../Lib/enc28j60.c **** } + 85:../../../../Lib/enc28j60.c **** + 86:../../../../Lib/enc28j60.c **** uint8_t enc28j60ReadOp(uint8_t op, uint8_t address) + 87:../../../../Lib/enc28j60.c **** { + 88:../../../../Lib/enc28j60.c **** uint8_t result; + 89:../../../../Lib/enc28j60.c **** //spiTake(); + 90:../../../../Lib/enc28j60.c **** spiEnableEnc28j60(); + 91:../../../../Lib/enc28j60.c **** + 92:../../../../Lib/enc28j60.c **** // issue read command + 93:../../../../Lib/enc28j60.c **** spiSendENC(op | (address & ADDR_MASK)); + 94:../../../../Lib/enc28j60.c **** + 95:../../../../Lib/enc28j60.c **** // read data + 96:../../../../Lib/enc28j60.c **** result = spiSendENC(0x00); + 97:../../../../Lib/enc28j60.c **** + 98:../../../../Lib/enc28j60.c **** // do dummy read if needed (for mac and mii, see datasheet page 29) + 99:../../../../Lib/enc28j60.c **** if(address & 0x80) + 100:../../../../Lib/enc28j60.c **** { + 101:../../../../Lib/enc28j60.c **** result = spiSendENC(0x00); + 102:../../../../Lib/enc28j60.c **** } + 103:../../../../Lib/enc28j60.c **** + 104:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 105:../../../../Lib/enc28j60.c **** // spiGive(); + 106:../../../../Lib/enc28j60.c **** return result; + 107:../../../../Lib/enc28j60.c **** } + 108:../../../../Lib/enc28j60.c **** + 109:../../../../Lib/enc28j60.c **** void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data) + 110:../../../../Lib/enc28j60.c **** { + 111:../../../../Lib/enc28j60.c **** // spiTake(); + 112:../../../../Lib/enc28j60.c **** spiEnableEnc28j60(); + 113:../../../../Lib/enc28j60.c **** // issue write command + 114:../../../../Lib/enc28j60.c **** //spiSend(op | (address & ADDR_MASK)); + 115:../../../../Lib/enc28j60.c **** spiSendENC(op | (address & ADDR_MASK)); + 116:../../../../Lib/enc28j60.c **** spiSendENC(data); + 117:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 118:../../../../Lib/enc28j60.c **** // spiGive(); + 119:../../../../Lib/enc28j60.c **** } + 120:../../../../Lib/enc28j60.c **** + 121:../../../../Lib/enc28j60.c **** void enc28j60ReadBuffer(uint16_t len, uint8_t* data) + 122:../../../../Lib/enc28j60.c **** { + 123:../../../../Lib/enc28j60.c **** // spiTake(); + 124:../../../../Lib/enc28j60.c **** spiEnableEnc28j60(); + 125:../../../../Lib/enc28j60.c **** spiSendENC(ENC28J60_READ_BUF_MEM); + 126:../../../../Lib/enc28j60.c **** while(len) + 127:../../../../Lib/enc28j60.c **** { + 128:../../../../Lib/enc28j60.c **** len--; + 129:../../../../Lib/enc28j60.c **** *data = spiSendENC(0x00); + 130:../../../../Lib/enc28j60.c **** data++; + 131:../../../../Lib/enc28j60.c **** } + 132:../../../../Lib/enc28j60.c **** *data='\0'; + 133:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 134:../../../../Lib/enc28j60.c **** // spiGive(); + 135:../../../../Lib/enc28j60.c **** } + 136:../../../../Lib/enc28j60.c **** + 137:../../../../Lib/enc28j60.c **** void enc28j60WriteBuffer(uint16_t len, uint8_t* data) + 138:../../../../Lib/enc28j60.c **** { + 139:../../../../Lib/enc28j60.c **** //spiTake(); + 140:../../../../Lib/enc28j60.c **** spiEnableEnc28j60(); + 141:../../../../Lib/enc28j60.c **** // issue write command + 142:../../../../Lib/enc28j60.c **** //spiSend(ENC28J60_WRITE_BUF_MEM); // + 143:../../../../Lib/enc28j60.c **** spiSendENC(ENC28J60_WRITE_BUF_MEM); + 144:../../../../Lib/enc28j60.c **** while(len) + 145:../../../../Lib/enc28j60.c **** { + 146:../../../../Lib/enc28j60.c **** len--; + 147:../../../../Lib/enc28j60.c **** spiSendENC(*data); // write data + 148:../../../../Lib/enc28j60.c **** data++; + 149:../../../../Lib/enc28j60.c **** } + 150:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 151:../../../../Lib/enc28j60.c **** //spiGive(); + 152:../../../../Lib/enc28j60.c **** } + 153:../../../../Lib/enc28j60.c **** + 154:../../../../Lib/enc28j60.c **** // void enc28j60WriteRoundBuffer(uint8_t len, roundBuffer *buffer) + 155:../../../../Lib/enc28j60.c **** // { + 156:../../../../Lib/enc28j60.c **** // spiTake(); + 157:../../../../Lib/enc28j60.c **** // spiEnableEnc28j60(); + 158:../../../../Lib/enc28j60.c **** // // issue write command + 159:../../../../Lib/enc28j60.c **** // //spiSend(ENC28J60_WRITE_BUF_MEM); // + 160:../../../../Lib/enc28j60.c **** // spiSend(ENC28J60_WRITE_BUF_MEM); + 161:../../../../Lib/enc28j60.c **** // uint8_t data; + 162:../../../../Lib/enc28j60.c **** // while(len) + 163:../../../../Lib/enc28j60.c **** // { + 164:../../../../Lib/enc28j60.c **** // len--; + 165:../../../../Lib/enc28j60.c **** // data = *buffer->readIdx.ptr16; + 166:../../../../Lib/enc28j60.c **** // buffer->readIdx.ptr.L++; + 167:../../../../Lib/enc28j60.c **** // + 168:../../../../Lib/enc28j60.c **** // spiSend(*data); // write data + 169:../../../../Lib/enc28j60.c **** // } + 170:../../../../Lib/enc28j60.c **** // spiDisableEnc28j60(); + 171:../../../../Lib/enc28j60.c **** // spiGive(); + 172:../../../../Lib/enc28j60.c **** // } + 173:../../../../Lib/enc28j60.c **** + 174:../../../../Lib/enc28j60.c **** + 175:../../../../Lib/enc28j60.c **** void enc28j60SetBank(uint8_t address) + 176:../../../../Lib/enc28j60.c **** { + 177:../../../../Lib/enc28j60.c **** // set the bank (if needed) + 178:../../../../Lib/enc28j60.c **** if((address & BANK_MASK) != Enc28j60Bank) + 179:../../../../Lib/enc28j60.c **** { + 180:../../../../Lib/enc28j60.c **** // set the bank + 181:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); + 182:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); + 183:../../../../Lib/enc28j60.c **** Enc28j60Bank = (address & BANK_MASK); + 184:../../../../Lib/enc28j60.c **** } + 185:../../../../Lib/enc28j60.c **** } + 186:../../../../Lib/enc28j60.c **** + 187:../../../../Lib/enc28j60.c **** uint8_t enc28j60Read(uint8_t address) + 188:../../../../Lib/enc28j60.c **** { + 189:../../../../Lib/enc28j60.c **** // set the bank + 190:../../../../Lib/enc28j60.c **** enc28j60SetBank(address); + 191:../../../../Lib/enc28j60.c **** // do the read + 192:../../../../Lib/enc28j60.c **** uint8_t result = enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); + 193:../../../../Lib/enc28j60.c **** return result; + 194:../../../../Lib/enc28j60.c **** } + 195:../../../../Lib/enc28j60.c **** + 196:../../../../Lib/enc28j60.c **** // read upper 8 bits + 197:../../../../Lib/enc28j60.c **** uint16_t enc28j60PhyReadH(uint8_t address) + 198:../../../../Lib/enc28j60.c **** { + 199:../../../../Lib/enc28j60.c **** // Set the right address and start the register read operation + 200:../../../../Lib/enc28j60.c **** enc28j60Write(MIREGADR, address); + 201:../../../../Lib/enc28j60.c **** enc28j60Write(MICMD, MICMD_MIIRD); + 202:../../../../Lib/enc28j60.c **** + 203:../../../../Lib/enc28j60.c **** vTaskDelay(0); + 204:../../../../Lib/enc28j60.c **** + 205:../../../../Lib/enc28j60.c **** // wait until the PHY read completes + 206:../../../../Lib/enc28j60.c **** while(enc28j60Read(MISTAT) & MISTAT_BUSY) + 207:../../../../Lib/enc28j60.c **** vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zawieszenie + 208:../../../../Lib/enc28j60.c **** + 209:../../../../Lib/enc28j60.c **** // reset reading bit + 210:../../../../Lib/enc28j60.c **** enc28j60Write(MICMD, 0x00); + 211:../../../../Lib/enc28j60.c **** + 212:../../../../Lib/enc28j60.c **** return (enc28j60Read(MIRDH)); + 213:../../../../Lib/enc28j60.c **** } + 214:../../../../Lib/enc28j60.c **** + 215:../../../../Lib/enc28j60.c **** void enc28j60Write(uint8_t address, uint8_t data) + 216:../../../../Lib/enc28j60.c **** { + 217:../../../../Lib/enc28j60.c **** // set the bank + 218:../../../../Lib/enc28j60.c **** enc28j60SetBank(address); + 219:../../../../Lib/enc28j60.c **** // do the write + 220:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); + 221:../../../../Lib/enc28j60.c **** } + 222:../../../../Lib/enc28j60.c **** + 223:../../../../Lib/enc28j60.c **** void enc28j60PhyWrite(uint8_t address, uint16_t data) + 224:../../../../Lib/enc28j60.c **** { + 225:../../../../Lib/enc28j60.c **** // set the PHY register address + 226:../../../../Lib/enc28j60.c **** enc28j60Write(MIREGADR, address); + 227:../../../../Lib/enc28j60.c **** // write the PHY data + 228:../../../../Lib/enc28j60.c **** enc28j60Write(MIWRL, data); + 229:../../../../Lib/enc28j60.c **** enc28j60Write(MIWRH, data>>8); + 230:../../../../Lib/enc28j60.c **** // wait until the PHY write completes + 231:../../../../Lib/enc28j60.c **** + 232:../../../../Lib/enc28j60.c **** while(enc28j60Read(MISTAT) & MISTAT_BUSY) + 233:../../../../Lib/enc28j60.c **** { + 234:../../../../Lib/enc28j60.c **** vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + 235:../../../../Lib/enc28j60.c **** } + 236:../../../../Lib/enc28j60.c **** } + 237:../../../../Lib/enc28j60.c **** + 238:../../../../Lib/enc28j60.c **** void enc28j60Init(uint8_t* macaddr) + 239:../../../../Lib/enc28j60.c **** { + 240:../../../../Lib/enc28j60.c **** // perform system reset + 241:../../../../Lib/enc28j60.c **** + 242:../../../../Lib/enc28j60.c **** //ENC28j60 reset is on PE2 TODO add in hardware.c macros for that. + 243:../../../../Lib/enc28j60.c **** ENC_RST_ON; // PORTE &= ~0x04; + 244:../../../../Lib/enc28j60.c **** vTaskDelay(5); // 50ms + 245:../../../../Lib/enc28j60.c **** ENC_RST_OFF; //PORTE |= 0x04; + 246:../../../../Lib/enc28j60.c **** vTaskDelay(5); // 50ms + 247:../../../../Lib/enc28j60.c **** + 248:../../../../Lib/enc28j60.c **** // check CLKRDY bit to see if reset is complete + 249:../../../../Lib/enc28j60.c **** // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait. + 250:../../../../Lib/enc28j60.c **** //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); + 251:../../../../Lib/enc28j60.c **** // do bank 0 stuff + 252:../../../../Lib/enc28j60.c **** // initialize receive buffer + 253:../../../../Lib/enc28j60.c **** // 16-bit transfers, must write low byte first + 254:../../../../Lib/enc28j60.c **** // set receive buffer start address + 255:../../../../Lib/enc28j60.c **** gNextPacketPtr = RXSTART_INIT; + 256:../../../../Lib/enc28j60.c **** // Rx start + 257:../../../../Lib/enc28j60.c **** enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); + 258:../../../../Lib/enc28j60.c **** enc28j60Write(ERXSTH, RXSTART_INIT>>8); + 259:../../../../Lib/enc28j60.c **** // set receive pointer address + 260:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + 261:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + 262:../../../../Lib/enc28j60.c **** // RX end + 263:../../../../Lib/enc28j60.c **** enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + 264:../../../../Lib/enc28j60.c **** enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + 265:../../../../Lib/enc28j60.c **** // TX start + 266:../../../../Lib/enc28j60.c **** enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + 267:../../../../Lib/enc28j60.c **** enc28j60Write(ETXSTH, TXSTART_INIT>>8); + 268:../../../../Lib/enc28j60.c **** // TX end + 269:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF); + 270:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDH, TXSTOP_INIT>>8); + 271:../../../../Lib/enc28j60.c **** + 272:../../../../Lib/enc28j60.c **** // do bank 1 stuff, packet filter: + 273:../../../../Lib/enc28j60.c **** // For broadcast packets we allow only ARP packtets + 274:../../../../Lib/enc28j60.c **** // All other packets should be unicast only for our mac (MAADR) + 275:../../../../Lib/enc28j60.c **** // + 276:../../../../Lib/enc28j60.c **** // The pattern to match on is therefore + 277:../../../../Lib/enc28j60.c **** // Type ETH.DST + 278:../../../../Lib/enc28j60.c **** // ARP BROADCAST + 279:../../../../Lib/enc28j60.c **** // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 + 280:../../../../Lib/enc28j60.c **** // in binary these poitions are:11 0000 0011 1111 + 281:../../../../Lib/enc28j60.c **** // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 + 282:../../../../Lib/enc28j60.c **** //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); //Bez wejsca dla broadcastu ( + 283:../../../../Lib/enc28j60.c **** enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_MCEN); //Z wejsciem dla ca + 284:../../../../Lib/enc28j60.c **** enc28j60Write(EPMM0, 0x3f); + 285:../../../../Lib/enc28j60.c **** enc28j60Write(EPMM1, 0x30); + 286:../../../../Lib/enc28j60.c **** enc28j60Write(EPMCSL, 0xf9); + 287:../../../../Lib/enc28j60.c **** enc28j60Write(EPMCSH, 0xf7); + 288:../../../../Lib/enc28j60.c **** // + 289:../../../../Lib/enc28j60.c **** // + 290:../../../../Lib/enc28j60.c **** // do bank 2 stuff + 291:../../../../Lib/enc28j60.c **** // enable MAC receive + 292:../../../../Lib/enc28j60.c **** enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + 293:../../../../Lib/enc28j60.c **** // bring MAC out of reset + 294:../../../../Lib/enc28j60.c **** enc28j60Write(MACON2, 0x00); + 295:../../../../Lib/enc28j60.c **** // enable automatic padding to 60bytes and CRC operations + 296:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + 297:../../../../Lib/enc28j60.c **** // set inter-frame gap (non-back-to-back) + 298:../../../../Lib/enc28j60.c **** enc28j60Write(MAIPGL, 0x12); + 299:../../../../Lib/enc28j60.c **** enc28j60Write(MAIPGH, 0x0C); + 300:../../../../Lib/enc28j60.c **** // set inter-frame gap (back-to-back) + 301:../../../../Lib/enc28j60.c **** enc28j60Write(MABBIPG, 0x12); + 302:../../../../Lib/enc28j60.c **** // Set the maximum packet size which the controller will accept + 303:../../../../Lib/enc28j60.c **** // Do not send packets longer than MAX_FRAMELEN: + 304:../../../../Lib/enc28j60.c **** enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + 305:../../../../Lib/enc28j60.c **** enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + 306:../../../../Lib/enc28j60.c **** + 307:../../../../Lib/enc28j60.c **** // do bank 3 stuff + 308:../../../../Lib/enc28j60.c **** // write MAC address + 309:../../../../Lib/enc28j60.c **** + 310:../../../../Lib/enc28j60.c **** nicSetMacAddress(macaddr); + 311:../../../../Lib/enc28j60.c **** + 312:../../../../Lib/enc28j60.c **** // no loopback of transmitted frames + 313:../../../../Lib/enc28j60.c **** enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + 314:../../../../Lib/enc28j60.c **** + 315:../../../../Lib/enc28j60.c **** enc28j60SetBank(ECON1); // switch to bank 0 + 316:../../../../Lib/enc28j60.c **** // enable interrutps + 317:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + 318:../../../../Lib/enc28j60.c **** // enable packet reception + 319:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); + 320:../../../../Lib/enc28j60.c **** } + 321:../../../../Lib/enc28j60.c **** + 322:../../../../Lib/enc28j60.c **** // read the revision of the chip: + 323:../../../../Lib/enc28j60.c **** uint8_t enc28j60getrev(void) + 324:../../../../Lib/enc28j60.c **** { + 325:../../../../Lib/enc28j60.c **** return(enc28j60Read(EREVID)); + 326:../../../../Lib/enc28j60.c **** } + 327:../../../../Lib/enc28j60.c **** + 328:../../../../Lib/enc28j60.c **** // link status + 329:../../../../Lib/enc28j60.c **** uint8_t enc28j60linkup(void) + 330:../../../../Lib/enc28j60.c **** { + 331:../../../../Lib/enc28j60.c **** // bit 10 (= bit 3 in upper reg) + 332:../../../../Lib/enc28j60.c **** return(enc28j60PhyReadH(PHSTAT2) && 4); + 333:../../../../Lib/enc28j60.c **** } + 334:../../../../Lib/enc28j60.c **** + 335:../../../../Lib/enc28j60.c **** void nicSend(uint16_t len) + 336:../../../../Lib/enc28j60.c **** { + 337:../../../../Lib/enc28j60.c **** // Check no transmit in progress + 338:../../../../Lib/enc28j60.c **** while (enc28j60ReadOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS) + 339:../../../../Lib/enc28j60.c **** { + 340:../../../../Lib/enc28j60.c **** // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. + 341:../../../../Lib/enc28j60.c **** if( (enc28j60Read(EIR) & EIR_TXERIF) ) + 342:../../../../Lib/enc28j60.c **** { + 343:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); + 344:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); + 345:../../../../Lib/enc28j60.c **** } + 346:../../../../Lib/enc28j60.c **** vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + 347:../../../../Lib/enc28j60.c **** } + 348:../../../../Lib/enc28j60.c **** // Set the write pointer to start of transmit buffer area + 349:../../../../Lib/enc28j60.c **** enc28j60Write(EWRPTL, TXSTART_INIT&0xFF); + 350:../../../../Lib/enc28j60.c **** enc28j60Write(EWRPTH, TXSTART_INIT>>8); + 351:../../../../Lib/enc28j60.c **** // Set the TXND pointer to correspond to the packet size given + 352:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF); + 353:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + 354:../../../../Lib/enc28j60.c **** // write per-packet control byte (0x00 means use macon3 settings) + 355:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + 356:../../../../Lib/enc28j60.c **** // copy the packet into the transmit buffer + 357:../../../../Lib/enc28j60.c **** enc28j60WriteBuffer(len, nicState.layer2.buf); + 358:../../../../Lib/enc28j60.c **** // send the contents of the transmit buffer onto the network + 359:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); + 360:../../../../Lib/enc28j60.c **** } + 361:../../../../Lib/enc28j60.c **** + 362:../../../../Lib/enc28j60.c **** // just probe if there might be a packet + 363:../../../../Lib/enc28j60.c **** uint8_t enc28j60hasRxPkt(void) + 364:../../../../Lib/enc28j60.c **** { + 365:../../../../Lib/enc28j60.c **** if( enc28j60Read(EPKTCNT) ==0 ) + 366:../../../../Lib/enc28j60.c **** { + 367:../../../../Lib/enc28j60.c **** return(0); + 368:../../../../Lib/enc28j60.c **** } + 369:../../../../Lib/enc28j60.c **** return(1); + 370:../../../../Lib/enc28j60.c **** } + 371:../../../../Lib/enc28j60.c **** + 372:../../../../Lib/enc28j60.c **** uint16_t nicPoll(void) + 373:../../../../Lib/enc28j60.c **** { + 374:../../../../Lib/enc28j60.c **** uint16_t rxstat; + 375:../../../../Lib/enc28j60.c **** uint16_t len; + 376:../../../../Lib/enc28j60.c **** // check if a packet has been received and buffered + 377:../../../../Lib/enc28j60.c **** //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ + 378:../../../../Lib/enc28j60.c **** // The above does not work. See Rev. B4 Silicon Errata point 6. + 379:../../../../Lib/enc28j60.c **** if( enc28j60Read(EPKTCNT) == 0 ) + 380:../../../../Lib/enc28j60.c **** { + 381:../../../../Lib/enc28j60.c **** return(0); + 382:../../../../Lib/enc28j60.c **** } + 383:../../../../Lib/enc28j60.c **** + 384:../../../../Lib/enc28j60.c **** // Set the read pointer to the start of the received packet + 385:../../../../Lib/enc28j60.c **** enc28j60Write(ERDPTL, (gNextPacketPtr &0xFF)); + 386:../../../../Lib/enc28j60.c **** enc28j60Write(ERDPTH, (gNextPacketPtr)>>8); + 387:../../../../Lib/enc28j60.c **** // read the next packet pointer + 388:../../../../Lib/enc28j60.c **** gNextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 389:../../../../Lib/enc28j60.c **** gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 390:../../../../Lib/enc28j60.c **** // read the packet length (see datasheet page 43) + 391:../../../../Lib/enc28j60.c **** len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 392:../../../../Lib/enc28j60.c **** len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 393:../../../../Lib/enc28j60.c **** len-=4; //remove the CRC count + 394:../../../../Lib/enc28j60.c **** // read the receive status (see datasheet page 43) + 395:../../../../Lib/enc28j60.c **** rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 396:../../../../Lib/enc28j60.c **** rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8; + 397:../../../../Lib/enc28j60.c **** // limit retrieve length + 398:../../../../Lib/enc28j60.c **** if (len> nicState.bufferSize -1) + 399:../../../../Lib/enc28j60.c **** { + 400:../../../../Lib/enc28j60.c **** len= nicState.bufferSize-1; + 401:../../../../Lib/enc28j60.c **** } + 402:../../../../Lib/enc28j60.c **** // check CRC and symbol errors (see datasheet page 44, table 7-3): + 403:../../../../Lib/enc28j60.c **** // The ERXFCON.CRCEN is set by default. Normally we should not + 404:../../../../Lib/enc28j60.c **** // need to check this. + 405:../../../../Lib/enc28j60.c **** + 406:../../../../Lib/enc28j60.c **** if ((rxstat & 0x80)==0) + 407:../../../../Lib/enc28j60.c **** { + 408:../../../../Lib/enc28j60.c **** // invalid + 409:../../../../Lib/enc28j60.c **** len=0; + 410:../../../../Lib/enc28j60.c **** } + 411:../../../../Lib/enc28j60.c **** else + 412:../../../../Lib/enc28j60.c **** { + 413:../../../../Lib/enc28j60.c **** // copy the packet from the receive buffer + 414:../../../../Lib/enc28j60.c **** enc28j60ReadBuffer(len, nicState.layer2.buf); + 415:../../../../Lib/enc28j60.c **** } + 416:../../../../Lib/enc28j60.c **** // Move the RX read pointer to the start of the next received packet + 417:../../../../Lib/enc28j60.c **** // This frees the memory we just read out + 418:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTL, (gNextPacketPtr &0xFF)); + 419:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, (gNextPacketPtr)>>8); + 420:../../../../Lib/enc28j60.c **** + 421:../../../../Lib/enc28j60.c **** #if RXSTART_INIT > 0 + 422:../../../../Lib/enc28j60.c **** // Move the RX read pointer to the start of the next received packet + 423:../../../../Lib/enc28j60.c **** // This frees the memory we just read out. + 424:../../../../Lib/enc28j60.c **** // However, compensate for the errata point 13, rev B4: enver write an even address! + 425:../../../../Lib/enc28j60.c **** //FIXME remove this warning + 426:../../../../Lib/enc28j60.c **** if ((gNextPacketPtr - 1 < RXSTART_INIT) || (gNextPacketPtr -1 > RXSTOP_INIT)) + 427:../../../../Lib/enc28j60.c **** { + 428:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTL, (RXSTOP_INIT)&0xFF); + 429:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, (RXSTOP_INIT)>>8); + 430:../../../../Lib/enc28j60.c **** } + 431:../../../../Lib/enc28j60.c **** else + 432:../../../../Lib/enc28j60.c **** { + 433:../../../../Lib/enc28j60.c **** #endif + 434:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTL, (gNextPacketPtr-1)&0xFF); + 435:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8); + 436:../../../../Lib/enc28j60.c **** #if RXSTART_INIT > 0 + 437:../../../../Lib/enc28j60.c **** } + 438:../../../../Lib/enc28j60.c **** #endif + 439:../../../../Lib/enc28j60.c **** // decrement the packet counter indicate we are done with this packet + 440:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + 441:../../../../Lib/enc28j60.c **** return(len); + 442:../../../../Lib/enc28j60.c **** } + 443:../../../../Lib/enc28j60.c **** + 444:../../../../Lib/enc28j60.c **** void spiEnableEnc28j60(void) {}; + 274 .LM0: + 275 .LFBB1: + 276 /* prologue: function */ + 277 /* frame size = 0 */ + 278 /* stack size = 0 */ + 279 .L__stack_usage = 0 + 280 0000 0895 ret + 282 .Lscope1: + 284 .stabd 78,0,0 + 286 .weak spiDisableEnc28j60 + 288 spiDisableEnc28j60: + 289 .stabd 46,0,0 + 445:../../../../Lib/enc28j60.c **** void spiDisableEnc28j60(void) {}; + 291 .LM1: + 292 .LFBB2: + 293 /* prologue: function */ + 294 /* frame size = 0 */ + 295 /* stack size = 0 */ + 296 .L__stack_usage = 0 + 297 0002 0895 ret + 299 .Lscope2: + 301 .stabd 78,0,0 + 307 enc28j60WriteOp: + 308 .stabd 46,0,0 + 110:../../../../Lib/enc28j60.c **** // spiTake(); + 310 .LM2: + 311 .LFBB3: + 110:../../../../Lib/enc28j60.c **** // spiTake(); + 313 .LM3: + 314 0004 CF93 push r28 + 315 0006 DF93 push r29 + 316 0008 00D0 rcall . + 317 000a 1F92 push __zero_reg__ + 318 000c CDB7 in r28,__SP_L__ + 319 000e DEB7 in r29,__SP_H__ + 320 /* prologue: function */ + 321 /* frame size = 3 */ + 322 /* stack size = 5 */ + 323 .L__stack_usage = 5 + 112:../../../../Lib/enc28j60.c **** // issue write command + 325 .LM4: + 326 0010 4B83 std Y+3,r20 + 327 0012 6A83 std Y+2,r22 + 328 0014 8983 std Y+1,r24 + 329 0016 0E94 0000 call spiEnableEnc28j60 + 115:../../../../Lib/enc28j60.c **** spiSendENC(data); + 331 .LM5: + 332 001a 6A81 ldd r22,Y+2 + 333 001c 6F71 andi r22,lo8(31) + 334 001e 8981 ldd r24,Y+1 + 335 0020 862B or r24,r22 + 336 0022 0E94 0000 call spiSendENC + 116:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 338 .LM6: + 339 0026 4B81 ldd r20,Y+3 + 340 0028 842F mov r24,r20 + 341 002a 0E94 0000 call spiSendENC + 342 /* epilogue start */ + 119:../../../../Lib/enc28j60.c **** + 344 .LM7: + 345 002e 0F90 pop __tmp_reg__ + 346 0030 0F90 pop __tmp_reg__ + 347 0032 0F90 pop __tmp_reg__ + 348 0034 DF91 pop r29 + 349 0036 CF91 pop r28 + 117:../../../../Lib/enc28j60.c **** // spiGive(); + 351 .LM8: + 352 0038 0C94 0000 jmp spiDisableEnc28j60 + 354 .Lscope3: + 356 .stabd 78,0,0 + 360 enc28j60SetBank: + 361 .stabd 46,0,0 + 176:../../../../Lib/enc28j60.c **** // set the bank (if needed) + 363 .LM9: + 364 .LFBB4: + 365 003c 1F93 push r17 + 366 003e CF93 push r28 + 367 0040 DF93 push r29 + 368 /* prologue: function */ + 369 /* frame size = 0 */ + 370 /* stack size = 3 */ + 371 .L__stack_usage = 3 + 178:../../../../Lib/enc28j60.c **** { + 373 .LM10: + 374 0042 182F mov r17,r24 + 375 0044 1076 andi r17,lo8(96) + 376 0046 C12F mov r28,r17 + 377 0048 D0E0 ldi r29,0 + 378 004a 2091 0000 lds r18,Enc28j60Bank + 379 004e 30E0 ldi r19,0 + 380 0050 C217 cp r28,r18 + 381 0052 D307 cpc r29,r19 + 382 0054 01F0 breq .L4 + 181:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); + 384 .LM11: + 385 0056 43E0 ldi r20,lo8(3) + 386 0058 6FE1 ldi r22,lo8(31) + 387 005a 80EA ldi r24,lo8(-96) + 388 005c 0E94 0000 call enc28j60WriteOp + 182:../../../../Lib/enc28j60.c **** Enc28j60Bank = (address & BANK_MASK); + 390 .LM12: + 391 0060 AE01 movw r20,r28 + 392 0062 85E0 ldi r24,5 + 393 1: + 394 0064 5595 asr r21 + 395 0066 4795 ror r20 + 396 0068 8A95 dec r24 + 397 006a 01F4 brne 1b + 398 006c 6FE1 ldi r22,lo8(31) + 399 006e 80E8 ldi r24,lo8(-128) + 400 0070 0E94 0000 call enc28j60WriteOp + 183:../../../../Lib/enc28j60.c **** } + 402 .LM13: + 403 0074 1093 0000 sts Enc28j60Bank,r17 + 404 .L4: + 405 /* epilogue start */ + 185:../../../../Lib/enc28j60.c **** + 407 .LM14: + 408 0078 DF91 pop r29 + 409 007a CF91 pop r28 + 410 007c 1F91 pop r17 + 411 007e 0895 ret + 413 .Lscope4: + 415 .stabd 78,0,0 + 420 enc28j60Write: + 421 .stabd 46,0,0 + 216:../../../../Lib/enc28j60.c **** // set the bank + 423 .LM15: + 424 .LFBB5: + 425 0080 1F93 push r17 + 426 0082 CF93 push r28 + 427 0084 DF93 push r29 + 428 0086 1F92 push __zero_reg__ + 429 0088 CDB7 in r28,__SP_L__ + 430 008a DEB7 in r29,__SP_H__ + 431 /* prologue: function */ + 432 /* frame size = 1 */ + 433 /* stack size = 4 */ + 434 .L__stack_usage = 4 + 435 008c 182F mov r17,r24 + 218:../../../../Lib/enc28j60.c **** // do the write + 437 .LM16: + 438 008e 6983 std Y+1,r22 + 439 0090 0E94 0000 call enc28j60SetBank + 220:../../../../Lib/enc28j60.c **** } + 441 .LM17: + 442 0094 4981 ldd r20,Y+1 + 443 0096 612F mov r22,r17 + 444 0098 80E4 ldi r24,lo8(64) + 445 /* epilogue start */ + 221:../../../../Lib/enc28j60.c **** + 447 .LM18: + 448 009a 0F90 pop __tmp_reg__ + 449 009c DF91 pop r29 + 450 009e CF91 pop r28 + 451 00a0 1F91 pop r17 + 220:../../../../Lib/enc28j60.c **** } + 453 .LM19: + 454 00a2 0C94 0000 jmp enc28j60WriteOp + 456 .Lscope5: + 458 .stabd 78,0,0 + 463 enc28j60ReadOp: + 464 .stabd 46,0,0 + 87:../../../../Lib/enc28j60.c **** uint8_t result; + 466 .LM20: + 467 .LFBB6: + 468 00a6 1F93 push r17 + 469 00a8 CF93 push r28 + 470 00aa DF93 push r29 + 471 00ac 1F92 push __zero_reg__ + 472 00ae CDB7 in r28,__SP_L__ + 473 00b0 DEB7 in r29,__SP_H__ + 474 /* prologue: function */ + 475 /* frame size = 1 */ + 476 /* stack size = 4 */ + 477 .L__stack_usage = 4 + 478 00b2 162F mov r17,r22 + 90:../../../../Lib/enc28j60.c **** + 480 .LM21: + 481 00b4 8983 std Y+1,r24 + 482 00b6 0E94 0000 call spiEnableEnc28j60 + 93:../../../../Lib/enc28j60.c **** + 484 .LM22: + 485 00ba 912F mov r25,r17 + 486 00bc 9F71 andi r25,lo8(31) + 487 00be 8981 ldd r24,Y+1 + 488 00c0 892B or r24,r25 + 489 00c2 0E94 0000 call spiSendENC + 96:../../../../Lib/enc28j60.c **** + 491 .LM23: + 492 00c6 80E0 ldi r24,0 + 493 00c8 0E94 0000 call spiSendENC + 99:../../../../Lib/enc28j60.c **** { + 495 .LM24: + 496 00cc 17FF sbrs r17,7 + 497 00ce 00C0 rjmp .L9 + 101:../../../../Lib/enc28j60.c **** } + 499 .LM25: + 500 00d0 80E0 ldi r24,0 + 501 00d2 0E94 0000 call spiSendENC + 502 .L9: + 104:../../../../Lib/enc28j60.c **** // spiGive(); + 504 .LM26: + 505 00d6 8983 std Y+1,r24 + 506 00d8 0E94 0000 call spiDisableEnc28j60 + 107:../../../../Lib/enc28j60.c **** + 508 .LM27: + 509 00dc 8981 ldd r24,Y+1 + 510 /* epilogue start */ + 511 00de 0F90 pop __tmp_reg__ + 512 00e0 DF91 pop r29 + 513 00e2 CF91 pop r28 + 514 00e4 1F91 pop r17 + 515 00e6 0895 ret + 520 .Lscope6: + 522 .stabd 78,0,0 + 526 enc28j60Read: + 527 .stabd 46,0,0 + 188:../../../../Lib/enc28j60.c **** // set the bank + 529 .LM28: + 530 .LFBB7: + 531 00e8 CF93 push r28 + 532 00ea DF93 push r29 + 533 00ec 1F92 push __zero_reg__ + 534 00ee CDB7 in r28,__SP_L__ + 535 00f0 DEB7 in r29,__SP_H__ + 536 /* prologue: function */ + 537 /* frame size = 1 */ + 538 /* stack size = 3 */ + 539 .L__stack_usage = 3 + 540 00f2 682F mov r22,r24 + 190:../../../../Lib/enc28j60.c **** // do the read + 542 .LM29: + 543 00f4 6983 std Y+1,r22 + 544 00f6 0E94 0000 call enc28j60SetBank + 192:../../../../Lib/enc28j60.c **** return result; + 546 .LM30: + 547 00fa 6981 ldd r22,Y+1 + 548 00fc 80E0 ldi r24,0 + 549 /* epilogue start */ + 194:../../../../Lib/enc28j60.c **** + 551 .LM31: + 552 00fe 0F90 pop __tmp_reg__ + 553 0100 DF91 pop r29 + 554 0102 CF91 pop r28 + 192:../../../../Lib/enc28j60.c **** return result; + 556 .LM32: + 557 0104 0C94 0000 jmp enc28j60ReadOp + 559 .Lscope7: + 561 .stabd 78,0,0 + 565 enc28j60PhyWrite: + 566 .stabd 46,0,0 + 224:../../../../Lib/enc28j60.c **** // set the PHY register address + 568 .LM33: + 569 .LFBB8: + 570 0108 1F93 push r17 + 571 010a CF93 push r28 + 572 010c DF93 push r29 + 573 010e 1F92 push __zero_reg__ + 574 0110 CDB7 in r28,__SP_L__ + 575 0112 DEB7 in r29,__SP_H__ + 576 /* prologue: function */ + 577 /* frame size = 1 */ + 578 /* stack size = 4 */ + 579 .L__stack_usage = 4 + 580 0114 162F mov r17,r22 + 226:../../../../Lib/enc28j60.c **** // write the PHY data + 582 .LM34: + 583 0116 682F mov r22,r24 + 584 0118 84ED ldi r24,lo8(-44) + 585 011a 7983 std Y+1,r23 + 586 011c 0E94 0000 call enc28j60Write + 228:../../../../Lib/enc28j60.c **** enc28j60Write(MIWRH, data>>8); + 588 .LM35: + 589 0120 612F mov r22,r17 + 590 0122 86ED ldi r24,lo8(-42) + 591 0124 0E94 0000 call enc28j60Write + 229:../../../../Lib/enc28j60.c **** // wait until the PHY write completes + 593 .LM36: + 594 0128 7981 ldd r23,Y+1 + 595 012a 672F mov r22,r23 + 596 012c 87ED ldi r24,lo8(-41) + 597 012e 0E94 0000 call enc28j60Write + 598 .L12: + 232:../../../../Lib/enc28j60.c **** { + 600 .LM37: + 601 0132 8AEE ldi r24,lo8(-22) + 602 0134 0E94 0000 call enc28j60Read + 603 0138 80FF sbrs r24,0 + 604 013a 00C0 rjmp .L14 + 234:../../../../Lib/enc28j60.c **** } + 606 .LM38: + 607 013c 80E0 ldi r24,0 + 608 013e 90E0 ldi r25,0 + 609 0140 0E94 0000 call vTaskDelay + 610 0144 00C0 rjmp .L12 + 611 .L14: + 612 /* epilogue start */ + 236:../../../../Lib/enc28j60.c **** + 614 .LM39: + 615 0146 0F90 pop __tmp_reg__ + 616 0148 DF91 pop r29 + 617 014a CF91 pop r28 + 618 014c 1F91 pop r17 + 619 014e 0895 ret + 621 .Lscope8: + 623 .stabd 78,0,0 + 625 .global enc28j60getrev + 627 enc28j60getrev: + 628 .stabd 46,0,0 + 324:../../../../Lib/enc28j60.c **** return(enc28j60Read(EREVID)); + 630 .LM40: + 631 .LFBB9: + 632 /* prologue: function */ + 633 /* frame size = 0 */ + 634 /* stack size = 0 */ + 635 .L__stack_usage = 0 + 325:../../../../Lib/enc28j60.c **** } + 637 .LM41: + 638 0150 82E7 ldi r24,lo8(114) + 639 0152 0C94 0000 jmp enc28j60Read + 641 .Lscope9: + 643 .stabd 78,0,0 + 645 .global enc28j60hasRxPkt + 647 enc28j60hasRxPkt: + 648 .stabd 46,0,0 + 364:../../../../Lib/enc28j60.c **** if( enc28j60Read(EPKTCNT) ==0 ) + 650 .LM42: + 651 .LFBB10: + 652 /* prologue: function */ + 653 /* frame size = 0 */ + 654 /* stack size = 0 */ + 655 .L__stack_usage = 0 + 365:../../../../Lib/enc28j60.c **** { + 657 .LM43: + 658 0156 89E3 ldi r24,lo8(57) + 659 0158 0E94 0000 call enc28j60Read + 660 015c 91E0 ldi r25,lo8(1) + 661 015e 8111 cpse r24,__zero_reg__ + 662 0160 00C0 rjmp .L17 + 663 0162 90E0 ldi r25,0 + 664 .L17: + 370:../../../../Lib/enc28j60.c **** + 666 .LM44: + 667 0164 892F mov r24,r25 + 668 0166 0895 ret + 670 .Lscope10: + 672 .stabd 78,0,0 + 674 .global enc28j60linkup + 676 enc28j60linkup: + 677 .stabd 46,0,0 + 330:../../../../Lib/enc28j60.c **** // bit 10 (= bit 3 in upper reg) + 679 .LM45: + 680 .LFBB11: + 681 /* prologue: function */ + 682 /* frame size = 0 */ + 683 /* stack size = 0 */ + 684 .L__stack_usage = 0 + 685 .LBB4: + 686 .LBB5: + 200:../../../../Lib/enc28j60.c **** enc28j60Write(MICMD, MICMD_MIIRD); + 688 .LM46: + 689 0168 61E1 ldi r22,lo8(17) + 690 016a 84ED ldi r24,lo8(-44) + 691 016c 0E94 0000 call enc28j60Write + 201:../../../../Lib/enc28j60.c **** + 693 .LM47: + 694 0170 61E0 ldi r22,lo8(1) + 695 0172 82ED ldi r24,lo8(-46) + 696 0174 0E94 0000 call enc28j60Write + 697 .L20: + 207:../../../../Lib/enc28j60.c **** + 699 .LM48: + 700 0178 80E0 ldi r24,0 + 701 017a 90E0 ldi r25,0 + 702 017c 0E94 0000 call vTaskDelay + 206:../../../../Lib/enc28j60.c **** vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zawieszenie + 704 .LM49: + 705 0180 8AEE ldi r24,lo8(-22) + 706 0182 0E94 0000 call enc28j60Read + 707 0186 80FD sbrc r24,0 + 708 0188 00C0 rjmp .L20 + 210:../../../../Lib/enc28j60.c **** + 710 .LM50: + 711 018a 60E0 ldi r22,0 + 712 018c 82ED ldi r24,lo8(-46) + 713 018e 0E94 0000 call enc28j60Write + 212:../../../../Lib/enc28j60.c **** } + 715 .LM51: + 716 0192 89ED ldi r24,lo8(-39) + 717 0194 0E94 0000 call enc28j60Read + 718 .LBE5: + 719 .LBE4: + 332:../../../../Lib/enc28j60.c **** } + 721 .LM52: + 722 0198 91E0 ldi r25,lo8(1) + 723 019a 8111 cpse r24,__zero_reg__ + 724 019c 00C0 rjmp .L21 + 725 019e 90E0 ldi r25,0 + 726 .L21: + 333:../../../../Lib/enc28j60.c **** + 728 .LM53: + 729 01a0 892F mov r24,r25 + 730 01a2 0895 ret + 732 .Lscope11: + 734 .stabd 78,0,0 + 737 .weak nicSend + 739 nicSend: + 740 .stabd 46,0,0 + 336:../../../../Lib/enc28j60.c **** // Check no transmit in progress + 742 .LM54: + 743 .LFBB12: + 744 01a4 0F93 push r16 + 745 01a6 1F93 push r17 + 746 01a8 CF93 push r28 + 747 01aa DF93 push r29 + 748 /* prologue: function */ + 749 /* frame size = 0 */ + 750 /* stack size = 4 */ + 751 .L__stack_usage = 4 + 752 01ac EC01 movw r28,r24 + 753 .L23: + 338:../../../../Lib/enc28j60.c **** { + 755 .LM55: + 756 01ae 6FE1 ldi r22,lo8(31) + 757 01b0 80E0 ldi r24,0 + 758 01b2 0E94 0000 call enc28j60ReadOp + 759 01b6 83FF sbrs r24,3 + 760 01b8 00C0 rjmp .L31 + 341:../../../../Lib/enc28j60.c **** { + 762 .LM56: + 763 01ba 8CE1 ldi r24,lo8(28) + 764 01bc 0E94 0000 call enc28j60Read + 765 01c0 81FF sbrs r24,1 + 766 01c2 00C0 rjmp .L24 + 343:../../../../Lib/enc28j60.c **** enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); + 768 .LM57: + 769 01c4 40E8 ldi r20,lo8(-128) + 770 01c6 6FE1 ldi r22,lo8(31) + 771 01c8 80E8 ldi r24,lo8(-128) + 772 01ca 0E94 0000 call enc28j60WriteOp + 344:../../../../Lib/enc28j60.c **** } + 774 .LM58: + 775 01ce 40E8 ldi r20,lo8(-128) + 776 01d0 6FE1 ldi r22,lo8(31) + 777 01d2 80EA ldi r24,lo8(-96) + 778 01d4 0E94 0000 call enc28j60WriteOp + 779 .L24: + 346:../../../../Lib/enc28j60.c **** } + 781 .LM59: + 782 01d8 80E0 ldi r24,0 + 783 01da 90E0 ldi r25,0 + 784 01dc 0E94 0000 call vTaskDelay + 785 01e0 00C0 rjmp .L23 + 786 .L31: + 349:../../../../Lib/enc28j60.c **** enc28j60Write(EWRPTH, TXSTART_INIT>>8); + 788 .LM60: + 789 01e2 6FEF ldi r22,lo8(-1) + 790 01e4 82E0 ldi r24,lo8(2) + 791 01e6 0E94 0000 call enc28j60Write + 350:../../../../Lib/enc28j60.c **** // Set the TXND pointer to correspond to the packet size given + 793 .LM61: + 794 01ea 69E1 ldi r22,lo8(25) + 795 01ec 83E0 ldi r24,lo8(3) + 796 01ee 0E94 0000 call enc28j60Write + 352:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + 798 .LM62: + 799 01f2 6C2F mov r22,r28 + 800 01f4 6150 subi r22,lo8(-(-1)) + 801 01f6 86E0 ldi r24,lo8(6) + 802 01f8 0E94 0000 call enc28j60Write + 353:../../../../Lib/enc28j60.c **** // write per-packet control byte (0x00 means use macon3 settings) + 804 .LM63: + 805 01fc CE01 movw r24,r28 + 806 01fe 8150 subi r24,1 + 807 0200 964E sbci r25,-26 + 808 0202 692F mov r22,r25 + 809 0204 87E0 ldi r24,lo8(7) + 810 0206 0E94 0000 call enc28j60Write + 355:../../../../Lib/enc28j60.c **** // copy the packet into the transmit buffer + 812 .LM64: + 813 020a 40E0 ldi r20,0 + 814 020c 60E0 ldi r22,0 + 815 020e 8AE7 ldi r24,lo8(122) + 816 0210 0E94 0000 call enc28j60WriteOp + 357:../../../../Lib/enc28j60.c **** // send the contents of the transmit buffer onto the network + 818 .LM65: + 819 0214 0091 0000 lds r16,nicState+8 + 820 0218 1091 0000 lds r17,nicState+8+1 + 821 .LBB8: + 822 .LBB9: + 140:../../../../Lib/enc28j60.c **** // issue write command + 824 .LM66: + 825 021c 0E94 0000 call spiEnableEnc28j60 + 143:../../../../Lib/enc28j60.c **** while(len) + 827 .LM67: + 828 0220 8AE7 ldi r24,lo8(122) + 829 0222 0E94 0000 call spiSendENC + 830 0226 C00F add r28,r16 + 831 0228 D11F adc r29,r17 + 832 .L26: + 144:../../../../Lib/enc28j60.c **** { + 834 .LM68: + 835 022a 0C17 cp r16,r28 + 836 022c 1D07 cpc r17,r29 + 837 022e 01F0 breq .L32 + 147:../../../../Lib/enc28j60.c **** data++; + 839 .LM69: + 840 0230 F801 movw r30,r16 + 841 0232 8191 ld r24,Z+ + 842 0234 8F01 movw r16,r30 + 843 0236 0E94 0000 call spiSendENC + 844 023a 00C0 rjmp .L26 + 845 .L32: + 150:../../../../Lib/enc28j60.c **** //spiGive(); + 847 .LM70: + 848 023c 0E94 0000 call spiDisableEnc28j60 + 849 .LBE9: + 850 .LBE8: + 359:../../../../Lib/enc28j60.c **** } + 852 .LM71: + 853 0240 48E0 ldi r20,lo8(8) + 854 0242 6FE1 ldi r22,lo8(31) + 855 0244 80E8 ldi r24,lo8(-128) + 856 /* epilogue start */ + 360:../../../../Lib/enc28j60.c **** + 858 .LM72: + 859 0246 DF91 pop r29 + 860 0248 CF91 pop r28 + 861 024a 1F91 pop r17 + 862 024c 0F91 pop r16 + 359:../../../../Lib/enc28j60.c **** } + 864 .LM73: + 865 024e 0C94 0000 jmp enc28j60WriteOp + 870 .Lscope12: + 872 .stabd 78,0,0 + 874 .weak nicPoll + 876 nicPoll: + 877 .stabd 46,0,0 + 373:../../../../Lib/enc28j60.c **** uint16_t rxstat; + 879 .LM74: + 880 .LFBB13: + 881 0252 EF92 push r14 + 882 0254 FF92 push r15 + 883 0256 0F93 push r16 + 884 0258 1F93 push r17 + 885 025a CF93 push r28 + 886 025c DF93 push r29 + 887 /* prologue: function */ + 888 /* frame size = 0 */ + 889 /* stack size = 6 */ + 890 .L__stack_usage = 6 + 379:../../../../Lib/enc28j60.c **** { + 892 .LM75: + 893 025e 89E3 ldi r24,lo8(57) + 894 0260 0E94 0000 call enc28j60Read + 895 0264 8823 tst r24 + 896 0266 01F4 brne .+2 + 897 0268 00C0 rjmp .L39 + 385:../../../../Lib/enc28j60.c **** enc28j60Write(ERDPTH, (gNextPacketPtr)>>8); + 899 .LM76: + 900 026a 6091 0000 lds r22,gNextPacketPtr + 901 026e 80E0 ldi r24,0 + 902 0270 0E94 0000 call enc28j60Write + 386:../../../../Lib/enc28j60.c **** // read the next packet pointer + 904 .LM77: + 905 0274 6091 0000 lds r22,gNextPacketPtr+1 + 906 0278 81E0 ldi r24,lo8(1) + 907 027a 0E94 0000 call enc28j60Write + 388:../../../../Lib/enc28j60.c **** gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 909 .LM78: + 910 027e 60E0 ldi r22,0 + 911 0280 8AE3 ldi r24,lo8(58) + 912 0282 0E94 0000 call enc28j60ReadOp + 913 0286 90E0 ldi r25,0 + 914 0288 9093 0000 sts gNextPacketPtr+1,r25 + 915 028c 8093 0000 sts gNextPacketPtr,r24 + 389:../../../../Lib/enc28j60.c **** // read the packet length (see datasheet page 43) + 917 .LM79: + 918 0290 60E0 ldi r22,0 + 919 0292 8AE3 ldi r24,lo8(58) + 920 0294 0E94 0000 call enc28j60ReadOp + 921 0298 2091 0000 lds r18,gNextPacketPtr + 922 029c 3091 0000 lds r19,gNextPacketPtr+1 + 923 02a0 382B or r19,r24 + 924 02a2 3093 0000 sts gNextPacketPtr+1,r19 + 925 02a6 2093 0000 sts gNextPacketPtr,r18 + 391:../../../../Lib/enc28j60.c **** len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 927 .LM80: + 928 02aa 60E0 ldi r22,0 + 929 02ac 8AE3 ldi r24,lo8(58) + 930 02ae 0E94 0000 call enc28j60ReadOp + 931 02b2 C82F mov r28,r24 + 392:../../../../Lib/enc28j60.c **** len-=4; //remove the CRC count + 933 .LM81: + 934 02b4 60E0 ldi r22,0 + 935 02b6 8AE3 ldi r24,lo8(58) + 936 02b8 0E94 0000 call enc28j60ReadOp + 937 02bc F82E mov r15,r24 + 395:../../../../Lib/enc28j60.c **** rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8; + 939 .LM82: + 940 02be 60E0 ldi r22,0 + 941 02c0 8AE3 ldi r24,lo8(58) + 942 02c2 0E94 0000 call enc28j60ReadOp + 943 02c6 082F mov r16,r24 + 396:../../../../Lib/enc28j60.c **** // limit retrieve length + 945 .LM83: + 946 02c8 60E0 ldi r22,0 + 947 02ca 8AE3 ldi r24,lo8(58) + 948 02cc 0E94 0000 call enc28j60ReadOp + 398:../../../../Lib/enc28j60.c **** { + 950 .LM84: + 951 02d0 2091 0000 lds r18,nicState + 952 02d4 3091 0000 lds r19,nicState+1 + 406:../../../../Lib/enc28j60.c **** { + 954 .LM85: + 955 02d8 07FF sbrs r16,7 + 956 02da 00C0 rjmp .L40 + 398:../../../../Lib/enc28j60.c **** { + 958 .LM86: + 959 02dc 2150 subi r18,1 + 960 02de 3109 sbc r19,__zero_reg__ + 392:../../../../Lib/enc28j60.c **** len-=4; //remove the CRC count + 962 .LM87: + 963 02e0 D0E0 ldi r29,0 + 964 02e2 DF29 or r29,r15 + 965 02e4 2497 sbiw r28,4 + 966 02e6 2C17 cp r18,r28 + 967 02e8 3D07 cpc r19,r29 + 968 02ea 00F4 brsh .L36 + 969 02ec E901 movw r28,r18 + 970 .L36: + 414:../../../../Lib/enc28j60.c **** } + 972 .LM88: + 973 02ee 0091 0000 lds r16,nicState+8 + 974 02f2 1091 0000 lds r17,nicState+8+1 + 975 .LBB12: + 976 .LBB13: + 124:../../../../Lib/enc28j60.c **** spiSendENC(ENC28J60_READ_BUF_MEM); + 978 .LM89: + 979 02f6 0E94 0000 call spiEnableEnc28j60 + 125:../../../../Lib/enc28j60.c **** while(len) + 981 .LM90: + 982 02fa 8AE3 ldi r24,lo8(58) + 983 02fc 0E94 0000 call spiSendENC + 984 0300 7801 movw r14,r16 + 985 0302 EC0E add r14,r28 + 986 0304 FD1E adc r15,r29 + 987 .L37: + 126:../../../../Lib/enc28j60.c **** { + 989 .LM91: + 990 0306 0E15 cp r16,r14 + 991 0308 1F05 cpc r17,r15 + 992 030a 01F0 breq .L41 + 129:../../../../Lib/enc28j60.c **** data++; + 994 .LM92: + 995 030c 80E0 ldi r24,0 + 996 030e 0E94 0000 call spiSendENC + 997 0312 F801 movw r30,r16 + 998 0314 8193 st Z+,r24 + 999 0316 8F01 movw r16,r30 + 1000 0318 00C0 rjmp .L37 + 1001 .L41: + 132:../../../../Lib/enc28j60.c **** spiDisableEnc28j60(); + 1003 .LM93: + 1004 031a F801 movw r30,r16 + 1005 031c 1082 st Z,__zero_reg__ + 133:../../../../Lib/enc28j60.c **** // spiGive(); + 1007 .LM94: + 1008 031e 0E94 0000 call spiDisableEnc28j60 + 1009 0322 00C0 rjmp .L35 + 1010 .L40: + 1011 .LBE13: + 1012 .LBE12: + 409:../../../../Lib/enc28j60.c **** } + 1014 .LM95: + 1015 0324 C0E0 ldi r28,0 + 1016 0326 D0E0 ldi r29,0 + 1017 .L35: + 418:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, (gNextPacketPtr)>>8); + 1019 .LM96: + 1020 0328 6091 0000 lds r22,gNextPacketPtr + 1021 032c 8CE0 ldi r24,lo8(12) + 1022 032e 0E94 0000 call enc28j60Write + 419:../../../../Lib/enc28j60.c **** + 1024 .LM97: + 1025 0332 6091 0000 lds r22,gNextPacketPtr+1 + 1026 0336 8DE0 ldi r24,lo8(13) + 1027 0338 0E94 0000 call enc28j60Write + 434:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8); + 1029 .LM98: + 1030 033c 6091 0000 lds r22,gNextPacketPtr + 1031 0340 6150 subi r22,lo8(-(-1)) + 1032 0342 8CE0 ldi r24,lo8(12) + 1033 0344 0E94 0000 call enc28j60Write + 435:../../../../Lib/enc28j60.c **** #if RXSTART_INIT > 0 + 1035 .LM99: + 1036 0348 8091 0000 lds r24,gNextPacketPtr + 1037 034c 9091 0000 lds r25,gNextPacketPtr+1 + 1038 0350 0197 sbiw r24,1 + 1039 0352 692F mov r22,r25 + 1040 0354 8DE0 ldi r24,lo8(13) + 1041 0356 0E94 0000 call enc28j60Write + 440:../../../../Lib/enc28j60.c **** return(len); + 1043 .LM100: + 1044 035a 40E4 ldi r20,lo8(64) + 1045 035c 6EE1 ldi r22,lo8(30) + 1046 035e 80E8 ldi r24,lo8(-128) + 1047 0360 0E94 0000 call enc28j60WriteOp + 441:../../../../Lib/enc28j60.c **** } + 1049 .LM101: + 1050 0364 CE01 movw r24,r28 + 1051 0366 00C0 rjmp .L34 + 1052 .L39: + 381:../../../../Lib/enc28j60.c **** } + 1054 .LM102: + 1055 0368 80E0 ldi r24,0 + 1056 036a 90E0 ldi r25,0 + 1057 .L34: + 1058 /* epilogue start */ + 442:../../../../Lib/enc28j60.c **** + 1060 .LM103: + 1061 036c DF91 pop r29 + 1062 036e CF91 pop r28 + 1063 0370 1F91 pop r17 + 1064 0372 0F91 pop r16 + 1065 0374 FF90 pop r15 + 1066 0376 EF90 pop r14 + 1067 0378 0895 ret + 1072 .Lscope13: + 1074 .stabd 78,0,0 + 1077 .weak nicSetMacAddress + 1079 nicSetMacAddress: + 1080 .stabd 46,0,0 + 446:../../../../Lib/enc28j60.c **** + 447:../../../../Lib/enc28j60.c **** void nicSetMacAddress(uint8_t* macaddr) + 448:../../../../Lib/enc28j60.c **** { + 1082 .LM104: + 1083 .LFBB14: + 1084 037a CF93 push r28 + 1085 037c DF93 push r29 + 1086 /* prologue: function */ + 1087 /* frame size = 0 */ + 1088 /* stack size = 2 */ + 1089 .L__stack_usage = 2 + 1090 037e EC01 movw r28,r24 + 449:../../../../Lib/enc28j60.c **** //NOTE: MAC address in ENC28J60 is byte-backward + 450:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR5, macaddr[0]); + 1092 .LM105: + 1093 0380 6881 ld r22,Y + 1094 0382 84EE ldi r24,lo8(-28) + 1095 0384 0E94 0000 call enc28j60Write + 451:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR4, macaddr[1]); + 1097 .LM106: + 1098 0388 6981 ldd r22,Y+1 + 1099 038a 85EE ldi r24,lo8(-27) + 1100 038c 0E94 0000 call enc28j60Write + 452:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR3, macaddr[2]); + 1102 .LM107: + 1103 0390 6A81 ldd r22,Y+2 + 1104 0392 82EE ldi r24,lo8(-30) + 1105 0394 0E94 0000 call enc28j60Write + 453:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR2, macaddr[3]); + 1107 .LM108: + 1108 0398 6B81 ldd r22,Y+3 + 1109 039a 83EE ldi r24,lo8(-29) + 1110 039c 0E94 0000 call enc28j60Write + 454:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR1, macaddr[4]); + 1112 .LM109: + 1113 03a0 6C81 ldd r22,Y+4 + 1114 03a2 80EE ldi r24,lo8(-32) + 1115 03a4 0E94 0000 call enc28j60Write + 455:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR0, macaddr[5]); + 1117 .LM110: + 1118 03a8 6D81 ldd r22,Y+5 + 1119 03aa 81EE ldi r24,lo8(-31) + 1120 /* epilogue start */ + 456:../../../../Lib/enc28j60.c **** //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); + 457:../../../../Lib/enc28j60.c **** } + 1122 .LM111: + 1123 03ac DF91 pop r29 + 1124 03ae CF91 pop r28 + 455:../../../../Lib/enc28j60.c **** enc28j60Write(MAADR0, macaddr[5]); + 1126 .LM112: + 1127 03b0 0C94 0000 jmp enc28j60Write + 1129 .Lscope14: + 1131 .stabd 78,0,0 + 1133 .weak nicMacInit + 1135 nicMacInit: + 1136 .stabd 46,0,0 + 77:../../../../Lib/enc28j60.c **** vTaskDelay (5); + 1138 .LM113: + 1139 .LFBB15: + 1140 /* prologue: function */ + 1141 /* frame size = 0 */ + 1142 /* stack size = 0 */ + 1143 .L__stack_usage = 0 + 78:../../../../Lib/enc28j60.c **** enc28j60Init (nicState.mac.addr); + 1145 .LM114: + 1146 03b4 85E0 ldi r24,lo8(5) + 1147 03b6 90E0 ldi r25,0 + 1148 03b8 0E94 0000 call vTaskDelay + 1149 .LBB16: + 1150 .LBB17: + 243:../../../../Lib/enc28j60.c **** vTaskDelay(5); // 50ms + 1152 .LM115: + 1153 03bc 1A98 cbi 0x3,2 + 244:../../../../Lib/enc28j60.c **** ENC_RST_OFF; //PORTE |= 0x04; + 1155 .LM116: + 1156 03be 85E0 ldi r24,lo8(5) + 1157 03c0 90E0 ldi r25,0 + 1158 03c2 0E94 0000 call vTaskDelay + 245:../../../../Lib/enc28j60.c **** vTaskDelay(5); // 50ms + 1160 .LM117: + 1161 03c6 1A9A sbi 0x3,2 + 246:../../../../Lib/enc28j60.c **** + 1163 .LM118: + 1164 03c8 85E0 ldi r24,lo8(5) + 1165 03ca 90E0 ldi r25,0 + 1166 03cc 0E94 0000 call vTaskDelay + 255:../../../../Lib/enc28j60.c **** // Rx start + 1168 .LM119: + 1169 03d0 1092 0000 sts gNextPacketPtr+1,__zero_reg__ + 1170 03d4 1092 0000 sts gNextPacketPtr,__zero_reg__ + 257:../../../../Lib/enc28j60.c **** enc28j60Write(ERXSTH, RXSTART_INIT>>8); + 1172 .LM120: + 1173 03d8 60E0 ldi r22,0 + 1174 03da 88E0 ldi r24,lo8(8) + 1175 03dc 0E94 0000 call enc28j60Write + 258:../../../../Lib/enc28j60.c **** // set receive pointer address + 1177 .LM121: + 1178 03e0 60E0 ldi r22,0 + 1179 03e2 89E0 ldi r24,lo8(9) + 1180 03e4 0E94 0000 call enc28j60Write + 260:../../../../Lib/enc28j60.c **** enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + 1182 .LM122: + 1183 03e8 60E0 ldi r22,0 + 1184 03ea 8CE0 ldi r24,lo8(12) + 1185 03ec 0E94 0000 call enc28j60Write + 261:../../../../Lib/enc28j60.c **** // RX end + 1187 .LM123: + 1188 03f0 60E0 ldi r22,0 + 1189 03f2 8DE0 ldi r24,lo8(13) + 1190 03f4 0E94 0000 call enc28j60Write + 263:../../../../Lib/enc28j60.c **** enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + 1192 .LM124: + 1193 03f8 6EEF ldi r22,lo8(-2) + 1194 03fa 8AE0 ldi r24,lo8(10) + 1195 03fc 0E94 0000 call enc28j60Write + 264:../../../../Lib/enc28j60.c **** // TX start + 1197 .LM125: + 1198 0400 69E1 ldi r22,lo8(25) + 1199 0402 8BE0 ldi r24,lo8(11) + 1200 0404 0E94 0000 call enc28j60Write + 266:../../../../Lib/enc28j60.c **** enc28j60Write(ETXSTH, TXSTART_INIT>>8); + 1202 .LM126: + 1203 0408 6FEF ldi r22,lo8(-1) + 1204 040a 84E0 ldi r24,lo8(4) + 1205 040c 0E94 0000 call enc28j60Write + 267:../../../../Lib/enc28j60.c **** // TX end + 1207 .LM127: + 1208 0410 69E1 ldi r22,lo8(25) + 1209 0412 85E0 ldi r24,lo8(5) + 1210 0414 0E94 0000 call enc28j60Write + 269:../../../../Lib/enc28j60.c **** enc28j60Write(ETXNDH, TXSTOP_INIT>>8); + 1212 .LM128: + 1213 0418 6FEF ldi r22,lo8(-1) + 1214 041a 86E0 ldi r24,lo8(6) + 1215 041c 0E94 0000 call enc28j60Write + 270:../../../../Lib/enc28j60.c **** + 1217 .LM129: + 1218 0420 6FE1 ldi r22,lo8(31) + 1219 0422 87E0 ldi r24,lo8(7) + 1220 0424 0E94 0000 call enc28j60Write + 283:../../../../Lib/enc28j60.c **** enc28j60Write(EPMM0, 0x3f); + 1222 .LM130: + 1223 0428 62EB ldi r22,lo8(-78) + 1224 042a 88E3 ldi r24,lo8(56) + 1225 042c 0E94 0000 call enc28j60Write + 284:../../../../Lib/enc28j60.c **** enc28j60Write(EPMM1, 0x30); + 1227 .LM131: + 1228 0430 6FE3 ldi r22,lo8(63) + 1229 0432 88E2 ldi r24,lo8(40) + 1230 0434 0E94 0000 call enc28j60Write + 285:../../../../Lib/enc28j60.c **** enc28j60Write(EPMCSL, 0xf9); + 1232 .LM132: + 1233 0438 60E3 ldi r22,lo8(48) + 1234 043a 89E2 ldi r24,lo8(41) + 1235 043c 0E94 0000 call enc28j60Write + 286:../../../../Lib/enc28j60.c **** enc28j60Write(EPMCSH, 0xf7); + 1237 .LM133: + 1238 0440 69EF ldi r22,lo8(-7) + 1239 0442 80E3 ldi r24,lo8(48) + 1240 0444 0E94 0000 call enc28j60Write + 287:../../../../Lib/enc28j60.c **** // + 1242 .LM134: + 1243 0448 67EF ldi r22,lo8(-9) + 1244 044a 81E3 ldi r24,lo8(49) + 1245 044c 0E94 0000 call enc28j60Write + 292:../../../../Lib/enc28j60.c **** // bring MAC out of reset + 1247 .LM135: + 1248 0450 6DE0 ldi r22,lo8(13) + 1249 0452 80EC ldi r24,lo8(-64) + 1250 0454 0E94 0000 call enc28j60Write + 294:../../../../Lib/enc28j60.c **** // enable automatic padding to 60bytes and CRC operations + 1252 .LM136: + 1253 0458 60E0 ldi r22,0 + 1254 045a 81EC ldi r24,lo8(-63) + 1255 045c 0E94 0000 call enc28j60Write + 296:../../../../Lib/enc28j60.c **** // set inter-frame gap (non-back-to-back) + 1257 .LM137: + 1258 0460 42E3 ldi r20,lo8(50) + 1259 0462 62EC ldi r22,lo8(-62) + 1260 0464 80E8 ldi r24,lo8(-128) + 1261 0466 0E94 0000 call enc28j60WriteOp + 298:../../../../Lib/enc28j60.c **** enc28j60Write(MAIPGH, 0x0C); + 1263 .LM138: + 1264 046a 62E1 ldi r22,lo8(18) + 1265 046c 86EC ldi r24,lo8(-58) + 1266 046e 0E94 0000 call enc28j60Write + 299:../../../../Lib/enc28j60.c **** // set inter-frame gap (back-to-back) + 1268 .LM139: + 1269 0472 6CE0 ldi r22,lo8(12) + 1270 0474 87EC ldi r24,lo8(-57) + 1271 0476 0E94 0000 call enc28j60Write + 301:../../../../Lib/enc28j60.c **** // Set the maximum packet size which the controller will accept + 1273 .LM140: + 1274 047a 62E1 ldi r22,lo8(18) + 1275 047c 84EC ldi r24,lo8(-60) + 1276 047e 0E94 0000 call enc28j60Write + 304:../../../../Lib/enc28j60.c **** enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + 1278 .LM141: + 1279 0482 6CED ldi r22,lo8(-36) + 1280 0484 8AEC ldi r24,lo8(-54) + 1281 0486 0E94 0000 call enc28j60Write + 305:../../../../Lib/enc28j60.c **** + 1283 .LM142: + 1284 048a 65E0 ldi r22,lo8(5) + 1285 048c 8BEC ldi r24,lo8(-53) + 1286 048e 0E94 0000 call enc28j60Write + 310:../../../../Lib/enc28j60.c **** + 1288 .LM143: + 1289 0492 80E0 ldi r24,lo8(nicState+2) + 1290 0494 90E0 ldi r25,hi8(nicState+2) + 1291 0496 0E94 0000 call nicSetMacAddress + 313:../../../../Lib/enc28j60.c **** + 1293 .LM144: + 1294 049a 60E0 ldi r22,0 + 1295 049c 71E0 ldi r23,lo8(1) + 1296 049e 80E1 ldi r24,lo8(16) + 1297 04a0 0E94 0000 call enc28j60PhyWrite + 315:../../../../Lib/enc28j60.c **** // enable interrutps + 1299 .LM145: + 1300 04a4 8FE1 ldi r24,lo8(31) + 1301 04a6 0E94 0000 call enc28j60SetBank + 317:../../../../Lib/enc28j60.c **** // enable packet reception + 1303 .LM146: + 1304 04aa 40EC ldi r20,lo8(-64) + 1305 04ac 6BE1 ldi r22,lo8(27) + 1306 04ae 80E8 ldi r24,lo8(-128) + 1307 04b0 0E94 0000 call enc28j60WriteOp + 319:../../../../Lib/enc28j60.c **** } + 1309 .LM147: + 1310 04b4 44E0 ldi r20,lo8(4) + 1311 04b6 6FE1 ldi r22,lo8(31) + 1312 04b8 80E8 ldi r24,lo8(-128) + 1313 04ba 0E94 0000 call enc28j60WriteOp + 1314 .LBE17: + 1315 .LBE16: + 81:../../../../Lib/enc28j60.c **** enc28j60PhyWrite (PHLCON, 0x476); + 1317 .LM148: + 1318 04be 85E0 ldi r24,lo8(5) + 1319 04c0 90E0 ldi r25,0 + 1320 04c2 0E94 0000 call vTaskDelay + 82:../../../../Lib/enc28j60.c **** vTaskDelay (2); + 1322 .LM149: + 1323 04c6 66E7 ldi r22,lo8(118) + 1324 04c8 74E0 ldi r23,lo8(4) + 1325 04ca 84E1 ldi r24,lo8(20) + 1326 04cc 0E94 0000 call enc28j60PhyWrite + 83:../../../../Lib/enc28j60.c **** } + 1328 .LM150: + 1329 04d0 82E0 ldi r24,lo8(2) + 1330 04d2 90E0 ldi r25,0 + 1331 04d4 0C94 0000 jmp vTaskDelay + 1333 .Lscope15: + 1335 .stabd 78,0,0 + 1338 .weak nicGetMacAddress + 1340 nicGetMacAddress: + 1341 .stabd 46,0,0 + 458:../../../../Lib/enc28j60.c **** + 459:../../../../Lib/enc28j60.c **** void nicGetMacAddress(uint8_t* macaddr) + 460:../../../../Lib/enc28j60.c **** { + 1343 .LM151: + 1344 .LFBB16: + 1345 04d8 CF93 push r28 + 1346 04da DF93 push r29 + 1347 /* prologue: function */ + 1348 /* frame size = 0 */ + 1349 /* stack size = 2 */ + 1350 .L__stack_usage = 2 + 1351 04dc EC01 movw r28,r24 + 461:../../../../Lib/enc28j60.c **** macaddr[5] = enc28j60Read(MAADR0); + 1353 .LM152: + 1354 04de 81EE ldi r24,lo8(-31) + 1355 04e0 0E94 0000 call enc28j60Read + 1356 04e4 8D83 std Y+5,r24 + 462:../../../../Lib/enc28j60.c **** macaddr[4] = enc28j60Read(MAADR1); + 1358 .LM153: + 1359 04e6 80EE ldi r24,lo8(-32) + 1360 04e8 0E94 0000 call enc28j60Read + 1361 04ec 8C83 std Y+4,r24 + 463:../../../../Lib/enc28j60.c **** macaddr[3] = enc28j60Read(MAADR2); + 1363 .LM154: + 1364 04ee 83EE ldi r24,lo8(-29) + 1365 04f0 0E94 0000 call enc28j60Read + 1366 04f4 8B83 std Y+3,r24 + 464:../../../../Lib/enc28j60.c **** macaddr[2] = enc28j60Read(MAADR3); + 1368 .LM155: + 1369 04f6 82EE ldi r24,lo8(-30) + 1370 04f8 0E94 0000 call enc28j60Read + 1371 04fc 8A83 std Y+2,r24 + 465:../../../../Lib/enc28j60.c **** macaddr[1] = enc28j60Read(MAADR4); + 1373 .LM156: + 1374 04fe 85EE ldi r24,lo8(-27) + 1375 0500 0E94 0000 call enc28j60Read + 1376 0504 8983 std Y+1,r24 + 466:../../../../Lib/enc28j60.c **** macaddr[0] = enc28j60Read(MAADR5); + 1378 .LM157: + 1379 0506 84EE ldi r24,lo8(-28) + 1380 0508 0E94 0000 call enc28j60Read + 1381 050c 8883 st Y,r24 + 1382 /* epilogue start */ + 467:../../../../Lib/enc28j60.c **** //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); + 468:../../../../Lib/enc28j60.c **** } + 1384 .LM158: + 1385 050e DF91 pop r29 + 1386 0510 CF91 pop r28 + 1387 0512 0895 ret + 1389 .Lscope16: + 1391 .stabd 78,0,0 + 1393 .weak nicRegDump + 1395 nicRegDump: + 1396 .stabd 46,0,0 + 469:../../../../Lib/enc28j60.c **** + 470:../../../../Lib/enc28j60.c **** void nicRegDump(FILE *stream) + 471:../../../../Lib/enc28j60.c **** { + 1398 .LM159: + 1399 .LFBB17: + 1400 0514 CF93 push r28 + 1401 0516 DF93 push r29 + 1402 /* prologue: function */ + 1403 /* frame size = 0 */ + 1404 /* stack size = 2 */ + 1405 .L__stack_usage = 2 + 1406 0518 EC01 movw r28,r24 + 472:../../../../Lib/enc28j60.c **** uint8_t temp; + 473:../../../../Lib/enc28j60.c **** fprintf_P(stream, PSTR("ENC28j60 stan rejestrow:\r\n")); + 1408 .LM160: + 1409 051a 80E0 ldi r24,lo8(__c.3546) + 1410 051c 90E0 ldi r25,hi8(__c.3546) + 1411 051e 9F93 push r25 + 1412 0520 8F93 push r24 + 1413 0522 DF93 push r29 + 1414 0524 CF93 push r28 + 1415 0526 0E94 0000 call fprintf_P + 474:../../../../Lib/enc28j60.c **** + 475:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR0); fprintf_P(stream, PSTR("\tMAADR0 0x%x\r\n"), temp); + 1417 .LM161: + 1418 052a 81EE ldi r24,lo8(-31) + 1419 052c 0E94 0000 call enc28j60Read + 1420 0530 1F92 push __zero_reg__ + 1421 0532 8F93 push r24 + 1422 0534 80E0 ldi r24,lo8(__c.3548) + 1423 0536 90E0 ldi r25,hi8(__c.3548) + 1424 0538 9F93 push r25 + 1425 053a 8F93 push r24 + 1426 053c DF93 push r29 + 1427 053e CF93 push r28 + 1428 0540 0E94 0000 call fprintf_P + 476:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR1); fprintf_P(stream, PSTR("\tMAADR1 0x%x\r\n"), temp); + 1430 .LM162: + 1431 0544 80EE ldi r24,lo8(-32) + 1432 0546 0E94 0000 call enc28j60Read + 1433 054a 1F92 push __zero_reg__ + 1434 054c 8F93 push r24 + 1435 054e 80E0 ldi r24,lo8(__c.3550) + 1436 0550 90E0 ldi r25,hi8(__c.3550) + 1437 0552 9F93 push r25 + 1438 0554 8F93 push r24 + 1439 0556 DF93 push r29 + 1440 0558 CF93 push r28 + 1441 055a 0E94 0000 call fprintf_P + 477:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR2); fprintf_P(stream, PSTR("\tMAADR2 0x%x\r\n"), temp); + 1443 .LM163: + 1444 055e 83EE ldi r24,lo8(-29) + 1445 0560 0E94 0000 call enc28j60Read + 1446 0564 1F92 push __zero_reg__ + 1447 0566 8F93 push r24 + 1448 0568 80E0 ldi r24,lo8(__c.3552) + 1449 056a 90E0 ldi r25,hi8(__c.3552) + 1450 056c 9F93 push r25 + 1451 056e 8F93 push r24 + 1452 0570 DF93 push r29 + 1453 0572 CF93 push r28 + 1454 0574 0E94 0000 call fprintf_P + 478:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR3); fprintf_P(stream, PSTR("\tMAADR3 0x%x\r\n"), temp); + 1456 .LM164: + 1457 0578 82EE ldi r24,lo8(-30) + 1458 057a 0E94 0000 call enc28j60Read + 1459 057e 1F92 push __zero_reg__ + 1460 0580 8F93 push r24 + 1461 0582 80E0 ldi r24,lo8(__c.3554) + 1462 0584 90E0 ldi r25,hi8(__c.3554) + 1463 0586 9F93 push r25 + 1464 0588 8F93 push r24 + 1465 058a DF93 push r29 + 1466 058c CF93 push r28 + 1467 058e 0E94 0000 call fprintf_P + 479:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR4); fprintf_P(stream, PSTR("\tMAADR4 0x%x\r\n"), temp); + 1469 .LM165: + 1470 0592 85EE ldi r24,lo8(-27) + 1471 0594 0E94 0000 call enc28j60Read + 1472 0598 1F92 push __zero_reg__ + 1473 059a 8F93 push r24 + 1474 059c 80E0 ldi r24,lo8(__c.3556) + 1475 059e 90E0 ldi r25,hi8(__c.3556) + 1476 05a0 9F93 push r25 + 1477 05a2 8F93 push r24 + 1478 05a4 DF93 push r29 + 1479 05a6 CF93 push r28 + 1480 05a8 0E94 0000 call fprintf_P + 480:../../../../Lib/enc28j60.c **** temp = enc28j60Read(MAADR5); fprintf_P(stream, PSTR("\tMAADR5 0x%x\r\n"), temp); + 1482 .LM166: + 1483 05ac 8DB7 in r24,__SP_L__ + 1484 05ae 9EB7 in r25,__SP_H__ + 1485 05b0 8296 adiw r24,34 + 1486 05b2 0FB6 in __tmp_reg__,__SREG__ + 1487 05b4 F894 cli + 1488 05b6 9EBF out __SP_H__,r25 + 1489 05b8 0FBE out __SREG__,__tmp_reg__ + 1490 05ba 8DBF out __SP_L__,r24 + 1491 05bc 84EE ldi r24,lo8(-28) + 1492 05be 0E94 0000 call enc28j60Read + 1493 05c2 1F92 push __zero_reg__ + 1494 05c4 8F93 push r24 + 1495 05c6 80E0 ldi r24,lo8(__c.3558) + 1496 05c8 90E0 ldi r25,hi8(__c.3558) + 1497 05ca 9F93 push r25 + 1498 05cc 8F93 push r24 + 1499 05ce DF93 push r29 + 1500 05d0 CF93 push r28 + 1501 05d2 0E94 0000 call fprintf_P + 1502 05d6 0F90 pop __tmp_reg__ + 1503 05d8 0F90 pop __tmp_reg__ + 1504 05da 0F90 pop __tmp_reg__ + 1505 05dc 0F90 pop __tmp_reg__ + 1506 05de 0F90 pop __tmp_reg__ + 1507 05e0 0F90 pop __tmp_reg__ + 1508 /* epilogue start */ + 481:../../../../Lib/enc28j60.c **** } + 1510 .LM167: + 1511 05e2 DF91 pop r29 + 1512 05e4 CF91 pop r28 + 1513 05e6 0895 ret + 1515 .Lscope17: + 1517 .stabd 78,0,0 + 1518 .section .progmem.data,"a",@progbits + 1521 __c.3558: + 1522 0000 094D 4141 .string "\tMAADR5 0x%x\r\n" + 1522 4452 3520 + 1522 3078 2578 + 1522 0D0A 00 + 1525 __c.3556: + 1526 000f 094D 4141 .string "\tMAADR4 0x%x\r\n" + 1526 4452 3420 + 1526 3078 2578 + 1526 0D0A 00 + 1529 __c.3554: + 1530 001e 094D 4141 .string "\tMAADR3 0x%x\r\n" + 1530 4452 3320 + 1530 3078 2578 + 1530 0D0A 00 + 1533 __c.3552: + 1534 002d 094D 4141 .string "\tMAADR2 0x%x\r\n" + 1534 4452 3220 + 1534 3078 2578 + 1534 0D0A 00 + 1537 __c.3550: + 1538 003c 094D 4141 .string "\tMAADR1 0x%x\r\n" + 1538 4452 3120 + 1538 3078 2578 + 1538 0D0A 00 + 1541 __c.3548: + 1542 004b 094D 4141 .string "\tMAADR0 0x%x\r\n" + 1542 4452 3020 + 1542 3078 2578 + 1542 0D0A 00 + 1545 __c.3546: + 1546 005a 454E 4332 .string "ENC28j60 stan rejestrow:\r\n" + 1546 386A 3630 + 1546 2073 7461 + 1546 6E20 7265 + 1546 6A65 7374 + 1547 .local gNextPacketPtr + 1548 .comm gNextPacketPtr,2,1 + 1549 .local Enc28j60Bank + 1550 .comm Enc28j60Bank,1,1 + 1551 .comm czasRtc,7,1 + 1552 .comm sockets,2,1 + 1553 .comm tcpDebugLevel,1,1 + 1554 .comm tcpDebugStream,2,1 + 1555 .comm IpMyConfig,15,1 + 1556 .comm udpDbgLevel,1,1 + 1557 .comm udpDbgStream,2,1 + 1558 .comm udpSocket,2,1 + 1559 .comm icmpDebugLevel,1,1 + 1560 .comm icmpDebug,2,1 + 1561 .comm arpDebugLevel,1,1 + 1562 .comm arpDebug,2,1 + 1563 .comm nicState,14,1 + 1564 .comm xSemaphoreRs485,2,1 + 1565 .comm lockSensors,2,1 + 1566 .comm portB,1,1 + 1567 .comm portA,1,1 + 1568 .comm xSemaphoreSpiSS,2,1 + 1569 .comm rollers,2,1 + 1570 .comm wwwport,1,1 + 1571 .comm klastry,128,1 + 1595 .text + 1597 .Letext0: + 1598 .ident "GCC: (GNU) 4.9.2" + 1599 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 enc28j60.c + /tmp/ccQF2lF2.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccQF2lF2.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccQF2lF2.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccQF2lF2.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccQF2lF2.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccQF2lF2.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccQF2lF2.s:271 .text:0000000000000000 spiEnableEnc28j60 + /tmp/ccQF2lF2.s:288 .text:0000000000000002 spiDisableEnc28j60 + /tmp/ccQF2lF2.s:307 .text:0000000000000004 enc28j60WriteOp + /tmp/ccQF2lF2.s:360 .text:000000000000003c enc28j60SetBank + /tmp/ccQF2lF2.s:1548 .bss:0000000000000002 Enc28j60Bank + /tmp/ccQF2lF2.s:420 .text:0000000000000080 enc28j60Write + /tmp/ccQF2lF2.s:463 .text:00000000000000a6 enc28j60ReadOp + /tmp/ccQF2lF2.s:526 .text:00000000000000e8 enc28j60Read + /tmp/ccQF2lF2.s:565 .text:0000000000000108 enc28j60PhyWrite + /tmp/ccQF2lF2.s:627 .text:0000000000000150 enc28j60getrev + /tmp/ccQF2lF2.s:647 .text:0000000000000156 enc28j60hasRxPkt + /tmp/ccQF2lF2.s:676 .text:0000000000000168 enc28j60linkup + /tmp/ccQF2lF2.s:739 .text:00000000000001a4 nicSend + *COM*:000000000000000e nicState + /tmp/ccQF2lF2.s:876 .text:0000000000000252 nicPoll + .bss:0000000000000000 gNextPacketPtr + /tmp/ccQF2lF2.s:1079 .text:000000000000037a nicSetMacAddress + /tmp/ccQF2lF2.s:1135 .text:00000000000003b4 nicMacInit + /tmp/ccQF2lF2.s:1340 .text:00000000000004d8 nicGetMacAddress + /tmp/ccQF2lF2.s:1395 .text:0000000000000514 nicRegDump + /tmp/ccQF2lF2.s:1545 .progmem.data:000000000000005a __c.3546 + /tmp/ccQF2lF2.s:1541 .progmem.data:000000000000004b __c.3548 + /tmp/ccQF2lF2.s:1537 .progmem.data:000000000000003c __c.3550 + /tmp/ccQF2lF2.s:1533 .progmem.data:000000000000002d __c.3552 + /tmp/ccQF2lF2.s:1529 .progmem.data:000000000000001e __c.3554 + /tmp/ccQF2lF2.s:1525 .progmem.data:000000000000000f __c.3556 + /tmp/ccQF2lF2.s:1521 .progmem.data:0000000000000000 __c.3558 + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +spiSendENC +vTaskDelay +fprintf_P +__do_clear_bss diff --git a/Lib/ff.c b/Lib/ff.c new file mode 100644 index 0000000..ff34b19 --- /dev/null +++ b/Lib/ff.c @@ -0,0 +1,3553 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.08 (C)ChaN, 2010 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed fname member in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 8085 +#error Wrong include file (ff.h). +#endif + + +/* FAT sub-type boundaries */ +/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */ +#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */ + + +/* Definitions corresponds to multiple sector size */ +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->ssize) +#else +#error Wrong sector size. +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + +/*------------------------------------------------------------*/ +/* Work area */ + +#if !_DRIVES +#error Number of drives must not be 0. +#endif +static +WORD Fsid; /* File system mount ID */ +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 0 /* No LFN */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN with static LFN working buffer */ +static WCHAR LfnBuf[_MAX_LFN + 1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof(int)) { + *(int*)d = *(int*)s; + d += sizeof(int); s += sizeof(int); + cnt -= sizeof(int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +int lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* File shareing control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_SHARE + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dj, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_SHARE; i++) { + if (dj->fs->flsem[i].ctr) { /* Existing entry */ + if (dj->fs->flsem[i].clu == dj->sclust && /* The file is found (identified with its location) */ + dj->fs->flsem[i].idx == dj->index) break; + } else { /* Blank entry */ + be++; + } + } + if (i == _FS_SHARE) /* The file has not been opened */ + return (be || acc != 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ + + /* The file has been opened. Reject any open against writing file and all write mode open */ + return (acc || dj->fs->flsem[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock ( /* Check if an entry is available for a new file */ + FATFS* fs /* File system object */ +) +{ + UINT i; + + for (i = 0; i < _FS_SHARE && fs->flsem[i].ctr; i++) ; + return (i == _FS_SHARE) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */ + DIR* dj, /* Directory object pointing the file to register or increment */ + int acc /* Desired access mode (0:Read, !0:Write) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_SHARE; i++) { /* Find the file */ + if (dj->fs->flsem[i].ctr && + dj->fs->flsem[i].clu == dj->sclust && + dj->fs->flsem[i].idx == dj->index) break; + } + + if (i == _FS_SHARE) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_SHARE && dj->fs->flsem[i].ctr; i++) ; + if (i == _FS_SHARE) return 0; /* No space to register (int err) */ + dj->fs->flsem[i].clu = dj->sclust; + dj->fs->flsem[i].idx = dj->index; + } + + if (acc && dj->fs->flsem[i].ctr) return 0; /* Access violation (int err) */ + + dj->fs->flsem[i].ctr = acc ? 0x100 : dj->fs->flsem[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement file open counter */ + FATFS* fs, /* File system object */ + UINT i /* Semaphore index */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_SHARE) { + n = fs->flsem[i].ctr; + if (n >= 0x100) n = 0; + if (n) n--; + fs->flsem[i].ctr = n; + res = FR_OK; + } else { + res = FR_INT_ERR; + } + return res; +} + +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drv, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, (void*)0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Chack range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "last link" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ + DIR *dj, /* Pointer to directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to generated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + int i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_sdi(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contiguous entry */ + if (++n == ne) break; /* A contiguous entry that required count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_sdi(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ +#if _USE_LFN + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const TCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */ +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = excvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if extended char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE nt, *dir; + TCHAR *p, c; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = (TCHAR)0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + TCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (TCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const TCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading separator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ + res = dir_sdi(dj, 0); + dj->dir = 0; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + ns = *(dj->fn+NS); + if (res != FR_OK) { /* Failed to find the object */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occured */ + /* Object not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ + dj->sclust = 0; dj->dir = 0; /* It is the root dir */ + res = FR_OK; + if (!(ns & NS_LAST)) continue; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; + } + break; + } + if (ns & NS_LAST) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ + const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, b, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + const TCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume (initialize the file system object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive (Supports only generic partitionings, FDISK and SFD) */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */ + if (fmt == 1) { /* Not an FAT-VBR, the disk may be partitioned */ + /* Check the partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= b; /* Number of sectors for FAT area */ + + fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be 1,2,4...128) */ + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / 32)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */ + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / 32); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->database = bsect + sysect; /* Data start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (FAT size must not be less than FAT sectors */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->last_clust = 0; + + /* Get fsinfo if available */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ + fs->winsect = 0; /* Invalidate sector cache */ + fs->wflag = 0; +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_SHARE /* Clear file lock semaphores */ + for (vol = 0; vol < _FS_SHARE; vol++) + fs->flsem[vol].ctr = 0; +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const TCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + fp->fs = 0; /* Clear file object */ + +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + INIT_BUF(dj); + if (res == FR_OK) + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; + +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_SHARE + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_SHARE + res = enq_lock(dj.fs) ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) { /* Cannot create new */ + res = FR_EXIST; + } else { + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) + mode |= FA__WRITTEN; /* Set file changed flag */ + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_SHARE + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* No cluster link map table */ +#endif + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = buff; + + + *br = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + BYTE csect; + + + *bw = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or stretch cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + +#if _FS_READONLY + FATFS *fs = fp->fs; + res = validate(fs, fp->id); + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + +#else + res = f_sync(fp); /* Flush cached data */ +#if _FS_SHARE + if (res == FR_OK) { /* Decrement open counter */ +#if _FS_REENTRANT + res = validate(fp->fs, fp->id); + if (res == FR_OK) { + res = dec_lock(fp->fs, fp->lockid); + unlock_fs(fp->fs, FR_OK); + } +#else + res = dec_lock(fp->fs, fp->lockid); +#endif + } +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, *tbl = fp->cltbl; + BYTE csc; + + tlen = *tbl++; + if (ofs == CREATE_LINKMAP) { /* Create link map table */ + cl = fp->org_clust; + if (cl) { + do { + if (tlen < 4) { /* Not enough table items */ + res = FR_NOT_ENOUGH_CORE; break; + } + tcl = cl; ncl = 0; + do { /* Get a fragment and store the top and length */ + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + *tbl++ = ncl; *tbl++ = tcl; + tlen -= 2; + } while (cl < fp->fs->n_fatent); + } + *tbl = 0; /* Terminate table */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + dsc = (ofs - 1) / SS(fp->fs); + cl = dsc / fp->fs->csize; + for (;;) { + ncl = *tbl++; + if (!ncl) ABORT(fp->fs, FR_INT_ERR); + if (cl < ncl) break; + cl -= ncl; tbl++; + } + fp->curr_clust = cl + *tbl; + csc = (BYTE)(dsc & (fp->fs->csize - 1)); + dsc = clust2sect(fp->fs, fp->curr_clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += csc; + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INIT_BUF(*dj); + res = follow_path(dj, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the current dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_sdi(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dj, 0); + } else { + INIT_BUF(*dj); + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) { + *nclst = (*fatfs)->free_clust; + } else { + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < (*fatfs)->n_fatent); + } else { + clst = (*fatfs)->n_fatent; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) break; + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + } + } + LEAVE_FF(*fatfs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__ERROR) { /* Check abort flag */ + res = FR_INT_ERR; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj); + if (res == FR_OK /* Not empty dir */ +#if _FS_RPATH + || dclst == sdj.fs->cdir /* Current dir */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync(dj.fs); + } + } + } + FREE_BUF(); + } + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tim = get_fattime(); + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = move_window(dj.fs, 0); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dcl); + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + ST_WORD(dir+32+DIR_FstClusLO, pcl); + ST_WORD(dir+32+DIR_FstClusHI, pcl >> 16); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */ + ST_WORD(dir+DIR_FstClusLO, dcl); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR *path_old, /* Pointer to the old name */ + const TCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + res = chk_mounted(&path_old, &djo.fs, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption or error can cause cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djn.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djn.fs, dw); + dir = djn.fs->win+32; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + djn.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 */ +#define N_FATS 1 /* 1 or 2 */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit size [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + BYTE fmt, md, *tbl; + DWORD n_clst, vs, n; + UINT as, i; + DWORD b_vol, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Area size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd == 1) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; + if (au & (au - 1)) au = 0; /* Check validity of the allocation unit size */ + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + if (_MAX_SS != 512 && au < SS(fs)) au = SS(fs); + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT syb-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = N_ROOTDIR * 32UL / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_DISK_ERR; + if (!n || n > 32768) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest boundary from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT start */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Create partition table if required */ + if (sfd == 1) { + md = 0xF0; + } else { + DWORD n_disk = b_vol + n_vol; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_vol < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + md = 0xF8; + } + + /* Create VBR */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + as = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, as); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + as = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */ + ST_WORD(tbl+BPB_RootEntCnt, as); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Original (VBR) */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Backup (VBR+6) */ + disk_write(drv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + for (i = 0; i < N_FATS; i++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0x0FFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0x0FFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector write */ + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + n = (fmt == FS_FAT32) ? as : n_dir; + while (n--) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_vol + 1, 1); /* Original (VBR+1) */ + disk_write(drv, tbl, b_vol + 7, 1); /* Backup (VBR+7) */ + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fil /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; /* Break on EOF or error */ + c = s[0]; +#if _LFN_UNICODE /* Read a character in UTF-8 encoding */ + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequense */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; + c = ((c & 0x1F) << 6) | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequense */ + f_read(fil, s, 2, &rc); + if (rc != 2) break; + c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequense */ + c = '?'; + } + } + } +#endif +#if _USE_STRFUNC >= 2 + if (c == '\r') continue; /* Strip '\r' */ +#endif + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + UINT bw, btw; + BYTE s[3]; + + +#if _USE_STRFUNC >= 2 + if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + +#if _LFN_UNICODE /* Write the character in UTF-8 encoding */ + if (c < 0x80) { /* 7-bit */ + s[0] = (BYTE)c; + btw = 1; + } else { + if (c < 0x800) { /* 11-bit */ + s[0] = (BYTE)(0xC0 | (c >> 6)); + s[1] = (BYTE)(0x80 | (c & 0x3F)); + btw = 2; + } else { /* 16-bit */ + s[0] = (BYTE)(0xE0 | (c >> 12)); + s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F)); + s[2] = (BYTE)(0x80 | (c & 0x3F)); + btw = 3; + } + } +#else /* Write the character without conversion */ + s[0] = (BYTE)c; + btw = 1; +#endif + f_write(fil, s, btw, &bw); /* Write the char to the file */ + return (bw == btw) ? 1 : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const TCHAR* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT i, w; + ULONG val; + TCHAR c, d, s[16]; + int res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *str++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + cc = f_puts(va_arg(arp, TCHAR*), fil); continue; + case 'C' : /* Character */ + cc = f_putc((TCHAR)va_arg(arp, int), fil); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown */ + cc = f_putc(c, fil); continue; + } + + /* Get an argument */ + val = (f & 2) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : va_arg(arp, unsigned int)); + if (d == 'D' && (val & 0x80000000)) { + val = 0 - val; + f |= 4; + } + /* Put it in numeral string */ + i = 0; + do { + d = (TCHAR)(val % r); val /= r; + if (d > 9) { + d += 7; + if (c == 'x') d += 0x20; + } + s[i++] = d + '0'; + } while (val && i < sizeof(s) / sizeof(s[0])); + if (f & 4) s[i++] = '-'; + cc = 0; + while (i < w-- && cc != EOF) { + cc = f_putc((TCHAR)((f & 1) ? '0' : ' '), fil); + res++; + } + do { + cc = f_putc(s[--i], fil); + res++; + } while (i && cc != EOF); + if (cc != EOF) cc = 0; + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/Lib/include/Rs485_prot.h b/Lib/include/Rs485_prot.h new file mode 100644 index 0000000..508c6e0 --- /dev/null +++ b/Lib/include/Rs485_prot.h @@ -0,0 +1,116 @@ +#ifndef RS485_PROT_H +#define RS485_PROT_H + +#include +#include +#include "ramdysk.h" +#include "protocol1.h" +#include "softwareConfig.h" + +#ifdef LANG_EN +#define PRINT_RS485_DEVICE 1 +#endif /*LANG_EN*/ +#ifdef LANG_PL +#define PRINT_RS485_DEVICE 1 +#endif /*LANG_PL*/ + +//@{ + +struct helloRespParsed +{ + uint8_t stateRoller1; //7 - moving up, 6 - moving down, 5-0 - position + uint8_t stateRoller2; //7 - moving up, 6 0 moving down, 5-0 - position + uint8_t settings; + char firmware[5]; +}; + +union helloResponse +{ + uint8_t data[HELLO_RESP_LEN]; + struct helloRespParsed parsed; +}; + + + +struct sterRolet +{ + uint8_t state; + uint8_t address; + union helloResponse response; + uint8_t empty; +}; + + +struct sterRolet *rollers; + + +// ******************************** Hardware specyfic function *********************** +void takeRs485(void) __attribute__ ((weak)); +void releaseRs485(void) __attribute__ ((weak)); +void uartRs485SendByte(uint8_t c) __attribute__ ((weak)); +uint8_t rs485Receive(uint8_t *c, uint8_t timeout) __attribute__ ((weak)); +uint8_t flushRs485RecBuffer(void) __attribute__ ((weak)); + + +void rollersMemInit(void); + +#ifdef PRINT_RS485_DEVICE +/** + * Prints list of Rs485 devices + * @param stream - outpuf stream + * @return number of printed devices + */ +uint8_t printRs485devices(FILE *stream); +#endif /*PRINT_RS485_DEVICE*/ + + +/** + * Sends Ping and waits for response + * @param devAddr - device address + * @return 0 - All OK + */ +uint8_t rs485ping(uint8_t devAddr); + + +void sendSettings(uint8_t addr, uint8_t value); + +void saveSettings(uint8_t addr); + +/** + * Sends Hello message to the roller driver and reads its response + * @param devAddr - device address + * @return 0 - All OK, 1 - no space in memory to write info, 2 - no response, 3 - wrong address + */ +uint8_t rs485rollerHello(uint8_t devAddr); + +/** + * Flash remote device connected to Rs485 bus + * @param file - file descriptor with firmware + * @param devAddr - device address + * @return 0 - All OK + */ +uint8_t rs485xModemFlash(struct ramPlikFd *file, uint8_t devAddr, FILE *debStr); + +/** + * Move curtain up + * @param deviceAddr - remote module address + * @param curtainNo - number of curtain (0 or 1) + * @param pos - position of curtain + * @return 0 - All OK + */ +uint8_t rs485curtainUp(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos); + +uint8_t rs485Led(uint8_t deviceAddr, uint8_t ledNo, uint8_t time); + + +/** + * Move curtain down + * @param deviceAddr - remote module address + * @param curtainNo - number of curtain (0 or 1) + * @param pos - position of curtain + * @return 0 - All OK + */ +uint8_t rs485curtainDown(uint8_t deviceAddr, uint8_t curtainNo, uint8_t pos); + +//@} +#endif diff --git a/Lib/include/cmdline.h b/Lib/include/cmdline.h new file mode 100755 index 0000000..9048b4b --- /dev/null +++ b/Lib/include/cmdline.h @@ -0,0 +1,181 @@ +/** + * @file cmdline.h + * @author Pascal Stang, Adam Kaliszan + * @brief Command-Line Interface Library + * @ingroup protocols + * @version 0.6 + * Created 2003.07.16 + * Revised 2010.04.23 + * Editor Tabs 2 + * Target MCU Atmel AVR Series + * + * @par Description + * This library provides cammand lineinterpreter, that works on many instances. + * Each instance requires: separate input/output stream, and separate instance of cmdState struct + * The library was optimised under memory consumption. + * + * @note: This code is currently below version 1.0, and therefore is considered + * to be lacking in some functionality or documentation, or may not be fully + * tested. Nonetheless, you can expect most functions to work. + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt +*/ +//----- Include Files --------------------------------------------------------- +#ifndef CMDLINE_H +#define CMDLINE_H + +#include +#include // editor recognizes now types like uint8_t + + +#include "softwareConfig.h" + +//@{ + + +// constants/macros/typdefs +struct cmdState; +struct command; +enum cliExecuteResult; + +typedef struct command command_t; +typedef struct cmdState cmdState_t; +typedef enum cliExecuteResult cliExRes_t; + +typedef cliExRes_t (*CmdlineFuncPtrType)(cmdState_t *state); + +enum cmdBufferHistory +{ + NOT_COPIED = 0, + COPIED = 1 +}; + +enum cliModeState +{ + NR_NORMAL, + NR_ENABLE, + NR_CONFIGURE, + RESTRICTED_NORMAL +}; + +enum cliExecuteResult +{ + OK_SILENT =0, + OK_INFORM, + SYNTAX_ERROR, + ERROR_SILENT, + ERROR_INFORM, + ERROR_OPERATION_NOT_ALLOWED +}; + +enum cliHistoryAction +{ + CMDLINE_HISTORY_SAVE, + CMDLINE_HISTORY_PREV, + CMDLINE_HISTORY_NEXT +}; + +struct cmdState +{ + char *CmdlineBuffer; /// CLI buffer. + char *CmdlineExcBuffer; /// CLI processing buffer. + char *CmdlineHistory[CMD_STATE_HISTORY]; /// CLI history. History Size = 3. Sorry for Hardcodding + + uint8_t bufferMaxSize; /// Total buffer size / CMD_STATE_HISTORY + uint8_t CmdlineBufferLength; /// Number of writen chars in buffer + uint8_t CmdlineBufferEditPos; /// Edit position in the buffer + + uint8_t historyWrIdx; /// History write index (0 - CMD_STATE_HISTORY-1) + uint8_t historyDepthIdx; /// History depth index. Read idx = (historyWrIdx - historyDepthIdx) & CMD_STATE_HISTORY_MASK + enum cmdBufferHistory bufferHistoryState; /// Buffer history state + + uint8_t CmdlineInputVT100State; /// Commandline State TODO add enum type + const char* command_str; /// Executing command string + const char* command_help_str; /// Executing command help string + CmdlineFuncPtrType CmdlineExecFunction; /// Pointer to the funtion that match to the string writen in buffer + uint8_t argc; /// Index of last argument + + FILE *myStdInOut; /// Input / output stream descriptor + + uint8_t errno; /// Error number + uint16_t err1; /// Additional error info 1 + uint8_t err2; /// Additional error info 1 + + enum cliModeState cliMode; /// CLI mode (NORMAL, ENABLED, CONFIGURE) + const command_t *cmdList; /// Each CLI mode has own command list +}; + +struct command +{ + const char *commandStr; /// Command string + const char *commandHelpStr; /// Command help string + CmdlineFuncPtrType commandFun; /// Command function pointer +}; + + +// functions + +/** + * call this function to pass input charaters from the user terminal + * @param c - new char + * @param state - cli state + */ +void cmdlineInputFunc(char c, cmdState_t *state); + +/** + * call this function in task + * @param state - cli state + */ +void cmdlineMainLoop(cmdState_t *state); + +/** + * Get last argument index. + * @param state - cli state + * @return last argument index + */ +uint8_t cmdLineGetLastArgIdx(cmdState_t *state); + +// argument retrieval commands +/** + * returns a string pointer to argument number [argnum] on the command line + * @param argnum - argument no. Number of first arg is 1 + * @param state - cli state + * @return char pointer + */ +char* cmdlineGetArgStr(uint8_t argnum, cmdState_t *state); + +/** + * returns the decimal integer interpretation of argument number [argnum] + * @param argnum - argument no. Number of first arg is 1 + * @param state - cli state + * @return long int + */ +long cmdlineGetArgInt (uint8_t argnum, cmdState_t *state); + +/** + * returns the hex integer interpretation of argument number [argnum] + * @param argnum - argument no. Number of first arg is 1 + * @param state - cli state + */ +long cmdlineGetArgHex (uint8_t argnum, cmdState_t *state); + +/** + * Print all commands available for cmdState and its description + * @param state - command line interpreter state + */ +void cmdPrintHelp(cmdState_t *state); + +/** + * Konfiguruje strukturÄ™ do obsÅ‚ugi sesji interpretera poleceÅ„ + * @param state - wskaźnik do struktury ze stanem sesji interpretera poleceÅ„ + * @param buffPtr - wskaźnik do poczÄ…tku bufora. 1/4 bufora przeznaczona jest na buforowanie polecenia, 3/4 na zapamiÄ™tanie 3 ostatnich poleceÅ„ + * @param bufferTotalSize - dÅ‚ugość przydzielonego bufora. Min 32 * CMD_STATE_HISTORY bajtów + * @param *stream - input/output stream + * @param *commands - pointer to the command table + * @param mode - command line interpreter mode + */ +void cmdStateConfigure(cmdState_t * state, char *buffPtr, uint16_t bufferTotalSize, FILE *stream, const command_t *commands, enum cliModeState mode); + +//@} +#endif diff --git a/Lib/include/ds1305.h b/Lib/include/ds1305.h new file mode 100644 index 0000000..926898e --- /dev/null +++ b/Lib/include/ds1305.h @@ -0,0 +1,144 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : Ds1305 RTC freeRtos Driver +* Author : Adam Kaliszan +* Copyright: GPL V2 +* +*This driver provides: +* - time read/set operation +* - alarm handling +* - chip memory read/write +* - api for Fat32 library +*Driver uses mutexex and is condition race free. Function can be invoken in any thread. +*****************************************************************************/ +//@{ + + +#ifndef DS1305_H +#define DS1305_H + +#include +#include "spiXmega.h" +#include "hardwareConfig.h" + + +void spiEnableDS1305(void) __attribute__ ((weak)); +void spiDisableDS1305(void) __attribute__ ((weak)); + +struct timeBCD +{ + uint8_t seconds; /// Sekundy: Odczyt(0x00), Zapis(0x80) + uint8_t minutes; /// Minuty: Odczyt(0x01), Zapis(0x81) + uint8_t hour; /// Godzina: Odczyt(0x02), Zapis(0x82) (bit 6 oznacza system 12h/24h) + uint8_t day; /// DzieÅ„(1-7): Odczyt(0x03), Zapis(0x83) (pierwsze 3 bity, pozostaÅ‚e majÄ… wartość 0) + uint8_t dateDay; /// DzieÅ„ miesiÄ…ca: Odczyt(0x04), Zapis(0x84) + uint8_t dateMonth; /// MiesiÄ…c: Odczyt(0x05), Zapis(0x85) + uint8_t dateYear; /// Rok: Odczyt(0x06), Zapis(0x86) (należy dopisać na poczÄ…tek 20) +}; + +#if USE_DECODED_TIME_STRUCT +struct timeDecoded +{ + struct /// Sekundy: Odczyt(0x00), Zapis(0x80) + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :3; // Cyfra dziesiÄ™tna (3 bity) + } seconds; + + struct /// Minuty: Odczyt(0x01), Zapis(0x81) + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :3; // Cyfra dziesiÄ™tna (3 bity) + } minutes; + + union /// Godzina: Odczyt(0x02), Zapis(0x82) + { + struct // System 12 godzinny + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :1; // Cyfra dziesiÄ™tna (1 bit) + uint8_t AmPm :1; // 0 - Am, 1 - Pm + uint8_t syst24 :1; // 0 - system 12 godzinny, 1 - system 24 godzinny + } syst12; + struct // System 24 godzinny + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :2; // Cyfra dziesiÄ™tna (2 bity) + uint8_t syst24 :1; // 0 - system 12 godzinny, 1 - system 24 godzinny + } syst24; + } hours; + + uint8_t day; /// DzieÅ„(1-7): Odczyt(0x03), Zapis(0x83) (pierwsze 3 bity, pozostaÅ‚e majÄ… wartość 0) + + struct /// DzieÅ„ miesiÄ…ca: Odczyt(0x04), Zapis(0x84) + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :2; // Cyfra dziesiÄ™tna (2 bity) + } dateDay; + + struct /// MiesiÄ…c: Odczyt(0x05), Zapis(0x85) + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :2; // Cyfra dziesiÄ™tna (2 bity ??? tak byÅ‚o w specyfikacji) + } dateMonth; + + struct /// Rok: Odczyt(0x06), Zapis(0x86) (należy dopisać na poczÄ…tek 20) + { + uint8_t cJedn :4; // Cyfra jednostek + uint8_t cDzies :4; // Cyfra dziesiÄ™tna (4 bity) + } dateYear; +}; + +union time +{ + struct timeBCD BCD; + struct timeDecoded Decoded; +}; +#endif /* USE_DECODED_TIME_STRUCT */ + +typedef struct timeBCD timeBCD_t; +#if USE_DECODED_TIME_STRUCT +typedef struct timeDecoded timeDecoded_t; +typedef union time time_t; +#endif /* USE_DECODED_TIME_STRUCT */ + + +//------------------ Functions --------------------------------- + +void readTimeBCD (timeBCD_t *time); + +#if USE_DECODED_TIME_STRUCT +void readTimeDecoded (timeDecoded_t *time); +void readTime (time_t *time); +#endif /* USE_DECODED_TIME_STRUCT */ + +void setTimeBCD (timeBCD_t *time); +#if USE_DECODED_TIME_STRUCT +void setTimeDecoded (timeDecoded_t *time); +void setTime (time_t *time); +#endif /* USE_DECODED_TIME_STRUCT */ + +/** + * Uruchamia kwarc, wyÅ‚Ä…cza blokadÄ™ przed zapisem do pamiÄ™ci + */ +void ds1305start(void); + +/** + * Zapisuje do pamiÄ™ci nieulotnej ukÅ‚adu RTC. + * @param addr - adres pierwszej komórki do zapisu (0-95) + * @param length - liczba bajtów do zapisu + * @param *data - wskaźnik do tablicy z bajtami do zapisu + */ +uint8_t ds1305writeMem (uint8_t addr, uint8_t length, uint8_t *data); + +/** + * Odczytuje z pamiÄ™ci nieulotnej ukÅ‚adu RTC. + * @param addr - adres pierwszej komórki do odczytu (0-95) + * @param length - liczba bajtów do odczytu + * @param *data - wskaźnik do tablicy, w której zostanÄ… zapisane odczytane bajty + */ +uint8_t ds1305readMem (uint8_t addr, uint8_t length, uint8_t *data); + +#endif +//@} diff --git a/Lib/include/enc28j60.h b/Lib/include/enc28j60.h new file mode 100644 index 0000000..d46c563 --- /dev/null +++ b/Lib/include/enc28j60.h @@ -0,0 +1,285 @@ +/** + * vim:sw=2:ts=2:si:et + * @file enc28j60.h + * Title : Microchip ENC28J60 Ethernet Interface Driver + * @author Pascal Stang, Adam Kaliszan + * @version 0.2 + * Copyright: GPL V2 + * + * This driver provides initialization and transmit/receive + * functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. + * This chip is novel in that it is a full MAC+PHY interface all in a 28-pin + * chip, using an SPI interface to the host processor. + * + * + */ +//@{ + + +#ifndef ENC28J60_H +#define ENC28J60_H + +#include +#include +#include +#include + +#include "main.h" +#include "nic.h" +#include "spiXmega.h" +#include "hardwareConfig.h" +#include "memory_x.h" + +// ENC28J60 Control Registers +// Control register definitions are a combination of address, +// bank number, and Ethernet/MAC/PHY indicator bits. +// - Register address (bits 0-4) +// - Bank number (bits 5-6) +// - MAC/PHY indicator (bit 7) +#define ADDR_MASK 0x1F +#define BANK_MASK 0x60 +#define SPRD_MASK 0x80 +// All-bank registers +#define EIE 0x1B +#define EIR 0x1C +#define ESTAT 0x1D +#define ECON2 0x1E +#define ECON1 0x1F +// Bank 0 registers +#define ERDPTL (0x00|0x00) +#define ERDPTH (0x01|0x00) +#define EWRPTL (0x02|0x00) +#define EWRPTH (0x03|0x00) +#define ETXSTL (0x04|0x00) +#define ETXSTH (0x05|0x00) +#define ETXNDL (0x06|0x00) +#define ETXNDH (0x07|0x00) +#define ERXSTL (0x08|0x00) +#define ERXSTH (0x09|0x00) +#define ERXNDL (0x0A|0x00) +#define ERXNDH (0x0B|0x00) +#define ERXRDPTL (0x0C|0x00) +#define ERXRDPTH (0x0D|0x00) +#define ERXWRPTL (0x0E|0x00) +#define ERXWRPTH (0x0F|0x00) +#define EDMASTL (0x10|0x00) +#define EDMASTH (0x11|0x00) +#define EDMANDL (0x12|0x00) +#define EDMANDH (0x13|0x00) +#define EDMADSTL (0x14|0x00) +#define EDMADSTH (0x15|0x00) +#define EDMACSL (0x16|0x00) +#define EDMACSH (0x17|0x00) +// Bank 1 registers +#define EHT0 (0x00|0x20) +#define EHT1 (0x01|0x20) +#define EHT2 (0x02|0x20) +#define EHT3 (0x03|0x20) +#define EHT4 (0x04|0x20) +#define EHT5 (0x05|0x20) +#define EHT6 (0x06|0x20) +#define EHT7 (0x07|0x20) +#define EPMM0 (0x08|0x20) +#define EPMM1 (0x09|0x20) +#define EPMM2 (0x0A|0x20) +#define EPMM3 (0x0B|0x20) +#define EPMM4 (0x0C|0x20) +#define EPMM5 (0x0D|0x20) +#define EPMM6 (0x0E|0x20) +#define EPMM7 (0x0F|0x20) +#define EPMCSL (0x10|0x20) +#define EPMCSH (0x11|0x20) +#define EPMOL (0x14|0x20) +#define EPMOH (0x15|0x20) +#define EWOLIE (0x16|0x20) +#define EWOLIR (0x17|0x20) +#define ERXFCON (0x18|0x20) +#define EPKTCNT (0x19|0x20) +// Bank 2 registers +#define MACON1 (0x00|0x40|0x80) +#define MACON2 (0x01|0x40|0x80) +#define MACON3 (0x02|0x40|0x80) +#define MACON4 (0x03|0x40|0x80) +#define MABBIPG (0x04|0x40|0x80) +#define MAIPGL (0x06|0x40|0x80) +#define MAIPGH (0x07|0x40|0x80) +#define MACLCON1 (0x08|0x40|0x80) +#define MACLCON2 (0x09|0x40|0x80) +#define MAMXFLL (0x0A|0x40|0x80) +#define MAMXFLH (0x0B|0x40|0x80) +#define MAPHSUP (0x0D|0x40|0x80) +#define MICON (0x11|0x40|0x80) +#define MICMD (0x12|0x40|0x80) +#define MIREGADR (0x14|0x40|0x80) +#define MIWRL (0x16|0x40|0x80) +#define MIWRH (0x17|0x40|0x80) +#define MIRDL (0x18|0x40|0x80) +#define MIRDH (0x19|0x40|0x80) +// Bank 3 registers +#define MAADR1 (0x00|0x60|0x80) +#define MAADR0 (0x01|0x60|0x80) +#define MAADR3 (0x02|0x60|0x80) +#define MAADR2 (0x03|0x60|0x80) +#define MAADR5 (0x04|0x60|0x80) +#define MAADR4 (0x05|0x60|0x80) +#define EBSTSD (0x06|0x60) +#define EBSTCON (0x07|0x60) +#define EBSTCSL (0x08|0x60) +#define EBSTCSH (0x09|0x60) +#define MISTAT (0x0A|0x60|0x80) +#define EREVID (0x12|0x60) +#define ECOCON (0x15|0x60) +#define EFLOCON (0x17|0x60) +#define EPAUSL (0x18|0x60) +#define EPAUSH (0x19|0x60) +// PHY registers +#define PHCON1 0x00 +#define PHSTAT1 0x01 +#define PHHID1 0x02 +#define PHHID2 0x03 +#define PHCON2 0x10 +#define PHSTAT2 0x11 +#define PHIE 0x12 +#define PHIR 0x13 +#define PHLCON 0x14 + +// ENC28J60 ERXFCON Register Bit Definitions +#define ERXFCON_UCEN 0x80 +#define ERXFCON_ANDOR 0x40 +#define ERXFCON_CRCEN 0x20 +#define ERXFCON_PMEN 0x10 +#define ERXFCON_MPEN 0x08 +#define ERXFCON_HTEN 0x04 +#define ERXFCON_MCEN 0x02 +#define ERXFCON_BCEN 0x01 +// ENC28J60 EIE Register Bit Definitions +#define EIE_INTIE 0x80 +#define EIE_PKTIE 0x40 +#define EIE_DMAIE 0x20 +#define EIE_LINKIE 0x10 +#define EIE_TXIE 0x08 +#define EIE_WOLIE 0x04 +#define EIE_TXERIE 0x02 +#define EIE_RXERIE 0x01 +// ENC28J60 EIR Register Bit Definitions +#define EIR_PKTIF 0x40 +#define EIR_DMAIF 0x20 +#define EIR_LINKIF 0x10 +#define EIR_TXIF 0x08 +#define EIR_WOLIF 0x04 +#define EIR_TXERIF 0x02 +#define EIR_RXERIF 0x01 +// ENC28J60 ESTAT Register Bit Definitions +#define ESTAT_INT 0x80 +#define ESTAT_LATECOL 0x10 +#define ESTAT_RXBUSY 0x04 +#define ESTAT_TXABRT 0x02 +#define ESTAT_CLKRDY 0x01 +// ENC28J60 ECON2 Register Bit Definitions +#define ECON2_AUTOINC 0x80 +#define ECON2_PKTDEC 0x40 +#define ECON2_PWRSV 0x20 +#define ECON2_VRPS 0x08 +// ENC28J60 ECON1 Register Bit Definitions +#define ECON1_TXRST 0x80 +#define ECON1_RXRST 0x40 +#define ECON1_DMAST 0x20 +#define ECON1_CSUMEN 0x10 +#define ECON1_TXRTS 0x08 +#define ECON1_RXEN 0x04 +#define ECON1_BSEL1 0x02 +#define ECON1_BSEL0 0x01 +// ENC28J60 MACON1 Register Bit Definitions +#define MACON1_LOOPBK 0x10 +#define MACON1_TXPAUS 0x08 +#define MACON1_RXPAUS 0x04 +#define MACON1_PASSALL 0x02 +#define MACON1_MARXEN 0x01 +// ENC28J60 MACON2 Register Bit Definitions +#define MACON2_MARST 0x80 +#define MACON2_RNDRST 0x40 +#define MACON2_MARXRST 0x08 +#define MACON2_RFUNRST 0x04 +#define MACON2_MATXRST 0x02 +#define MACON2_TFUNRST 0x01 +// ENC28J60 MACON3 Register Bit Definitions +#define MACON3_PADCFG2 0x80 +#define MACON3_PADCFG1 0x40 +#define MACON3_PADCFG0 0x20 +#define MACON3_TXCRCEN 0x10 +#define MACON3_PHDRLEN 0x08 +#define MACON3_HFRMLEN 0x04 +#define MACON3_FRMLNEN 0x02 +#define MACON3_FULDPX 0x01 +// ENC28J60 MICMD Register Bit Definitions +#define MICMD_MIISCAN 0x02 +#define MICMD_MIIRD 0x01 +// ENC28J60 MISTAT Register Bit Definitions +#define MISTAT_NVALID 0x04 +#define MISTAT_SCAN 0x02 +#define MISTAT_BUSY 0x01 +// ENC28J60 PHY PHCON1 Register Bit Definitions +#define PHCON1_PRST 0x8000 +#define PHCON1_PLOOPBK 0x4000 +#define PHCON1_PPWRSV 0x0800 +#define PHCON1_PDPXMD 0x0100 +// ENC28J60 PHY PHSTAT1 Register Bit Definitions +#define PHSTAT1_PFDPX 0x1000 +#define PHSTAT1_PHDPX 0x0800 +#define PHSTAT1_LLSTAT 0x0004 +#define PHSTAT1_JBSTAT 0x0002 +// ENC28J60 PHY PHCON2 Register Bit Definitions +#define PHCON2_FRCLINK 0x4000 +#define PHCON2_TXDIS 0x2000 +#define PHCON2_JABBER 0x0400 +#define PHCON2_HDLDIS 0x0100 + +// ENC28J60 Packet Control Byte Bit Definitions +#define PKTCTRL_PHUGEEN 0x08 +#define PKTCTRL_PPADEN 0x04 +#define PKTCTRL_PCRCEN 0x02 +#define PKTCTRL_POVERRIDE 0x01 + +// SPI operation codes +#define ENC28J60_READ_CTRL_REG 0x00 +#define ENC28J60_READ_BUF_MEM 0x3A +#define ENC28J60_WRITE_CTRL_REG 0x40 +#define ENC28J60_WRITE_BUF_MEM 0x7A +#define ENC28J60_BIT_FIELD_SET 0x80 +#define ENC28J60_BIT_FIELD_CLR 0xA0 +#define ENC28J60_SOFT_RESET 0xFF + + +// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata +// buffer boundaries applied to internal 8K ram +// the entire available packet buffer space is allocated +// +// start with recbuf at 0/ +#define RXSTART_INIT 0x0 +// receive buffer end +#define RXSTOP_INIT (0x1FFF-0x0600-1) +// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (1536 bytes) +#define TXSTART_INIT (0x1FFF-0x0600) +// stp TX buffer at end of mem +#define TXSTOP_INIT 0x1FFF +// +// max frame length which the conroller will accept: +#define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518) +//#define MAX_FRAMELEN 600 + +extern nicState_t nicState; + +void nicMacInit(void); + +void nicSend(uint16_t len); +uint16_t nicPoll(void); + +void nicGetMacAddress(uint8_t* macaddr); +void nicSetMacAddress(uint8_t* macaddr); +void nicRegDump(FILE *stream); + +void spiEnableEnc28j60(void) __attribute__ ((weak)); +void spiDisableEnc28j60(void) __attribute__ ((weak)); + +#endif +//@} diff --git a/Lib/include/ff.h b/Lib/include/ff.h new file mode 100644 index 0000000..1352520 --- /dev/null +++ b/Lib/include/ff.h @@ -0,0 +1,709 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 8085 /* Revision ID */ + + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Definitions corresponds to volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ +typedef struct { + BYTE pd; /** Physical drive# */ + BYTE pt; /** Partition # (0-3) */ +} PARTITION; +extern const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ + +#else /* Single partition configuration */ +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* Definitions corresponds to file shareing feature */ + +#if _FS_SHARE +#if _FS_READONLY +#error _FS_SHARE must be 0 on R/O cfg. +#endif +typedef struct { + DWORD clu; /** File ID 1, directory */ + WORD idx; /** File ID 2, index in the directory */ + WORD ctr; /** File open counter, 0:none, 0x01..0xFF:read open count, 0x100:in write open */ +} FILESEM; +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /** FAT sub-type (0:Not mounted) */ + BYTE drv; /** Physical drive number */ + BYTE csize; /** Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /** Number of FAT copies (1,2) */ + BYTE wflag; /** win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /** fsinfo dirty flag (1:must be written back) */ + WORD id; /** File system mount ID */ + WORD n_rootdir; /** Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /** Bytes per sector (512,1024,2048,4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /** Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /** Last allocated cluster */ + DWORD free_clust; /** Number of free clusters */ + DWORD fsi_sector; /** fsinfo sector (FAT32) */ +#endif +#if _FS_RPATH + DWORD cdir; /** Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /** Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /** Sectors per FAT */ + DWORD fatbase; /** FAT start sector */ + DWORD dirbase; /** Root directory start sector (FAT32:Cluster#) */ + DWORD database; /** Data start sector */ + DWORD winsect; /** Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /** Disk access window for Directory, FAT (and Data on tiny cfg) */ +#if _FS_SHARE + FILESEM flsem[_FS_SHARE]; /** File lock semaphores */ +#endif +} FATFS; + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /** Pointer to the owner file system object */ + WORD id; /** Owner file system mount ID */ + BYTE flag; /** File status flags */ + BYTE pad1; + DWORD fptr; /** File read/write pointer */ + DWORD fsize; /** File size */ + DWORD org_clust; /** File start cluster (0 when fsize==0) */ + DWORD curr_clust; /** Current cluster */ + DWORD dsect; /** Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /** Sector containing the directory entry */ + BYTE* dir_ptr; /** Ponter to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /** Pointer to the cluster link map table */ +#endif +#if _FS_SHARE + UINT lockid; /** File lock ID */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /** File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /** Pointer to the owner file system object */ + WORD id; /** Owner file system mount ID */ + WORD index; /** Current read/write index number */ + DWORD sclust; /** Table start cluster (0:Root dir) */ + DWORD clust; /** Current cluster */ + DWORD sect; /** Current sector */ + BYTE* dir; /** Pointer to the current SFN entry in the win[] */ + BYTE* fn; /** Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /** Pointer to the LFN working buffer */ + WORD lfn_idx; /** Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /** File size */ + WORD fdate; /** Last modified date */ + WORD ftime; /** Last modified time */ + BYTE fattrib; /** Attribute */ + TCHAR fname[13]; /** Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /** Pointer to the LFN buffer */ + int lfsize; /** Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /** (0) Succeeded */ + FR_DISK_ERR, /** (1) A hard error occured in the low level disk I/O layer */ + FR_INT_ERR, /** (2) Assertion failed */ + FR_NOT_READY, /** (3) The physical drive cannot work */ + FR_NO_FILE, /** (4) Could not find the file */ + FR_NO_PATH, /** (5) Could not find the path */ + FR_INVALID_NAME, /** (6) The path name format is invalid */ + FR_DENIED, /** (7) Acces denied due to prohibited access or directory full */ + FR_EXIST, /** (8) Acces denied due to prohibited access */ + FR_INVALID_OBJECT, /** (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /** (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /** (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /** (12) The volume has no work area */ + FR_NO_FILESYSTEM, /** (13) There is no valid FAT volume on the physical drive */ + FR_MKFS_ABORTED, /** (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /** (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /** (16) The operation is rejected according to the file shareing policy */ + FR_NOT_ENOUGH_CORE, /** (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES /** (18) Number of open files > _FS_SHARE */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +/** + * Mount/Unmount a logical drive + */ +FRESULT f_mount (BYTE, FATFS*); + +/** + * Open or create a file + */ +FRESULT f_open (FIL*, const TCHAR*, BYTE); + +/** + * Read data from a file + */ +FRESULT f_read (FIL*, void*, UINT, UINT*); + +/** + * Move file pointer of a file object + */ +FRESULT f_lseek (FIL*, DWORD); + +/** + * Close an open file object + */ +FRESULT f_close (FIL*); + +/** + * Open an existing directory + */ +FRESULT f_opendir (DIR*, const TCHAR*); + +/** + * Read a directory item + */ +FRESULT f_readdir (DIR*, FILINFO*); + +/** + * Get file status + */ +FRESULT f_stat (const TCHAR*, FILINFO*); + +#if !_FS_READONLY +/** + * Write data to a file + */ +FRESULT f_write (FIL*, const void*, UINT, UINT*); + +/** + * Get number of free clusters on the drive + */ +FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); + +/** + * Truncate file + */ +FRESULT f_truncate (FIL*); + +/** + * Flush cached data of a writing file + */ +FRESULT f_sync (FIL*); + +/** + * Delete an existing file or directory + */ +FRESULT f_unlink (const TCHAR*); + +/** + * Create a new directory + */ +FRESULT f_mkdir (const TCHAR*); + +/** + * Change attriburte of the file/dir + */ +FRESULT f_chmod (const TCHAR*, BYTE, BYTE); + +/** + * Change timestamp of the file/dir + */ +FRESULT f_utime (const TCHAR*, const FILINFO*); + +/** + * Rename/Move a file or directory + */ +FRESULT f_rename (const TCHAR*, const TCHAR*); +#endif + +#if _USE_FORWARD +/** + * Forward data to the stream + */ +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); +#endif + +#if _USE_MKFS +/** + * Create a file system on the drive + */ +FRESULT f_mkfs (BYTE, BYTE, UINT); +#endif + +#if _FS_RPATH +/** + *Change current directory + */ +FRESULT f_chdir (const TCHAR*); + +/** + * Change current drive + */ +FRESULT f_chdrive (BYTE); +#endif + +#if _USE_STRFUNC +/** + * Put a character to the file + */ +int f_putc (TCHAR, FIL*); + +/** + * Put a string to the file + */ +int f_puts (const TCHAR*, FIL*); + +/** + * Put a formatted string to the file + */ +int f_printf (FIL*, const TCHAR*, ...); + +/** + * Get a string from the file + */ +TCHAR* f_gets (TCHAR*, int, FIL*); + +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) + +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) + +#ifndef EOF +#define EOF (-1) +#endif + +#endif + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT); /* Allocate memory block */ +void ff_memfree (void*); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE, _SYNC_t*); /* Create a sync object */ +int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ +int ff_req_grant (_SYNC_t); /* Lock sync object */ +void ff_rel_grant (_SYNC_t); /* Unlock sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#define FA__ERROR 0x80 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek function */ +#define CREATE_LINKMAP 0xFFFFFFFF + + +/* FatFs refers the members in the FAT structures with byte offset instead of +/ structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + + +#endif /* _FATFS */ diff --git a/Lib/include/integer.h b/Lib/include/integer.h new file mode 100644 index 0000000..76c1683 --- /dev/null +++ b/Lib/include/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/Lib/include/lcd.h b/Lib/include/lcd.h new file mode 100644 index 0000000..3627fb8 --- /dev/null +++ b/Lib/include/lcd.h @@ -0,0 +1,64 @@ +#ifndef LCD_H +#define LCD_H +// PB5 D4, PB2 D7 +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "main.h" +#include +#include +#include + + +#define HD44780_CLEAR 0x01 +#define HD44780_HOME 0x02 +#define HD44780_ENTRY_MODE 0x04 + #define HD44780_EM_SHIFT_CURSOR 0 + #define HD44780_EM_SHIFT_DISPLAY 1 + #define HD44780_EM_DECREMENT 0 + #define HD44780_EM_INCREMENT 2 +#define HD44780_DISPLAY_ONOFF 0x08 + #define HD44780_DISPLAY_OFF 0 + #define HD44780_DISPLAY_ON 4 + #define HD44780_CURSOR_OFF 0 + #define HD44780_CURSOR_ON 2 + #define HD44780_CURSOR_NOBLINK 0 + #define HD44780_CURSOR_BLINK 1 + +#define HD44780_DISPLAY_CURSOR_SHIFT 0x10 + #define HD44780_SHIFT_CURSOR 0 + #define HD44780_SHIFT_DISPLAY 8 + #define HD44780_SHIFT_LEFT 0 + #define HD44780_SHIFT_RIGHT 4 +#define HD44780_FUNCTION_SET 0x20 + #define HD44780_FONT5x7 0 + #define HD44780_FONT5x10 4 + #define HD44780_ONE_LINE 0 + #define HD44780_TWO_LINE 8 + #define HD44780_4_BIT 0 + #define HD44780_8_BIT 16 +#define HD44780_CGRAM_SET 0x40 +#define HD44780_DDRAM_SET 0x80 + +//#define LCD_DATA PORTB.0UT; +#define LCD_D4 0x20 +#define LCD_D5 0x10 +#define LCD_D6 0x08 +#define LCD_D7 0x04 +extern xQueueHandle xLCDrec; +unsigned char odwroc(unsigned char dana); +void polbajt(unsigned char data); +void lcd_set_write_instruction(void); +void lcd_set_write_data(void); +void lcd_write_byte (char c); +void lcd_clear_and_home(void); +void lcd_home(void); +void lcd_goto(uint8_t line, uint8_t pos); +void lcd_line_one(void); +void lcd_line_two(void); +void lcd_write_data(char c); +void lcd_write_string(char *x, uint8_t len ); +void lcd_write_string_0(char *x); +void lcd_write_string_p(const char *s); +void lcd_init(void); +#endif diff --git a/Lib/include/mcp3008.h b/Lib/include/mcp3008.h new file mode 100644 index 0000000..79a65e6 --- /dev/null +++ b/Lib/include/mcp3008.h @@ -0,0 +1,40 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MCP3008 / MCP3004 A/C converter driver +* Author : Adam Kaliszan adam.kaliszan@gmail.com +* Copyright : GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexes and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ + +#ifndef MCP3008_H +#define MCP3008_H + +#include +#include "main.h" +#include "spiXmega.h" + + +// functions + +void enableSpiMCP3008(void) __attribute__ ((weak)); +void disableSpiMCP3008(void) __attribute__ ((weak)); + +/** + * Zwraca watość próbki dla pojedynczego wejÅ›cia + * @param inputNo - numer wejÅ›cia (0-7). + */ +uint16_t MCP3008_getSampleSingle(uint8_t inputNo); + +/** + * Zwraca watość próbki dla różnicowego wejÅ›cia + * @param inputNo - numer wejÅ›cia (0-7). + */ +uint16_t MCP3008_getSampleDiff(uint8_t inputNo); + +#endif +//@} diff --git a/Lib/include/mcp4150.h b/Lib/include/mcp4150.h new file mode 100644 index 0000000..6d60f41 --- /dev/null +++ b/Lib/include/mcp4150.h @@ -0,0 +1,34 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MCP3008 / MCP3004 A/C converter driver +* Author : Adam Kaliszan adam.kaliszan@gmail.com +* Copyright : GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexes and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ + +#ifndef MCP4140_H +#define MCP4150_H + +#include +#include "main.h" +#include "spiXmega.h" + + +// functions + +void enableSpiMCP4150(void) __attribute__ ((weak)); +void disableSpiMCP4150(void) __attribute__ ((weak)); + +/** + * Ustawia wartość rezystancji + * @param inputNo - WARTOŚĆ OD 0 DO 255. + */ +void MCP4150_setValue(uint8_t value); + +#endif +//@} \ No newline at end of file diff --git a/Lib/include/memory_x.h b/Lib/include/memory_x.h new file mode 100644 index 0000000..6925a36 --- /dev/null +++ b/Lib/include/memory_x.h @@ -0,0 +1,25 @@ +#ifndef MEMORY_X_H +#define MEMORY_X_H + +#include "hardwareConfig.h" +#include + +#ifdef HEAP_BEGIN +/** + * Allocate memory + * @param size - amount of memory to allocate + */ +void *xmalloc(size_t size); +#else +#define xmalloc( SIZE ) malloc(SIZE) +#endif + +#ifdef HEAP_BEGIN +/** + * Amount of free space on heap + * @return number of free bytes on heap + */ +size_t xmallocAvailable(void); +#endif + +#endif /*MEMORY_X_H*/ diff --git a/Lib/include/mpc23s17.h b/Lib/include/mpc23s17.h new file mode 100644 index 0000000..a4e5f6d --- /dev/null +++ b/Lib/include/mpc23s17.h @@ -0,0 +1,112 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MPC23s17 parrarel I/O 16 bit port driver +* Author : Adam Kaliszan +* Copyright: GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexex and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ + + +#ifndef MPC32S17_H +#define MPC32S17_H + +#include +#include "main.h" +#include "spiXmega.h" + +#define B0_IODIRA 0x00 +#define B0_IODIRB 0x01 + +#define B0_GPIOA 0x12 +#define B0_GPIOB 0x13 +#define B0_OLATA 0x14 +#define B0_OLATB 0x15 + + +volatile uint8_t portA; +volatile uint8_t portB; + +// functions + +void enableSpiMPC23S17(void) __attribute__ ((weak)); +void disableSpiMPC23S17(void) __attribute__ ((weak)); + +/** + * Ustawia kierunek na porcie A + * @param portAdir - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetDirA(uint8_t portAdir, uint8_t addr); + +/** + * Ustawia kierunek na porcie B + * @param portBdir - stan portu wyjÅ›ciowego + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetDirB(uint8_t portBdir, uint8_t addr); + +/** + * Ustawia wyjÅ›cie na porcie A + * @param portAout - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetPortA(uint8_t portAout, uint8_t addr); + +/** + * Ustawia wybrane bity na wyjÅ›ciu portu A + * @param portAout - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetBitsOnPortA(uint8_t portAout, uint8_t addr); + +/** + * Zeruje wybrane bity na wyjÅ›ciu portu A + * @param portAout - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17ClearBitsOnPortA(uint8_t portAout, uint8_t addr); + +/** + * Ustawia wyjÅ›cie na porcie B + * @param portBout - stan portu wyjÅ›ciowego + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetPortB(uint8_t portBout, uint8_t addr); + +/** + * Ustawia wybrane bity na wyjÅ›ciu portu B + * @param portAout - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17SetBitsOnPortB(uint8_t portAout, uint8_t addr); + +/** + * Zeruje wybrane bity na wyjÅ›ciu portu B + * @param portAout - kierunak dla każdej linni w porcie 0 - wejÅ›cie, 1 - wyjÅ›cie + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + */ +void MPC23s17ClearBitsOnPortB(uint8_t portAout, uint8_t addr); + + +/** + * Czyta wejÅ›cie portu A + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + * @return stan na wejÅ›ciu portu A + */ +uint8_t MPC23s17ReadPortA(uint8_t addr); + +/** + * Czyta wejÅ›cie portu B + * @param addr - adres (0-8) portu. Kilka scalaków MPC... może dziaÅ‚ać pod tÄ… samÄ… liniÄ… adresowÄ… CS w magistrali SPI + * @return stan na wejÅ›ciu portu B + */ +uint8_t MPC23s17ReadPortB(uint8_t addr); + + +#endif +//@} diff --git a/Lib/include/protocol1.h b/Lib/include/protocol1.h new file mode 100644 index 0000000..f060178 --- /dev/null +++ b/Lib/include/protocol1.h @@ -0,0 +1,99 @@ +#ifndef PROTOCOL1_H +#define PROTOCOL1_H 1 + +// Addressing devices on RS 485 bus +#define FIRST_ROLLER_DRIVER_ADDR 1 +#define LAST_ROLLER_DRIVER_ADDR 31 + +#define FIRST_LIGHT_DRIVER_ADDR 32 +#define LAST_LIGHT_DRIVER_ADDR 63 + +#define FIRST_SENSOR_ADDR 64 +#define LAST_SENSOR_ADDR 95 + +// *********************************** General message format ***************************************************** +#define HDR_LEN 4 +#define SYNC 0x5A + +// + header (4 bytes) + data + CRC + +// +------+----------+---------+--------+-------+ +-------+-------+-------+ +// | SYNC | op. code | address | length | data1 | ... | dataN | CrcHi | CrcLo | +// | 0x5A | | | | | | | | | +// +------+----------+---------+--------+-------+ +-------+-------+-------+ +// +// CRC is calculated according to all bytes without CRC Hi and Lo on the frame end (including sync and excluding CrcHi and CrcLo) + +// *********************************** Ping message ************************************************************** +#define rPING 0x80 +// ping: master->slave +// +------+------+---------+--------+-------+ +-------+-------+-------+ +// | SYNC | type | address | length | data1 | ... | dataX | CrcHi | CrcLo | +// | 0x5A | 0x80 | | X | | | | | | +// +------+------+---------+--------+-------+ +-------+-------+-------+ + + +// ping response: slave->master +// +------+------+---------+--------+-------+ +-------+-------+-------+ +// | SYNC | type | address | length | data1 | ... | dataX | CrcHi | CrcLo | +// | 0x5A | 0x80 | 0 | X | | | | | | +// +------+------+---------+--------+-------+ +-------+-------+-------+ + +// *********************************** Hello message ************************************************************** +#define rHELLO 0x82 + +// hello: master->slave +// +------+------+---------+--------+-------+-------+ +// | SYNC | type | address | length | CrcHi | CrcLo | +// | 0x5A | 0x82 | | 0 | | | +// +------+------+---------+--------+-------+-------+ + + +// hello response: slave->master +// +------+------+---------+--------+--------+--------+-------+-------+-------+-------+-------+-------+-------+-------+ +// | SYNC | type | address | length | data1 | data2 | data3 | data4 | data5 | data6 | data7 | data8 | CrcHi | CrcLo | +// | 0x5A | 0x82 | 0 | 7 | state1 | state2 |setting|version|version|version|version|Version| | | +// | | | | | | | |'v'/'b'| | '.' | | | | | +// +------+------+---------+--------+--------+--------+-------+-------+-------+-------+-------+-------+-------+-------+ + +//offsets of hello response data field +#define HELLO_RESP_STATE1 0 +#define HELLO_RESP_STATE2 1 +#define HELLO_RESP_VER 2 +#define HELLO_RESP_VER_LEN 5 +#define HELLO_RESP_LEN 3+HELLO_RESP_VER_LEN + + + +// *********************************** Flash firmware message ***************************************************** +#define rFLASH 0x81 + + +// *********************************** Roller blind 1 down ********************************************************* +#define rOpuscRolete1 0x10 + +// *********************************** Roller blind 1 down ********************************************************* +#define rOpuscRolete2 0x11 + +// *********************************** Roller blind 1 up *********************************************************** +#define rPodniesRolete1 0x20 + +// *********************************** Roller blind 2 up *********************************************************** +#define rPodniesRolete2 0x21 + +// *********************************** Roller 1 stop *********************************************************** +#define rZatrzymajRolete1 0x30 + +// *********************************** Roller 2 stop *********************************************************** +#define rZatrzymajRolete2 0x31 + +// *********************************** Configure module ************************************************************ +#define rUstaw 0x40 + +// *********************************** Write module Settings******************************************************** +#define rZapiszUstawienia 0x41 + + +// *********************************** Unknown message ************************************************************ +#define rUNKNOWN 0xFF + +#endif /* PROTOCOL1_H */ diff --git a/Lib/include/queueStream.h b/Lib/include/queueStream.h new file mode 100644 index 0000000..c3d9f7a --- /dev/null +++ b/Lib/include/queueStream.h @@ -0,0 +1,17 @@ +#ifndef QUEUE_STREAM_H +#define QUEUE_STREAM_H + +#include +#include +#include "FreeRTOS.h" +#include "queue.h" + +typedef struct +{ + xQueueHandle Rx; + xQueueHandle Tx; +} streamBuffers_t; + +void initQueueStream(FILE *stream, streamBuffers_t *buffer, xQueueHandle Rx, xQueueHandle Tx); + +#endif diff --git a/Lib/include/ramdysk.h b/Lib/include/ramdysk.h new file mode 100644 index 0000000..6cf93f6 --- /dev/null +++ b/Lib/include/ramdysk.h @@ -0,0 +1,179 @@ +#ifndef RAMDYSK_H +#define RAMDYSK_H + +#include "main.h" +#include + +#define L_KLASTROW 128 +#define KLASTER_OFFSET 256-L_KLASTROW + +#define dataPtr(KLASTER,OFFSET) (uint8_t *)((((KLASTER)+KLASTER_OFFSET)<<8) + (OFFSET)) //Makro zamienia lokalizacjÄ™ w pliku na adres pamiÄ™ci + +uint8_t klastry[128]; /// Rozmiar klastra 256 bajtów -- Å‚Ä…cznie system plików obsÅ‚uguje 32 kB + +/** + * Struktura zapisana w tablicy Fat dla każdego pliku. + * Jest zapisana w klastrach. Im wiÄ™cej struktur takich, tym mniej miejsca na zawartość plików + * Rozmiar struktury ma 16 bajtów (16 struktor w 1 klastrze) + */ +struct ramPlik +{ + uint8_t pierwszyKlaster; /// Numer pierwszego klastra + uint8_t rozmiarLo; /// Liczba zapisanych danych (mniej znaczÄ…cy bajt) + uint8_t rozmiarHi; /// Liczba zapisanych danych (bardziej znaczÄ…cy bajt) + uint8_t lAktOtw; /// Liczba procesów, które otwaÅ‚y ten plik do odczytu + + char nazwa[8]; /// Nazwa pliku + uint32_t dataMod; /// Data modyfikacji pliku +}; + +/** + * Deskryptor dla otwartego pliku. + * Kilka deskryptorów może być zwiÄ…zanych z tym samym plikiem + */ +struct ramPlikFd +{ + uint8_t *Wsk; /// Wskaźnik z adresem pamiÄ™ci, do którego bÄ™dzie zapis lub odczyt + uint8_t IndLo; /// Mniej znaczÄ…cy bajt indeksu pliku (zapisu lub odczytu) + uint8_t IndHi; /// Bardziej znaczÄ…cy bajt indeksu pliku +// uint8_t ostatniKlaster; /// Numer ostatniego klastera + + struct ramPlik *wpis; +}; + +/** + * Inicjalizacja systemu plików + */ +void ramDyskInit(void); + +/** + * Tworzy nowÄ… strukturÄ™ pliku odwzorowanÄ… w pamiÄ™ci i zwraca jego deskryptor. + * JeÅ›li plik istnieje, to zwracany jest jego deskryptor. + * @param [in] *nazwa - wskaźnik do tablicy z nazwÄ… pliku (do 8 znaków). + * @return 0 - plik zostaÅ‚ utworzony, 1 - plik nie zostaÅ‚ utworzony (brak miejsca, 2 - istnieje już plik o takiej nazwie. + */ +uint8_t ramDyskUtworzPlik(const char *nazwa); + +/** + * Otwiera istniejÄ…cÄ… strukturÄ™ pliku odwzorowanÄ… w pamiÄ™ci i zwraca jego deskryptor. + * @param [in] *nazwa - wskaźnik do tablicy z nazwÄ… pliku (do 8 znaków). + * @param [out] *fd - wskaźnik do deskryptora pliku, zostanie on odpowiednio zmodyfikowany. + * @return 0 - plik zostaÅ‚ otwarty, 1 - brak pliku, 2 - bÅ‚Ä…d. + */ +uint8_t ramDyskOtworzPlik(const char *nazwa, struct ramPlikFd *fd); + +/*! + * Usuwa strukturÄ™ pliku odwzorowanÄ… w pamiÄ™ci. + * WczeÅ›niej muszÄ… być zamkniÄ™te wszystkie deskryptory dla tego pliku. + * @param [in] *nazwa - wskaźnik do tablicy z nazwÄ… pliku (do 8 znaków). + * @return 0 - plik usuniÄ™ty, 1 - plik nie może być usuniÄ™ty ponieważ jest otwarty przez inne deskryptory. + */ +uint8_t ramDyskUsunPlik(const char *nazwa); + +/** + * Zamyka plik o podanym deskryptorze, wskaźnik deskryptora ustawiany jest na NULL + * @param [in,out] *fd - wskaźnik do deskryptora z plikiem do zamkniÄ™cia. + */ +void ramDyskZamknijPlik(struct ramPlikFd *fd); + + +/** + * CzyÅ›ci zawartość pliku i zwalnia klastry + * @param [in,out] *fd - deskryptor pliku do wyczyszczenia + * @return 0 - operacja zakoÅ„czona sukcesem, 1 - bÅ‚Ä…d (prawdopodobnei w implementacji) + */ +uint8_t ramDyskCzyscPlik(struct ramPlikFd *fd); + +/** + * Zapisuje do pliku. + * @param [in,out] *fd - wskaźnik do deskryptora pliku, do którego zostanie dopisany znak + * @param [in] znak - znak jaki zostanie dopisany + * @return 0 - operacja zakoÅ„czona sukcesem, 1 - bÅ‚Ä…d (brak pamiÄ™ci) + */ +uint8_t ramDyskZapiszBajtDoPliku(struct ramPlikFd *fd, uint8_t znak); + +/** + * Czyta z pliku odwzorowanego w pamiÄ™ci. + * @param [in,out] *fd - deskryptor pliku, z którego zostanie odczytany bajt + * @param [out] *bajt - wskaźnik na bajt do którego zostnie zapisany rezultat odczytu znaku z pliku. + * @return 0 - OK, 1 - czytamy poza plikiem + */ +uint8_t ramDyskCzytajBajtZPliku(struct ramPlikFd *fd, uint8_t *bajt); + +/** + * Zapisuje blok danych do pliku. + * @param [in,out] *fd - wskaźnik do deskryptora pliku, do którego zostanie dopisany blok danych + * @param [in] *znaki - wskaÅ›nik do tablicy, jaka zostanie zapisana do pliku + * @param [in,out] *dlugosc - wskaźnik do dÅ‚ugoÅ›ci tablicy danych, po zapisie jego wartość okreÅ›la liczbÄ™ zapisanych danych. + * @return 0 - operacja zakoÅ„czona sukcesem, 1 - bÅ‚Ä…d (brak pamiÄ™ci) + */ +uint8_t ramDyskZapiszBlokDoPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc); + +/** + * Czyta z pliku odwzorowanego w pamiÄ™ci i zapisuje do tablicy + * @param [in,out] *fd - deskryptor pliku, z którego zostanie odczytany bajt + * @param [out] *znaki - wskaźnik do tablicy, w której zostanÄ… zapisane odczytane z pliku znaki + * @param [in,out] *dlugosc - wskaźnik do liczby danych, jakÄ… chcemy odczytać. Po wykonanej operacji pod wskaźnikiem zapisana jest liczba odczytanych danych. + * @return 0 - OK, 1 - Plik jest pusty, 2 - Źle ustawiony indeks odczytu/zapisu (poza obszarem pliku), 3 - Nie udaÅ‚o siÄ™ znaleźć odpowiedniego klastra + */ +uint8_t ramDyskCzytajBlokZPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc); + +/** + * Ustawia indeks odczytu/zapisu dla deskryptora + * @param [in,out] *fd - deskryptor pliku, w którym zostanie przestawiony wskaźnik odczytu/zapisu + * @param [in] indeks - pozycja wskaźnika odczytu/zapisu + * @return 0 - OK, 1 - konieczne byÅ‚o zwiÄ™kszenie rozmiaru pliku, lecz zabrakÅ‚o pamiÄ™ci + */ +uint8_t ramDyskUstawWskaznik(struct ramPlikFd *fd, uint16_t indeks); + +/** + * Ustawia indeks odczytu/zapisu na koniec pliku + * @param [in,out] *fd - deskryptor pliku, w którym zostanie przestawiony wskaźnik odczytu/zapisu + * @return 0 - OK, 1 - zÅ‚y deskryptor pliku + */ +uint8_t ramDyskUstawWskaznikNaKoniec(struct ramPlikFd *fd); + +/** + * Zapewnia, że w pliku jest miejce do zapisu 128 bajtowego bloku danych o numerze nrBloku + * odebranego przez xModem. Indeks oraz wskaźnik pliku ustawiony jest na nastÄ™pny bajt za przydzielonym blokiem. + * Również uaktualniony jest rozmiar pliku. + * Funkcja zwraca wskaźnik na poczÄ…tek przydzielonego bloku. + * Funkcja obsÅ‚ugujÄ…ca transmisjÄ™ xModemowÄ… może bezpoÅ›rednio pisać do pamiÄ™ci, bez wykoszystania funkcji obsÅ‚ugujÄ…cych pliki. + * RozwiÄ…zanie to jest maÅ‚o eleganckie lecz wydajne. + * @param [in,out] *fd - deskryptor pliku, w którym zostanie przestawiony wskaźnik odczytu/zapisu + * @param [in] nrBloku - jaki ma być przesÅ‚any. Uwaga pierwszy blok ma nr 1, a nie 0). + * @return wskaźnik do pamiÄ™ci, pokazujÄ…cy na pocżątek bloku. + */ +uint8_t* ramDyskDodajBlokXmodem(struct ramPlikFd *fd, uint16_t nrBloku); + + +/** + * WyÅ›wietla pliki z głównego katalogu + * @param [in] *putchar_func - wskaźnik do funkcji wypisujÄ…cej znaki. + */ +void ramDyskDir(FILE *ostream); + +/** + * Zwraca liczbÄ™ wolnych klastrów (od 0 do 255). Klaster 0 jest zawsze traktowany jako zajÄ™ty. + * @return liczba wolnych klastrów. + */ +uint8_t ramDyskLiczbaWolnychKlastrow(void); + +/** + * Otwiera strumieÅ„ dla biblioteki StdIO + * @param nazwa - nazwa pliku do otwarcia + * @param fd - wskaźnik do deskryptora pliku. Należy wczeÅ›niej umieÅ›cić obiekt w pamiÄ™ci lub na stosie + * @param stream - wskaźnik do struktury FILE biblioteki StdIo + * @param flags - flagi + */ +uint8_t ramDyskOtworzPlikStdIo(const char *nazwa, struct ramPlikFd *fd, FILE *stream, uint8_t flags); + +/** + * Zamyka strumieÅ„ wejÅ›cia/wyjÅ›cia obsÅ‚ugujÄ…cy dziaÅ‚ajÄ…cy na Ram Pliku. Ważne by nie wywoÅ‚ywać tej funkcji z innym strumieniem. + * @param stream - wskaźnik do struktury FILE biblioteki StdIo + * @return liczba pozostaÅ‚ych deskryptorów zwiÄ…zanych z zamykanym plikiem + */ +uint8_t ramDyskZamknijPlikStdIo(FILE *stream); + + +#endif /* RAMDYSK_H */ diff --git a/Lib/include/sd_diskio.h b/Lib/include/sd_diskio.h new file mode 100644 index 0000000..5d8ac9c --- /dev/null +++ b/Lib/include/sd_diskio.h @@ -0,0 +1,114 @@ +#ifndef _DISKIO_H +#define _DISKIO_H + +#include "integer.h" +#include "spiXmega.h" +#include "hardware.h" + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +//@{ + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Disk Status Bits (DSTATUS) */ +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /** 0: Function succeeded */ + RES_ERROR, /** 1: Disk error */ + RES_NOTRDY, /** 2: Not ready */ + RES_PARERR /** 3: Invalid parameter */ +} DRESULT; + + +/** + * Initialize Disk Drive + * @param drv - drive number + */ +DSTATUS disk_initialize (uint8_t drv); + +/** + * Read Partial Sector + * @param dest - Pointer to the destination object + * @param sector - Sector number (LBA) + * @param sofs - Offset in the sector + * @param count - Number of byter to read (bytes or word ?) + * @return DRESULT + */ +DRESULT disk_readp (void* dest, DWORD sector, WORD sofs, WORD count); + +/** + * Write Partial Sector + * @param buff - Pointer to the data to be written, NULL:Initiate/Finalize write operation + * @param sc - Sector number (LBA) or Number of bytes to send + */ +DRESULT disk_writep (const BYTE* buff, DWORD sc); + +#define STA_NOINIT 0x01 /** Drive not initialized */ +#define STA_NODISK 0x02 /** No medium in the drive */ + + +//DRESULT disk_ioctl (BYTE, BYTE, void*); +//void disk_timerproc (void); + + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + +/* Definitions for MMC/SDC command */ + +#define CMD0 (0) /** GO_IDLE_STATE */ +#define CMD1 (1) /** SEND_OP_COND (MMC) */ +#define ACMD41 (0x80+41) /** SEND_OP_COND (SDC) */ +#define CMD8 (8) /** SEND_IF_COND */ +#define CMD9 (9) /** SEND_CSD */ +#define CMD10 (10) /** SEND_CID */ +#define CMD12 (12) /** STOP_TRANSMISSION */ +#define ACMD13 (0x80+13) /** SD_STATUS (SDC) */ +#define CMD16 (16) /** SET_BLOCKLEN */ +#define CMD17 (17) /** READ_SINGLE_BLOCK */ +#define CMD18 (18) /** READ_MULTIPLE_BLOCK */ +#define CMD23 (23) /** SET_BLOCK_COUNT (MMC) */ +#define ACMD23 (0x80+23) /** SET_WR_BLK_ERASE_COUNT (SDC) */ +#define CMD24 (24) /** WRITE_BLOCK */ +#define CMD25 (25) /** WRITE_MULTIPLE_BLOCK */ +#define CMD55 (55) /** APP_CMD */ +#define CMD58 (58) /** READ_OCR */ + + +/* Card type flags (CardType) */ +#define CT_MMC 0x01 /** MMC ver 3 */ +#define CT_SD1 0x02 /** SD ver 1 */ +#define CT_SD2 0x04 /** SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /** SD */ +#define CT_BLOCK 0x08 /** Block addressing */ + +//@} +#endif + diff --git a/Lib/include/spi.h b/Lib/include/spi.h new file mode 100644 index 0000000..0ae43a7 --- /dev/null +++ b/Lib/include/spi.h @@ -0,0 +1,60 @@ + +//@{ +#ifndef SPI_H +#define SPI_H + +#include "FreeRTOS.h" +#include "semphr.h" +#include "queue.h" +#include "task.h" +//#include "hardware.h" +//#include "hardwareConfig.h" + + +xSemaphoreHandle xSemaphoreSpiSS; /// Flaga blokujÄ…ca jednoczesny dostÄ™p do magistrali wielu urzÄ…dzeniom + +/** + * Inicjalizacja magistrali SPI, utworzenie semaforów + */ +void spiInit( void (*disableAllSpiDevicesFun)(void)); + +void spiSetCPHA(void); +void spiClearCPHA(void); +void spiSetCPOL(void); +void spiClearCPOL(void); + +/** + * WyÅ›lij do magistrali SPI. Po rozpoczÄ™ciu transmisji przeÅ‚Ä…czany jest wÄ…tek. + * Warto stosować w przypadku wÄ…tków o niskich priorytetach lub wolnej transmisji SPI + * @param uint8_t bajt do wysÅ‚ania + * @return odebrany bajt z magistrali SPI + */ +uint8_t spiSend(uint8_t data) __attribute__ ((weak)); + + + +/** + * WyÅ›lij do magistrali SPI. Sotosowana jest blokada wirujÄ…ca. + * Warto stosować gdy SPI dziaÅ‚a z dużą szybkoÅ›ciÄ… + * (czas wysÅ‚ania jest mniejszy od 2X czas przeÅ‚Ä…czenia wÄ…tku) + * @param uint8_t bajt do wysÅ‚ania + * @return odebrany bajt z magistrali SPI + */ +uint8_t spiSendSpinBlock(uint8_t data) __attribute__ ((weak)); + +/** + * Zajmuje magistralÄ™ SPI. + * Po zajÄ™ciu magistrali należy wybrać odpowiedniÄ… liniÄ™ adresowÄ… do urzÄ…dzenia z którym siÄ™ komunikujemy + * W momencie, gdy magistrala jest zajÄ™ta, inne zadania nie mogÄ… z niej korzystać. + * Uwaga na zakleszczenia. + */ +void spiTake(void); + +/** + * Zwalnia magistralÄ™ SPI. + * Przed zwolnieniem maigistrali należy odÅ‚Ä…czyć od niej wszystkie urzÄ…dzenia + */ +void spiGive(void); + +#endif +//@} \ No newline at end of file diff --git a/Lib/include/spiXmega.h b/Lib/include/spiXmega.h new file mode 100644 index 0000000..869ced6 --- /dev/null +++ b/Lib/include/spiXmega.h @@ -0,0 +1,66 @@ + +//@{ +#ifndef SPI_H +#define SPI_H + +#include "FreeRTOS.h" +#include "semphr.h" +#include "queue.h" +#include "task.h" +//#include "hardware.h" +//#include "hardwareConfig.h" + + +xSemaphoreHandle xSemaphoreSpiSS; /// Flaga blokujÄ…ca jednoczesny dostÄ™p do magistrali wielu urzÄ…dzeniom + +/** + * Inicjalizacja magistrali SPI, utworzenie semaforów + */ +void spiInit( void (*disableAllSpiDevicesFun)(void)); +void spiInitENC( void (*disableAllSpiDevicesFun)(void)); + +void spiSetCPHA(void); +void spiSetCPHAENC(void); +void spiClearCPHA(void); +void spiClearCPHAENC(void); +void spiSetCPOL(void); +void spiSetCPOLENC(void); +void spiClearCPOL(void); +void spiClearCPOLENC(void); + + +/** + * WyÅ›lij do magistrali SPI. Po rozpoczÄ™ciu transmisji przeÅ‚Ä…czany jest wÄ…tek. + * Warto stosować w przypadku wÄ…tków o niskich priorytetach lub wolnej transmisji SPI + * @param uint8_t bajt do wysÅ‚ania + * @return odebrany bajt z magistrali SPI + */ +uint8_t spiSend(uint8_t data) __attribute__ ((weak)); + + + +/** + * WyÅ›lij do magistrali SPI. Sotosowana jest blokada wirujÄ…ca. + * Warto stosować gdy SPI dziaÅ‚a z dużą szybkoÅ›ciÄ… + * (czas wysÅ‚ania jest mniejszy od 2X czas przeÅ‚Ä…czenia wÄ…tku) + * @param uint8_t bajt do wysÅ‚ania + * @return odebrany bajt z magistrali SPI + */ +uint8_t spiSendSpinBlock(uint8_t data) __attribute__ ((weak)); + +/** + * Zajmuje magistralÄ™ SPI. + * Po zajÄ™ciu magistrali należy wybrać odpowiedniÄ… liniÄ™ adresowÄ… do urzÄ…dzenia z którym siÄ™ komunikujemy + * W momencie, gdy magistrala jest zajÄ™ta, inne zadania nie mogÄ… z niej korzystać. + * Uwaga na zakleszczenia. + */ +void spiTake(void); + +/** + * Zwalnia magistralÄ™ SPI. + * Przed zwolnieniem maigistrali należy odÅ‚Ä…czyć od niej wszystkie urzÄ…dzenia + */ +void spiGive(void); + +#endif +//@} diff --git a/Lib/include/staryStack.h b/Lib/include/staryStack.h new file mode 100644 index 0000000..cf16905 --- /dev/null +++ b/Lib/include/staryStack.h @@ -0,0 +1,140 @@ +/********************************************* + * vim:sw=2:ts=2:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Adam Kaliszan + * Copyright: GPL V2 + * + * IP/ARP/UDP/TCP functions + * + *********************************************/ +#ifndef IP_ARP_UDP_TCP_H +#define IP_ARP_UDP_TCP_H +#include + +#include "enc_task.h" +//@{ + +/** + * Calculates CRC 16 bit checksum + * The Ip checksum is calculated over the ip header only starting + * with the header length field and a total length of 20 bytes unitl ip.dst + * You must set the IP checksum field to zero before you start the calculation. + * len for ip is 20. + * For UDP/TCP we do not make up the required pseudo header. Instead we + * use the ip.src and ip.dst fields of the real packet: + * The udp checksum calculation starts with the ip.src field + * Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len + * In other words the len here is 8 + length over which you actually + * want to calculate the checksum. + * You must set the checksum field to zero before you start + * the calculation. + * len for udp is: 8 + 8 + data length + * len for tcp is: 4+4 + 20 + option len + data length + * + * For more information on how this algorithm works see: + * http://www.netfor2.com/checksum.html + * http://www.msc.uky.edu/ken/cs471/notes/chap3.htm + * The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.html + * @param *buf1 - pointer to the buffer + * @param length - buffer length + * @param type + * @return CRC + */ +uint16_t checksum (uint8_t *buf1, uint16_t len, uint8_t type); +void make_eth (uint8_t *buf1); +void fill_ip_hdr_checksum (uint8_t *buf1); + +/** + * make a return ip header from a received ip packet + */ +void make_ip (uint8_t *buf1); + +/** + * make a return tcp header from a received tcp packet + * rel_ack_num is how much we must step the seq number received from the + * other side. We do not send more than 255 bytes of text (=data) in the tcp packet. + * If mss=1 then mss is included in the options list + * + * After calling this function you can fill in the first data byte at TCP_OPTIONS_P+4 + * If cp_seq=0 then an initial sequence number is used (should be use in synack) + * otherwise it is copied from the packet we received + */ +void make_tcphead (uint8_t *buf1,uint16_t rel_ack_num,uint8_t mss,uint8_t cp_seq); + +// you must call this function once before you use any of the other functions: +void init_ip_arp_udp_tcp (uint8_t *mymac,uint8_t *myip,uint8_t wwwp); + +uint8_t eth_type_is_arp_and_my_ip (uint8_t *buf1,uint16_t len); +uint8_t eth_type_is_ip_and_my_ip (uint8_t *buf1,uint16_t len); +void make_arp_answer_from_request(uint8_t *buf1); +void make_echo_reply_from_request(uint8_t *buf1,uint16_t len); +void make_udp_reply_from_request (uint8_t *buf1,char *data,uint8_t datalen,uint16_t port); + +void make_tcp_synack_from_syn (uint8_t *buf1); + +/** + *do some basic length calculations and store the result in static varibales + */ +void init_len_info (uint8_t *buf1); + +/** + *get a pointer to the start of tcp data in buf + * Returns 0 if there is no data + * You must call init_len_info once before calling this function + */ +uint16_t get_tcp_data_pointer (void); + + +/** + * Return memory addres to write to the buffer + * @param *buffer pointer to the beginning of TCP buffer + * @param *pos - write index + */ +char *getBufPosToWrite(uint8_t *buf, uint16_t pos); + + +/** + * fill in tcp data at position pos. pos=0 means start of tcp data. + * @param buf - output buffer + * @param pos - position to write in the buffer + * @param progmem_s - string stored in flash to write + * @return the position at which the string after this string could be filled. + */ +uint16_t fill_tcp_data_p (uint8_t *buf1,uint16_t pos, const prog_char *progmem_s); + +/** + * fill in tcp data at position pos. pos=0 means start of tcp data. + * @param buf - output buffer + * @param pos - position to write in the buffer + * @param s - string stored in ram to write + * @return the position at which the string after this string could be filled. + */ +uint16_t fill_tcp_data (uint8_t *buf1,uint16_t pos, const char *s); + +/** + * fill in tcp data at position pos. pos=0 means start of tcp data. + * @param buf - output buffer + * @param pos - position to write in the buffer + * @param data - one byte to write + * @return the position at which the string after this string could be filled. + */ +uint16_t add_tcp_byte (uint8_t *buf1,uint16_t pos, const char data); + +/** + * Make just an ack packet with no tcp data inside + * This will modify the eth/ip/tcp header + */ +void make_tcp_ack_from_any (uint8_t *buf1); + +/** + * you must have called init_len_info at some time before calling this function + * dlen is the amount of tcp data (http data) we send in this packet + * You can use this function only immediately after make_tcp_ack_from_any + * This is because this function will NOT modify the eth/ip/tcp header except for + * length and checksum + */ +void make_tcp_ack_with_data (uint8_t *buf1, uint16_t dlen); + +//@} +#endif /* IP_ARP_UDP_TCP_H */ diff --git a/Lib/include/tlvProt.h b/Lib/include/tlvProt.h new file mode 100644 index 0000000..3a55b87 --- /dev/null +++ b/Lib/include/tlvProt.h @@ -0,0 +1,71 @@ +#ifndef TLV_PROT +#define TLV_PROT + +#include +#include +#include +#include +#include + + +#include "FreeRTOS.h" +#include "hardwareConfig.h" + +#define TLV_SYNC 0x55 + +#ifndef TLV_BUF_LEN +#error "Define TLV_BUF_LEN in hardwareConfig.h file\nRecomended value 16-64" +#endif //TLV_BUF_LEN +#if TLV_BUF_LEN < 16 +#error "TLV bufer is too small" +#endif // TLV_BUF_LEN +#if TLV_BUF_LEN > 64 +#warning "TLV bufer is more than 64 bytes" +#endif // TLV_BUF_LEN + + +struct tlvInterpreter; + +typedef struct tlvInterpreter tlvInterpreter_t; + +typedef struct tlvMsg +{ + uint8_t sync; // = TLV_SYNC + uint8_t address; // Device address + uint8_t type; + uint8_t dtaLen; + uint8_t crcLo; + uint8_t crcHi; + uint8_t data[0]; +} tlvMsg_t; + + +typedef struct tlvCommand +{ + uint8_t type; + void (*fun)(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +} tlvCommand_t; + +struct tlvInterpreter +{ + uint8_t buffer[TLV_BUF_LEN]; + uint8_t bufIdx; + const tlvCommand_t *commands; + uint8_t noOfCmds; + FILE *ioStr; + FILE *errStr; +}; + +void tlvIinitializeInterpreter(tlvInterpreter_t *tlvInt, FILE *ioStr, FILE *errStr, const tlvCommand_t *commands); + +void tlvCalculateCrc(tlvMsg_t *message); +void tlvCalculateCrcSepDta(tlvMsg_t *message, const uint8_t dta[]); + +uint8_t tlvCheckCrc(tlvMsg_t *message); + +void tlvProcessDta(tlvInterpreter_t *tlvInt, uint8_t dta); +void sendTlvMsg(tlvMsg_t *message, FILE *ostream); +void sendTlvMsgDta(tlvMsg_t *message, const uint8_t const *msgDta, FILE *ostream); + + +#endif diff --git a/Lib/include/vt100.h b/Lib/include/vt100.h new file mode 100755 index 0000000..decfb9b --- /dev/null +++ b/Lib/include/vt100.h @@ -0,0 +1,88 @@ +/*! \file vt100.h \brief VT100 terminal function library. */ +//***************************************************************************** +// +// File Name : 'vt100.h' +// Title : VT100 terminal function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +/// @ingroup general +/// @defgroup vt100 VT100 Terminal Function Library (vt100.c) +/// @code #include "vt100.h" \endcode +/// @par Overview +/// This library provides functions for sending VT100 escape codes to +/// control a connected VT100 or ANSI terminal.� Commonly useful functions +/// include setting the cursor position, clearing the screen, setting the text +/// attributes (bold, inverse, blink, etc), and setting the text color.� This +/// library will slowly be expanded to include support for codes as needed and +/// may eventually receive VT100 escape codes too. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef VT100_H +#define VT100_H + +#include "main.h" + +// constants/macros/typdefs +// text attributes + + +// defines +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_CR 0x0D +#define ASCII_LF 0x0A +#define ASCII_ESC 0x1B +#define ASCII_DEL 0x7F + +#define VT100_ARROWUP 'A' +#define VT100_ARROWDOWN 'B' +#define VT100_ARROWRIGHT 'C' +#define VT100_ARROWLEFT 'D' +#define VT100_ATTR_OFF 0 +#define VT100_BOLD 1 +#define VT100_USCORE 4 +#define VT100_BLINK 5 +#define VT100_REVERSE 7 +#define VT100_BOLD_OFF 21 +#define VT100_USCORE_OFF 24 +#define VT100_BLINK_OFF 25 +#define VT100_REVERSE_OFF 27 + + +// functions + +//! vt100Init() initializes terminal and vt100 library +/// Run this init routine once before using any other vt100 function. +void vt100Init(cmdState_t *state); + +//! vt100ClearScreen() clears the terminal screen +void vt100ClearScreen(cmdState_t *state); + +//! vt100SetAttr() sets the text attributes like BOLD or REVERSE +/// Text written to the terminal after this function is called will have +/// the desired attribuutes. +void vt100SetAttr(uint8_t attr, cmdState_t *state); + +//! vt100SetCursorMode() sets the cursor to visible or invisible +void vt100SetCursorMode(uint8_t visible, cmdState_t *state); + +//! vt100SetCursorPos() sets the cursor position +/// All text which is written to the terminal after a SetCursorPos command +/// will begin at the new location of the cursor. +void vt100SetCursorPos(uint8_t line, uint8_t col, cmdState_t *state); + +#endif +// \ No newline at end of file diff --git a/Lib/include/xModemCommands.h b/Lib/include/xModemCommands.h new file mode 100644 index 0000000..8daff39 --- /dev/null +++ b/Lib/include/xModemCommands.h @@ -0,0 +1,15 @@ +#ifndef X_MODEM_COMMANDS_H +#define X_MODEM_COMMANDS_H 1 + +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#endif /* X_MODEM_COMMANDS_H */ + diff --git a/Lib/include/xmodem.h b/Lib/include/xmodem.h new file mode 100644 index 0000000..296efa6 --- /dev/null +++ b/Lib/include/xmodem.h @@ -0,0 +1,67 @@ +/** + * XModem Transmit/Receive z obsÅ‚ugÄ… CRC. + * DziaÅ‚a tylko z ram plikami. Wskaźnik z pliku jest jego podrÄ™cznym buforem. + * Zapis i odczyt z ram pliku odbywa siÄ™ bezpiÅ›rednio z pominiÄ™ciem api do zapisu i odczytu. + * Użycie api ogranicza siÄ™ do ustawiania wskaźnika na nowo przydzielone obszary pamiÄ™ci. + */ +#ifndef XMODEM_H +#define XMODEM_H + +#include "main.h" +#include "ramdysk.h" + +//@{ + +/** + * Struktura do obsÅ‚ugi protokoÅ‚u Xmodem + * + */ +struct xmodemUchwyt +{ + FILE strumien; /// StrumieÅ„ do obsÅ‚ugi transmisji danych. + struct ramPlikFd *fd; /// Deskryptor ram pliku. Tutaj dane sÄ… zapisywane przy odbiorze lub z tÄ…d pobiera siÄ™ dane do wysÅ‚ania. + /// DziaÅ‚a on też jako bufor tymczasowy. +// uint8_t (*zapis)(uint8_t, void*, uint16_t); /// Wskaźnik na funkcjÄ™ obsÅ‚ugujÄ…cÄ… zapis do strumienia. +// uint8_t (*odczyt)(uint8_t*, void*, uint16_t); /// Wskaźnik na funkcjÄ™ czytajÄ…cÄ… ze strumienia. + +// void *strumienWy; /// Wskaźnik do strumienia przez który wysyÅ‚ane sÄ… dane. Typ strumienia zależy od funkcji wysyÅ‚ajÄ…cej dane. +// void *strumienWe; /// Wskaźnik do strumienia przez który odbierane sÄ… dane. Typ strumienia zależy od funkcji odbierajÄ…cej dane. + + uint8_t crcLo; /// Mniej znaczÄ…cy bajt odebranej sumy kontrolnej. + uint8_t crcHi; /// Bardziej znaczÄ…cy bajt odebranej sumy kontrolnej. + uint8_t nrBlokuZdalny; /// Odczytany numer 128 bajtowego bloku. Pierwszy zaczyna siÄ™ od 1. + uint8_t nrBlokuZdalnyNeg; /// Odczytany, zanegowany numer 128 bajtowego bloku. Pierwszy zaczyna siÄ™ od 1. + uint8_t nrBloku; /// Lokalny numer bloku + uint16_t crcLokalne; /// CRC obliczane przez funkcjÄ™ lokalnÄ…. +}; + +/** + * Tworzy uchwyt do obsÅ‚ugi Xmodemu. + * @param [out] *uchwyt - wskaźnik do struktury uchwytu protokoÅ‚u xmodem, która zostanie odpowiednio skonfigorowana + * @param [in] *fd - wskaźnik do deskryptora ram pliku + * @return 0 - wszystko OK + */ +//uint8_t xmodemUstawUchwyt(struct xmodemUchwyt *uchwyt, struct ramPlikFd *fd); + +/** + * Rozpoczyna odbiór danych, a nastÄ™pnie obsÅ‚uguje pobieranie danych. + * Wymagane jest wczeÅ›niej utworzenie struktury xmodemUchwyt, w której sÄ… funkcje + * do odbierania i wysyÅ‚ania znaków oraz deskryptor do ram pliku, w którym zapisane sÄ… dane. + * Ram plik dziaÅ‚Ä… też jako bufor tymczasowy + * @param [in,out] *uchwyt - wskaźnik do struktury uchwytu protokoÅ‚u xmodem. + * @return 0 - wszystko OK + */ +//uint8_t xmodemOdbierz(struct xmodemUchwyt *uchwyt); + +/** + * Rozpoczyna i obsÅ‚uguje wysyÅ‚anie danych. + * Wymagane jest wczeÅ›niej utworzenie struktury xmodemUchwyt, w której sÄ… funkcje + * do odbierania i wysyÅ‚ania znaków oraz deskryptor do ram pliku, w którym zapisane sÄ… dane. + * Ram plik dziaÅ‚Ä… też jako bufor tymczasowy + * @param [in,out] *uchwyt - wskaźnik do struktury uchwytu protokoÅ‚u xmodem. + * @return 0 - wszystko OK + */ +//uint8_t xmodemWyslij(struct xmodemUchwyt *uchwyt); +//@} +#endif + diff --git a/Lib/lcd.c b/Lib/lcd.c new file mode 100644 index 0000000..add3c58 --- /dev/null +++ b/Lib/lcd.c @@ -0,0 +1,216 @@ +#include + +#include +#include +#include + +// This implementation uses Port B for the Data port, all 8 bits of it +#define DATA_PORT PORTB + + +// This implementation uses Port B for the Control port +#define LCD_RS PIN2_bm /* RS on pin PB2 */ +#define LCD_E PIN1_bm /* E on pin PB1 */ +#define COMM_PORT PORTA + +void polbajt(unsigned char data) +{ + //PORTB.OUT=0x00; + if(data&0x01) + { + DATA_PORT.OUTSET=PIN5_bm;//dla portu A ->PIN4_bm;//|=0x10;//LCD_D4; + + } + else + { + DATA_PORT.OUTCLR=PIN5_bm;//PIN4_bm;//=~(0x10);//LCD_D4; + } + + if(data&0x02) + { + DATA_PORT.OUTSET=PIN4_bm;//PIN5_bm;//|=0x20;//LCD_D5; + } + else + { + DATA_PORT.OUTCLR=PIN4_bm;//PIN5_bm;//&=~(0x20);//LCD_D5; + } + + if(data&0x04) + { + DATA_PORT.OUTSET=PIN3_bm;//PIN6_bm;//|=0x40;//LCD_D6; + } + else + { + DATA_PORT.OUTCLR=PIN3_bm;//PIN6_bm;//&=~(0x40);//LCD_D6; + } + + if(data&0x08) + { + PORTB.OUTSET=PIN2_bm;//PIN7_bm;//|=0x80;//LCD_D7; + } + else + { + DATA_PORT.OUTCLR=PIN2_bm;//PIN7_bm;//&=~(0x80);//LCD_D7; + } +} + +// This function clears the RS line to write a command +void lcd_set_write_instruction(void) { + COMM_PORT.OUTCLR = LCD_RS; // set RS line low + _delay_us(50); +} + + +// This function sets the RS line to write data +void lcd_set_write_data(void) { + COMM_PORT.OUTSET = LCD_RS; // set RS line high + _delay_us(50); +} + + + +// This function writes a byte to the LCD +void lcd_write_byte (char c) { + //c=(c<<2); + //DATA_PORT.OUT = c; // Place data on Data Port + polbajt(c>>4); + COMM_PORT.OUTSET = LCD_E; // set E line high + _delay_us(1); + COMM_PORT.OUTCLR = LCD_E; // set E line low to latch data into LCD + + polbajt(c); + //_delay_us(1); + COMM_PORT.OUTSET = LCD_E; // set E line high + _delay_us(1); + COMM_PORT.OUTCLR = LCD_E; // set E line low to latch data into LCD + _delay_ms(10); +} + + +// This function clears LCD and sets address to beginning of first line +void lcd_clear_and_home(void) { + lcd_set_write_instruction(); + lcd_write_byte(0x01); + _delay_ms(50); + lcd_write_byte(0x02); + _delay_ms(50); +} + + +// This function sets address to beginning of first line + void lcd_home() { + lcd_set_write_instruction(); + lcd_write_byte(0x02); + _delay_ms(50); +} + + +// This function moves cursor to a given line and position +// line is either 0 (first line) or 1 (second line) +// pos is the character position from 0 to 15. +void lcd_goto(uint8_t line, uint8_t pos) +{ + uint8_t position = 0; + + lcd_set_write_instruction(); + switch(line) + { + case 0: position = 0; + break; + case 1: position = 0x40; + break; + } + lcd_write_byte(0x80 | (position + pos)); + } + + +// This function moves the cursor to 1st character of 1st line +void lcd_line_one(void) { lcd_goto(0, 0); } + + +// This function moves the cursor to 1st character if 2nd line +void lcd_line_two(void) { lcd_goto(1, 0); } + + +// This function writes a character to the LCD +void lcd_write_data(char c) { + lcd_set_write_data(); + lcd_write_byte(c); +} + + +// This function writes a string (in SRAM) of given length to the LCD +void lcd_write_string(char *x, uint8_t len ) { + while (--len > 0) + lcd_write_data(*x++); +} + + +// This function writes a null-terminated string (in SRAM) to the LCD +void lcd_write_string_0(char *x) { + while (*x) + lcd_write_data(*x++); +} + + +// Same as above, but the string is located in program memory, +// so "lpm" instructions are needed to fetch it, and a \0 +// must be defined at the end of the string to terminate it. +void lcd_write_string_p(const char *s) +{ + char c; + + for (c = pgm_read_byte(s); c; ++s, c = pgm_read_byte(s)) + lcd_write_data(c); +} + + +// This function initializes the LCD plus any AVR ports etc +void lcd_init(void) { + + portENTER_CRITICAL(); + { + xLCDrec = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + } + portEXIT_CRITICAL(); + // Initialise the AVR ports and any other hardware bits + DATA_PORT.OUT = 0x00; // initial data lines all low + DATA_PORT.DIRSET = 0xff; // set the 8-bit data port to all outputs + COMM_PORT.OUTCLR = LCD_E | LCD_RS; // all LCD control lines low + COMM_PORT.DIRSET = LCD_E | LCD_RS; // set the LCD control line pins to outputs + + // Now do the actual LCD initialisations + + // startup delay - make it long to allow time for power to settle + // (you want wish to remove this line) + _delay_ms(500); + DATA_PORT.OUTSET=PIN4_bm|PIN5_bm; + COMM_PORT.OUTSET = LCD_E; + + _delay_us(1); + COMM_PORT.OUTCLR = LCD_E; + _delay_ms(5); // czekaj 5ms + + // LCD display initialisation by instruction magic sequence + lcd_set_write_instruction(); + lcd_write_byte(0x28);//(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT); // function set + _delay_us(50); + lcd_set_write_instruction(); + lcd_write_byte(0x28);//(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT); // function set + _delay_us(50); + lcd_set_write_instruction(); + lcd_write_byte(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // display on/off control + _delay_us(50); + lcd_set_write_instruction(); + lcd_write_byte(0x01); // display clear + _delay_ms(5); + lcd_set_write_instruction(); + lcd_write_byte(0x06); // entry mode set + _delay_ms(5); + //lcd_write_byte(0x14); // Cursor shift + + + lcd_clear_and_home(); // LCD cleared and cursor is brought to + // the beginning of 1st line + +} \ No newline at end of file diff --git a/Lib/mcp3008.c b/Lib/mcp3008.c new file mode 100644 index 0000000..36fecde --- /dev/null +++ b/Lib/mcp3008.c @@ -0,0 +1,64 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MPC23s17 parrarel I/O 16 bit port driver +* Author : Adam Kaliszan adam.kaliszan@gmail.com +* Copyright : GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexes and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ +#include +#include +#include "mcp3008.h" +#include "spiXmega.h" + +void enableSpiMCP3008(void) {}; +void disableSpiMCP3008(void) {}; + + +uint16_t MCP3008_getSampleDiff(uint8_t inputNo) +{ + uint8_t resultLo; + uint8_t resultHi; + inputNo = inputNo << 4; + inputNo &= 0x70; + + spiTake(); + enableSpiMCP3008(); + + spiSend(0x01); //Start + resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + resultLo = spiSend(0); //X X X X X X X X + + disableSpiMCP3008(); + spiGive(); + + resultHi &= 0x03; + return resultHi << 8 | resultLo; +} + +uint16_t MCP3008_getSampleSingle(uint8_t inputNo) +{ + uint8_t resultLo; + uint8_t resultHi; + inputNo = inputNo << 4; + inputNo &= 0x70; + inputNo |= 0x80; + + spiTake(); + enableSpiMCP3008(); + + spiSend(0x01); //Start + resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + resultLo = spiSend(0); //X X X X X X X X + + disableSpiMCP3008(); + spiGive(); + + resultHi &= 0x03; + return resultHi << 8 | resultLo; +} +//@} \ No newline at end of file diff --git a/Lib/mcp3008.lst b/Lib/mcp3008.lst new file mode 100644 index 0000000..36f1696 --- /dev/null +++ b/Lib/mcp3008.lst @@ -0,0 +1,259 @@ + 1 .file "mcp3008.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 .weak enableSpiMCP3008 + 277 enableSpiMCP3008: + 278 .stabd 46,0,0 + 1:../../../../Lib/mcp3008.c **** /***************************************************************************** + 2:../../../../Lib/mcp3008.c **** * vim:sw=2:ts=2:si:et + 3:../../../../Lib/mcp3008.c **** * + 4:../../../../Lib/mcp3008.c **** * Title : MPC23s17 parrarel I/O 16 bit port driver + 5:../../../../Lib/mcp3008.c **** * Author : Adam Kaliszan adam.kaliszan@gmail.com + 6:../../../../Lib/mcp3008.c **** * Copyright : GPL V2 + 7:../../../../Lib/mcp3008.c **** * + 8:../../../../Lib/mcp3008.c **** *This driver provides: + 9:../../../../Lib/mcp3008.c **** * - read/set operation + 10:../../../../Lib/mcp3008.c **** *Driver uses mutexes and is condition race free. Function can be invoken by any thread. + 11:../../../../Lib/mcp3008.c **** *****************************************************************************/ + 12:../../../../Lib/mcp3008.c **** //@{ + 13:../../../../Lib/mcp3008.c **** #include + 14:../../../../Lib/mcp3008.c **** #include + 15:../../../../Lib/mcp3008.c **** #include "mcp3008.h" + 16:../../../../Lib/mcp3008.c **** #include "spiXmega.h" + 17:../../../../Lib/mcp3008.c **** + 18:../../../../Lib/mcp3008.c **** void enableSpiMCP3008(void) {}; + 280 .LM0: + 281 .LFBB1: + 282 /* prologue: function */ + 283 /* frame size = 0 */ + 284 /* stack size = 0 */ + 285 .L__stack_usage = 0 + 286 0000 0895 ret + 288 .Lscope1: + 290 .stabd 78,0,0 + 292 .weak disableSpiMCP3008 + 294 disableSpiMCP3008: + 295 .stabd 46,0,0 + 19:../../../../Lib/mcp3008.c **** void disableSpiMCP3008(void) {}; + 297 .LM1: + 298 .LFBB2: + 299 /* prologue: function */ + 300 /* frame size = 0 */ + 301 /* stack size = 0 */ + 302 .L__stack_usage = 0 + 303 0002 0895 ret + 305 .Lscope2: + 307 .stabd 78,0,0 + 310 .global MCP3008_getSampleDiff + 312 MCP3008_getSampleDiff: + 313 .stabd 46,0,0 + 20:../../../../Lib/mcp3008.c **** + 21:../../../../Lib/mcp3008.c **** + 22:../../../../Lib/mcp3008.c **** uint16_t MCP3008_getSampleDiff(uint8_t inputNo) + 23:../../../../Lib/mcp3008.c **** { + 315 .LM2: + 316 .LFBB3: + 318 .LM3: + 319 0004 CF93 push r28 + 320 0006 DF93 push r29 + 321 /* prologue: function */ + 322 /* frame size = 0 */ + 323 /* stack size = 2 */ + 324 .L__stack_usage = 2 + 24:../../../../Lib/mcp3008.c **** uint8_t resultLo; + 25:../../../../Lib/mcp3008.c **** uint8_t resultHi; + 26:../../../../Lib/mcp3008.c **** inputNo = inputNo << 4; + 326 .LM4: + 327 0008 C82F mov r28,r24 + 328 000a C295 swap r28 + 329 000c C07F andi r28,lo8(-16) + 27:../../../../Lib/mcp3008.c **** inputNo &= 0x70; + 28:../../../../Lib/mcp3008.c **** + 29:../../../../Lib/mcp3008.c **** spiTake(); + 331 .LM5: + 332 000e 0E94 0000 call spiTake + 30:../../../../Lib/mcp3008.c **** enableSpiMCP3008(); + 334 .LM6: + 335 0012 0E94 0000 call enableSpiMCP3008 + 31:../../../../Lib/mcp3008.c **** + 32:../../../../Lib/mcp3008.c **** spiSend(0x01); //Start + 337 .LM7: + 338 0016 81E0 ldi r24,lo8(1) + 339 0018 0E94 0000 call spiSend + 33:../../../../Lib/mcp3008.c **** resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + 341 .LM8: + 342 001c 8C2F mov r24,r28 + 343 001e 8077 andi r24,lo8(112) + 344 0020 0E94 0000 call spiSend + 345 0024 D82F mov r29,r24 + 34:../../../../Lib/mcp3008.c **** resultLo = spiSend(0); //X X X X X X X X + 347 .LM9: + 348 0026 80E0 ldi r24,0 + 349 0028 0E94 0000 call spiSend + 350 002c C82F mov r28,r24 + 35:../../../../Lib/mcp3008.c **** + 36:../../../../Lib/mcp3008.c **** disableSpiMCP3008(); + 352 .LM10: + 353 002e 0E94 0000 call disableSpiMCP3008 + 37:../../../../Lib/mcp3008.c **** spiGive(); + 355 .LM11: + 356 0032 0E94 0000 call spiGive + 38:../../../../Lib/mcp3008.c **** + 39:../../../../Lib/mcp3008.c **** resultHi &= 0x03; + 358 .LM12: + 359 0036 D370 andi r29,lo8(3) + 40:../../../../Lib/mcp3008.c **** return resultHi << 8 | resultLo; + 361 .LM13: + 362 0038 8C2F mov r24,r28 + 363 003a 90E0 ldi r25,0 + 41:../../../../Lib/mcp3008.c **** } + 365 .LM14: + 366 003c 9D2B or r25,r29 + 367 /* epilogue start */ + 368 003e DF91 pop r29 + 369 0040 CF91 pop r28 + 370 0042 0895 ret + 375 .Lscope3: + 377 .stabd 78,0,0 + 380 .global MCP3008_getSampleSingle + 382 MCP3008_getSampleSingle: + 383 .stabd 46,0,0 + 42:../../../../Lib/mcp3008.c **** + 43:../../../../Lib/mcp3008.c **** uint16_t MCP3008_getSampleSingle(uint8_t inputNo) + 44:../../../../Lib/mcp3008.c **** { + 385 .LM15: + 386 .LFBB4: + 387 0044 CF93 push r28 + 388 0046 DF93 push r29 + 389 /* prologue: function */ + 390 /* frame size = 0 */ + 391 /* stack size = 2 */ + 392 .L__stack_usage = 2 + 45:../../../../Lib/mcp3008.c **** uint8_t resultLo; + 46:../../../../Lib/mcp3008.c **** uint8_t resultHi; + 47:../../../../Lib/mcp3008.c **** inputNo = inputNo << 4; + 394 .LM16: + 395 0048 8295 swap r24 + 396 004a 807F andi r24,lo8(-16) + 48:../../../../Lib/mcp3008.c **** inputNo &= 0x70; + 398 .LM17: + 399 004c C82F mov r28,r24 + 400 004e C077 andi r28,lo8(112) + 49:../../../../Lib/mcp3008.c **** inputNo |= 0x80; + 50:../../../../Lib/mcp3008.c **** + 51:../../../../Lib/mcp3008.c **** spiTake(); + 402 .LM18: + 403 0050 0E94 0000 call spiTake + 52:../../../../Lib/mcp3008.c **** enableSpiMCP3008(); + 405 .LM19: + 406 0054 0E94 0000 call enableSpiMCP3008 + 53:../../../../Lib/mcp3008.c **** + 54:../../../../Lib/mcp3008.c **** spiSend(0x01); //Start + 408 .LM20: + 409 0058 81E0 ldi r24,lo8(1) + 410 005a 0E94 0000 call spiSend + 55:../../../../Lib/mcp3008.c **** resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + 412 .LM21: + 413 005e 8C2F mov r24,r28 + 414 0060 8068 ori r24,lo8(-128) + 415 0062 0E94 0000 call spiSend + 416 0066 D82F mov r29,r24 + 56:../../../../Lib/mcp3008.c **** resultLo = spiSend(0); //X X X X X X X X + 418 .LM22: + 419 0068 80E0 ldi r24,0 + 420 006a 0E94 0000 call spiSend + 421 006e C82F mov r28,r24 + 57:../../../../Lib/mcp3008.c **** + 58:../../../../Lib/mcp3008.c **** disableSpiMCP3008(); + 423 .LM23: + 424 0070 0E94 0000 call disableSpiMCP3008 + 59:../../../../Lib/mcp3008.c **** spiGive(); + 426 .LM24: + 427 0074 0E94 0000 call spiGive + 60:../../../../Lib/mcp3008.c **** + 61:../../../../Lib/mcp3008.c **** resultHi &= 0x03; + 429 .LM25: + 430 0078 D370 andi r29,lo8(3) + 62:../../../../Lib/mcp3008.c **** return resultHi << 8 | resultLo; + 432 .LM26: + 433 007a 8C2F mov r24,r28 + 434 007c 90E0 ldi r25,0 + 63:../../../../Lib/mcp3008.c **** } + 436 .LM27: + 437 007e 9D2B or r25,r29 + 438 /* epilogue start */ + 439 0080 DF91 pop r29 + 440 0082 CF91 pop r28 + 441 0084 0895 ret + 446 .Lscope4: + 448 .stabd 78,0,0 + 449 .comm czasRtc,7,1 + 450 .comm sockets,2,1 + 451 .comm tcpDebugLevel,1,1 + 452 .comm tcpDebugStream,2,1 + 453 .comm IpMyConfig,15,1 + 454 .comm udpDbgLevel,1,1 + 455 .comm udpDbgStream,2,1 + 456 .comm udpSocket,2,1 + 457 .comm icmpDebugLevel,1,1 + 458 .comm icmpDebug,2,1 + 459 .comm arpDebugLevel,1,1 + 460 .comm arpDebug,2,1 + 461 .comm nicState,14,1 + 462 .comm xSemaphoreRs485,2,1 + 463 .comm lockSensors,2,1 + 464 .comm portB,1,1 + 465 .comm portA,1,1 + 466 .comm xSemaphoreSpiSS,2,1 + 467 .comm rollers,2,1 + 468 .comm wwwport,1,1 + 469 .comm klastry,128,1 + 491 .weak spiSend + 493 .Letext0: + 494 .ident "GCC: (GNU) 4.9.2" + 495 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 mcp3008.c + /tmp/ccsZ9vk1.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccsZ9vk1.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccsZ9vk1.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccsZ9vk1.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccsZ9vk1.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccsZ9vk1.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccsZ9vk1.s:277 .text:0000000000000000 enableSpiMCP3008 + /tmp/ccsZ9vk1.s:294 .text:0000000000000002 disableSpiMCP3008 + /tmp/ccsZ9vk1.s:312 .text:0000000000000004 MCP3008_getSampleDiff + /tmp/ccsZ9vk1.s:382 .text:0000000000000044 MCP3008_getSampleSingle + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +spiTake +spiSend +spiGive +__do_clear_bss diff --git a/Lib/mcp4150.c b/Lib/mcp4150.c new file mode 100644 index 0000000..a8d2d40 --- /dev/null +++ b/Lib/mcp4150.c @@ -0,0 +1,37 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MPC23s17 parrarel I/O 16 bit port driver +* Author : Adam Kaliszan adam.kaliszan@gmail.com +* Copyright : GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexes and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ +#include +#include +#include "mcp4150.h" +#include "spiXmega.h" + +void enableSpiMCP4150(void) {}; +void disableSpiMCP4150(void) {}; + +/** + * Ustawia wartość rezystancji + * @param inputNo - WARTOŚĆ OD 0 DO 255. + */ +void MCP4150_setValue(uint8_t value) +{ + spiTake(); + enableSpiMCP4150(); + + spiSend(0x11); + spiSend(value); + + disableSpiMCP4150(); + spiGive(); +} + +//@} \ No newline at end of file diff --git a/Lib/mcp4150.lst b/Lib/mcp4150.lst new file mode 100644 index 0000000..5e9a681 --- /dev/null +++ b/Lib/mcp4150.lst @@ -0,0 +1,163 @@ + 1 .file "mcp4150.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 .weak enableSpiMCP4150 + 277 enableSpiMCP4150: + 278 .stabd 46,0,0 + 1:../../../../Lib/mcp4150.c **** /***************************************************************************** + 2:../../../../Lib/mcp4150.c **** * vim:sw=2:ts=2:si:et + 3:../../../../Lib/mcp4150.c **** * + 4:../../../../Lib/mcp4150.c **** * Title : MPC23s17 parrarel I/O 16 bit port driver + 5:../../../../Lib/mcp4150.c **** * Author : Adam Kaliszan adam.kaliszan@gmail.com + 6:../../../../Lib/mcp4150.c **** * Copyright : GPL V2 + 7:../../../../Lib/mcp4150.c **** * + 8:../../../../Lib/mcp4150.c **** *This driver provides: + 9:../../../../Lib/mcp4150.c **** * - read/set operation + 10:../../../../Lib/mcp4150.c **** *Driver uses mutexes and is condition race free. Function can be invoken by any thread. + 11:../../../../Lib/mcp4150.c **** *****************************************************************************/ + 12:../../../../Lib/mcp4150.c **** //@{ + 13:../../../../Lib/mcp4150.c **** #include + 14:../../../../Lib/mcp4150.c **** #include + 15:../../../../Lib/mcp4150.c **** #include "mcp4150.h" + 16:../../../../Lib/mcp4150.c **** #include "spiXmega.h" + 17:../../../../Lib/mcp4150.c **** + 18:../../../../Lib/mcp4150.c **** void enableSpiMCP4150(void) {}; + 280 .LM0: + 281 .LFBB1: + 282 /* prologue: function */ + 283 /* frame size = 0 */ + 284 /* stack size = 0 */ + 285 .L__stack_usage = 0 + 286 0000 0895 ret + 288 .Lscope1: + 290 .stabd 78,0,0 + 292 .weak disableSpiMCP4150 + 294 disableSpiMCP4150: + 295 .stabd 46,0,0 + 19:../../../../Lib/mcp4150.c **** void disableSpiMCP4150(void) {}; + 297 .LM1: + 298 .LFBB2: + 299 /* prologue: function */ + 300 /* frame size = 0 */ + 301 /* stack size = 0 */ + 302 .L__stack_usage = 0 + 303 0002 0895 ret + 305 .Lscope2: + 307 .stabd 78,0,0 + 310 .global MCP4150_setValue + 312 MCP4150_setValue: + 313 .stabd 46,0,0 + 20:../../../../Lib/mcp4150.c **** + 21:../../../../Lib/mcp4150.c **** /** + 22:../../../../Lib/mcp4150.c **** * Ustawia wartość rezystancji + 23:../../../../Lib/mcp4150.c **** * @param inputNo - WARTOŚĆ OD 0 DO 255. + 24:../../../../Lib/mcp4150.c **** */ + 25:../../../../Lib/mcp4150.c **** void MCP4150_setValue(uint8_t value) + 26:../../../../Lib/mcp4150.c **** { + 315 .LM2: + 316 .LFBB3: + 318 .LM3: + 319 0004 CF93 push r28 + 320 /* prologue: function */ + 321 /* frame size = 0 */ + 322 /* stack size = 1 */ + 323 .L__stack_usage = 1 + 324 0006 C82F mov r28,r24 + 27:../../../../Lib/mcp4150.c **** spiTake(); + 326 .LM4: + 327 0008 0E94 0000 call spiTake + 28:../../../../Lib/mcp4150.c **** enableSpiMCP4150(); + 329 .LM5: + 330 000c 0E94 0000 call enableSpiMCP4150 + 29:../../../../Lib/mcp4150.c **** + 30:../../../../Lib/mcp4150.c **** spiSend(0x11); + 332 .LM6: + 333 0010 81E1 ldi r24,lo8(17) + 334 0012 0E94 0000 call spiSend + 31:../../../../Lib/mcp4150.c **** spiSend(value); + 336 .LM7: + 337 0016 8C2F mov r24,r28 + 338 0018 0E94 0000 call spiSend + 32:../../../../Lib/mcp4150.c **** + 33:../../../../Lib/mcp4150.c **** disableSpiMCP4150(); + 340 .LM8: + 341 001c 0E94 0000 call disableSpiMCP4150 + 342 /* epilogue start */ + 34:../../../../Lib/mcp4150.c **** spiGive(); + 35:../../../../Lib/mcp4150.c **** } + 344 .LM9: + 345 0020 CF91 pop r28 + 34:../../../../Lib/mcp4150.c **** spiGive(); + 347 .LM10: + 348 0022 0C94 0000 jmp spiGive + 350 .Lscope3: + 352 .stabd 78,0,0 + 353 .comm czasRtc,7,1 + 354 .comm sockets,2,1 + 355 .comm tcpDebugLevel,1,1 + 356 .comm tcpDebugStream,2,1 + 357 .comm IpMyConfig,15,1 + 358 .comm udpDbgLevel,1,1 + 359 .comm udpDbgStream,2,1 + 360 .comm udpSocket,2,1 + 361 .comm icmpDebugLevel,1,1 + 362 .comm icmpDebug,2,1 + 363 .comm arpDebugLevel,1,1 + 364 .comm arpDebug,2,1 + 365 .comm nicState,14,1 + 366 .comm xSemaphoreRs485,2,1 + 367 .comm lockSensors,2,1 + 368 .comm portB,1,1 + 369 .comm portA,1,1 + 370 .comm xSemaphoreSpiSS,2,1 + 371 .comm rollers,2,1 + 372 .comm wwwport,1,1 + 373 .comm klastry,128,1 + 395 .weak spiSend + 397 .Letext0: + 398 .ident "GCC: (GNU) 4.9.2" + 399 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 mcp4150.c + /tmp/ccZk7fY0.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccZk7fY0.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccZk7fY0.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccZk7fY0.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccZk7fY0.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccZk7fY0.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccZk7fY0.s:277 .text:0000000000000000 enableSpiMCP4150 + /tmp/ccZk7fY0.s:294 .text:0000000000000002 disableSpiMCP4150 + /tmp/ccZk7fY0.s:312 .text:0000000000000004 MCP4150_setValue + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +spiTake +spiSend +spiGive +__do_clear_bss diff --git a/Lib/memory_x.c b/Lib/memory_x.c new file mode 100644 index 0000000..979ae73 --- /dev/null +++ b/Lib/memory_x.c @@ -0,0 +1,21 @@ +#include "hardwareConfig.h" +#include "memory_x.h" + + +#ifdef HEAP_BEGIN +char *heapEnd = (char *)HEAP_BEGIN; + +void *xmalloc(size_t size) +{ + void *result = malloc(size); + + heapEnd = (char *)(result); + heapEnd += size; + return result; +} + +size_t xmallocAvailable(void) +{ + return __malloc_heap_end - heapEnd + 1; +} +#endif diff --git a/Lib/memory_x.lst b/Lib/memory_x.lst new file mode 100644 index 0000000..6629185 --- /dev/null +++ b/Lib/memory_x.lst @@ -0,0 +1,100 @@ + 1 .file "memory_x.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 73 .global xmalloc + 75 xmalloc: + 76 .stabd 46,0,0 + 1:../../../../Lib/memory_x.c **** #include "hardwareConfig.h" + 2:../../../../Lib/memory_x.c **** #include "memory_x.h" + 3:../../../../Lib/memory_x.c **** + 4:../../../../Lib/memory_x.c **** + 5:../../../../Lib/memory_x.c **** #ifdef HEAP_BEGIN + 6:../../../../Lib/memory_x.c **** char *heapEnd = (char *)HEAP_BEGIN; + 7:../../../../Lib/memory_x.c **** + 8:../../../../Lib/memory_x.c **** void *xmalloc(size_t size) + 9:../../../../Lib/memory_x.c **** { + 78 .LM0: + 79 .LFBB1: + 80 0000 CF93 push r28 + 81 0002 DF93 push r29 + 82 /* prologue: function */ + 83 /* frame size = 0 */ + 84 /* stack size = 2 */ + 85 .L__stack_usage = 2 + 86 0004 EC01 movw r28,r24 + 10:../../../../Lib/memory_x.c **** void *result = malloc(size); + 88 .LM1: + 89 0006 0E94 0000 call malloc + 11:../../../../Lib/memory_x.c **** + 12:../../../../Lib/memory_x.c **** heapEnd = (char *)(result); + 13:../../../../Lib/memory_x.c **** heapEnd += size; + 91 .LM2: + 92 000a C80F add r28,r24 + 93 000c D91F adc r29,r25 + 94 000e D093 0000 sts heapEnd+1,r29 + 95 0012 C093 0000 sts heapEnd,r28 + 96 /* epilogue start */ + 14:../../../../Lib/memory_x.c **** return result; + 15:../../../../Lib/memory_x.c **** } + 98 .LM3: + 99 0016 DF91 pop r29 + 100 0018 CF91 pop r28 + 101 001a 0895 ret + 103 .Lscope1: + 105 .stabd 78,0,0 + 107 .global xmallocAvailable + 109 xmallocAvailable: + 110 .stabd 46,0,0 + 16:../../../../Lib/memory_x.c **** + 17:../../../../Lib/memory_x.c **** size_t xmallocAvailable(void) + 18:../../../../Lib/memory_x.c **** { + 112 .LM4: + 113 .LFBB2: + 114 /* prologue: function */ + 115 /* frame size = 0 */ + 116 /* stack size = 0 */ + 117 .L__stack_usage = 0 + 19:../../../../Lib/memory_x.c **** return __malloc_heap_end - heapEnd + 1; + 119 .LM5: + 120 001c 8091 0000 lds r24,__malloc_heap_end + 121 0020 9091 0000 lds r25,__malloc_heap_end+1 + 122 0024 2091 0000 lds r18,heapEnd + 123 0028 3091 0000 lds r19,heapEnd+1 + 124 002c 821B sub r24,r18 + 125 002e 930B sbc r25,r19 + 20:../../../../Lib/memory_x.c **** } + 127 .LM6: + 128 0030 0196 adiw r24,1 + 129 0032 0895 ret + 131 .Lscope2: + 133 .stabd 78,0,0 + 134 .global heapEnd + 135 .data + 138 heapEnd: + 139 0000 0011 .word 4352 + 141 .text + 143 .Letext0: + 144 .ident "GCC: (GNU) 4.9.2" + 145 .global __do_copy_data +DEFINED SYMBOLS + *ABS*:0000000000000000 memory_x.c + /tmp/ccVG9VBA.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccVG9VBA.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccVG9VBA.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccVG9VBA.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccVG9VBA.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccVG9VBA.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccVG9VBA.s:75 .text:0000000000000000 xmalloc + /tmp/ccVG9VBA.s:138 .data:0000000000000000 heapEnd + /tmp/ccVG9VBA.s:109 .text:000000000000001c xmallocAvailable + +UNDEFINED SYMBOLS +malloc +__malloc_heap_end +__do_copy_data diff --git a/Lib/mpc23s17.c b/Lib/mpc23s17.c new file mode 100644 index 0000000..825634e --- /dev/null +++ b/Lib/mpc23s17.c @@ -0,0 +1,194 @@ +/***************************************************************************** +* vim:sw=2:ts=2:si:et +* +* Title : MPC23s17 parrarel I/O 16 bit port driver +* Author : Adam Kaliszan +* Copyright: GPL V2 +* +*This driver provides: +* - read/set operation +*Driver uses mutexex and is condition race free. Function can be invoken by any thread. +*****************************************************************************/ +//@{ +#include +#include +#include "mpc23s17.h" +#include "spiXmega.h" + +void enableSpiMPC23S17(void) {} +void disableSpiMPC23S17(void) {} + + +void MPC23s17SetDirA(uint8_t portAdir, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_IODIRA); + spiSend(portAdir); + + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17SetDirB(uint8_t portBdir, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + enableSpiMPC23S17(); + + spiSend(addr); + spiSend(B0_IODIRB); + spiSend(portBdir); + + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17SetPortA(uint8_t portAout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + enableSpiMPC23S17(); + portA = portAout; + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17SetBitsOnPortA(uint8_t portAout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portA |= portAout; + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17ClearBitsOnPortA(uint8_t portAout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portA &= (~portAout); + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17SetPortB(uint8_t portBout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB = portBout; + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17SetBitsOnPortB(uint8_t portBout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB |= portBout; + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + disableSpiMPC23S17(); + spiGive(); +} + +void MPC23s17ClearBitsOnPortB(uint8_t portBout, uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB &= (~portBout); + + spiTake(); + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + + disableSpiMPC23S17(); + spiGive(); +} + +uint8_t MPC23s17ReadPortA(uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + enableSpiMPC23S17(); + + spiSend(addr); + spiSend(B0_GPIOA); + uint8_t result = spiSend(addr); + + disableSpiMPC23S17(); + spiGive(); + + return result; +} + +uint8_t MPC23s17ReadPortB(uint8_t addr) +{ + addr = addr<<1; + addr &= 0x0E; + addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + enableSpiMPC23S17(); + + spiSend(addr); + spiSend(B0_GPIOB); + uint8_t result = spiSend(addr); + + disableSpiMPC23S17(); + spiGive(); + + return result; +} diff --git a/Lib/mpc23s17.lst b/Lib/mpc23s17.lst new file mode 100644 index 0000000..65a270e --- /dev/null +++ b/Lib/mpc23s17.lst @@ -0,0 +1,750 @@ + 1 .file "mpc23s17.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 .weak enableSpiMPC23S17 + 277 enableSpiMPC23S17: + 278 .stabd 46,0,0 + 1:../../../../Lib/mpc23s17.c **** /***************************************************************************** + 2:../../../../Lib/mpc23s17.c **** * vim:sw=2:ts=2:si:et + 3:../../../../Lib/mpc23s17.c **** * + 4:../../../../Lib/mpc23s17.c **** * Title : MPC23s17 parrarel I/O 16 bit port driver + 5:../../../../Lib/mpc23s17.c **** * Author : Adam Kaliszan + 6:../../../../Lib/mpc23s17.c **** * Copyright: GPL V2 + 7:../../../../Lib/mpc23s17.c **** * + 8:../../../../Lib/mpc23s17.c **** *This driver provides: + 9:../../../../Lib/mpc23s17.c **** * - read/set operation + 10:../../../../Lib/mpc23s17.c **** *Driver uses mutexex and is condition race free. Function can be invoken by any thread. + 11:../../../../Lib/mpc23s17.c **** *****************************************************************************/ + 12:../../../../Lib/mpc23s17.c **** //@{ + 13:../../../../Lib/mpc23s17.c **** #include + 14:../../../../Lib/mpc23s17.c **** #include + 15:../../../../Lib/mpc23s17.c **** #include "mpc23s17.h" + 16:../../../../Lib/mpc23s17.c **** #include "spiXmega.h" + 17:../../../../Lib/mpc23s17.c **** + 18:../../../../Lib/mpc23s17.c **** void enableSpiMPC23S17(void) {} + 280 .LM0: + 281 .LFBB1: + 282 /* prologue: function */ + 283 /* frame size = 0 */ + 284 /* stack size = 0 */ + 285 .L__stack_usage = 0 + 286 0000 0895 ret + 288 .Lscope1: + 290 .stabd 78,0,0 + 292 .weak disableSpiMPC23S17 + 294 disableSpiMPC23S17: + 295 .stabd 46,0,0 + 19:../../../../Lib/mpc23s17.c **** void disableSpiMPC23S17(void) {} + 297 .LM1: + 298 .LFBB2: + 299 /* prologue: function */ + 300 /* frame size = 0 */ + 301 /* stack size = 0 */ + 302 .L__stack_usage = 0 + 303 0002 0895 ret + 305 .Lscope2: + 307 .stabd 78,0,0 + 311 .global MPC23s17SetDirA + 313 MPC23s17SetDirA: + 314 .stabd 46,0,0 + 20:../../../../Lib/mpc23s17.c **** + 21:../../../../Lib/mpc23s17.c **** + 22:../../../../Lib/mpc23s17.c **** void MPC23s17SetDirA(uint8_t portAdir, uint8_t addr) + 23:../../../../Lib/mpc23s17.c **** { + 316 .LM2: + 317 .LFBB3: + 319 .LM3: + 320 0004 CF93 push r28 + 321 0006 DF93 push r29 + 322 /* prologue: function */ + 323 /* frame size = 0 */ + 324 /* stack size = 2 */ + 325 .L__stack_usage = 2 + 326 0008 D82F mov r29,r24 + 24:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 328 .LM4: + 329 000a C62F mov r28,r22 + 330 000c CC0F lsl r28 + 25:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 332 .LM5: + 333 000e CE70 andi r28,lo8(14) + 26:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 27:../../../../Lib/mpc23s17.c **** + 28:../../../../Lib/mpc23s17.c **** spiTake(); + 335 .LM6: + 336 0010 0E94 0000 call spiTake + 29:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 338 .LM7: + 339 0014 0E94 0000 call enableSpiMPC23S17 + 30:../../../../Lib/mpc23s17.c **** spiSend(addr); + 341 .LM8: + 342 0018 8C2F mov r24,r28 + 343 001a 8064 ori r24,lo8(64) + 344 001c 0E94 0000 call spiSend + 31:../../../../Lib/mpc23s17.c **** spiSend(B0_IODIRA); + 346 .LM9: + 347 0020 80E0 ldi r24,0 + 348 0022 0E94 0000 call spiSend + 32:../../../../Lib/mpc23s17.c **** spiSend(portAdir); + 350 .LM10: + 351 0026 8D2F mov r24,r29 + 352 0028 0E94 0000 call spiSend + 33:../../../../Lib/mpc23s17.c **** + 34:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 354 .LM11: + 355 002c 0E94 0000 call disableSpiMPC23S17 + 356 /* epilogue start */ + 35:../../../../Lib/mpc23s17.c **** spiGive(); + 36:../../../../Lib/mpc23s17.c **** } + 358 .LM12: + 359 0030 DF91 pop r29 + 360 0032 CF91 pop r28 + 35:../../../../Lib/mpc23s17.c **** spiGive(); + 362 .LM13: + 363 0034 0C94 0000 jmp spiGive + 365 .Lscope3: + 367 .stabd 78,0,0 + 371 .global MPC23s17SetDirB + 373 MPC23s17SetDirB: + 374 .stabd 46,0,0 + 37:../../../../Lib/mpc23s17.c **** + 38:../../../../Lib/mpc23s17.c **** void MPC23s17SetDirB(uint8_t portBdir, uint8_t addr) + 39:../../../../Lib/mpc23s17.c **** { + 376 .LM14: + 377 .LFBB4: + 378 0038 CF93 push r28 + 379 003a DF93 push r29 + 380 /* prologue: function */ + 381 /* frame size = 0 */ + 382 /* stack size = 2 */ + 383 .L__stack_usage = 2 + 384 003c D82F mov r29,r24 + 40:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 386 .LM15: + 387 003e C62F mov r28,r22 + 388 0040 CC0F lsl r28 + 41:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 390 .LM16: + 391 0042 CE70 andi r28,lo8(14) + 42:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 43:../../../../Lib/mpc23s17.c **** + 44:../../../../Lib/mpc23s17.c **** spiTake(); + 393 .LM17: + 394 0044 0E94 0000 call spiTake + 45:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 396 .LM18: + 397 0048 0E94 0000 call enableSpiMPC23S17 + 46:../../../../Lib/mpc23s17.c **** + 47:../../../../Lib/mpc23s17.c **** spiSend(addr); + 399 .LM19: + 400 004c 8C2F mov r24,r28 + 401 004e 8064 ori r24,lo8(64) + 402 0050 0E94 0000 call spiSend + 48:../../../../Lib/mpc23s17.c **** spiSend(B0_IODIRB); + 404 .LM20: + 405 0054 81E0 ldi r24,lo8(1) + 406 0056 0E94 0000 call spiSend + 49:../../../../Lib/mpc23s17.c **** spiSend(portBdir); + 408 .LM21: + 409 005a 8D2F mov r24,r29 + 410 005c 0E94 0000 call spiSend + 50:../../../../Lib/mpc23s17.c **** + 51:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 412 .LM22: + 413 0060 0E94 0000 call disableSpiMPC23S17 + 414 /* epilogue start */ + 52:../../../../Lib/mpc23s17.c **** spiGive(); + 53:../../../../Lib/mpc23s17.c **** } + 416 .LM23: + 417 0064 DF91 pop r29 + 418 0066 CF91 pop r28 + 52:../../../../Lib/mpc23s17.c **** spiGive(); + 420 .LM24: + 421 0068 0C94 0000 jmp spiGive + 423 .Lscope4: + 425 .stabd 78,0,0 + 429 .global MPC23s17SetPortA + 431 MPC23s17SetPortA: + 432 .stabd 46,0,0 + 54:../../../../Lib/mpc23s17.c **** + 55:../../../../Lib/mpc23s17.c **** void MPC23s17SetPortA(uint8_t portAout, uint8_t addr) + 56:../../../../Lib/mpc23s17.c **** { + 434 .LM25: + 435 .LFBB5: + 436 006c 1F93 push r17 + 437 006e CF93 push r28 + 438 0070 DF93 push r29 + 439 0072 1F92 push __zero_reg__ + 440 0074 CDB7 in r28,__SP_L__ + 441 0076 DEB7 in r29,__SP_H__ + 442 /* prologue: function */ + 443 /* frame size = 1 */ + 444 /* stack size = 4 */ + 445 .L__stack_usage = 4 + 57:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 447 .LM26: + 448 0078 660F lsl r22 + 58:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 450 .LM27: + 451 007a 162F mov r17,r22 + 452 007c 1E70 andi r17,lo8(14) + 59:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 60:../../../../Lib/mpc23s17.c **** + 61:../../../../Lib/mpc23s17.c **** spiTake(); + 454 .LM28: + 455 007e 8983 std Y+1,r24 + 456 0080 0E94 0000 call spiTake + 62:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 458 .LM29: + 459 0084 0E94 0000 call enableSpiMPC23S17 + 63:../../../../Lib/mpc23s17.c **** portA = portAout; + 461 .LM30: + 462 0088 8981 ldd r24,Y+1 + 463 008a 8093 0000 sts portA,r24 + 64:../../../../Lib/mpc23s17.c **** spiSend(addr); + 465 .LM31: + 466 008e 812F mov r24,r17 + 467 0090 8064 ori r24,lo8(64) + 468 0092 0E94 0000 call spiSend + 65:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATA); + 470 .LM32: + 471 0096 84E1 ldi r24,lo8(20) + 472 0098 0E94 0000 call spiSend + 66:../../../../Lib/mpc23s17.c **** spiSend(portA); + 474 .LM33: + 475 009c 8091 0000 lds r24,portA + 476 00a0 0E94 0000 call spiSend + 67:../../../../Lib/mpc23s17.c **** + 68:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 478 .LM34: + 479 00a4 0E94 0000 call disableSpiMPC23S17 + 480 /* epilogue start */ + 69:../../../../Lib/mpc23s17.c **** spiGive(); + 70:../../../../Lib/mpc23s17.c **** } + 482 .LM35: + 483 00a8 0F90 pop __tmp_reg__ + 484 00aa DF91 pop r29 + 485 00ac CF91 pop r28 + 486 00ae 1F91 pop r17 + 69:../../../../Lib/mpc23s17.c **** spiGive(); + 488 .LM36: + 489 00b0 0C94 0000 jmp spiGive + 491 .Lscope5: + 493 .stabd 78,0,0 + 497 .global MPC23s17SetBitsOnPortA + 499 MPC23s17SetBitsOnPortA: + 500 .stabd 46,0,0 + 71:../../../../Lib/mpc23s17.c **** + 72:../../../../Lib/mpc23s17.c **** void MPC23s17SetBitsOnPortA(uint8_t portAout, uint8_t addr) + 73:../../../../Lib/mpc23s17.c **** { + 502 .LM37: + 503 .LFBB6: + 504 00b4 CF93 push r28 + 505 /* prologue: function */ + 506 /* frame size = 0 */ + 507 /* stack size = 1 */ + 508 .L__stack_usage = 1 + 74:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 510 .LM38: + 511 00b6 C62F mov r28,r22 + 512 00b8 CC0F lsl r28 + 75:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 514 .LM39: + 515 00ba CE70 andi r28,lo8(14) + 76:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 77:../../../../Lib/mpc23s17.c **** + 78:../../../../Lib/mpc23s17.c **** portA |= portAout; + 517 .LM40: + 518 00bc 9091 0000 lds r25,portA + 519 00c0 892B or r24,r25 + 520 00c2 8093 0000 sts portA,r24 + 79:../../../../Lib/mpc23s17.c **** + 80:../../../../Lib/mpc23s17.c **** spiTake(); + 522 .LM41: + 523 00c6 0E94 0000 call spiTake + 81:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 525 .LM42: + 526 00ca 0E94 0000 call enableSpiMPC23S17 + 82:../../../../Lib/mpc23s17.c **** spiSend(addr); + 528 .LM43: + 529 00ce 8C2F mov r24,r28 + 530 00d0 8064 ori r24,lo8(64) + 531 00d2 0E94 0000 call spiSend + 83:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATA); + 533 .LM44: + 534 00d6 84E1 ldi r24,lo8(20) + 535 00d8 0E94 0000 call spiSend + 84:../../../../Lib/mpc23s17.c **** spiSend(portA); + 537 .LM45: + 538 00dc 8091 0000 lds r24,portA + 539 00e0 0E94 0000 call spiSend + 85:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 541 .LM46: + 542 00e4 0E94 0000 call disableSpiMPC23S17 + 543 /* epilogue start */ + 86:../../../../Lib/mpc23s17.c **** spiGive(); + 87:../../../../Lib/mpc23s17.c **** } + 545 .LM47: + 546 00e8 CF91 pop r28 + 86:../../../../Lib/mpc23s17.c **** spiGive(); + 548 .LM48: + 549 00ea 0C94 0000 jmp spiGive + 551 .Lscope6: + 553 .stabd 78,0,0 + 557 .global MPC23s17ClearBitsOnPortA + 559 MPC23s17ClearBitsOnPortA: + 560 .stabd 46,0,0 + 88:../../../../Lib/mpc23s17.c **** + 89:../../../../Lib/mpc23s17.c **** void MPC23s17ClearBitsOnPortA(uint8_t portAout, uint8_t addr) + 90:../../../../Lib/mpc23s17.c **** { + 562 .LM49: + 563 .LFBB7: + 564 00ee CF93 push r28 + 565 /* prologue: function */ + 566 /* frame size = 0 */ + 567 /* stack size = 1 */ + 568 .L__stack_usage = 1 + 91:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 570 .LM50: + 571 00f0 C62F mov r28,r22 + 572 00f2 CC0F lsl r28 + 92:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 574 .LM51: + 575 00f4 CE70 andi r28,lo8(14) + 93:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 94:../../../../Lib/mpc23s17.c **** + 95:../../../../Lib/mpc23s17.c **** portA &= (~portAout); + 577 .LM52: + 578 00f6 9091 0000 lds r25,portA + 579 00fa 8095 com r24 + 580 00fc 9823 and r25,r24 + 581 00fe 9093 0000 sts portA,r25 + 96:../../../../Lib/mpc23s17.c **** + 97:../../../../Lib/mpc23s17.c **** spiTake(); + 583 .LM53: + 584 0102 0E94 0000 call spiTake + 98:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 586 .LM54: + 587 0106 0E94 0000 call enableSpiMPC23S17 + 99:../../../../Lib/mpc23s17.c **** spiSend(addr); + 589 .LM55: + 590 010a 8C2F mov r24,r28 + 591 010c 8064 ori r24,lo8(64) + 592 010e 0E94 0000 call spiSend + 100:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATA); + 594 .LM56: + 595 0112 84E1 ldi r24,lo8(20) + 596 0114 0E94 0000 call spiSend + 101:../../../../Lib/mpc23s17.c **** spiSend(portA); + 598 .LM57: + 599 0118 8091 0000 lds r24,portA + 600 011c 0E94 0000 call spiSend + 102:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 602 .LM58: + 603 0120 0E94 0000 call disableSpiMPC23S17 + 604 /* epilogue start */ + 103:../../../../Lib/mpc23s17.c **** spiGive(); + 104:../../../../Lib/mpc23s17.c **** } + 606 .LM59: + 607 0124 CF91 pop r28 + 103:../../../../Lib/mpc23s17.c **** spiGive(); + 609 .LM60: + 610 0126 0C94 0000 jmp spiGive + 612 .Lscope7: + 614 .stabd 78,0,0 + 618 .global MPC23s17SetPortB + 620 MPC23s17SetPortB: + 621 .stabd 46,0,0 + 105:../../../../Lib/mpc23s17.c **** + 106:../../../../Lib/mpc23s17.c **** void MPC23s17SetPortB(uint8_t portBout, uint8_t addr) + 107:../../../../Lib/mpc23s17.c **** { + 623 .LM61: + 624 .LFBB8: + 625 012a CF93 push r28 + 626 /* prologue: function */ + 627 /* frame size = 0 */ + 628 /* stack size = 1 */ + 629 .L__stack_usage = 1 + 108:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 631 .LM62: + 632 012c C62F mov r28,r22 + 633 012e CC0F lsl r28 + 109:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 635 .LM63: + 636 0130 CE70 andi r28,lo8(14) + 110:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 111:../../../../Lib/mpc23s17.c **** + 112:../../../../Lib/mpc23s17.c **** portB = portBout; + 638 .LM64: + 639 0132 8093 0000 sts portB,r24 + 113:../../../../Lib/mpc23s17.c **** + 114:../../../../Lib/mpc23s17.c **** spiTake(); + 641 .LM65: + 642 0136 0E94 0000 call spiTake + 115:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 644 .LM66: + 645 013a 0E94 0000 call enableSpiMPC23S17 + 116:../../../../Lib/mpc23s17.c **** spiSend(addr); + 647 .LM67: + 648 013e 8C2F mov r24,r28 + 649 0140 8064 ori r24,lo8(64) + 650 0142 0E94 0000 call spiSend + 117:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATB); + 652 .LM68: + 653 0146 85E1 ldi r24,lo8(21) + 654 0148 0E94 0000 call spiSend + 118:../../../../Lib/mpc23s17.c **** spiSend(portB); + 656 .LM69: + 657 014c 8091 0000 lds r24,portB + 658 0150 0E94 0000 call spiSend + 119:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 660 .LM70: + 661 0154 0E94 0000 call disableSpiMPC23S17 + 662 /* epilogue start */ + 120:../../../../Lib/mpc23s17.c **** spiGive(); + 121:../../../../Lib/mpc23s17.c **** } + 664 .LM71: + 665 0158 CF91 pop r28 + 120:../../../../Lib/mpc23s17.c **** spiGive(); + 667 .LM72: + 668 015a 0C94 0000 jmp spiGive + 670 .Lscope8: + 672 .stabd 78,0,0 + 676 .global MPC23s17SetBitsOnPortB + 678 MPC23s17SetBitsOnPortB: + 679 .stabd 46,0,0 + 122:../../../../Lib/mpc23s17.c **** + 123:../../../../Lib/mpc23s17.c **** void MPC23s17SetBitsOnPortB(uint8_t portBout, uint8_t addr) + 124:../../../../Lib/mpc23s17.c **** { + 681 .LM73: + 682 .LFBB9: + 683 015e CF93 push r28 + 684 /* prologue: function */ + 685 /* frame size = 0 */ + 686 /* stack size = 1 */ + 687 .L__stack_usage = 1 + 125:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 689 .LM74: + 690 0160 C62F mov r28,r22 + 691 0162 CC0F lsl r28 + 126:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 693 .LM75: + 694 0164 CE70 andi r28,lo8(14) + 127:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 128:../../../../Lib/mpc23s17.c **** + 129:../../../../Lib/mpc23s17.c **** portB |= portBout; + 696 .LM76: + 697 0166 9091 0000 lds r25,portB + 698 016a 892B or r24,r25 + 699 016c 8093 0000 sts portB,r24 + 130:../../../../Lib/mpc23s17.c **** + 131:../../../../Lib/mpc23s17.c **** spiTake(); + 701 .LM77: + 702 0170 0E94 0000 call spiTake + 132:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 704 .LM78: + 705 0174 0E94 0000 call enableSpiMPC23S17 + 133:../../../../Lib/mpc23s17.c **** spiSend(addr); + 707 .LM79: + 708 0178 8C2F mov r24,r28 + 709 017a 8064 ori r24,lo8(64) + 710 017c 0E94 0000 call spiSend + 134:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATB); + 712 .LM80: + 713 0180 85E1 ldi r24,lo8(21) + 714 0182 0E94 0000 call spiSend + 135:../../../../Lib/mpc23s17.c **** spiSend(portB); + 716 .LM81: + 717 0186 8091 0000 lds r24,portB + 718 018a 0E94 0000 call spiSend + 136:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 720 .LM82: + 721 018e 0E94 0000 call disableSpiMPC23S17 + 722 /* epilogue start */ + 137:../../../../Lib/mpc23s17.c **** spiGive(); + 138:../../../../Lib/mpc23s17.c **** } + 724 .LM83: + 725 0192 CF91 pop r28 + 137:../../../../Lib/mpc23s17.c **** spiGive(); + 727 .LM84: + 728 0194 0C94 0000 jmp spiGive + 730 .Lscope9: + 732 .stabd 78,0,0 + 736 .global MPC23s17ClearBitsOnPortB + 738 MPC23s17ClearBitsOnPortB: + 739 .stabd 46,0,0 + 139:../../../../Lib/mpc23s17.c **** + 140:../../../../Lib/mpc23s17.c **** void MPC23s17ClearBitsOnPortB(uint8_t portBout, uint8_t addr) + 141:../../../../Lib/mpc23s17.c **** { + 741 .LM85: + 742 .LFBB10: + 743 0198 CF93 push r28 + 744 /* prologue: function */ + 745 /* frame size = 0 */ + 746 /* stack size = 1 */ + 747 .L__stack_usage = 1 + 142:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 749 .LM86: + 750 019a C62F mov r28,r22 + 751 019c CC0F lsl r28 + 143:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 753 .LM87: + 754 019e CE70 andi r28,lo8(14) + 144:../../../../Lib/mpc23s17.c **** addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 145:../../../../Lib/mpc23s17.c **** + 146:../../../../Lib/mpc23s17.c **** portB &= (~portBout); + 756 .LM88: + 757 01a0 9091 0000 lds r25,portB + 758 01a4 8095 com r24 + 759 01a6 9823 and r25,r24 + 760 01a8 9093 0000 sts portB,r25 + 147:../../../../Lib/mpc23s17.c **** + 148:../../../../Lib/mpc23s17.c **** spiTake(); + 762 .LM89: + 763 01ac 0E94 0000 call spiTake + 149:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 765 .LM90: + 766 01b0 0E94 0000 call enableSpiMPC23S17 + 150:../../../../Lib/mpc23s17.c **** spiSend(addr); + 768 .LM91: + 769 01b4 8C2F mov r24,r28 + 770 01b6 8064 ori r24,lo8(64) + 771 01b8 0E94 0000 call spiSend + 151:../../../../Lib/mpc23s17.c **** spiSend(B0_OLATB); + 773 .LM92: + 774 01bc 85E1 ldi r24,lo8(21) + 775 01be 0E94 0000 call spiSend + 152:../../../../Lib/mpc23s17.c **** spiSend(portB); + 777 .LM93: + 778 01c2 8091 0000 lds r24,portB + 779 01c6 0E94 0000 call spiSend + 153:../../../../Lib/mpc23s17.c **** + 154:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 781 .LM94: + 782 01ca 0E94 0000 call disableSpiMPC23S17 + 783 /* epilogue start */ + 155:../../../../Lib/mpc23s17.c **** spiGive(); + 156:../../../../Lib/mpc23s17.c **** } + 785 .LM95: + 786 01ce CF91 pop r28 + 155:../../../../Lib/mpc23s17.c **** spiGive(); + 788 .LM96: + 789 01d0 0C94 0000 jmp spiGive + 791 .Lscope10: + 793 .stabd 78,0,0 + 796 .global MPC23s17ReadPortA + 798 MPC23s17ReadPortA: + 799 .stabd 46,0,0 + 157:../../../../Lib/mpc23s17.c **** + 158:../../../../Lib/mpc23s17.c **** uint8_t MPC23s17ReadPortA(uint8_t addr) + 159:../../../../Lib/mpc23s17.c **** { + 801 .LM97: + 802 .LFBB11: + 803 01d4 1F93 push r17 + 804 01d6 CF93 push r28 + 805 01d8 DF93 push r29 + 806 01da 1F92 push __zero_reg__ + 807 01dc CDB7 in r28,__SP_L__ + 808 01de DEB7 in r29,__SP_H__ + 809 /* prologue: function */ + 810 /* frame size = 1 */ + 811 /* stack size = 4 */ + 812 .L__stack_usage = 4 + 160:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 814 .LM98: + 815 01e0 880F lsl r24 + 161:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 817 .LM99: + 818 01e2 8E70 andi r24,lo8(14) + 162:../../../../Lib/mpc23s17.c **** addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 820 .LM100: + 821 01e4 182F mov r17,r24 + 822 01e6 1164 ori r17,lo8(65) + 163:../../../../Lib/mpc23s17.c **** + 164:../../../../Lib/mpc23s17.c **** spiTake(); + 824 .LM101: + 825 01e8 0E94 0000 call spiTake + 165:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 827 .LM102: + 828 01ec 0E94 0000 call enableSpiMPC23S17 + 166:../../../../Lib/mpc23s17.c **** + 167:../../../../Lib/mpc23s17.c **** spiSend(addr); + 830 .LM103: + 831 01f0 812F mov r24,r17 + 832 01f2 0E94 0000 call spiSend + 168:../../../../Lib/mpc23s17.c **** spiSend(B0_GPIOA); + 834 .LM104: + 835 01f6 82E1 ldi r24,lo8(18) + 836 01f8 0E94 0000 call spiSend + 169:../../../../Lib/mpc23s17.c **** uint8_t result = spiSend(addr); + 838 .LM105: + 839 01fc 812F mov r24,r17 + 840 01fe 0E94 0000 call spiSend + 170:../../../../Lib/mpc23s17.c **** + 171:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 842 .LM106: + 843 0202 8983 std Y+1,r24 + 844 0204 0E94 0000 call disableSpiMPC23S17 + 172:../../../../Lib/mpc23s17.c **** spiGive(); + 846 .LM107: + 847 0208 0E94 0000 call spiGive + 173:../../../../Lib/mpc23s17.c **** + 174:../../../../Lib/mpc23s17.c **** return result; + 175:../../../../Lib/mpc23s17.c **** } + 849 .LM108: + 850 020c 8981 ldd r24,Y+1 + 851 /* epilogue start */ + 852 020e 0F90 pop __tmp_reg__ + 853 0210 DF91 pop r29 + 854 0212 CF91 pop r28 + 855 0214 1F91 pop r17 + 856 0216 0895 ret + 861 .Lscope11: + 863 .stabd 78,0,0 + 866 .global MPC23s17ReadPortB + 868 MPC23s17ReadPortB: + 869 .stabd 46,0,0 + 176:../../../../Lib/mpc23s17.c **** + 177:../../../../Lib/mpc23s17.c **** uint8_t MPC23s17ReadPortB(uint8_t addr) + 178:../../../../Lib/mpc23s17.c **** { + 871 .LM109: + 872 .LFBB12: + 873 0218 1F93 push r17 + 874 021a CF93 push r28 + 875 021c DF93 push r29 + 876 021e 1F92 push __zero_reg__ + 877 0220 CDB7 in r28,__SP_L__ + 878 0222 DEB7 in r29,__SP_H__ + 879 /* prologue: function */ + 880 /* frame size = 1 */ + 881 /* stack size = 4 */ + 882 .L__stack_usage = 4 + 179:../../../../Lib/mpc23s17.c **** addr = addr<<1; + 884 .LM110: + 885 0224 880F lsl r24 + 180:../../../../Lib/mpc23s17.c **** addr &= 0x0E; + 887 .LM111: + 888 0226 8E70 andi r24,lo8(14) + 181:../../../../Lib/mpc23s17.c **** addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 890 .LM112: + 891 0228 182F mov r17,r24 + 892 022a 1164 ori r17,lo8(65) + 182:../../../../Lib/mpc23s17.c **** + 183:../../../../Lib/mpc23s17.c **** spiTake(); + 894 .LM113: + 895 022c 0E94 0000 call spiTake + 184:../../../../Lib/mpc23s17.c **** enableSpiMPC23S17(); + 897 .LM114: + 898 0230 0E94 0000 call enableSpiMPC23S17 + 185:../../../../Lib/mpc23s17.c **** + 186:../../../../Lib/mpc23s17.c **** spiSend(addr); + 900 .LM115: + 901 0234 812F mov r24,r17 + 902 0236 0E94 0000 call spiSend + 187:../../../../Lib/mpc23s17.c **** spiSend(B0_GPIOB); + 904 .LM116: + 905 023a 83E1 ldi r24,lo8(19) + 906 023c 0E94 0000 call spiSend + 188:../../../../Lib/mpc23s17.c **** uint8_t result = spiSend(addr); + 908 .LM117: + 909 0240 812F mov r24,r17 + 910 0242 0E94 0000 call spiSend + 189:../../../../Lib/mpc23s17.c **** + 190:../../../../Lib/mpc23s17.c **** disableSpiMPC23S17(); + 912 .LM118: + 913 0246 8983 std Y+1,r24 + 914 0248 0E94 0000 call disableSpiMPC23S17 + 191:../../../../Lib/mpc23s17.c **** spiGive(); + 916 .LM119: + 917 024c 0E94 0000 call spiGive + 192:../../../../Lib/mpc23s17.c **** + 193:../../../../Lib/mpc23s17.c **** return result; + 194:../../../../Lib/mpc23s17.c **** } + 919 .LM120: + 920 0250 8981 ldd r24,Y+1 + 921 /* epilogue start */ + 922 0252 0F90 pop __tmp_reg__ + 923 0254 DF91 pop r29 + 924 0256 CF91 pop r28 + 925 0258 1F91 pop r17 + 926 025a 0895 ret + 931 .Lscope12: + 933 .stabd 78,0,0 + 934 .comm portB,1,1 + 935 .comm portA,1,1 + 936 .comm czasRtc,7,1 + 937 .comm sockets,2,1 + 938 .comm tcpDebugLevel,1,1 + 939 .comm tcpDebugStream,2,1 + 940 .comm IpMyConfig,15,1 + 941 .comm udpDbgLevel,1,1 + 942 .comm udpDbgStream,2,1 + 943 .comm udpSocket,2,1 + 944 .comm icmpDebugLevel,1,1 + 945 .comm icmpDebug,2,1 + 946 .comm arpDebugLevel,1,1 + 947 .comm arpDebug,2,1 + 948 .comm nicState,14,1 + 949 .comm xSemaphoreRs485,2,1 + 950 .comm lockSensors,2,1 + 951 .comm xSemaphoreSpiSS,2,1 + 952 .comm rollers,2,1 + 953 .comm wwwport,1,1 + 954 .comm klastry,128,1 + 976 .weak spiSend + 978 .Letext0: + 979 .ident "GCC: (GNU) 4.9.2" + 980 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 mpc23s17.c + /tmp/cci90RbV.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cci90RbV.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cci90RbV.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cci90RbV.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cci90RbV.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cci90RbV.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cci90RbV.s:277 .text:0000000000000000 enableSpiMPC23S17 + /tmp/cci90RbV.s:294 .text:0000000000000002 disableSpiMPC23S17 + /tmp/cci90RbV.s:313 .text:0000000000000004 MPC23s17SetDirA + /tmp/cci90RbV.s:373 .text:0000000000000038 MPC23s17SetDirB + /tmp/cci90RbV.s:431 .text:000000000000006c MPC23s17SetPortA + *COM*:0000000000000001 portA + /tmp/cci90RbV.s:499 .text:00000000000000b4 MPC23s17SetBitsOnPortA + /tmp/cci90RbV.s:559 .text:00000000000000ee MPC23s17ClearBitsOnPortA + /tmp/cci90RbV.s:620 .text:000000000000012a MPC23s17SetPortB + *COM*:0000000000000001 portB + /tmp/cci90RbV.s:678 .text:000000000000015e MPC23s17SetBitsOnPortB + /tmp/cci90RbV.s:738 .text:0000000000000198 MPC23s17ClearBitsOnPortB + /tmp/cci90RbV.s:798 .text:00000000000001d4 MPC23s17ReadPortA + /tmp/cci90RbV.s:868 .text:0000000000000218 MPC23s17ReadPortB + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +spiTake +spiSend +spiGive +__do_clear_bss diff --git a/Lib/net/arp.c b/Lib/net/arp.c new file mode 100644 index 0000000..ef182d7 --- /dev/null +++ b/Lib/net/arp.c @@ -0,0 +1,242 @@ +/** + * @file arp.c + * @version 0.2 + * @author Pascal Stang, Adam Kaliszan + * \brief ARP Protocol Library. + * + * Created : 7.09.2004 + * Revised : 29.11.2010 + * Editor Tabs : 4 + * + */ + + +#include "arp.h" + + +/// Single ARP table entry/record +struct ArpEntry +{ + uint32_t ipaddr; ///< remote-note IP address + struct netEthAddr ethaddr; ///< remote-node ethernet (hardware/mac) address + uint8_t time; ///< time to live (in ARP table); this is decremented by arpTimer() +}; + +// global variables +struct ArpEntry ArpTable[ARP_TABLE_SIZE]; ///< ARP table of matched IP<->MAC associations + +#ifdef ARP_DEBUG + +void setArpDebug(FILE *stream, uint8_t level) +{ + arpDebug = stream; + arpDebugLevel = level; + if (level == 0) + arpDebug = NULL; +} +#endif /*ARP_DEBUG*/ + +void arpInit() +{ + + memset(ArpTable, 0, sizeof(ArpTable)); + arpDebug = NULL; +} + +void arpArpIn(void) +{ +#ifdef ARP_DEBUG + if (arpDebug != NULL) + { + if (arpDebugLevel > 1) + fprintf_P(arpDebug, PSTR("Received ARP Request\r\n")); + if (arpDebugLevel > 2) + arpPrintHeader(arpDebug, nicState.layer3.arp); + } +#endif + +// for now, we just reply to requests +// need to add ARP cache + if((nicState.layer3.arp->dipaddr == IpMyConfig.ip) && (nicState.layer3.arp->opcode == htons(ARP_OPCODE_REQUEST)) ) + { +// in ARP header +// copy sender's address info to dest. fields + nicState.layer3.arp->dhwaddr = nicState.layer3.arp->shwaddr; + nicState.layer3.arp->dipaddr = nicState.layer3.arp->sipaddr; +// fill in our information + nicState.layer3.arp->shwaddr = nicState.mac; + nicState.layer3.arp->sipaddr = IpMyConfig.ip; +// change op to reply + nicState.layer3.arp->opcode = htons(ARP_OPCODE_REPLY); + +// in ethernet header + nicState.layer2.ethHeader->dest = nicState.layer2.ethHeader->src; + nicState.layer2.ethHeader->src = nicState.mac; + +#ifdef ARP_DEBUG + if (arpDebug != NULL) + { + if (arpDebugLevel > 0) + fprintf_P(arpDebug, PSTR("Sending ARP Reply\r\n")); + if (arpDebugLevel > 2) + arpPrintHeader(arpDebug, nicState.layer3.arp); + } +#endif +// send reply! + nicSend(sizeof(struct netArpHeader) + ETH_HEADER_LEN); + } +} + +void arpIpIn(void) +{ +#ifdef ARP_DEBUG + if (arpDebug != NULL) + { + if (arpDebugLevel > 0) + { + fprintf_P(arpDebug, PSTR("ARP IP in MAC: ")); + netPrintEthAddr(arpDebug, &nicState.layer2.ethHeader->src); + fprintf_P(arpDebug, PSTR(" IP: ")); + netPrintIPAddr(arpDebug, nicState.layer3.ip->srcipaddr); + fprintf_P(arpDebug, PSTR("\r\n")); + } + } +#endif + int8_t index; + +// check if sender is already present in arp table + index = arpMatchIp(nicState.layer3.ip->srcipaddr); + if(index != -1) + { +// sender's IP address found, update ARP entry + ArpTable[index].ethaddr = nicState.layer2.ethHeader->src; + ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; +// and we're done + return; + } + +// sender was not present in table, +// must add in empty/expired slot + for(index=0; indexsrc; + ArpTable[index].ipaddr = nicState.layer3.ip->srcipaddr; + ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; +// and we're done + return; + } + } +// no space in table, we give up +} + +void arpIpOut(uint32_t phyDstIp) +{ + int index; +// check if destination is already present in arp table +// use the physical dstIp if it's provided, otherwise the dstIp in packet + if(phyDstIp) + index = arpMatchIp(phyDstIp); + else + index = arpMatchIp(nicState.layer3.ip->destipaddr); +// fill in ethernet info + if(index != -1) + { +// ARP entry present, fill eth address(es) + nicState.layer2.ethHeader->src = nicState.mac; + nicState.layer2.ethHeader->dest = ArpTable[index].ethaddr; + nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + } + else + { +// not in table, must send ARP request + nicState.layer2.ethHeader->src = nicState.mac; +// TODO MUST CHANGE, but for now, send this one broadcast +// before sending frame, must copy buffer + memset(nicState.layer2.ethHeader->dest.addr, 0xFF, 6); + nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + } +} + +void arpTimer(void) +{ + int index; +// this function meant to be called on a regular time interval + +// decrement time-to-live for all entries + for(index=0; indexopcode == htons(ARP_OPCODE_REQUEST)) + fprintf_P(stream, PSTR("REQUEST")); + else if(packet->opcode == htons(ARP_OPCODE_REPLY)) + fprintf_P(stream, PSTR("REPLY")); + else + fprintf_P(stream, PSTR("UNKNOWN")); + fprintf_P(stream, PSTR("\r\n")); +// print source hardware address + fprintf_P(stream, PSTR("SrcHwAddr : ")); netPrintEthAddr(stream, &packet->shwaddr); fprintf_P(stream, PSTR("\r\n")); +// print source protocol address + fprintf_P(stream, PSTR("SrcProtoAddr: ")); netPrintIPAddr(stream, packet->sipaddr); fprintf_P(stream, PSTR("\r\n")); +// print target hardware address + fprintf_P(stream, PSTR("DstHwAddr : ")); netPrintEthAddr(stream, &packet->dhwaddr); fprintf_P(stream, PSTR("\r\n")); +// print target protocol address + fprintf_P(stream, PSTR("DstProtoAddr: ")); netPrintIPAddr(stream, packet->dipaddr); fprintf_P(stream, PSTR("\r\n")); +} +#endif /*ARP_DEBUG*/ + +void arpPrintTable(FILE *stream) +{ + uint8_t i; + + // print ARP table + fprintf_P(stream, PSTR("Time Eth Address IP Address\r\n")); + fprintf_P(stream, PSTR("-----------------------------------\r\n")); + fprintf_P(stream, PSTR(" MY ")); + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR(" ")); + netPrintIPAddr(stream, IpMyConfig.ip); + fprintf_P(stream, PSTR("\r\n")); + + for(i=0; iMAC associations + 27:../../../../Lib/net/arp.c **** + 28:../../../../Lib/net/arp.c **** #ifdef ARP_DEBUG + 29:../../../../Lib/net/arp.c **** + 30:../../../../Lib/net/arp.c **** void setArpDebug(FILE *stream, uint8_t level) + 31:../../../../Lib/net/arp.c **** { + 170 .LM0: + 171 .LFBB1: + 172 /* prologue: function */ + 173 /* frame size = 0 */ + 174 /* stack size = 0 */ + 175 .L__stack_usage = 0 + 32:../../../../Lib/net/arp.c **** arpDebug = stream; + 177 .LM1: + 178 0000 9093 0000 sts arpDebug+1,r25 + 179 0004 8093 0000 sts arpDebug,r24 + 33:../../../../Lib/net/arp.c **** arpDebugLevel = level; + 181 .LM2: + 182 0008 6093 0000 sts arpDebugLevel,r22 + 34:../../../../Lib/net/arp.c **** if (level == 0) + 184 .LM3: + 185 000c 6111 cpse r22,__zero_reg__ + 186 000e 00C0 rjmp .L1 + 35:../../../../Lib/net/arp.c **** arpDebug = NULL; + 188 .LM4: + 189 0010 1092 0000 sts arpDebug+1,__zero_reg__ + 190 0014 1092 0000 sts arpDebug,__zero_reg__ + 191 .L1: + 192 0018 0895 ret + 194 .Lscope1: + 196 .stabd 78,0,0 + 198 .global arpInit + 200 arpInit: + 201 .stabd 46,0,0 + 36:../../../../Lib/net/arp.c **** } + 37:../../../../Lib/net/arp.c **** #endif /*ARP_DEBUG*/ + 38:../../../../Lib/net/arp.c **** + 39:../../../../Lib/net/arp.c **** void arpInit() + 40:../../../../Lib/net/arp.c **** { + 203 .LM5: + 204 .LFBB2: + 205 /* prologue: function */ + 206 /* frame size = 0 */ + 207 /* stack size = 0 */ + 208 .L__stack_usage = 0 + 41:../../../../Lib/net/arp.c **** + 42:../../../../Lib/net/arp.c **** memset(ArpTable, 0, sizeof(ArpTable)); + 210 .LM6: + 211 001a 8EE6 ldi r24,lo8(110) + 212 001c E0E0 ldi r30,lo8(ArpTable) + 213 001e F0E0 ldi r31,hi8(ArpTable) + 214 0020 DF01 movw r26,r30 + 215 0: + 216 0022 1D92 st X+,__zero_reg__ + 217 0024 8A95 dec r24 + 218 0026 01F4 brne 0b + 43:../../../../Lib/net/arp.c **** arpDebug = NULL; + 220 .LM7: + 221 0028 1092 0000 sts arpDebug+1,__zero_reg__ + 222 002c 1092 0000 sts arpDebug,__zero_reg__ + 223 0030 0895 ret + 225 .Lscope2: + 227 .stabd 78,0,0 + 229 .global arpTimer + 231 arpTimer: + 232 .stabd 46,0,0 + 44:../../../../Lib/net/arp.c **** } + 45:../../../../Lib/net/arp.c **** + 46:../../../../Lib/net/arp.c **** void arpArpIn(void) + 47:../../../../Lib/net/arp.c **** { + 48:../../../../Lib/net/arp.c **** #ifdef ARP_DEBUG + 49:../../../../Lib/net/arp.c **** if (arpDebug != NULL) + 50:../../../../Lib/net/arp.c **** { + 51:../../../../Lib/net/arp.c **** if (arpDebugLevel > 1) + 52:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("Received ARP Request\r\n")); + 53:../../../../Lib/net/arp.c **** if (arpDebugLevel > 2) + 54:../../../../Lib/net/arp.c **** arpPrintHeader(arpDebug, nicState.layer3.arp); + 55:../../../../Lib/net/arp.c **** } + 56:../../../../Lib/net/arp.c **** #endif + 57:../../../../Lib/net/arp.c **** + 58:../../../../Lib/net/arp.c **** // for now, we just reply to requests + 59:../../../../Lib/net/arp.c **** // need to add ARP cache + 60:../../../../Lib/net/arp.c **** if((nicState.layer3.arp->dipaddr == IpMyConfig.ip) && (nicState.layer3.arp->opcode == htons(ARP_O + 61:../../../../Lib/net/arp.c **** { + 62:../../../../Lib/net/arp.c **** // in ARP header + 63:../../../../Lib/net/arp.c **** // copy sender's address info to dest. fields + 64:../../../../Lib/net/arp.c **** nicState.layer3.arp->dhwaddr = nicState.layer3.arp->shwaddr; + 65:../../../../Lib/net/arp.c **** nicState.layer3.arp->dipaddr = nicState.layer3.arp->sipaddr; + 66:../../../../Lib/net/arp.c **** // fill in our information + 67:../../../../Lib/net/arp.c **** nicState.layer3.arp->shwaddr = nicState.mac; + 68:../../../../Lib/net/arp.c **** nicState.layer3.arp->sipaddr = IpMyConfig.ip; + 69:../../../../Lib/net/arp.c **** // change op to reply + 70:../../../../Lib/net/arp.c **** nicState.layer3.arp->opcode = htons(ARP_OPCODE_REPLY); + 71:../../../../Lib/net/arp.c **** + 72:../../../../Lib/net/arp.c **** // in ethernet header + 73:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->dest = nicState.layer2.ethHeader->src; + 74:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->src = nicState.mac; + 75:../../../../Lib/net/arp.c **** + 76:../../../../Lib/net/arp.c **** #ifdef ARP_DEBUG + 77:../../../../Lib/net/arp.c **** if (arpDebug != NULL) + 78:../../../../Lib/net/arp.c **** { + 79:../../../../Lib/net/arp.c **** if (arpDebugLevel > 0) + 80:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("Sending ARP Reply\r\n")); + 81:../../../../Lib/net/arp.c **** if (arpDebugLevel > 2) + 82:../../../../Lib/net/arp.c **** arpPrintHeader(arpDebug, nicState.layer3.arp); + 83:../../../../Lib/net/arp.c **** } + 84:../../../../Lib/net/arp.c **** #endif + 85:../../../../Lib/net/arp.c **** // send reply! + 86:../../../../Lib/net/arp.c **** nicSend(sizeof(struct netArpHeader) + ETH_HEADER_LEN); + 87:../../../../Lib/net/arp.c **** } + 88:../../../../Lib/net/arp.c **** } + 89:../../../../Lib/net/arp.c **** + 90:../../../../Lib/net/arp.c **** void arpIpIn(void) + 91:../../../../Lib/net/arp.c **** { + 92:../../../../Lib/net/arp.c **** #ifdef ARP_DEBUG + 93:../../../../Lib/net/arp.c **** if (arpDebug != NULL) + 94:../../../../Lib/net/arp.c **** { + 95:../../../../Lib/net/arp.c **** if (arpDebugLevel > 0) + 96:../../../../Lib/net/arp.c **** { + 97:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("ARP IP in MAC: ")); + 98:../../../../Lib/net/arp.c **** netPrintEthAddr(arpDebug, &nicState.layer2.ethHeader->src); + 99:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR(" IP: ")); + 100:../../../../Lib/net/arp.c **** netPrintIPAddr(arpDebug, nicState.layer3.ip->srcipaddr); + 101:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("\r\n")); + 102:../../../../Lib/net/arp.c **** } + 103:../../../../Lib/net/arp.c **** } + 104:../../../../Lib/net/arp.c **** #endif + 105:../../../../Lib/net/arp.c **** int8_t index; + 106:../../../../Lib/net/arp.c **** + 107:../../../../Lib/net/arp.c **** // check if sender is already present in arp table + 108:../../../../Lib/net/arp.c **** index = arpMatchIp(nicState.layer3.ip->srcipaddr); + 109:../../../../Lib/net/arp.c **** if(index != -1) + 110:../../../../Lib/net/arp.c **** { + 111:../../../../Lib/net/arp.c **** // sender's IP address found, update ARP entry + 112:../../../../Lib/net/arp.c **** ArpTable[index].ethaddr = nicState.layer2.ethHeader->src; + 113:../../../../Lib/net/arp.c **** ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 114:../../../../Lib/net/arp.c **** // and we're done + 115:../../../../Lib/net/arp.c **** return; + 116:../../../../Lib/net/arp.c **** } + 117:../../../../Lib/net/arp.c **** + 118:../../../../Lib/net/arp.c **** // sender was not present in table, + 119:../../../../Lib/net/arp.c **** // must add in empty/expired slot + 120:../../../../Lib/net/arp.c **** for(index=0; indexsrc; + 126:../../../../Lib/net/arp.c **** ArpTable[index].ipaddr = nicState.layer3.ip->srcipaddr; + 127:../../../../Lib/net/arp.c **** ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 128:../../../../Lib/net/arp.c **** // and we're done + 129:../../../../Lib/net/arp.c **** return; + 130:../../../../Lib/net/arp.c **** } + 131:../../../../Lib/net/arp.c **** } + 132:../../../../Lib/net/arp.c **** // no space in table, we give up + 133:../../../../Lib/net/arp.c **** } + 134:../../../../Lib/net/arp.c **** + 135:../../../../Lib/net/arp.c **** void arpIpOut(uint32_t phyDstIp) + 136:../../../../Lib/net/arp.c **** { + 137:../../../../Lib/net/arp.c **** int index; + 138:../../../../Lib/net/arp.c **** // check if destination is already present in arp table + 139:../../../../Lib/net/arp.c **** // use the physical dstIp if it's provided, otherwise the dstIp in packet + 140:../../../../Lib/net/arp.c **** if(phyDstIp) + 141:../../../../Lib/net/arp.c **** index = arpMatchIp(phyDstIp); + 142:../../../../Lib/net/arp.c **** else + 143:../../../../Lib/net/arp.c **** index = arpMatchIp(nicState.layer3.ip->destipaddr); + 144:../../../../Lib/net/arp.c **** // fill in ethernet info + 145:../../../../Lib/net/arp.c **** if(index != -1) + 146:../../../../Lib/net/arp.c **** { + 147:../../../../Lib/net/arp.c **** // ARP entry present, fill eth address(es) + 148:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->src = nicState.mac; + 149:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->dest = ArpTable[index].ethaddr; + 150:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + 151:../../../../Lib/net/arp.c **** } + 152:../../../../Lib/net/arp.c **** else + 153:../../../../Lib/net/arp.c **** { + 154:../../../../Lib/net/arp.c **** // not in table, must send ARP request + 155:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->src = nicState.mac; + 156:../../../../Lib/net/arp.c **** // TODO MUST CHANGE, but for now, send this one broadcast + 157:../../../../Lib/net/arp.c **** // before sending frame, must copy buffer + 158:../../../../Lib/net/arp.c **** memset(nicState.layer2.ethHeader->dest.addr, 0xFF, 6); + 159:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + 160:../../../../Lib/net/arp.c **** } + 161:../../../../Lib/net/arp.c **** } + 162:../../../../Lib/net/arp.c **** + 163:../../../../Lib/net/arp.c **** void arpTimer(void) + 164:../../../../Lib/net/arp.c **** { + 234 .LM8: + 235 .LFBB3: + 236 /* prologue: function */ + 237 /* frame size = 0 */ + 238 /* stack size = 0 */ + 239 .L__stack_usage = 0 + 240 0032 E0E0 ldi r30,lo8(ArpTable+10) + 241 0034 F0E0 ldi r31,hi8(ArpTable+10) + 242 .L7: + 165:../../../../Lib/net/arp.c **** int index; + 166:../../../../Lib/net/arp.c **** // this function meant to be called on a regular time interval + 167:../../../../Lib/net/arp.c **** + 168:../../../../Lib/net/arp.c **** // decrement time-to-live for all entries + 169:../../../../Lib/net/arp.c **** for(index=0; indexsrc); + 355 .LM22: + 356 00a2 20E0 ldi r18,lo8(__c.2495) + 357 00a4 30E0 ldi r19,hi8(__c.2495) + 358 00a6 3F93 push r19 + 359 00a8 2F93 push r18 + 360 00aa 9F93 push r25 + 361 00ac 8F93 push r24 + 362 00ae 0E94 0000 call fprintf_P + 98:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR(" IP: ")); + 364 .LM23: + 365 00b2 6091 0000 lds r22,nicState+8 + 366 00b6 7091 0000 lds r23,nicState+8+1 + 367 00ba 6A5F subi r22,-6 + 368 00bc 7F4F sbci r23,-1 + 369 00be 8091 0000 lds r24,arpDebug + 370 00c2 9091 0000 lds r25,arpDebug+1 + 371 00c6 0E94 0000 call netPrintEthAddr + 99:../../../../Lib/net/arp.c **** netPrintIPAddr(arpDebug, nicState.layer3.ip->srcipaddr); + 373 .LM24: + 374 00ca 80E0 ldi r24,lo8(__c.2497) + 375 00cc 90E0 ldi r25,hi8(__c.2497) + 376 00ce 9F93 push r25 + 377 00d0 8F93 push r24 + 378 00d2 8091 0000 lds r24,arpDebug+1 + 379 00d6 8F93 push r24 + 380 00d8 8091 0000 lds r24,arpDebug + 381 00dc 8F93 push r24 + 382 00de 0E94 0000 call fprintf_P + 100:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("\r\n")); + 384 .LM25: + 385 00e2 E091 0000 lds r30,nicState+10 + 386 00e6 F091 0000 lds r31,nicState+10+1 + 387 00ea 4485 ldd r20,Z+12 + 388 00ec 5585 ldd r21,Z+13 + 389 00ee 6685 ldd r22,Z+14 + 390 00f0 7785 ldd r23,Z+15 + 391 00f2 8091 0000 lds r24,arpDebug + 392 00f6 9091 0000 lds r25,arpDebug+1 + 393 00fa 0E94 0000 call netPrintIPAddr + 101:../../../../Lib/net/arp.c **** } + 395 .LM26: + 396 00fe 80E0 ldi r24,lo8(__c.2499) + 397 0100 90E0 ldi r25,hi8(__c.2499) + 398 0102 9F93 push r25 + 399 0104 8F93 push r24 + 400 0106 8091 0000 lds r24,arpDebug+1 + 401 010a 8F93 push r24 + 402 010c 8091 0000 lds r24,arpDebug + 403 0110 8F93 push r24 + 404 0112 0E94 0000 call fprintf_P + 405 0116 8DB7 in r24,__SP_L__ + 406 0118 9EB7 in r25,__SP_H__ + 407 011a 0C96 adiw r24,12 + 408 011c 0FB6 in __tmp_reg__,__SREG__ + 409 011e F894 cli + 410 0120 9EBF out __SP_H__,r25 + 411 0122 0FBE out __SREG__,__tmp_reg__ + 412 0124 8DBF out __SP_L__,r24 + 413 .L17: + 108:../../../../Lib/net/arp.c **** if(index != -1) + 415 .LM27: + 416 0126 C091 0000 lds r28,nicState+10 + 417 012a D091 0000 lds r29,nicState+10+1 + 418 012e 6C85 ldd r22,Y+12 + 419 0130 7D85 ldd r23,Y+13 + 420 0132 8E85 ldd r24,Y+14 + 421 0134 9F85 ldd r25,Y+15 + 422 0136 0E94 0000 call arpMatchIp + 109:../../../../Lib/net/arp.c **** { + 424 .LM28: + 425 013a 8F3F cpi r24,lo8(-1) + 426 013c 01F0 breq .L18 + 112:../../../../Lib/net/arp.c **** ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 428 .LM29: + 429 013e 2BE0 ldi r18,lo8(11) + 430 0140 8202 muls r24,r18 + 431 0142 C001 movw r24,r0 + 432 0144 1124 clr __zero_reg__ + 433 0146 DC01 movw r26,r24 + 434 0148 A050 subi r26,lo8(-(ArpTable+4)) + 435 014a B040 sbci r27,hi8(-(ArpTable+4)) + 436 014c E091 0000 lds r30,nicState+8 + 437 0150 F091 0000 lds r31,nicState+8+1 + 438 0154 26E0 ldi r18,lo8(6) + 439 0156 3696 adiw r30,6 + 440 0: + 441 0158 0190 ld r0,Z+ + 442 015a 0D92 st X+,r0 + 443 015c 2A95 dec r18 + 444 015e 01F4 brne 0b + 113:../../../../Lib/net/arp.c **** // and we're done + 446 .LM30: + 447 0160 FC01 movw r30,r24 + 448 0162 E050 subi r30,lo8(-(ArpTable)) + 449 0164 F040 sbci r31,hi8(-(ArpTable)) + 450 0166 20E8 ldi r18,lo8(-128) + 451 0168 2287 std Z+10,r18 + 115:../../../../Lib/net/arp.c **** } + 453 .LM31: + 454 016a 00C0 rjmp .L16 + 455 .L18: + 456 016c E0E0 ldi r30,lo8(ArpTable+10) + 457 016e F0E0 ldi r31,hi8(ArpTable+10) + 109:../../../../Lib/net/arp.c **** { + 459 .LM32: + 460 0170 20E0 ldi r18,0 + 461 0172 30E0 ldi r19,0 + 462 .L21: + 122:../../../../Lib/net/arp.c **** { + 464 .LM33: + 465 0174 8081 ld r24,Z + 466 0176 8111 cpse r24,__zero_reg__ + 467 0178 00C0 rjmp .L20 + 125:../../../../Lib/net/arp.c **** ArpTable[index].ipaddr = nicState.layer3.ip->srcipaddr; + 469 .LM34: + 470 017a 4BE0 ldi r20,lo8(11) + 471 017c 429F mul r20,r18 + 472 017e C001 movw r24,r0 + 473 0180 439F mul r20,r19 + 474 0182 900D add r25,r0 + 475 0184 1124 clr __zero_reg__ + 476 0186 DC01 movw r26,r24 + 477 0188 A050 subi r26,lo8(-(ArpTable+4)) + 478 018a B040 sbci r27,hi8(-(ArpTable+4)) + 479 018c E091 0000 lds r30,nicState+8 + 480 0190 F091 0000 lds r31,nicState+8+1 + 481 0194 26E0 ldi r18,lo8(6) + 482 0196 3696 adiw r30,6 + 483 0: + 484 0198 0190 ld r0,Z+ + 485 019a 0D92 st X+,r0 + 486 019c 2A95 dec r18 + 487 019e 01F4 brne 0b + 126:../../../../Lib/net/arp.c **** ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 489 .LM35: + 490 01a0 FC01 movw r30,r24 + 491 01a2 E050 subi r30,lo8(-(ArpTable)) + 492 01a4 F040 sbci r31,hi8(-(ArpTable)) + 493 01a6 8C85 ldd r24,Y+12 + 494 01a8 9D85 ldd r25,Y+13 + 495 01aa AE85 ldd r26,Y+14 + 496 01ac BF85 ldd r27,Y+15 + 497 01ae 8083 st Z,r24 + 498 01b0 9183 std Z+1,r25 + 499 01b2 A283 std Z+2,r26 + 500 01b4 B383 std Z+3,r27 + 127:../../../../Lib/net/arp.c **** // and we're done + 502 .LM36: + 503 01b6 80E8 ldi r24,lo8(-128) + 504 01b8 8287 std Z+10,r24 + 129:../../../../Lib/net/arp.c **** } + 506 .LM37: + 507 01ba 00C0 rjmp .L16 + 508 .L20: + 509 01bc 2F5F subi r18,-1 + 510 01be 3F4F sbci r19,-1 + 511 01c0 3B96 adiw r30,11 + 120:../../../../Lib/net/arp.c **** { + 513 .LM38: + 514 01c2 2A30 cpi r18,10 + 515 01c4 3105 cpc r19,__zero_reg__ + 516 01c6 01F4 brne .L21 + 517 .L16: + 518 /* epilogue start */ + 133:../../../../Lib/net/arp.c **** + 520 .LM39: + 521 01c8 DF91 pop r29 + 522 01ca CF91 pop r28 + 523 01cc 0895 ret + 525 .Lscope5: + 527 .stabd 78,0,0 + 530 .global arpIpOut + 532 arpIpOut: + 533 .stabd 46,0,0 + 136:../../../../Lib/net/arp.c **** int index; + 535 .LM40: + 536 .LFBB6: + 537 /* prologue: function */ + 538 /* frame size = 0 */ + 539 /* stack size = 0 */ + 540 .L__stack_usage = 0 + 140:../../../../Lib/net/arp.c **** index = arpMatchIp(phyDstIp); + 542 .LM41: + 543 01ce 6115 cp r22,__zero_reg__ + 544 01d0 7105 cpc r23,__zero_reg__ + 545 01d2 8105 cpc r24,__zero_reg__ + 546 01d4 9105 cpc r25,__zero_reg__ + 547 01d6 01F4 brne .L34 + 143:../../../../Lib/net/arp.c **** // fill in ethernet info + 549 .LM42: + 550 01d8 E091 0000 lds r30,nicState+10 + 551 01dc F091 0000 lds r31,nicState+10+1 + 552 01e0 6089 ldd r22,Z+16 + 553 01e2 7189 ldd r23,Z+17 + 554 01e4 8289 ldd r24,Z+18 + 555 01e6 9389 ldd r25,Z+19 + 556 .L34: + 557 01e8 0E94 0000 call arpMatchIp + 558 01ec A091 0000 lds r26,nicState+8 + 559 01f0 B091 0000 lds r27,nicState+8+1 + 145:../../../../Lib/net/arp.c **** { + 561 .LM43: + 562 01f4 8F3F cpi r24,-1 + 563 01f6 2FEF ldi r18,-1 + 564 01f8 9207 cpc r25,r18 + 565 01fa 01F0 breq .L32 + 148:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->dest = ArpTable[index].ethaddr; + 567 .LM44: + 568 01fc 26E0 ldi r18,lo8(6) + 569 01fe E0E0 ldi r30,lo8(nicState+2) + 570 0200 F0E0 ldi r31,hi8(nicState+2) + 571 0202 1696 adiw r26,6 + 572 0: + 573 0204 0190 ld r0,Z+ + 574 0206 0D92 st X+,r0 + 575 0208 2A95 dec r18 + 576 020a 01F4 brne 0b + 149:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + 578 .LM45: + 579 020c A091 0000 lds r26,nicState+8 + 580 0210 B091 0000 lds r27,nicState+8+1 + 581 0214 2BE0 ldi r18,lo8(11) + 582 0216 289F mul r18,r24 + 583 0218 F001 movw r30,r0 + 584 021a 299F mul r18,r25 + 585 021c F00D add r31,r0 + 586 021e 1124 clr __zero_reg__ + 587 0220 E050 subi r30,lo8(-(ArpTable+4)) + 588 0222 F040 sbci r31,hi8(-(ArpTable+4)) + 589 0224 86E0 ldi r24,lo8(6) + 590 0: + 591 0226 0190 ld r0,Z+ + 592 0228 0D92 st X+,r0 + 593 022a 8A95 dec r24 + 594 022c 01F4 brne 0b + 595 022e 00C0 rjmp .L35 + 596 .L32: + 155:../../../../Lib/net/arp.c **** // TODO MUST CHANGE, but for now, send this one broadcast + 598 .LM46: + 599 0230 86E0 ldi r24,lo8(6) + 600 0232 E0E0 ldi r30,lo8(nicState+2) + 601 0234 F0E0 ldi r31,hi8(nicState+2) + 602 0236 1696 adiw r26,6 + 603 0: + 604 0238 0190 ld r0,Z+ + 605 023a 0D92 st X+,r0 + 606 023c 8A95 dec r24 + 607 023e 01F4 brne 0b + 158:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + 609 .LM47: + 610 0240 46E0 ldi r20,lo8(6) + 611 0242 50E0 ldi r21,0 + 612 0244 6FEF ldi r22,lo8(-1) + 613 0246 70E0 ldi r23,0 + 614 0248 8091 0000 lds r24,nicState+8 + 615 024c 9091 0000 lds r25,nicState+8+1 + 616 0250 0E94 0000 call memset + 617 .L35: + 159:../../../../Lib/net/arp.c **** } + 619 .LM48: + 620 0254 E091 0000 lds r30,nicState+8 + 621 0258 F091 0000 lds r31,nicState+8+1 + 622 025c 88E0 ldi r24,lo8(8) + 623 025e 90E0 ldi r25,0 + 624 0260 9587 std Z+13,r25 + 625 0262 8487 std Z+12,r24 + 626 0264 0895 ret + 631 .Lscope6: + 633 .stabd 78,0,0 + 636 .global arpPrintHeader + 638 arpPrintHeader: + 639 .stabd 46,0,0 + 193:../../../../Lib/net/arp.c **** + 194:../../../../Lib/net/arp.c **** #if ARP_DEBUG + 195:../../../../Lib/net/arp.c **** void arpPrintHeader(FILE *stream, struct netArpHeader* packet) + 196:../../../../Lib/net/arp.c **** { + 641 .LM49: + 642 .LFBB7: + 643 0266 EF92 push r14 + 644 0268 FF92 push r15 + 645 026a 0F93 push r16 + 646 026c 1F93 push r17 + 647 026e CF93 push r28 + 648 0270 DF93 push r29 + 649 /* prologue: function */ + 650 /* frame size = 0 */ + 651 /* stack size = 6 */ + 652 .L__stack_usage = 6 + 653 0272 EC01 movw r28,r24 + 654 0274 8B01 movw r16,r22 + 197:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("ARP Packet:\r\n")); + 656 .LM50: + 657 0276 80E0 ldi r24,lo8(__c.2527) + 658 0278 90E0 ldi r25,hi8(__c.2527) + 659 027a 9F93 push r25 + 660 027c 8F93 push r24 + 661 027e DF93 push r29 + 662 0280 CF93 push r28 + 663 0282 0E94 0000 call fprintf_P + 198:../../../../Lib/net/arp.c **** //debugPrintHexTable(60, (unsigned char*)&packet); + 199:../../../../Lib/net/arp.c **** // print operation type + 200:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("Operation : ")); + 665 .LM51: + 666 0286 80E0 ldi r24,lo8(__c.2529) + 667 0288 90E0 ldi r25,hi8(__c.2529) + 668 028a 9F93 push r25 + 669 028c 8F93 push r24 + 670 028e DF93 push r29 + 671 0290 CF93 push r28 + 672 0292 0E94 0000 call fprintf_P + 201:../../../../Lib/net/arp.c **** if(packet->opcode == htons(ARP_OPCODE_REQUEST)) + 674 .LM52: + 675 0296 F801 movw r30,r16 + 676 0298 E680 ldd r14,Z+6 + 677 029a F780 ldd r15,Z+7 + 678 029c 81E0 ldi r24,lo8(1) + 679 029e 90E0 ldi r25,0 + 680 02a0 0E94 0000 call htons + 681 02a4 2DB7 in r18,__SP_L__ + 682 02a6 3EB7 in r19,__SP_H__ + 683 02a8 285F subi r18,-8 + 684 02aa 3F4F sbci r19,-1 + 685 02ac 0FB6 in __tmp_reg__,__SREG__ + 686 02ae F894 cli + 687 02b0 3EBF out __SP_H__,r19 + 688 02b2 0FBE out __SREG__,__tmp_reg__ + 689 02b4 2DBF out __SP_L__,r18 + 690 02b6 E816 cp r14,r24 + 691 02b8 F906 cpc r15,r25 + 692 02ba 01F4 brne .L37 + 202:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("REQUEST")); + 694 .LM53: + 695 02bc 80E0 ldi r24,lo8(__c.2531) + 696 02be 90E0 ldi r25,hi8(__c.2531) + 697 02c0 00C0 rjmp .L40 + 698 .L37: + 203:../../../../Lib/net/arp.c **** else if(packet->opcode == htons(ARP_OPCODE_REPLY)) + 700 .LM54: + 701 02c2 F801 movw r30,r16 + 702 02c4 E680 ldd r14,Z+6 + 703 02c6 F780 ldd r15,Z+7 + 704 02c8 82E0 ldi r24,lo8(2) + 705 02ca 90E0 ldi r25,0 + 706 02cc 0E94 0000 call htons + 707 02d0 E816 cp r14,r24 + 708 02d2 F906 cpc r15,r25 + 709 02d4 01F4 brne .L39 + 204:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("REPLY")); + 711 .LM55: + 712 02d6 80E0 ldi r24,lo8(__c.2533) + 713 02d8 90E0 ldi r25,hi8(__c.2533) + 714 02da 00C0 rjmp .L40 + 715 .L39: + 205:../../../../Lib/net/arp.c **** else + 206:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("UNKNOWN")); + 717 .LM56: + 718 02dc 80E0 ldi r24,lo8(__c.2535) + 719 02de 90E0 ldi r25,hi8(__c.2535) + 720 .L40: + 721 02e0 9F93 push r25 + 722 02e2 8F93 push r24 + 723 02e4 DF93 push r29 + 724 02e6 CF93 push r28 + 725 02e8 0E94 0000 call fprintf_P + 726 02ec 0F90 pop __tmp_reg__ + 727 02ee 0F90 pop __tmp_reg__ + 728 02f0 0F90 pop __tmp_reg__ + 729 02f2 0F90 pop __tmp_reg__ + 207:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("\r\n")); + 731 .LM57: + 732 02f4 80E0 ldi r24,lo8(__c.2537) + 733 02f6 90E0 ldi r25,hi8(__c.2537) + 734 02f8 9F93 push r25 + 735 02fa 8F93 push r24 + 736 02fc DF93 push r29 + 737 02fe CF93 push r28 + 738 0300 0E94 0000 call fprintf_P + 208:../../../../Lib/net/arp.c **** // print source hardware address + 209:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("SrcHwAddr : ")); netPrintEthAddr(stream, &packet->shwaddr); fprintf_ + 740 .LM58: + 741 0304 80E0 ldi r24,lo8(__c.2539) + 742 0306 90E0 ldi r25,hi8(__c.2539) + 743 0308 9F93 push r25 + 744 030a 8F93 push r24 + 745 030c DF93 push r29 + 746 030e CF93 push r28 + 747 0310 0E94 0000 call fprintf_P + 748 0314 B801 movw r22,r16 + 749 0316 685F subi r22,-8 + 750 0318 7F4F sbci r23,-1 + 751 031a CE01 movw r24,r28 + 752 031c 0E94 0000 call netPrintEthAddr + 753 0320 80E0 ldi r24,lo8(__c.2541) + 754 0322 90E0 ldi r25,hi8(__c.2541) + 755 0324 9F93 push r25 + 756 0326 8F93 push r24 + 757 0328 DF93 push r29 + 758 032a CF93 push r28 + 759 032c 0E94 0000 call fprintf_P + 210:../../../../Lib/net/arp.c **** // print source protocol address + 211:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("SrcProtoAddr: ")); netPrintIPAddr(stream, packet->sipaddr); fprintf_ + 761 .LM59: + 762 0330 80E0 ldi r24,lo8(__c.2543) + 763 0332 90E0 ldi r25,hi8(__c.2543) + 764 0334 9F93 push r25 + 765 0336 8F93 push r24 + 766 0338 DF93 push r29 + 767 033a CF93 push r28 + 768 033c 0E94 0000 call fprintf_P + 769 0340 F801 movw r30,r16 + 770 0342 4685 ldd r20,Z+14 + 771 0344 5785 ldd r21,Z+15 + 772 0346 6089 ldd r22,Z+16 + 773 0348 7189 ldd r23,Z+17 + 774 034a CE01 movw r24,r28 + 775 034c 0E94 0000 call netPrintIPAddr + 776 0350 80E0 ldi r24,lo8(__c.2545) + 777 0352 90E0 ldi r25,hi8(__c.2545) + 778 0354 9F93 push r25 + 779 0356 8F93 push r24 + 780 0358 DF93 push r29 + 781 035a CF93 push r28 + 782 035c 0E94 0000 call fprintf_P + 212:../../../../Lib/net/arp.c **** // print target hardware address + 213:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("DstHwAddr : ")); netPrintEthAddr(stream, &packet->dhwaddr); fprintf_ + 784 .LM60: + 785 0360 80E0 ldi r24,lo8(__c.2547) + 786 0362 90E0 ldi r25,hi8(__c.2547) + 787 0364 9F93 push r25 + 788 0366 8F93 push r24 + 789 0368 DF93 push r29 + 790 036a CF93 push r28 + 791 036c 0E94 0000 call fprintf_P + 792 0370 B801 movw r22,r16 + 793 0372 6E5E subi r22,-18 + 794 0374 7F4F sbci r23,-1 + 795 0376 CE01 movw r24,r28 + 796 0378 0E94 0000 call netPrintEthAddr + 797 037c 80E0 ldi r24,lo8(__c.2549) + 798 037e 90E0 ldi r25,hi8(__c.2549) + 799 0380 9F93 push r25 + 800 0382 8F93 push r24 + 801 0384 DF93 push r29 + 802 0386 CF93 push r28 + 803 0388 0E94 0000 call fprintf_P + 214:../../../../Lib/net/arp.c **** // print target protocol address + 215:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("DstProtoAddr: ")); netPrintIPAddr(stream, packet->dipaddr); fprintf_ + 805 .LM61: + 806 038c 80E0 ldi r24,lo8(__c.2551) + 807 038e 90E0 ldi r25,hi8(__c.2551) + 808 0390 9F93 push r25 + 809 0392 8F93 push r24 + 810 0394 DF93 push r29 + 811 0396 CF93 push r28 + 812 0398 0E94 0000 call fprintf_P + 813 039c 2DB7 in r18,__SP_L__ + 814 039e 3EB7 in r19,__SP_H__ + 815 03a0 205E subi r18,-32 + 816 03a2 3F4F sbci r19,-1 + 817 03a4 0FB6 in __tmp_reg__,__SREG__ + 818 03a6 F894 cli + 819 03a8 3EBF out __SP_H__,r19 + 820 03aa 0FBE out __SREG__,__tmp_reg__ + 821 03ac 2DBF out __SP_L__,r18 + 822 03ae F801 movw r30,r16 + 823 03b0 408D ldd r20,Z+24 + 824 03b2 518D ldd r21,Z+25 + 825 03b4 628D ldd r22,Z+26 + 826 03b6 738D ldd r23,Z+27 + 827 03b8 CE01 movw r24,r28 + 828 03ba 0E94 0000 call netPrintIPAddr + 829 03be 80E0 ldi r24,lo8(__c.2553) + 830 03c0 90E0 ldi r25,hi8(__c.2553) + 831 03c2 9F93 push r25 + 832 03c4 8F93 push r24 + 833 03c6 DF93 push r29 + 834 03c8 CF93 push r28 + 835 03ca 0E94 0000 call fprintf_P + 836 03ce 0F90 pop __tmp_reg__ + 837 03d0 0F90 pop __tmp_reg__ + 838 03d2 0F90 pop __tmp_reg__ + 839 03d4 0F90 pop __tmp_reg__ + 840 /* epilogue start */ + 216:../../../../Lib/net/arp.c **** } + 842 .LM62: + 843 03d6 DF91 pop r29 + 844 03d8 CF91 pop r28 + 845 03da 1F91 pop r17 + 846 03dc 0F91 pop r16 + 847 03de FF90 pop r15 + 848 03e0 EF90 pop r14 + 849 03e2 0895 ret + 851 .Lscope7: + 853 .stabd 78,0,0 + 855 .global arpArpIn + 857 arpArpIn: + 858 .stabd 46,0,0 + 47:../../../../Lib/net/arp.c **** #ifdef ARP_DEBUG + 860 .LM63: + 861 .LFBB8: + 862 03e4 CF93 push r28 + 863 03e6 DF93 push r29 + 864 /* prologue: function */ + 865 /* frame size = 0 */ + 866 /* stack size = 2 */ + 867 .L__stack_usage = 2 + 49:../../../../Lib/net/arp.c **** { + 869 .LM64: + 870 03e8 8091 0000 lds r24,arpDebug + 871 03ec 9091 0000 lds r25,arpDebug+1 + 872 03f0 0097 sbiw r24,0 + 873 03f2 01F0 breq .L43 + 51:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("Received ARP Request\r\n")); + 875 .LM65: + 876 03f4 2091 0000 lds r18,arpDebugLevel + 877 03f8 2230 cpi r18,lo8(2) + 878 03fa 00F0 brlo .L44 + 52:../../../../Lib/net/arp.c **** if (arpDebugLevel > 2) + 880 .LM66: + 881 03fc 20E0 ldi r18,lo8(__c.2488) + 882 03fe 30E0 ldi r19,hi8(__c.2488) + 883 0400 3F93 push r19 + 884 0402 2F93 push r18 + 885 0404 9F93 push r25 + 886 0406 8F93 push r24 + 887 0408 0E94 0000 call fprintf_P + 888 040c 0F90 pop __tmp_reg__ + 889 040e 0F90 pop __tmp_reg__ + 890 0410 0F90 pop __tmp_reg__ + 891 0412 0F90 pop __tmp_reg__ + 892 .L44: + 53:../../../../Lib/net/arp.c **** arpPrintHeader(arpDebug, nicState.layer3.arp); + 894 .LM67: + 895 0414 8091 0000 lds r24,arpDebugLevel + 896 0418 8330 cpi r24,lo8(3) + 897 041a 00F0 brlo .L43 + 54:../../../../Lib/net/arp.c **** } + 899 .LM68: + 900 041c 6091 0000 lds r22,nicState+10 + 901 0420 7091 0000 lds r23,nicState+10+1 + 902 0424 8091 0000 lds r24,arpDebug + 903 0428 9091 0000 lds r25,arpDebug+1 + 904 042c 0E94 0000 call arpPrintHeader + 905 .L43: + 60:../../../../Lib/net/arp.c **** { + 907 .LM69: + 908 0430 E091 0000 lds r30,nicState+10 + 909 0434 F091 0000 lds r31,nicState+10+1 + 910 0438 408D ldd r20,Z+24 + 911 043a 518D ldd r21,Z+25 + 912 043c 628D ldd r22,Z+26 + 913 043e 738D ldd r23,Z+27 + 914 0440 8091 0000 lds r24,IpMyConfig + 915 0444 9091 0000 lds r25,IpMyConfig+1 + 916 0448 A091 0000 lds r26,IpMyConfig+2 + 917 044c B091 0000 lds r27,IpMyConfig+3 + 918 0450 4817 cp r20,r24 + 919 0452 5907 cpc r21,r25 + 920 0454 6A07 cpc r22,r26 + 921 0456 7B07 cpc r23,r27 + 922 0458 01F0 breq .+2 + 923 045a 00C0 rjmp .L41 + 60:../../../../Lib/net/arp.c **** { + 925 .LM70: + 926 045c C681 ldd r28,Z+6 + 927 045e D781 ldd r29,Z+7 + 928 0460 81E0 ldi r24,lo8(1) + 929 0462 90E0 ldi r25,0 + 930 0464 0E94 0000 call htons + 931 0468 C817 cp r28,r24 + 932 046a D907 cpc r29,r25 + 933 046c 01F0 breq .+2 + 934 046e 00C0 rjmp .L41 + 64:../../../../Lib/net/arp.c **** nicState.layer3.arp->dipaddr = nicState.layer3.arp->sipaddr; + 936 .LM71: + 937 0470 C091 0000 lds r28,nicState+10 + 938 0474 D091 0000 lds r29,nicState+10+1 + 939 0478 86E0 ldi r24,lo8(6) + 940 047a FE01 movw r30,r28 + 941 047c 3896 adiw r30,8 + 942 047e DE01 movw r26,r28 + 943 0480 5296 adiw r26,18 + 944 0: + 945 0482 0190 ld r0,Z+ + 946 0484 0D92 st X+,r0 + 947 0486 8A95 dec r24 + 948 0488 01F4 brne 0b + 65:../../../../Lib/net/arp.c **** // fill in our information + 950 .LM72: + 951 048a 8E85 ldd r24,Y+14 + 952 048c 9F85 ldd r25,Y+15 + 953 048e A889 ldd r26,Y+16 + 954 0490 B989 ldd r27,Y+17 + 955 0492 888F std Y+24,r24 + 956 0494 998F std Y+25,r25 + 957 0496 AA8F std Y+26,r26 + 958 0498 BB8F std Y+27,r27 + 67:../../../../Lib/net/arp.c **** nicState.layer3.arp->sipaddr = IpMyConfig.ip; + 960 .LM73: + 961 049a 86E0 ldi r24,lo8(6) + 962 049c E0E0 ldi r30,lo8(nicState+2) + 963 049e F0E0 ldi r31,hi8(nicState+2) + 964 04a0 DE01 movw r26,r28 + 965 04a2 1896 adiw r26,8 + 966 0: + 967 04a4 0190 ld r0,Z+ + 968 04a6 0D92 st X+,r0 + 969 04a8 8A95 dec r24 + 970 04aa 01F4 brne 0b + 68:../../../../Lib/net/arp.c **** // change op to reply + 972 .LM74: + 973 04ac 8091 0000 lds r24,IpMyConfig + 974 04b0 9091 0000 lds r25,IpMyConfig+1 + 975 04b4 A091 0000 lds r26,IpMyConfig+2 + 976 04b8 B091 0000 lds r27,IpMyConfig+3 + 977 04bc 8E87 std Y+14,r24 + 978 04be 9F87 std Y+15,r25 + 979 04c0 A88B std Y+16,r26 + 980 04c2 B98B std Y+17,r27 + 70:../../../../Lib/net/arp.c **** + 982 .LM75: + 983 04c4 82E0 ldi r24,lo8(2) + 984 04c6 90E0 ldi r25,0 + 985 04c8 0E94 0000 call htons + 986 04cc 9F83 std Y+7,r25 + 987 04ce 8E83 std Y+6,r24 + 73:../../../../Lib/net/arp.c **** nicState.layer2.ethHeader->src = nicState.mac; + 989 .LM76: + 990 04d0 A091 0000 lds r26,nicState+8 + 991 04d4 B091 0000 lds r27,nicState+8+1 + 992 04d8 86E0 ldi r24,lo8(6) + 993 04da FD01 movw r30,r26 + 994 04dc 3696 adiw r30,6 + 995 0: + 996 04de 0190 ld r0,Z+ + 997 04e0 0D92 st X+,r0 + 998 04e2 8A95 dec r24 + 999 04e4 01F4 brne 0b + 74:../../../../Lib/net/arp.c **** + 1001 .LM77: + 1002 04e6 A091 0000 lds r26,nicState+8 + 1003 04ea B091 0000 lds r27,nicState+8+1 + 1004 04ee 86E0 ldi r24,lo8(6) + 1005 04f0 E0E0 ldi r30,lo8(nicState+2) + 1006 04f2 F0E0 ldi r31,hi8(nicState+2) + 1007 04f4 1696 adiw r26,6 + 1008 0: + 1009 04f6 0190 ld r0,Z+ + 1010 04f8 0D92 st X+,r0 + 1011 04fa 8A95 dec r24 + 1012 04fc 01F4 brne 0b + 77:../../../../Lib/net/arp.c **** { + 1014 .LM78: + 1015 04fe 8091 0000 lds r24,arpDebug + 1016 0502 9091 0000 lds r25,arpDebug+1 + 1017 0506 0097 sbiw r24,0 + 1018 0508 01F0 breq .L50 + 79:../../../../Lib/net/arp.c **** fprintf_P(arpDebug, PSTR("Sending ARP Reply\r\n")); + 1020 .LM79: + 1021 050a 2091 0000 lds r18,arpDebugLevel + 1022 050e 2223 tst r18 + 1023 0510 01F0 breq .L51 + 80:../../../../Lib/net/arp.c **** if (arpDebugLevel > 2) + 1025 .LM80: + 1026 0512 20E0 ldi r18,lo8(__c.2490) + 1027 0514 30E0 ldi r19,hi8(__c.2490) + 1028 0516 3F93 push r19 + 1029 0518 2F93 push r18 + 1030 051a 9F93 push r25 + 1031 051c 8F93 push r24 + 1032 051e 0E94 0000 call fprintf_P + 1033 0522 0F90 pop __tmp_reg__ + 1034 0524 0F90 pop __tmp_reg__ + 1035 0526 0F90 pop __tmp_reg__ + 1036 0528 0F90 pop __tmp_reg__ + 1037 .L51: + 81:../../../../Lib/net/arp.c **** arpPrintHeader(arpDebug, nicState.layer3.arp); + 1039 .LM81: + 1040 052a 8091 0000 lds r24,arpDebugLevel + 1041 052e 8330 cpi r24,lo8(3) + 1042 0530 00F0 brlo .L50 + 82:../../../../Lib/net/arp.c **** } + 1044 .LM82: + 1045 0532 6091 0000 lds r22,nicState+10 + 1046 0536 7091 0000 lds r23,nicState+10+1 + 1047 053a 8091 0000 lds r24,arpDebug + 1048 053e 9091 0000 lds r25,arpDebug+1 + 1049 0542 0E94 0000 call arpPrintHeader + 1050 .L50: + 86:../../../../Lib/net/arp.c **** } + 1052 .LM83: + 1053 0546 8AE2 ldi r24,lo8(42) + 1054 0548 90E0 ldi r25,0 + 1055 /* epilogue start */ + 88:../../../../Lib/net/arp.c **** + 1057 .LM84: + 1058 054a DF91 pop r29 + 1059 054c CF91 pop r28 + 86:../../../../Lib/net/arp.c **** } + 1061 .LM85: + 1062 054e 0C94 0000 jmp nicSend + 1063 .L41: + 1064 /* epilogue start */ + 88:../../../../Lib/net/arp.c **** + 1066 .LM86: + 1067 0552 DF91 pop r29 + 1068 0554 CF91 pop r28 + 1069 0556 0895 ret + 1071 .Lscope8: + 1073 .stabd 78,0,0 + 1075 .global arpPrintTable + 1077 arpPrintTable: + 1078 .stabd 46,0,0 + 217:../../../../Lib/net/arp.c **** #endif /*ARP_DEBUG*/ + 218:../../../../Lib/net/arp.c **** + 219:../../../../Lib/net/arp.c **** void arpPrintTable(FILE *stream) + 220:../../../../Lib/net/arp.c **** { + 1080 .LM87: + 1081 .LFBB9: + 1082 0558 AF92 push r10 + 1083 055a BF92 push r11 + 1084 055c CF92 push r12 + 1085 055e DF92 push r13 + 1086 0560 EF92 push r14 + 1087 0562 FF92 push r15 + 1088 0564 0F93 push r16 + 1089 0566 1F93 push r17 + 1090 0568 CF93 push r28 + 1091 056a DF93 push r29 + 1092 /* prologue: function */ + 1093 /* frame size = 0 */ + 1094 /* stack size = 10 */ + 1095 .L__stack_usage = 10 + 1096 056c EC01 movw r28,r24 + 221:../../../../Lib/net/arp.c **** uint8_t i; + 222:../../../../Lib/net/arp.c **** + 223:../../../../Lib/net/arp.c **** // print ARP table + 224:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("Time Eth Address IP Address\r\n")); + 1098 .LM88: + 1099 056e 80E0 ldi r24,lo8(__c.2559) + 1100 0570 90E0 ldi r25,hi8(__c.2559) + 1101 0572 9F93 push r25 + 1102 0574 8F93 push r24 + 1103 0576 DF93 push r29 + 1104 0578 CF93 push r28 + 1105 057a 0E94 0000 call fprintf_P + 225:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("-----------------------------------\r\n")); + 1107 .LM89: + 1108 057e 80E0 ldi r24,lo8(__c.2561) + 1109 0580 90E0 ldi r25,hi8(__c.2561) + 1110 0582 9F93 push r25 + 1111 0584 8F93 push r24 + 1112 0586 DF93 push r29 + 1113 0588 CF93 push r28 + 1114 058a 0E94 0000 call fprintf_P + 226:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR(" MY ")); + 1116 .LM90: + 1117 058e 80E0 ldi r24,lo8(__c.2563) + 1118 0590 90E0 ldi r25,hi8(__c.2563) + 1119 0592 9F93 push r25 + 1120 0594 8F93 push r24 + 1121 0596 DF93 push r29 + 1122 0598 CF93 push r28 + 1123 059a 0E94 0000 call fprintf_P + 227:../../../../Lib/net/arp.c **** netPrintEthAddr(stream, &nicState.mac); + 1125 .LM91: + 1126 059e 60E0 ldi r22,lo8(nicState+2) + 1127 05a0 70E0 ldi r23,hi8(nicState+2) + 1128 05a2 CE01 movw r24,r28 + 1129 05a4 0E94 0000 call netPrintEthAddr + 228:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR(" ")); + 1131 .LM92: + 1132 05a8 80E0 ldi r24,lo8(__c.2565) + 1133 05aa 90E0 ldi r25,hi8(__c.2565) + 1134 05ac 9F93 push r25 + 1135 05ae 8F93 push r24 + 1136 05b0 DF93 push r29 + 1137 05b2 CF93 push r28 + 1138 05b4 0E94 0000 call fprintf_P + 229:../../../../Lib/net/arp.c **** netPrintIPAddr(stream, IpMyConfig.ip); + 1140 .LM93: + 1141 05b8 4091 0000 lds r20,IpMyConfig + 1142 05bc 5091 0000 lds r21,IpMyConfig+1 + 1143 05c0 6091 0000 lds r22,IpMyConfig+2 + 1144 05c4 7091 0000 lds r23,IpMyConfig+3 + 1145 05c8 CE01 movw r24,r28 + 1146 05ca 0E94 0000 call netPrintIPAddr + 230:../../../../Lib/net/arp.c **** fprintf_P(stream, PSTR("\r\n")); + 1148 .LM94: + 1149 05ce 80E0 ldi r24,lo8(__c.2567) + 1150 05d0 90E0 ldi r25,hi8(__c.2567) + 1151 05d2 9F93 push r25 + 1152 05d4 8F93 push r24 + 1153 05d6 DF93 push r29 + 1154 05d8 CF93 push r28 + 1155 05da 0E94 0000 call fprintf_P + 1156 05de 00E0 ldi r16,lo8(ArpTable) + 1157 05e0 10E0 ldi r17,hi8(ArpTable) + 1158 05e2 8DB7 in r24,__SP_L__ + 1159 05e4 9EB7 in r25,__SP_H__ + 1160 05e6 4496 adiw r24,20 + 1161 05e8 0FB6 in __tmp_reg__,__SREG__ + 1162 05ea F894 cli + 1163 05ec 9EBF out __SP_H__,r25 + 1164 05ee 0FBE out __SREG__,__tmp_reg__ + 1165 05f0 8DBF out __SP_L__,r24 + 231:../../../../Lib/net/arp.c **** + 232:../../../../Lib/net/arp.c **** for(i=0; ilen[0]) << 8) + BUF->len[1]); +#else /* UIP_CONF_IPV6 */ + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; +#endif /* UIP_CONF_IPV6 */ + + /* First sum pseudoheader. */ + + /* IP protocol and length fields. This addition cannot carry. */ + sum = upper_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (u8_t *)&BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t)); + + /* Sum TCP header and data. */ + sum = chksum(sum, &nicState.layer2.buf[UIP_IPH_LEN + ETH_HEADER_LEN], + upper_layer_len); + + return (sum == 0) ? 0xffff : htons(sum); +} +/*---------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +u16_t +uip_icmp6chksum(void) +{ + return upper_layer_chksum(UIP_PROTO_ICMP6); + +} +#endif /* UIP_CONF_IPV6 */ +/*---------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/Lib/net/dhcp.c b/Lib/net/dhcp.c new file mode 100644 index 0000000..b3dd774 --- /dev/null +++ b/Lib/net/dhcp.c @@ -0,0 +1,300 @@ +/*! \file dhcp.c \brief DHCP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'dhcp.c' +// Title : DHCP Protocol Library +// Author : Pascal Stang +// Created : 9/17/2005 +// Revised : 9/17/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + +#include "global.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "netstack.h" + +#include "dhcp.h" + +#include "rprintf.h" + +// global variables +uint32_t DhcpServerIP; ///< IP address of the DHCP server that offered lease +uint32_t DhcpTransactID; ///< Unique transaction ID that identifies DHCP request/replies +uint32_t DhcpLeaseTime; ///< Number of seconds left in DHCP lease + +void dhcpInit(void) +{ + uint8_t macaddr[6]; + + // get interface mac address + nicGetMacAddress(macaddr); + // set transaction ID based on mac address + DhcpTransactID = *((uint32_t*)&macaddr); + // reset lease time + DhcpLeaseTime = 0; +} + +void dhcpIn(unsigned int len, struct netDhcpHeader* packet) +{ + uint8_t msgtype; + uint32_t sid; + uint8_t* optptr; + uint32_t val; + uint32_t netmask; + uint32_t gateway; + + #if NET_DEBUG >= 3 + dhcpPrintHeader(packet); + #endif + + // check that this is a reply, and for me + if((packet->bootp.op != BOOTP_OP_BOOTREPLY) || (packet->bootp.xid != DhcpTransactID)) + return; + + // process incoming packet + // check reply type + dhcpGetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &msgtype); + #if NET_DEBUG >= 2 + rprintf("DHCP: Received msgtype = %d\r\n", msgtype); + #endif + + if(msgtype == DHCP_MSG_DHCPOFFER) + { + // get DHCP server ID + dhcpGetOption(packet->options, DHCP_OPT_SERVERID, 4, &sid); + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Got offer from server "); netPrintIPAddr(htonl(sid)); rprintfCRLF(); + #endif + + // build DHCP request (on top of this reply) + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + // set operation + val = DHCP_MSG_DHCPREQUEST; + optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + // set the server ID + optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &sid); + // request the IP previously offered + optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.yiaddr); + // request additional information + ((uint8_t*)&val)[0] = DHCP_OPT_NETMASK; + ((uint8_t*)&val)[1] = DHCP_OPT_ROUTERS; + ((uint8_t*)&val)[2] = DHCP_OPT_DNSSERVERS; + ((uint8_t*)&val)[3] = DHCP_OPT_DOMAINNAME; + optptr = dhcpSetOption(optptr, DHCP_OPT_PARAMREQLIST, 4, &val); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending request in response to offer\r\n"); + #endif + // send DHCP request + DhcpServerIP = htonl(sid); + udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+6+6+6+1, (uint8_t*)packet); + + } + else if(msgtype == DHCP_MSG_DHCPACK) + { + // get netmask + dhcpGetOption(packet->options, DHCP_OPT_NETMASK, 4, &val); + netmask = htonl(val); + // get gateway + dhcpGetOption(packet->options, DHCP_OPT_ROUTERS, 4, &val); + gateway = htonl(val); + // get gateway + dhcpGetOption(packet->options, DHCP_OPT_LEASETIME, 4, &val); + DhcpLeaseTime = htonl(val); + + // assign new network info + ipSetConfig(htonl(packet->bootp.yiaddr), netmask, gateway); + + #ifdef DHCP_DEBUG + rprintf("DHCP: Got request ACK, bind complete\r\n"); + //debugPrintHexTable(len-DHCP_HEADER_LEN, (packet->options)); + // print info + ipPrintConfig(ipGetConfig()); + rprintfProgStrM("LeaseTm : "); rprintfNum(10,8,FALSE,' ',DhcpLeaseTime); rprintfCRLF(); + #endif + } +} + +void dhcpRequest(void) +{ + struct netDhcpHeader* packet; + uint32_t val; + + packet = (struct netDhcpHeader*)&netstackGetBuffer()[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]; + + // build BOOTP/DHCP header + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + packet->bootp.htype = BOOTP_HTYPE_ETHERNET; + packet->bootp.hlen = BOOTP_HLEN_ETHERNET; + packet->bootp.ciaddr = htonl(ipGetConfig()->ip); + packet->bootp.yiaddr = HTONL(0l); + packet->bootp.siaddr = HTONL(0l); + packet->bootp.giaddr = HTONL(0l); + nicGetMacAddress(&packet->bootp.chaddr[0]); // fill client hardware address + packet->bootp.xid = DhcpTransactID; + packet->bootp.flags = HTONS(1); + + // build DHCP request + // begin with magic cookie + packet->cookie = 0x63538263; + // set operation + val = DHCP_MSG_DHCPDISCOVER; + dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending Query\r\n"); + //dhcpPrintHeader(packet); + #endif + + // send request + udpSend(0xFFFFFFFF, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+1, (uint8_t*)packet); +} + +void dhcpRelease(void) +{ + struct netDhcpHeader* packet; + uint32_t val; + uint8_t* optptr; + + packet = (struct netDhcpHeader*)&netstackGetBuffer()[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]; + + // build BOOTP/DHCP header + packet->bootp.op = BOOTP_OP_BOOTREQUEST; // request type + packet->bootp.htype = BOOTP_HTYPE_ETHERNET; + packet->bootp.hlen = BOOTP_HLEN_ETHERNET; + packet->bootp.ciaddr = htonl(ipGetConfig()->ip); + packet->bootp.yiaddr = HTONL(0l); + packet->bootp.siaddr = HTONL(0l); + packet->bootp.giaddr = HTONL(0l); + nicGetMacAddress(&packet->bootp.chaddr[0]); // fill client hardware address + packet->bootp.xid = DhcpTransactID; // set trans ID (use part of MAC address) + packet->bootp.flags = HTONS(1); + + // build DHCP request + // begin with magic cookie + packet->cookie = 0x63538263; + // set operation + val = DHCP_MSG_DHCPRELEASE; + optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); + // set the server ID + val = htonl(DhcpServerIP); + optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &val); + // request the IP previously offered + optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.ciaddr); + + #ifdef DHCP_DEBUG + rprintfProgStrM("DHCP: Sending Release to "); netPrintIPAddr(DhcpServerIP); rprintfCRLF(); + //dhcpPrintHeader(packet); + #endif + + // send release + udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_HEADER_LEN+3+6+6+1, (uint8_t*)packet); + + // deconfigure ip addressing + ipSetConfig(0,0,0); + DhcpLeaseTime = 0; +} + +void dhcpTimer(void) +{ + // this function to be called once per second + + // decrement lease time + if(DhcpLeaseTime) + DhcpLeaseTime--; +} + +uint8_t dhcpGetOption(uint8_t* options, uint8_t optcode, uint8_t optlen, void* optvalptr) +{ + uint8_t i; + + // parse for desired option + for (;;) + { + // skip pad characters + if(*options == DHCP_OPT_PAD) + options++; + // break if end reached + else if(*options == DHCP_OPT_END) + break; + // check for desired option + else if(*options == optcode) + { + // found desired option + // limit size to actual option length + optlen = MIN(optlen, *(options+1)); + //if(*(options+1) < optlen) + // optlen = *(options+1); + + // copy contents of option + for(i=0; ibootp.op) + { + case BOOTP_OP_BOOTREQUEST: rprintfProgStrM("BOOTREQUEST"); break; + case BOOTP_OP_BOOTREPLY: rprintfProgStrM("BOOTREPLY"); break; + default: rprintfProgStrM("UNKNOWN"); break; + } + rprintfCRLF(); + // print transaction ID + rprintfProgStrM("XID : 0x"); rprintfu32(packet->bootp.xid); rprintfCRLF(); + // print client IP address + rprintfProgStrM("ClIpAddr: "); netPrintIPAddr(htonl(packet->bootp.ciaddr)); rprintfCRLF(); + // print 'your' IP address + rprintfProgStrM("YrIpAddr: "); netPrintIPAddr(htonl(packet->bootp.yiaddr)); rprintfCRLF(); + // print server IP address + rprintfProgStrM("SvIpAddr: "); netPrintIPAddr(htonl(packet->bootp.siaddr)); rprintfCRLF(); + // print gateway IP address + rprintfProgStrM("GwIpAddr: "); netPrintIPAddr(htonl(packet->bootp.giaddr)); rprintfCRLF(); + // print client hardware address + rprintfProgStrM("ClHwAddr: "); netPrintEthAddr((struct netEthAddr*)packet->bootp.chaddr); rprintfCRLF(); +} +#endif diff --git a/Lib/net/icmp.c b/Lib/net/icmp.c new file mode 100644 index 0000000..dc5806b --- /dev/null +++ b/Lib/net/icmp.c @@ -0,0 +1,123 @@ +/*! \file icmp.c \brief ICMP Protocol Library. */ +//***************************************************************************** +// +// File Name : 'icmp.c' +// Title : ICMP (Internet Control Message Protocol) Protocol Library +// Author : Pascal Stang +// Created : 9/10/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +//***************************************************************************** + + +#include "icmp.h" + + +//extern void nicSend(unsigned int len, unsigned char* packet); + +// global variables + + +// functions +void icmpInit(void) +{ + icmpDebug = NULL; + icmpDebugLevel = 0; +} + +void icmpIpIn(void) +{ + // check ICMP type + switch(nicState.layer4.icmp->type) + { + case ICMP_TYPE_ECHOREQUEST: + icmpEchoRequest(); // echo request + break; + default: +#if ICMP_DEBUG + if (icmpDebug != NULL) + { + if (icmpDebugLevel > 0) + fprintf_P(icmpDebug, PSTR("Unknown ICMP typeReceived ICMP request: ")); + } +#endif + break; + } +} + +void icmpEchoRequest(void) +{ +#if ICMP_DEBUG + if (icmpDebug != NULL) + { + if (icmpDebugLevel > 1) + fprintf_P(icmpDebug, PSTR("Received ICMP request: ")); + } +#endif + uint32_t tempIp; + + // change type to reply + nicState.layer4.icmp->type = ICMP_TYPE_ECHOREPLY; + // recalculate checksum + nicState.layer4.icmp->icmpchksum = 0; + nicState.layer4.icmp->icmpchksum = netChecksum((uint8_t*)(nicState.layer4.icmp), htons(nicState.layer3.ip->len)-IP_HEADER_LEN); + // return to sender + tempIp = nicState.layer3.ip->destipaddr; + nicState.layer3.ip->destipaddr = nicState.layer3.ip->srcipaddr; + nicState.layer3.ip->srcipaddr = tempIp; + // add ethernet routing + arpIpOut(0); + + // debugging + if (icmpDebug != NULL) + icmpPrintHeader(icmpDebug, nicState.layer3.ip, nicState.layer4.icmp); + //debugPrintHexTable(htons(packet->ip.len), (uint8_t*)packet); + + // send it (packet->ip.len+ETH_HEADER_LEN + nicSend(htons(nicState.layer3.ip->len) + ETH_HEADER_LEN); +#if ICMP_DEBUG + if (icmpDebug != NULL) + { + if (icmpDebugLevel > 1) + fprintf_P(icmpDebug, PSTR("Sending ICMP PONG\r\n")); + } +#endif +} + +#if ICMP_DEBUG +void setIcmpDebug(FILE *stream, uint8_t level) +{ + icmpDebug = stream; + icmpDebugLevel = level; +} +#endif + +void icmpPrintHeader(FILE *stream, struct netIpHeader *ipPacket, struct netIcmpHeader *icmpPacket) +{ + fprintf_P(stream, PSTR("ICMP Packet:\r\n")); +// print source IP address + fprintf_P(stream, PSTR("SrcIpAddr: ")); netPrintIPAddr(stream, ipPacket->srcipaddr); fprintf_P(stream, PSTR("\r\n")); +// print dest IP address + fprintf_P(stream, PSTR("DstIpAddr: ")); netPrintIPAddr(stream, ipPacket->destipaddr); fprintf_P(stream, PSTR("\r\n")); +// print type + fprintf_P(stream, PSTR("Type: 0x%x "), icmpPacket->type); +//switch(icmpPacket->type) +//{ +// case ICMP_TYPE_ECHOREQUEST: +// fprintf_P(stream, PSTR("E REQ")); +// break; +// case ICMP_TYPE_ECHOREPLY: +// fprintf_P(stream, PSTR("E REP")); +// break; +// default: +// fprintf_P(stream, ("???")); +// break; +//} +// fprintf_P(stream, PSTR("\r\n")); +// print code + fprintf_P(stream, PSTR("Code : 0x%x\r\n"), icmpPacket->icode); +} + diff --git a/Lib/net/icmp.lst b/Lib/net/icmp.lst new file mode 100644 index 0000000..3db4636 --- /dev/null +++ b/Lib/net/icmp.lst @@ -0,0 +1,580 @@ + 1 .file "icmp.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 164 .global icmpInit + 166 icmpInit: + 167 .stabd 46,0,0 + 1:../../../../Lib/net/icmp.c **** /*! \file icmp.c \brief ICMP Protocol Library. */ + 2:../../../../Lib/net/icmp.c **** //***************************************************************************** + 3:../../../../Lib/net/icmp.c **** // + 4:../../../../Lib/net/icmp.c **** // File Name : 'icmp.c' + 5:../../../../Lib/net/icmp.c **** // Title : ICMP (Internet Control Message Protocol) Protocol Library + 6:../../../../Lib/net/icmp.c **** // Author : Pascal Stang + 7:../../../../Lib/net/icmp.c **** // Created : 9/10/2004 + 8:../../../../Lib/net/icmp.c **** // Revised : 7/3/2005 + 9:../../../../Lib/net/icmp.c **** // Version : 0.1 + 10:../../../../Lib/net/icmp.c **** // Target MCU : Atmel AVR series + 11:../../../../Lib/net/icmp.c **** // Editor Tabs : 4 + 12:../../../../Lib/net/icmp.c **** // + 13:../../../../Lib/net/icmp.c **** //***************************************************************************** + 14:../../../../Lib/net/icmp.c **** + 15:../../../../Lib/net/icmp.c **** + 16:../../../../Lib/net/icmp.c **** #include "icmp.h" + 17:../../../../Lib/net/icmp.c **** + 18:../../../../Lib/net/icmp.c **** + 19:../../../../Lib/net/icmp.c **** //extern void nicSend(unsigned int len, unsigned char* packet); + 20:../../../../Lib/net/icmp.c **** + 21:../../../../Lib/net/icmp.c **** // global variables + 22:../../../../Lib/net/icmp.c **** + 23:../../../../Lib/net/icmp.c **** + 24:../../../../Lib/net/icmp.c **** // functions + 25:../../../../Lib/net/icmp.c **** void icmpInit(void) + 26:../../../../Lib/net/icmp.c **** { + 169 .LM0: + 170 .LFBB1: + 171 /* prologue: function */ + 172 /* frame size = 0 */ + 173 /* stack size = 0 */ + 174 .L__stack_usage = 0 + 27:../../../../Lib/net/icmp.c **** icmpDebug = NULL; + 176 .LM1: + 177 0000 1092 0000 sts icmpDebug+1,__zero_reg__ + 178 0004 1092 0000 sts icmpDebug,__zero_reg__ + 28:../../../../Lib/net/icmp.c **** icmpDebugLevel = 0; + 180 .LM2: + 181 0008 1092 0000 sts icmpDebugLevel,__zero_reg__ + 182 000c 0895 ret + 184 .Lscope1: + 186 .stabd 78,0,0 + 190 .global setIcmpDebug + 192 setIcmpDebug: + 193 .stabd 46,0,0 + 29:../../../../Lib/net/icmp.c **** } + 30:../../../../Lib/net/icmp.c **** + 31:../../../../Lib/net/icmp.c **** void icmpIpIn(void) + 32:../../../../Lib/net/icmp.c **** { + 33:../../../../Lib/net/icmp.c **** // check ICMP type + 34:../../../../Lib/net/icmp.c **** switch(nicState.layer4.icmp->type) + 35:../../../../Lib/net/icmp.c **** { + 36:../../../../Lib/net/icmp.c **** case ICMP_TYPE_ECHOREQUEST: + 37:../../../../Lib/net/icmp.c **** icmpEchoRequest(); // echo request + 38:../../../../Lib/net/icmp.c **** break; + 39:../../../../Lib/net/icmp.c **** default: + 40:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 41:../../../../Lib/net/icmp.c **** if (icmpDebug != NULL) + 42:../../../../Lib/net/icmp.c **** { + 43:../../../../Lib/net/icmp.c **** if (icmpDebugLevel > 0) + 44:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Unknown ICMP typeReceived ICMP request: ")); + 45:../../../../Lib/net/icmp.c **** } + 46:../../../../Lib/net/icmp.c **** #endif + 47:../../../../Lib/net/icmp.c **** break; + 48:../../../../Lib/net/icmp.c **** } + 49:../../../../Lib/net/icmp.c **** } + 50:../../../../Lib/net/icmp.c **** + 51:../../../../Lib/net/icmp.c **** void icmpEchoRequest(void) + 52:../../../../Lib/net/icmp.c **** { + 53:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 54:../../../../Lib/net/icmp.c **** if (icmpDebug != NULL) + 55:../../../../Lib/net/icmp.c **** { + 56:../../../../Lib/net/icmp.c **** if (icmpDebugLevel > 1) + 57:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Received ICMP request: ")); + 58:../../../../Lib/net/icmp.c **** } + 59:../../../../Lib/net/icmp.c **** #endif + 60:../../../../Lib/net/icmp.c **** uint32_t tempIp; + 61:../../../../Lib/net/icmp.c **** + 62:../../../../Lib/net/icmp.c **** // change type to reply + 63:../../../../Lib/net/icmp.c **** nicState.layer4.icmp->type = ICMP_TYPE_ECHOREPLY; + 64:../../../../Lib/net/icmp.c **** // recalculate checksum + 65:../../../../Lib/net/icmp.c **** nicState.layer4.icmp->icmpchksum = 0; + 66:../../../../Lib/net/icmp.c **** nicState.layer4.icmp->icmpchksum = netChecksum((uint8_t*)(nicState.layer4.icmp), htons(nicState.l + 67:../../../../Lib/net/icmp.c **** // return to sender + 68:../../../../Lib/net/icmp.c **** tempIp = nicState.layer3.ip->destipaddr; + 69:../../../../Lib/net/icmp.c **** nicState.layer3.ip->destipaddr = nicState.layer3.ip->srcipaddr; + 70:../../../../Lib/net/icmp.c **** nicState.layer3.ip->srcipaddr = tempIp; + 71:../../../../Lib/net/icmp.c **** // add ethernet routing + 72:../../../../Lib/net/icmp.c **** arpIpOut(0); + 73:../../../../Lib/net/icmp.c **** + 74:../../../../Lib/net/icmp.c **** // debugging + 75:../../../../Lib/net/icmp.c **** if (icmpDebug != NULL) + 76:../../../../Lib/net/icmp.c **** icmpPrintHeader(icmpDebug, nicState.layer3.ip, nicState.layer4.icmp); + 77:../../../../Lib/net/icmp.c **** //debugPrintHexTable(htons(packet->ip.len), (uint8_t*)packet); + 78:../../../../Lib/net/icmp.c **** + 79:../../../../Lib/net/icmp.c **** // send it (packet->ip.len+ETH_HEADER_LEN + 80:../../../../Lib/net/icmp.c **** nicSend(htons(nicState.layer3.ip->len) + ETH_HEADER_LEN); + 81:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 82:../../../../Lib/net/icmp.c **** if (icmpDebug != NULL) + 83:../../../../Lib/net/icmp.c **** { + 84:../../../../Lib/net/icmp.c **** if (icmpDebugLevel > 1) + 85:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Sending ICMP PONG\r\n")); + 86:../../../../Lib/net/icmp.c **** } + 87:../../../../Lib/net/icmp.c **** #endif + 88:../../../../Lib/net/icmp.c **** } + 89:../../../../Lib/net/icmp.c **** + 90:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 91:../../../../Lib/net/icmp.c **** void setIcmpDebug(FILE *stream, uint8_t level) + 92:../../../../Lib/net/icmp.c **** { + 195 .LM3: + 196 .LFBB2: + 197 /* prologue: function */ + 198 /* frame size = 0 */ + 199 /* stack size = 0 */ + 200 .L__stack_usage = 0 + 93:../../../../Lib/net/icmp.c **** icmpDebug = stream; + 202 .LM4: + 203 000e 9093 0000 sts icmpDebug+1,r25 + 204 0012 8093 0000 sts icmpDebug,r24 + 94:../../../../Lib/net/icmp.c **** icmpDebugLevel = level; + 206 .LM5: + 207 0016 6093 0000 sts icmpDebugLevel,r22 + 208 001a 0895 ret + 210 .Lscope2: + 212 .stabd 78,0,0 + 216 .global icmpPrintHeader + 218 icmpPrintHeader: + 219 .stabd 46,0,0 + 95:../../../../Lib/net/icmp.c **** } + 96:../../../../Lib/net/icmp.c **** #endif + 97:../../../../Lib/net/icmp.c **** + 98:../../../../Lib/net/icmp.c **** void icmpPrintHeader(FILE *stream, struct netIpHeader *ipPacket, struct netIcmpHeader *icmpPacket) + 99:../../../../Lib/net/icmp.c **** { + 221 .LM6: + 222 .LFBB3: + 223 001c EF92 push r14 + 224 001e FF92 push r15 + 225 0020 0F93 push r16 + 226 0022 1F93 push r17 + 227 0024 CF93 push r28 + 228 0026 DF93 push r29 + 229 /* prologue: function */ + 230 /* frame size = 0 */ + 231 /* stack size = 6 */ + 232 .L__stack_usage = 6 + 233 0028 EC01 movw r28,r24 + 234 002a 7B01 movw r14,r22 + 235 002c 8A01 movw r16,r20 + 100:../../../../Lib/net/icmp.c **** fprintf_P(stream, PSTR("ICMP Packet:\r\n")); + 237 .LM7: + 238 002e 80E0 ldi r24,lo8(__c.2502) + 239 0030 90E0 ldi r25,hi8(__c.2502) + 240 0032 9F93 push r25 + 241 0034 8F93 push r24 + 242 0036 DF93 push r29 + 243 0038 CF93 push r28 + 244 003a 0E94 0000 call fprintf_P + 101:../../../../Lib/net/icmp.c **** // print source IP address + 102:../../../../Lib/net/icmp.c **** fprintf_P(stream, PSTR("SrcIpAddr: ")); netPrintIPAddr(stream, ipPacket->srcipaddr); fprintf_P( + 246 .LM8: + 247 003e 80E0 ldi r24,lo8(__c.2504) + 248 0040 90E0 ldi r25,hi8(__c.2504) + 249 0042 9F93 push r25 + 250 0044 8F93 push r24 + 251 0046 DF93 push r29 + 252 0048 CF93 push r28 + 253 004a 0E94 0000 call fprintf_P + 254 004e F701 movw r30,r14 + 255 0050 4485 ldd r20,Z+12 + 256 0052 5585 ldd r21,Z+13 + 257 0054 6685 ldd r22,Z+14 + 258 0056 7785 ldd r23,Z+15 + 259 0058 CE01 movw r24,r28 + 260 005a 0E94 0000 call netPrintIPAddr + 261 005e 80E0 ldi r24,lo8(__c.2506) + 262 0060 90E0 ldi r25,hi8(__c.2506) + 263 0062 9F93 push r25 + 264 0064 8F93 push r24 + 265 0066 DF93 push r29 + 266 0068 CF93 push r28 + 267 006a 0E94 0000 call fprintf_P + 103:../../../../Lib/net/icmp.c **** // print dest IP address + 104:../../../../Lib/net/icmp.c **** fprintf_P(stream, PSTR("DstIpAddr: ")); netPrintIPAddr(stream, ipPacket->destipaddr); fprintf_P( + 269 .LM9: + 270 006e 80E0 ldi r24,lo8(__c.2508) + 271 0070 90E0 ldi r25,hi8(__c.2508) + 272 0072 9F93 push r25 + 273 0074 8F93 push r24 + 274 0076 DF93 push r29 + 275 0078 CF93 push r28 + 276 007a 0E94 0000 call fprintf_P + 277 007e F701 movw r30,r14 + 278 0080 4089 ldd r20,Z+16 + 279 0082 5189 ldd r21,Z+17 + 280 0084 6289 ldd r22,Z+18 + 281 0086 7389 ldd r23,Z+19 + 282 0088 CE01 movw r24,r28 + 283 008a 0E94 0000 call netPrintIPAddr + 284 008e 80E0 ldi r24,lo8(__c.2510) + 285 0090 90E0 ldi r25,hi8(__c.2510) + 286 0092 9F93 push r25 + 287 0094 8F93 push r24 + 288 0096 DF93 push r29 + 289 0098 CF93 push r28 + 290 009a 0E94 0000 call fprintf_P + 105:../../../../Lib/net/icmp.c **** // print type + 106:../../../../Lib/net/icmp.c **** fprintf_P(stream, PSTR("Type: 0x%x "), icmpPacket->type); + 292 .LM10: + 293 009e F801 movw r30,r16 + 294 00a0 8081 ld r24,Z + 295 00a2 1F92 push __zero_reg__ + 296 00a4 8F93 push r24 + 297 00a6 80E0 ldi r24,lo8(__c.2512) + 298 00a8 90E0 ldi r25,hi8(__c.2512) + 299 00aa 9F93 push r25 + 300 00ac 8F93 push r24 + 301 00ae DF93 push r29 + 302 00b0 CF93 push r28 + 303 00b2 0E94 0000 call fprintf_P + 107:../../../../Lib/net/icmp.c **** //switch(icmpPacket->type) + 108:../../../../Lib/net/icmp.c **** //{ + 109:../../../../Lib/net/icmp.c **** // case ICMP_TYPE_ECHOREQUEST: + 110:../../../../Lib/net/icmp.c **** // fprintf_P(stream, PSTR("E REQ")); + 111:../../../../Lib/net/icmp.c **** // break; + 112:../../../../Lib/net/icmp.c **** // case ICMP_TYPE_ECHOREPLY: + 113:../../../../Lib/net/icmp.c **** // fprintf_P(stream, PSTR("E REP")); + 114:../../../../Lib/net/icmp.c **** // break; + 115:../../../../Lib/net/icmp.c **** // default: + 116:../../../../Lib/net/icmp.c **** // fprintf_P(stream, ("???")); + 117:../../../../Lib/net/icmp.c **** // break; + 118:../../../../Lib/net/icmp.c **** //} + 119:../../../../Lib/net/icmp.c **** // fprintf_P(stream, PSTR("\r\n")); + 120:../../../../Lib/net/icmp.c **** // print code + 121:../../../../Lib/net/icmp.c **** fprintf_P(stream, PSTR("Code : 0x%x\r\n"), icmpPacket->icode); + 305 .LM11: + 306 00b6 F801 movw r30,r16 + 307 00b8 8181 ldd r24,Z+1 + 308 00ba 1F92 push __zero_reg__ + 309 00bc 8F93 push r24 + 310 00be 80E0 ldi r24,lo8(__c.2514) + 311 00c0 90E0 ldi r25,hi8(__c.2514) + 312 00c2 9F93 push r25 + 313 00c4 8F93 push r24 + 314 00c6 DF93 push r29 + 315 00c8 CF93 push r28 + 316 00ca 0E94 0000 call fprintf_P + 317 00ce 8DB7 in r24,__SP_L__ + 318 00d0 9EB7 in r25,__SP_H__ + 319 00d2 8096 adiw r24,32 + 320 00d4 0FB6 in __tmp_reg__,__SREG__ + 321 00d6 F894 cli + 322 00d8 9EBF out __SP_H__,r25 + 323 00da 0FBE out __SREG__,__tmp_reg__ + 324 00dc 8DBF out __SP_L__,r24 + 325 /* epilogue start */ + 122:../../../../Lib/net/icmp.c **** } + 327 .LM12: + 328 00de DF91 pop r29 + 329 00e0 CF91 pop r28 + 330 00e2 1F91 pop r17 + 331 00e4 0F91 pop r16 + 332 00e6 FF90 pop r15 + 333 00e8 EF90 pop r14 + 334 00ea 0895 ret + 336 .Lscope3: + 338 .stabd 78,0,0 + 340 .global icmpEchoRequest + 342 icmpEchoRequest: + 343 .stabd 46,0,0 + 52:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 345 .LM13: + 346 .LFBB4: + 347 00ec CF93 push r28 + 348 00ee DF93 push r29 + 349 /* prologue: function */ + 350 /* frame size = 0 */ + 351 /* stack size = 2 */ + 352 .L__stack_usage = 2 + 54:../../../../Lib/net/icmp.c **** { + 354 .LM14: + 355 00f0 8091 0000 lds r24,icmpDebug + 356 00f4 9091 0000 lds r25,icmpDebug+1 + 357 00f8 0097 sbiw r24,0 + 358 00fa 01F0 breq .L5 + 56:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Received ICMP request: ")); + 360 .LM15: + 361 00fc 2091 0000 lds r18,icmpDebugLevel + 362 0100 2230 cpi r18,lo8(2) + 363 0102 00F0 brlo .L5 + 57:../../../../Lib/net/icmp.c **** } + 365 .LM16: + 366 0104 20E0 ldi r18,lo8(__c.2488) + 367 0106 30E0 ldi r19,hi8(__c.2488) + 368 0108 3F93 push r19 + 369 010a 2F93 push r18 + 370 010c 9F93 push r25 + 371 010e 8F93 push r24 + 372 0110 0E94 0000 call fprintf_P + 373 0114 0F90 pop __tmp_reg__ + 374 0116 0F90 pop __tmp_reg__ + 375 0118 0F90 pop __tmp_reg__ + 376 011a 0F90 pop __tmp_reg__ + 377 .L5: + 63:../../../../Lib/net/icmp.c **** // recalculate checksum + 379 .LM17: + 380 011c E091 0000 lds r30,nicState+12 + 381 0120 F091 0000 lds r31,nicState+12+1 + 382 0124 1082 st Z,__zero_reg__ + 65:../../../../Lib/net/icmp.c **** nicState.layer4.icmp->icmpchksum = netChecksum((uint8_t*)(nicState.layer4.icmp), htons(nicState.l + 384 .LM18: + 385 0126 E091 0000 lds r30,nicState+12 + 386 012a F091 0000 lds r31,nicState+12+1 + 387 012e 1382 std Z+3,__zero_reg__ + 388 0130 1282 std Z+2,__zero_reg__ + 66:../../../../Lib/net/icmp.c **** // return to sender + 390 .LM19: + 391 0132 E091 0000 lds r30,nicState+10 + 392 0136 F091 0000 lds r31,nicState+10+1 + 393 013a 8281 ldd r24,Z+2 + 394 013c 9381 ldd r25,Z+3 + 395 013e 0E94 0000 call htons + 396 0142 C091 0000 lds r28,nicState+12 + 397 0146 D091 0000 lds r29,nicState+12+1 + 398 014a BC01 movw r22,r24 + 399 014c 6451 subi r22,20 + 400 014e 7109 sbc r23,__zero_reg__ + 401 0150 CE01 movw r24,r28 + 402 0152 0E94 0000 call netChecksum + 403 0156 9B83 std Y+3,r25 + 404 0158 8A83 std Y+2,r24 + 68:../../../../Lib/net/icmp.c **** nicState.layer3.ip->destipaddr = nicState.layer3.ip->srcipaddr; + 406 .LM20: + 407 015a E091 0000 lds r30,nicState+10 + 408 015e F091 0000 lds r31,nicState+10+1 + 409 0162 8089 ldd r24,Z+16 + 410 0164 9189 ldd r25,Z+17 + 411 0166 A289 ldd r26,Z+18 + 412 0168 B389 ldd r27,Z+19 + 69:../../../../Lib/net/icmp.c **** nicState.layer3.ip->srcipaddr = tempIp; + 414 .LM21: + 415 016a 4485 ldd r20,Z+12 + 416 016c 5585 ldd r21,Z+13 + 417 016e 6685 ldd r22,Z+14 + 418 0170 7785 ldd r23,Z+15 + 419 0172 408B std Z+16,r20 + 420 0174 518B std Z+17,r21 + 421 0176 628B std Z+18,r22 + 422 0178 738B std Z+19,r23 + 70:../../../../Lib/net/icmp.c **** // add ethernet routing + 424 .LM22: + 425 017a 8487 std Z+12,r24 + 426 017c 9587 std Z+13,r25 + 427 017e A687 std Z+14,r26 + 428 0180 B787 std Z+15,r27 + 72:../../../../Lib/net/icmp.c **** + 430 .LM23: + 431 0182 60E0 ldi r22,0 + 432 0184 70E0 ldi r23,0 + 433 0186 CB01 movw r24,r22 + 434 0188 0E94 0000 call arpIpOut + 75:../../../../Lib/net/icmp.c **** icmpPrintHeader(icmpDebug, nicState.layer3.ip, nicState.layer4.icmp); + 436 .LM24: + 437 018c 8091 0000 lds r24,icmpDebug + 438 0190 9091 0000 lds r25,icmpDebug+1 + 439 0194 0097 sbiw r24,0 + 440 0196 01F0 breq .L6 + 76:../../../../Lib/net/icmp.c **** //debugPrintHexTable(htons(packet->ip.len), (uint8_t*)packet); + 442 .LM25: + 443 0198 4091 0000 lds r20,nicState+12 + 444 019c 5091 0000 lds r21,nicState+12+1 + 445 01a0 6091 0000 lds r22,nicState+10 + 446 01a4 7091 0000 lds r23,nicState+10+1 + 447 01a8 0E94 0000 call icmpPrintHeader + 448 .L6: + 80:../../../../Lib/net/icmp.c **** #if ICMP_DEBUG + 450 .LM26: + 451 01ac E091 0000 lds r30,nicState+10 + 452 01b0 F091 0000 lds r31,nicState+10+1 + 453 01b4 8281 ldd r24,Z+2 + 454 01b6 9381 ldd r25,Z+3 + 455 01b8 0E94 0000 call htons + 456 01bc 0E96 adiw r24,14 + 457 01be 0E94 0000 call nicSend + 82:../../../../Lib/net/icmp.c **** { + 459 .LM27: + 460 01c2 8091 0000 lds r24,icmpDebug + 461 01c6 9091 0000 lds r25,icmpDebug+1 + 462 01ca 0097 sbiw r24,0 + 463 01cc 01F0 breq .L4 + 84:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Sending ICMP PONG\r\n")); + 465 .LM28: + 466 01ce 2091 0000 lds r18,icmpDebugLevel + 467 01d2 2230 cpi r18,lo8(2) + 468 01d4 00F0 brlo .L4 + 85:../../../../Lib/net/icmp.c **** } + 470 .LM29: + 471 01d6 20E0 ldi r18,lo8(__c.2491) + 472 01d8 30E0 ldi r19,hi8(__c.2491) + 473 01da 3F93 push r19 + 474 01dc 2F93 push r18 + 475 01de 9F93 push r25 + 476 01e0 8F93 push r24 + 477 01e2 0E94 0000 call fprintf_P + 478 01e6 0F90 pop __tmp_reg__ + 479 01e8 0F90 pop __tmp_reg__ + 480 01ea 0F90 pop __tmp_reg__ + 481 01ec 0F90 pop __tmp_reg__ + 482 .L4: + 483 /* epilogue start */ + 88:../../../../Lib/net/icmp.c **** + 485 .LM30: + 486 01ee DF91 pop r29 + 487 01f0 CF91 pop r28 + 488 01f2 0895 ret + 493 .Lscope4: + 495 .stabd 78,0,0 + 497 .global icmpIpIn + 499 icmpIpIn: + 500 .stabd 46,0,0 + 32:../../../../Lib/net/icmp.c **** // check ICMP type + 502 .LM31: + 503 .LFBB5: + 504 /* prologue: function */ + 505 /* frame size = 0 */ + 506 /* stack size = 0 */ + 507 .L__stack_usage = 0 + 34:../../../../Lib/net/icmp.c **** { + 509 .LM32: + 510 01f4 E091 0000 lds r30,nicState+12 + 511 01f8 F091 0000 lds r31,nicState+12+1 + 512 01fc 8081 ld r24,Z + 513 01fe 8830 cpi r24,lo8(8) + 514 0200 01F4 brne .L28 + 37:../../../../Lib/net/icmp.c **** break; + 516 .LM33: + 517 0202 0C94 0000 jmp icmpEchoRequest + 518 .L28: + 41:../../../../Lib/net/icmp.c **** { + 520 .LM34: + 521 0206 8091 0000 lds r24,icmpDebug + 522 020a 9091 0000 lds r25,icmpDebug+1 + 523 020e 0097 sbiw r24,0 + 524 0210 01F0 breq .L18 + 43:../../../../Lib/net/icmp.c **** fprintf_P(icmpDebug, PSTR("Unknown ICMP typeReceived ICMP request: ")); + 526 .LM35: + 527 0212 2091 0000 lds r18,icmpDebugLevel + 528 0216 2223 tst r18 + 529 0218 01F0 breq .L18 + 44:../../../../Lib/net/icmp.c **** } + 531 .LM36: + 532 021a 20E0 ldi r18,lo8(__c.2483) + 533 021c 30E0 ldi r19,hi8(__c.2483) + 534 021e 3F93 push r19 + 535 0220 2F93 push r18 + 536 0222 9F93 push r25 + 537 0224 8F93 push r24 + 538 0226 0E94 0000 call fprintf_P + 539 022a 0F90 pop __tmp_reg__ + 540 022c 0F90 pop __tmp_reg__ + 541 022e 0F90 pop __tmp_reg__ + 542 0230 0F90 pop __tmp_reg__ + 543 .L18: + 544 0232 0895 ret + 546 .Lscope5: + 548 .stabd 78,0,0 + 549 .section .progmem.data,"a",@progbits + 552 __c.2514: + 553 0000 436F 6465 .string "Code : 0x%x\r\n" + 553 2020 203A + 553 2030 7825 + 553 780D 0A00 + 556 __c.2512: + 557 0010 5479 7065 .string "Type: 0x%x " + 557 3A20 3078 + 557 2578 2020 + 557 2020 00 + 560 __c.2510: + 561 001f 0D0A 00 .string "\r\n" + 564 __c.2508: + 565 0022 4473 7449 .string "DstIpAddr: " + 565 7041 6464 + 565 723A 2000 + 568 __c.2506: + 569 002e 0D0A 00 .string "\r\n" + 572 __c.2504: + 573 0031 5372 6349 .string "SrcIpAddr: " + 573 7041 6464 + 573 723A 2000 + 576 __c.2502: + 577 003d 4943 4D50 .string "ICMP Packet:\r\n" + 577 2050 6163 + 577 6B65 743A + 577 0D0A 00 + 580 __c.2491: + 581 004c 5365 6E64 .string "Sending ICMP PONG\r\n" + 581 696E 6720 + 581 4943 4D50 + 581 2050 4F4E + 581 470D 0A00 + 584 __c.2488: + 585 0060 5265 6365 .string "Received ICMP request: " + 585 6976 6564 + 585 2049 434D + 585 5020 7265 + 585 7175 6573 + 588 __c.2483: + 589 0078 556E 6B6E .string "Unknown ICMP typeReceived ICMP request: " + 589 6F77 6E20 + 589 4943 4D50 + 589 2074 7970 + 589 6552 6563 + 590 .comm icmpDebugLevel,1,1 + 591 .comm icmpDebug,2,1 + 592 .comm arpDebugLevel,1,1 + 593 .comm arpDebug,2,1 + 594 .comm IpMyConfig,15,1 + 595 .comm udpDbgLevel,1,1 + 596 .comm udpDbgStream,2,1 + 597 .comm udpSocket,2,1 + 598 .comm nicState,14,1 + 599 .comm wwwport,1,1 + 610 .weak nicSend + 611 .text + 613 .Letext0: + 614 .ident "GCC: (GNU) 4.9.2" + 615 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 icmp.c + /tmp/ccnAFgeb.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccnAFgeb.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccnAFgeb.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccnAFgeb.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccnAFgeb.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccnAFgeb.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccnAFgeb.s:166 .text:0000000000000000 icmpInit + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 icmpDebugLevel + /tmp/ccnAFgeb.s:192 .text:000000000000000e setIcmpDebug + /tmp/ccnAFgeb.s:218 .text:000000000000001c icmpPrintHeader + /tmp/ccnAFgeb.s:576 .progmem.data:000000000000003d __c.2502 + /tmp/ccnAFgeb.s:572 .progmem.data:0000000000000031 __c.2504 + /tmp/ccnAFgeb.s:568 .progmem.data:000000000000002e __c.2506 + /tmp/ccnAFgeb.s:564 .progmem.data:0000000000000022 __c.2508 + /tmp/ccnAFgeb.s:560 .progmem.data:000000000000001f __c.2510 + /tmp/ccnAFgeb.s:556 .progmem.data:0000000000000010 __c.2512 + /tmp/ccnAFgeb.s:552 .progmem.data:0000000000000000 __c.2514 + /tmp/ccnAFgeb.s:342 .text:00000000000000ec icmpEchoRequest + /tmp/ccnAFgeb.s:584 .progmem.data:0000000000000060 __c.2488 + *COM*:000000000000000e nicState + /tmp/ccnAFgeb.s:580 .progmem.data:000000000000004c __c.2491 + /tmp/ccnAFgeb.s:499 .text:00000000000001f4 icmpIpIn + /tmp/ccnAFgeb.s:588 .progmem.data:0000000000000078 __c.2483 + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +fprintf_P +netPrintIPAddr +htons +netChecksum +arpIpOut +nicSend +__do_clear_bss diff --git a/Lib/net/icmp6.c b/Lib/net/icmp6.c new file mode 100644 index 0000000..c497377 --- /dev/null +++ b/Lib/net/icmp6.c @@ -0,0 +1,74 @@ +/** + * @file icmp6.c + * @brief ICMPv6 + * + */ + +#include "icmp6.h" +#include "include/nic.h" +#include "include/icmp6.h" + +/** \brief temporary IP address */ +static uip_ipaddr_t tmp_ipaddr; + + +void vICMP6DebugInit(FILE *stream) +{ + debugStream = stream; +} + +void +uip_icmp6_echo_request_input(void) +{ + /* + * we send an echo reply. It is trivial if there was no extension + * headers in the request otherwise we need to remove the extension + * headers and change a few fields + */ + + fprintf_P(debugStream, PSTR("Echo request\n\r")); + + /* IP header */ + //UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit; + UIP_IP_BUF->ttl = 64; + + /* + if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)){ + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); + uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + } else { + */ + //uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->srcipaddr); + //uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + //uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &tmp_ipaddr); + + memcpy(&tmp_ipaddr, &UIP_IP_BUF->srcipaddr, sizeof(uip_ip6addr_t)); + memcpy(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr, sizeof(uip_ip6addr_t)); + memcpy(&UIP_IP_BUF->destipaddr, &tmp_ipaddr, sizeof(uip_ip6addr_t)); + // } + + //if(uip_ext_len > 0) { + /* If there were extension headers*/ + + + /* Below is important for the correctness of UIP_ICMP_BUF and the + * checksum + * + uip_ext_len = 0; + /* Note: now UIP_ICMP_BUF points to the beginning of the echo reply */ + UIP_ICMP_BUF->type = ICMP6_ECHO_REPLY; + UIP_ICMP_BUF->icode = 0; + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + + return; +} + + + + + + + + diff --git a/Lib/net/include/arp.h b/Lib/net/include/arp.h new file mode 100644 index 0000000..7b683bc --- /dev/null +++ b/Lib/net/include/arp.h @@ -0,0 +1,164 @@ +/** + * @file arp.h + * @version 0.2 + * @brief ARP Protocol Library. + * @ingroup network + * @defgroup arp ARP Protocol Library (arp.c) + * @code #include "net/arp.h" @endcode + * @author Pascal Stang, Adam Kaliszan + * Created : 9/7/2004 + * Revised : 7/3/2005 + * Target MCU : Atmel AVR series + * Editor Tabs: 4 + * + * @par Description + * To send anything over ethernet (or most any other physical network) + * a packet must be addressed to a physical network node address, often + * called a MAC/hardware/ethernet address. This MAC address identifies + * a specific interface (like the ethernet card in your computer) on the + * network. + * ARP (Address Resolution Protocol) assists in mapping IP addresses to + * the MAC addresses required to actually get data to its destination. + * In other words, an IP address is not enough to send information over + * ethernet. You need the MAC address of the network interface/card that + * "owns" that IP address. ARP maintains a table mapping IP addresses to + * MAC addresses. This table can be filled by both listening to + * traffic on the network, as well as making specific ARP requests if + * an IP<->MAC mapping is not in the table. + * + * @note This code is currently below version 1.0, and therefore is considered + * to be lacking in some functionality or documentation, or may not be fully + * tested. Nonetheless, you can expect most functions to work. + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ + +#ifndef ARP_H +#define ARP_H + +#include +#include +#include + +#include "softwareConfig.h" +#include "net.h" +#include "nic.h" +#include "ip.h" + + +#ifndef ARP_TABLE_SIZE +#warning "ARP_TABLE_SIZE not defined in softwareConfig.h file" +#define ARP_TABLE_SIZE 8 +#endif + +#ifndef ARP_CACHE_TIME_TO_LIVE +#warning "ARP_CACHE_TIME_TO_LIVE not defined in softwareConfig.h file" +#define ARP_CACHE_TIME_TO_LIVE 100 +#endif + + + +extern struct ipConfig IpMyConfig; +extern nicState_t nicState; +#if ARP_DEBUG +FILE *arpDebug; +uint8_t arpDebugLevel; +void setArpDebug(FILE *stream, uint8_t level); +#endif /*ARP_DEBUG*/ + + +//@{ +/** + * Initialize ARP system. + * Clears ARP table and prepares it for use. This is typically done + * once at program initialization. + */ +void arpInit(void); + +/** + * Processes incoming ARP packets. + * This function is to be called when an ARP type packet has arrived + * over the network. If the packet type is an ARP request for us, + * an ARP reply will be generated and sent. + */ +void arpArpIn(void); + +/** + * Process incoming IP packets to harvest IP<->MAC relationships. + * This function should be called when IP packets are received over the + * network. It does nothing more than harvest the IP<->MAC address + * relationships from the ethernet and IP header of the packet. The + * packet is not changed nor processed. Nothing is sent on the network. + * Use of this command is not required, but it is a good way to + * automatically fill the ARP table with information about nodes that are + * active on the network. + + * @warning On very busy or heavily populated netorks, this can quickly + * fill the ARP table with unnecessary entries, and/or cause some CPU load. +*/ +void arpIpIn(void); + +/** + * Process outgoing IP packet to fill in ethernet header information. + * + * To be sent on a network, an IP packet must have the correct ethernet + * header information appended to the front. This function will fill + * in this information. + * + * A physical destination IP address argument is needed to support + * sending to a gateway (i.e. when a packet is destined for a node that + * is not on this network, IP addressing is as usual, but we phyiscally + * send the packet to the gateway's ethernet address/interface). + * + * @warning Technically, if an IP<->MAC address mapping is not in the + * ARP table, then the IP packet should be held while an ARP request is + * made, and the reply received. However, in single-threaded ram-limited + * embedded systems, such a holdup is unacceptable. This function instead + * sends the packet as an ethernet broadcast if a mapping cannot be found. + + * \todo Send the packet broadcast AND send an ARP request, if a mapping + * is not found. +*/ +void arpIpOut(uint32_t phyDstIp); + +/** + * Periodic ARP cache maintenance. + * This function is to be called once per second and will slowly + * expire old ARP cache entries. + */ +void arpTimer(void); + +/** + * Check if this IP address is present in the ARP cache. Internal function. + * If IP address is found, function returns index of entry. If not found, + * returns -1. + */ +int arpMatchIp(uint32_t ipaddr); + +#ifdef ARP_DEBUG + +/** + * Enable or disable ARP debug + * @param *stream - output stream + */ +void setArpDebug(FILE *stream, uint8_t level); + +/** + * Print diagnotic information about ARP packet. + * @param *stream - output stream + * @param *packet - arp packet + */ +void arpPrintHeader(FILE *stream, struct netArpHeader* packet); + +/** + * Print diagnotic information about ARP cache. + * @param *stream - output stream + */ +void arpPrintTable(FILE *stream); + +#endif /*ARP_DEBUG*/ + + +#endif +//@} diff --git a/Lib/net/include/checksum.h b/Lib/net/include/checksum.h new file mode 100644 index 0000000..54f20aa --- /dev/null +++ b/Lib/net/include/checksum.h @@ -0,0 +1,68 @@ +#ifndef __UIP_H__ +#define __UIP_H__ + +#include "net.h" +#include "nic.h" +#include "softwareConfig.h" +#include "ipv6.h" + +/** + * Calculate the Internet checksum over a buffer. + * + * The Internet checksum is the one's complement of the one's + * complement sum of all 16-bit words in the buffer. + * + * See RFC1071. + * + * \param buf A pointer to the buffer over which the checksum is to be + * computed. + * + * \param len The length of the buffer over which the checksum is to + * be computed. + * + * \return The Internet checksum of the buffer. + */ +u16_t uip_chksum(u16_t *buf, u16_t len); + +/** + * Calculate the IP header checksum of the packet header in uip_buf. + * + * The IP header checksum is the Internet checksum of the 20 bytes of + * the IP header. + * + * \return The IP header checksum of the IP header in the uip_buf + * buffer. + */ +u16_t uip_ipchksum(void); + +/** + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. + * + * The TCP checksum is the Internet checksum of data contents of the + * TCP segment, and a pseudo-header as defined in RFC793. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +/** + * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. + * + * The UDP checksum is the Internet checksum of data contents of the + * UDP segment, and a pseudo-header as defined in RFC768. + * + * \return The UDP checksum of the UDP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_udpchksum(void); + +/** + * Calculate the ICMP checksum of the packet in uip_buf. + * + * \return The ICMP checksum of the ICMP packet in uip_buf + */ +u16_t uip_icmp6chksum(void); + + +#endif /* __UIP_H__ */ diff --git a/Lib/net/include/icmp.h b/Lib/net/include/icmp.h new file mode 100644 index 0000000..8a5aec4 --- /dev/null +++ b/Lib/net/include/icmp.h @@ -0,0 +1,73 @@ +/** + * @file icmp.h + * @version 0.1 + * @author Pascal Stang, Adam Kaliszan + * @brief ICMP Protocol Library. + * @ingroup network + * @defgroup icmp ICMP Protocol Library (icmp.c) + * @code #include "net/icmp.h" @endcode + * @par Description + * ICMP (Internet Control Message Protocol) has many functions on the + * internet, including the handling of ECHO (ping) requests, relaying + * network route status, passing connection status messages, etc. + * + * This library currently handles only ICMP ECHO requests (ping), but + * may be expanded to include other useful ICMP operations as needed. + * + * Created : 10.09.2004 + * Revised : 28.11.2010 + * Target MCU : Atmel AVR series + * Editor Tabs : 2 + * + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ + +//@{ + +#ifndef ICMP_H +#define ICMP_H + +#include "net.h" +#include "nic.h" +#include "arp.h" + + +#include +#include + +#if ICMP_DEBUG +FILE *icmpDebug; +uint8_t icmpDebugLevel; + +/** + * Enable or disable icmp + * @param *stream - output stream + */ +void setIcmpDebug(FILE *stream, uint8_t level); + +#endif /*ICMP_DEBUG*/ + +/** + * Initialize ICMP protocol library. + */ +void icmpInit(void); + +/** + * Incoming IP packets of protocol ICMP should be passed to this function. + */ +void icmpIpIn(void); + +/** + * Forms and sends a reply in response to an ICMP ECHO request. + */ +void icmpEchoRequest(void); + +/** + * Print ICMP packet information. + */ +void icmpPrintHeader(FILE *stream, struct netIpHeader *ipPacket, struct netIcmpHeader *icmpPacket); + +#endif +//@} diff --git a/Lib/net/include/icmp6.h b/Lib/net/include/icmp6.h new file mode 100644 index 0000000..fb5f244 --- /dev/null +++ b/Lib/net/include/icmp6.h @@ -0,0 +1,167 @@ +#ifndef ICMP6_H +#define ICMP6_H + +/** + * @file icmp6.h + * @brief ICMPv6 + * + */ + + +#include "net.h" +#include "nic.h" +#include "softwareConfig.h" +#include "ipv6.h" +#include "checksum.h" + +#define PRINTF(...) fprintf_P(__VA_ARGS__) +#define PRINTF2(stream, ...) fprintf_P(stream, PSTR(__VA_ARGS__)) +//#define PRINT6ADDR(stream, addr) PRINTF(stream, PSTR("IPv6 addr: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \r\n"), ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15]) + + + + + +extern nicState_t nicState; + +/** \name ICMPv6 message types */ +/** @{ */ +#define ICMP6_DST_UNREACH 1 /**< dest unreachable */ +#define ICMP6_PACKET_TOO_BIG 2 /**< packet too big */ +#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */ +#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */ +#define ICMP6_ECHO_REQUEST 128 /**< Echo request */ +#define ICMP6_ECHO_REPLY 129 /**< Echo reply */ + +#define ICMP6_RS 133 /**< Router Solicitation */ +#define ICMP6_RA 134 /**< Router Advertisement */ +#define ICMP6_NS 135 /**< Neighbor Solicitation */ +#define ICMP6_NA 136 /**< Neighbor advertisement */ +#define ICMP6_REDIRECT 137 /**< Redirect */ +/** @} */ +#define UIP_ND6_OPT_LLAO_LEN 8 + +/** \name ND6 message length (excluding options) */ +/** @{ */ +#define UIP_ND6_NA_LEN 20 +#define UIP_ND6_NS_LEN 20 +/** @} */ + +/** \name ND6 option types */ +/** @{ */ +#define UIP_ND6_OPT_SLLAO 1 +#define UIP_ND6_OPT_TLLAO 2 +#define UIP_ND6_OPT_PREFIX_INFO 3 +#define UIP_ND6_OPT_REDIRECTED_HDR 4 +#define UIP_ND6_OPT_MTU 5 + +/** \brief HOP LIMIT to be used when sending ND messages (255) */ +#define UIP_ND6_HOP_LIMIT 0xff + + +/** \name Neighbor Advertisement flags masks */ +/** @{ */ +#define UIP_ND6_NA_FLAG_ROUTER 0x80 +#define UIP_ND6_NA_FLAG_SOLICITED 0x40 +#define UIP_ND6_NA_FLAG_OVERRIDE 0x20 +/** @} */ + +/** + * \name ND message structures + * @{ + */ + +/** + * \brief A neighbor solicitation constant part + * + * Possible option is: SLLAO + */ +struct uip_nd6_ns { + uint32_t reserved; + uip_ipaddr_t tgtipaddr; +}; + +/** + * \brief A neighbor advertisement constant part. + * + * Possible option is: TLLAO + */ +struct uip_nd6_na { + uint8_t flagsreserved; + uint8_t reserved[3]; + uip_ipaddr_t tgtipaddr; +}; + + +/** + * The sums below are quite used in ND. + */ +//#define uip_l2_l3_hdr_len (ETH_HEADER_LEN + UIP_IPH_LEN + uip_ext_len) +////#define uip_l2_l3_icmp_hdr_len (ETH_HEADER_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) +////#define uip_l3_hdr_len (IP_HEADER_LEN + uip_ext_len) +//#define uip_l2_l3_icmp_hdr_len (ETH_HEADER_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) + +//#define uip_l2_l3_icmp_hdr_len ETH_HEADER_LEN + IP_HEADER_LEN + uip_ext_len + UIP_ICMPH_LEN +#define UIP_ND6_NS_BUF ((struct uip_nd6_ns *)&nicState.layer2.buf[uip_l2_l3_icmp_hdr_len]) + +/** Pointer to ND option */ +#define UIP_ND6_OPT_HDR_BUF ((struct uip_nd6_opt_hdr *)&nicState.layer2.buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) + +//#define UIP_IP_BUF ((struct uip_ip_hdr *)&nicState.layer2.buf[14]) +//#define UIP_ICMP_BUF ((struct uip_icmp6_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_ND6_NA_BUF ((struct uip_nd6_na *)&nicState.layer2.buf[uip_l2_l3_icmp_hdr_len]) + + +/** \brief ND option header */ +struct uip_nd6_opt_hdr { + u8_t type; + u8_t len; +}; + +/** \brief ND option: both TLLAO and SLLAO */ +struct uip_nd6_opt_llao { + u8_t type; + u8_t len; + struct netEthAddr addr; +}; + + +/** + * The length of the extension headers + */ +extern uint8_t uip_ext_len; + + + +/** \name ICMPv6 RFC4443 Message processing and sending */ +/** @{ */ +/** \ + * brief Process an echo request + * + * Perform a few checks, then send an Echop reply. The reply is + * built here. + */ +void +uip_icmp6_echo_request_input(void); + +/** + * \brief Send an icmpv6 error message + * \param type type of the Error message + * \param code of the error message + * \param type 32 bit parameter of the error message, semantic depends on error + */ +//void uip_icmp6_error_output(u8_t type, u8_t code, uint32_t param); + + + +#if ICMP6_DEBUG +/** Debug Network Discovery */ +FILE *debugStream; + +/** Assign debug stram */ +void vICMP6DebugInit(FILE *stream); + +#endif /**ICMP6_DEBUG*/ + + +#endif/**ICMP6_H*/ \ No newline at end of file diff --git a/Lib/net/include/ip.h b/Lib/net/include/ip.h new file mode 100644 index 0000000..23acbae --- /dev/null +++ b/Lib/net/include/ip.h @@ -0,0 +1,136 @@ +/** + * @file ip.h + * @version 0.2 + * @brief IP (Internet Protocol) Library. + * @author Pascal Stang, Adam Kaliszan + * @ingroup network + * @defgroup ip IP (Internet Protocol) Library (ip.c) + * @code #include "net/ip.h" \endcode + * @par Description + * The IP (Internet Protocol) library provide support for sending IP and + * IP-related packets. It's not clear if additional features are needed + * or will be added, or even if this is the proper way to facilitate IP + * packet operations. + * Created : 30.08.2004 + * Revised : 28/11.2010 + * Target MCU : Atmel AVR series + * Editor Tabs : 2 + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ +#ifndef IP_H +#define IP_H + +#include +#include +#include + +#include "softwareConfig.h" +#include "net.h" +#include "icmp.h" +#include "nic.h" +#include "arp.h" +#include "udp.h" + + +//@{ +/** + * IP addressing/configuration structure + */ +struct ipConfig +{ + uint32_t ip; ///< IP address + uint32_t netmask; ///< netmask + uint32_t gateway; ///< gateway IP address + +#if IP_DEBUG + FILE* dbgStream; ///debug stream + uint8_t dbgLevel; +#endif +}; + +struct ipConfig IpMyConfig; ///< Local IP address/config structure +extern nicState_t nicState; + +#define IP_TIME_TO_LIVE 128 ///< default Time-To-Live (TTL) value to use in IP headers + + +#if IP_DEBUG +/** + * Enable or disable debug stream + * @param *stream - output stream. Do not use network stream. NULL value disable debug stream + * @param level - level of sending details (0-3) + */ +void setIpDebug(FILE *stream, uint8_t level); +#endif + + +void ipInit(void); +/** + * Read Ip config + * Initializes ARP + */ +void ipLoadConfig(void); + +/** + * Save Ip config + */ +void ipSaveConfig(void); + + +/** + * Process Ip v4 packet + */ +void netstackIPv4Process(void); + + + +/** + * Set our IP address and routing information. + * The myIp value will be used in the source field of IP packets. + * Use this function to set and reset the system IP address. + * @param myIp - local IP address + * @param netmask - 32 bit network mask + * @param gatewayIp - default gateway + */ +void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp); + +/** + * @param myIp - ip Address + */ +void ipSetConfigIp(uint32_t myIp); + +/** + * @param netmask - 32 bit network mask + */ +void ipSetConfigMask(uint32_t netmask); + +/** + * @param gatewayIp - default gateway + */ +void ipSetConfigGw(uint32_t gatewayIp); + +/** + * Get our local IP configuration. + * @return pointer to current IP address/configuration. + */ +struct ipConfig* ipGetConfig(void); + +/** + * Print IP configuration + * @param straem - input stream + * @param *config - pointer to IP config struct + */ +void ipPrintConfig(FILE *stream, struct ipConfig* config); + + +/** + * Send an IP packet. + */ +void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len); + + +#endif +//@} + diff --git a/Lib/net/include/ipv6-nd.h b/Lib/net/include/ipv6-nd.h new file mode 100644 index 0000000..7b514c6 --- /dev/null +++ b/Lib/net/include/ipv6-nd.h @@ -0,0 +1,50 @@ +#ifndef IPV6_ND_H +#define IPV6_ND_H + +/** + * @file ipv6-nd.h + * @brief IP Network Discovery + * + * Please Notice, that we do have a fwe strategies - Router Discovery/Solicitation, Neighbour Discovery/Solicitation + * For now, only Neighbour Discovery is implemented + */ + +#include "ipv6.h" +#include "softwareConfig.h" + +#define uip_eth_addr netEthAddr //tymczasowo, docelowo zamien na zmienna z liku net.h +#define MAX_TIME 128 +#define ENTRIES 8 + +#define UIP_ND6_REACHABLE_TIME 30000 +#define UIP_ND6_RETRANS_TIMER 1000 + + +typedef struct { + uip_ipaddr_t ipaddr; + struct netEthAddr addr; + uint32_t time; ///Idea - reference time measuerd in "tick count" +}neighbor_entry; + +neighbor_entry* entries; + + +void vNDinit(void); //init ND cache + +//void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct netEthAddr *addr); + +//neighbor_entry * find_entry(uip_ipaddr_t *ipaddr); + +void uip_nd6_io_ns_input(uint16_t packetLenght); + +#if IP_DEBUG +/** Debug Network Discovery */ +FILE *debugStream; + +/** Assign debug stram */ +void vNDDebugInit(FILE *stream); + +#endif /**ND_DEBUG*/ + + +#endif /**IPV6_ND_H*/ \ No newline at end of file diff --git a/Lib/net/include/ipv6.h b/Lib/net/include/ipv6.h new file mode 100644 index 0000000..5eeb883 --- /dev/null +++ b/Lib/net/include/ipv6.h @@ -0,0 +1,255 @@ +#ifndef IPV6_H +#define IPV6_H 1 + +/** + * Definicja zmiennych potrzebnych do obsÅ‚ugi IPv6 + * (część deklaracji może siÄ™ znajdować w pliku net.h i nic.h) + * + */ + +#include +#include +#include +#include +#include +#include "net.h" +#include "nic.h" +#include "softwareConfig.h" +#include "ip.h" +#include "ipv6Conf.h" +#include "uip-netif.h" +#include "icmp6.h" +#include "ipv6-nd.h" + +#if IPV6_SUPPORT + +/** Kompatybilność ze stosem Adama Kaliszana*/ +#define UIP_PROTO_ICMP IP_PROTO_ICMP //1 +#define UIP_PROTO_TCP IP_PROTO_TCP //6 +#define UIP_PROTO_UDP IP_PROTO_UDP //17 +#define UIP_PROTO_ICMP6 58 +#define UIP_LLADDR_LEN 6 //MAC 48 bit + +#define UIP_TTL IP_TIME_TO_LIVE + +#define PRINTF(...) fprintf_P(__VA_ARGS__) +#define PRINT6ADDR(stream, addr) PRINTF(stream, PSTR("\tIPv6 addr: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \r\n"),((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) + +/* + * IP addressing/configuration structure + +struct ipv6Config +{ + uip_ip6addr_t *ip; ///< IPv6 address + uint8_t prefix; ///< netmask (prefix) + uip_ip6addr_t *gateway; ///< gateway IPv6 address +}; */ + +typedef struct netEthAddr uip_lladdr_t; + +//struct ipv6Config Ipv6MyConfig; ///< Local IP address/config structure +extern struct uip_netif *uip_netif_physical_if; ///< Local IP address/config structure +extern nicState_t nicState; + +#if IP_DEBUG +FILE *debugStream; +#endif /*IP_DEBUG*/ + +/** + * \brief length of the extension headers read. updated each time we process + * a header + */ +uint8_t uip_ext_len; +/** \brief length of the header options read */ +uint8_t uip_ext_opt_offset; + +/** + * The sums below are quite used in ND. When used for uip_buf, we + * include link layer length when used for uip_len, we do not, hence + * we need values with and without LLH_LEN we do not use capital + * letters as these values are variable + */ +#define UIP_LLH_LEN ETH_HEADER_LEN +#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len) +#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) +#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len) +#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) + +/*---------------------------------------------------------------------------*/ +/* Buffers */ +/*---------------------------------------------------------------------------*/ +//#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) +#define UIP_IP_BUF ((struct uip_ipv6_hdr *)&nicState.layer2.buf[UIP_LLH_LEN]) +#define UIP_ICMP_BUF ((struct uip_icmp6_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_TCP_BUF ((struct netTcpHeader *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_EXT_BUF ((struct uip_ext_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_FRAG_BUF ((struct uip_frag_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_DESTO_BUF ((struct uip_desto_hdr *)&nicState.layer2.buf[uip_l2_l3_hdr_len]) +#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&nicState.layer2.buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) +#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&nicState.layer2.buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) +#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&nicState.layer2.buf[uip_l2_l3_icmp_hdr_len]) + +/** + * Construct an IPv6 address from eight 16-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ + (addr)->u16[0] = HTONS(addr0); \ + (addr)->u16[1] = HTONS(addr1); \ + (addr)->u16[2] = HTONS(addr2); \ + (addr)->u16[3] = HTONS(addr3); \ + (addr)->u16[4] = HTONS(addr4); \ + (addr)->u16[5] = HTONS(addr5); \ + (addr)->u16[6] = HTONS(addr6); \ + (addr)->u16[7] = HTONS(addr7); \ + } while(0) + +/** + * Construct an IPv6 address from eight 8-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr_u8(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8,addr9,addr10,addr11,addr12,addr13,addr14,addr15) do { \ + (addr)->u8[0] = addr0; \ + (addr)->u8[1] = addr1; \ + (addr)->u8[2] = addr2; \ + (addr)->u8[3] = addr3; \ + (addr)->u8[4] = addr4; \ + (addr)->u8[5] = addr5; \ + (addr)->u8[6] = addr6; \ + (addr)->u8[7] = addr7; \ + (addr)->u8[8] = addr8; \ + (addr)->u8[9] = addr9; \ + (addr)->u8[10] = addr10; \ + (addr)->u8[11] = addr11; \ + (addr)->u8[12] = addr12; \ + (addr)->u8[13] = addr13; \ + (addr)->u8[14] = addr14; \ + (addr)->u8[15] = addr15; \ + } while(0) + +/** + * Compare two IP addresses + * + * Compares two IP addresses. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * + * \hideinitializer + */ +#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) + +/** + * Compare two IP addresses with netmasks + * + * Compares two IP addresses with netmasks. The masks are used to mask + * out the bits that are to be compared. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, mask; + + uip_ipaddr(&mask, 255,255,255,0); + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&ipaddr2, 192,16,1,3); + if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0) + +/** + * Process Ip v6 packet + */ +void netstackIPv6Process(void); + +/** + * Switch src->dest, src=nic.mac. + */ +void swithEthAddresses(void); + +/** + * Init an IPv6 packet. + */ +void ipv6Init(void); + +/** + * Check IPv6 packet length. + */ +uint8_t checkPacketLen(void); + +/** + * @param myIp - ipv6 Address + */ +void ipSetConfigIpv6(uint32_t myIp); + +/** + * Get our local IPv6 configuration. + * @return pointer to current IPv6 address/configuration. + */ +//struct ipv6Config* ipv6GetConfig(void); + +/** + * Print IPv6 configuration + * @param straem - input stream + * @param *config - pointer to IPv6 config struct + */ +void ipv6PrintConfig(FILE *stream, struct uip_netif* config); + +/** + * Send an IPv6 packet. + */ +void ipv6Send(uint8_t protocol, uint16_t len); + + + +#if IP_DEBUG +/** + * Init debug stram + */ +void ipv6DebugInit(FILE *inDebugStream); + +/** + * Print IPv6 header information. + */ +void netPrintIpv6Header(FILE *stream); + +/** + * Print IPv6 header information. (Raw bits - hex format) + */ +void netPrintIpv6HeaderRAW(FILE *stream); + +/** + * Print IPv6 payload. (Raw bits - hex format) + */ +void netPrintIpv6PayloadRAW(FILE *stream); +#endif /*IP_DEBUG*/ + +#endif /* IPV6_SUPPORT */ +#endif /*IPV6_H*/ \ No newline at end of file diff --git a/Lib/net/include/ipv6Conf.h b/Lib/net/include/ipv6Conf.h new file mode 100644 index 0000000..87d2abe --- /dev/null +++ b/Lib/net/include/ipv6Conf.h @@ -0,0 +1,47 @@ +/** + * Konfiguracja protokoÅ‚u IPv6 + * + */ + + +/** IPv6 support - add UIP_CONF_IPV6 flag for compatibility with uip Adam Dunkel project*/ +#if IPV6_SUPPORT +#define UIP_CONF_IPV6 1 +#else +#define UIP_CONF_IPV6 0 +#endif + +#if UIP_CONF_IPV6 + +/** Types compatibility */ +#define u8_t uint8_t +#define u16_t uint16_t + +/** + * The size of the uIP packet buffer. + * + * The uIP packet buffer should not be smaller than 60 bytes, and does + * not need to be larger than 1514 bytes. Lower size results in lower + * TCP throughput, larger size results in higher TCP throughput. + * + * \hideinitializer + */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN +#else /* UIP_CONF_BUFFER_SIZE */ +#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE +#endif /* UIP_CONF_BUFFER_SIZE */ + +/** The maximum transmission unit at the IP Layer*/ +#define UIP_LINK_MTU 1280 + +#ifndef UIP_LITTLE_ENDIAN +#define UIP_LITTLE_ENDIAN 3412 +#endif /* UIP_LITTLE_ENDIAN */ +#ifndef UIP_BIG_ENDIAN +#define UIP_BIG_ENDIAN 1234 +#endif /* UIP_BIG_ENDIAN */ + + + +#endif /* UIP_CONF_IPV6 */ \ No newline at end of file diff --git a/Lib/net/include/net.h b/Lib/net/include/net.h new file mode 100644 index 0000000..e2905c4 --- /dev/null +++ b/Lib/net/include/net.h @@ -0,0 +1,340 @@ +/** + * @file net.c + * @author Pascal Stang, Adam Kaliszan + * @brief Network support library. + * @version 0.2 + * Created 30.08.2004 + * Revised 25.11.2010 + * Editor Tabs 2 + + * @ingroup network + * @defgroup net Network support library (net.c) + * @code #include "net/net.h" \endcode + * @par Description + * This is a general network support library including a multitude of + * structure definitions for various types of network packets, functions + * and macros for switching byte order, and an RFC-compliant function + * for calculating checksums. + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ + + +#ifndef NET_H +#define NET_H + +#include +#include +#include +// #include "ipv6Conf.h" +#include "softwareConfig.h" + +// ******* ETH ******* +#define ETH_HEADER_LEN 14 +// values of certain bytes: +#define ETHTYPE_ARP_H_V 0x08 +#define ETHTYPE_ARP_L_V 0x06 +#define ETHTYPE_IP_H_V 0x08 +#define ETHTYPE_IP_L_V 0x00 +// byte positions in the ethernet frame: +// +// Ethernet type field (2bytes): +#define ETH_TYPE_H_P 12 +#define ETH_TYPE_L_P 13 +// +#define ETH_DST_MAC 0 +#define ETH_SRC_MAC 6 + + +// ******* ARP ******* +#define ETH_ARP_OPCODE_REPLY_H_V 0x0 +#define ETH_ARP_OPCODE_REPLY_L_V 0x02 +// +#define ETHTYPE_ARP_L_V 0x06 +// arp.dst.ip +#define ETH_ARP_DST_IP_P 0x26 +// arp.opcode +#define ETH_ARP_OPCODE_H_P 0x14 +#define ETH_ARP_OPCODE_L_P 0x15 +// arp.src.mac +#define ETH_ARP_SRC_MAC_P 0x16 +#define ETH_ARP_SRC_IP_P 0x1c +#define ETH_ARP_DST_MAC_P 0x20 +#define ETH_ARP_DST_IP_P 0x26 + + +// ******* ICMP ******* +#define ICMP_TYPE_ECHOREPLY_V 0 +#define ICMP_TYPE_ECHOREQUEST_V 8 +// +#define ICMP_TYPE_P 0x22 +#define ICMP_CHECKSUM_P 0x24 + +// ******* UDP ******* +#define UDP_HEADER_LEN 8 +// +#define UDP_SRC_PORT_H_P 0x22 +#define UDP_SRC_PORT_L_P 0x23 +#define UDP_DST_PORT_H_P 0x24 +#define UDP_DST_PORT_L_P 0x25 +// +#define UDP_LEN_H_P 0x26 +#define UDP_LEN_L_P 0x27 +#define UDP_CHECKSUM_H_P 0x28 +#define UDP_CHECKSUM_L_P 0x29 +#define UDP_DATA_P 0x2a + +#define GNUC_PACKED + +//@{ +/** + * Representation of a 48-bit Ethernet address. + */ +//@} +struct netEthAddr +{ + uint8_t addr[6]; +} GNUC_PACKED; + +/// The Ethernet header +struct netEthHeader +{ + struct netEthAddr dest; + struct netEthAddr src; + uint16_t type; +} GNUC_PACKED; + + +#define ETHTYPE_ARP 0x0806 +#define ETHTYPE_IP 0x0800 +#define ETHTYPE_IP6 0x86dd + +/// The ARP header +struct netArpHeader +{ + uint16_t hwtype; + uint16_t protocol; + uint8_t hwlen; + uint8_t protolen; + uint16_t opcode; + struct netEthAddr shwaddr; + uint32_t sipaddr; + struct netEthAddr dhwaddr; + uint32_t dipaddr; +} GNUC_PACKED; + +#define ARP_OPCODE_REQUEST 1 +#define ARP_OPCODE_REPLY 2 +#define ARP_HWTYPE_ETH 1 + +/// The IP header +struct netIpHeader +{ + uint8_t vhl; + uint8_t tos; + uint16_t len; + uint16_t ipid; + uint16_t ipoffset; + uint8_t ttl; + uint8_t proto; + uint16_t ipchksum; + uint32_t srcipaddr; + uint32_t destipaddr; +} GNUC_PACKED; +#define IP_HEADER_LEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 + +#define IP_SRC_P 0x1a +#define IP_DST_P 0x1e +#define IP_HEADER_LEN_VER_P 0xe +#define IP_CHECKSUM_P 0x18 +#define IP_TTL_P 0x16 +#define IP_FLAGS_P 0x14 +#define IP_P 0xe +#define IP_TOTLEN_H_P 0x10 +#define IP_TOTLEN_L_P 0x11 + +#define IP_PROTO_P 0x17 + +#ifdef IPV6_SUPPORT + /**The IPv6 */ + + typedef union uip_ip6addr_t { + uint8_t u8[16]; /* Initializer, must come first!!! */ + uint16_t u16[8]; + } uip_ip6addr_t; + typedef uip_ip6addr_t uip_ipaddr_t; + + /** + * In IPv6 the length of the L3 headers before the transport header is + * not fixed, due to the possibility to include extension option headers + * after the IP header. hence we split here L3 and L4 headers + */ + /* The IPv6 header */ + struct uip_ipv6_hdr { + uint8_t vtc; + uint8_t tcflow; + uint16_t flow; + uint8_t len[2]; + uint8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; + }; + #define UIP_IPv6H_LEN 40 + #define UIP_IPH_LEN UIP_IPv6H_LEN + #define UIP_FRAGH_LEN 8 + + /** The ICMPv6 header. */ + struct uip_icmp6_hdr { + uint8_t type, icode; + uint16_t icmpchksum; + }; + #define IPV6_ICMPH_LEN 4 /* Size of ICMPv6 header */ + #define UIP_ICMPH_LEN IPV6_ICMPH_LEN + +#endif /*IPV6_SUPPORT*/ + + +/// The ICMP header +struct netIcmpHeader +{ + uint8_t type; + uint8_t icode; + uint16_t icmpchksum; + uint16_t id; + uint16_t seqno; +} GNUC_PACKED; +#define ICMP_HEADER_LEN 8 + +#define ICMP_TYPE_ECHOREPLY 0 +#define ICMP_TYPE_ECHOREQUEST 8 + +/// The UDP header +struct netUdpHeader +{ + uint16_t srcport; + uint16_t destport; + uint16_t udplen; + uint16_t udpchksum; +} GNUC_PACKED; +#define UDP_HEADER_LEN 8 + +/// The TCP header +struct netTcpHeader +{ + uint16_t srcport; + uint16_t destport; + uint32_t seqno; + uint32_t ackno; + uint8_t tcpoffset; + uint8_t flags; + uint16_t wnd; + uint16_t tcpchksum; + uint16_t urgp; +//uint8_t optdata[4]; +} GNUC_PACKED; +#define TCP_HEADER_LEN 20 + +#define TCP_FLAGS_FIN 0x01 +#define TCP_FLAGS_SYN 0x02 +#define TCP_FLAGS_RST 0x04 +#define TCP_FLAGS_PSH 0x08 +#define TCP_FLAGS_ACK 0x10 +#define TCP_FLAGS_URG 0x20 +#define TCP_FLAGS_ECE 0x40 //ECN-Echo +#define TCP_FLAGS_CWR 0x80 //Congestion Window Reduced + + +// the tcp seq number is 4 bytes 0x26-0x29 +//#define TCP_SEQ_H_P 0x26 +//#define TCP_SEQACK_H_P 0x2a +// flags: SYN=2 + +// plain len without the options: +//#define TCP_HEADER_LEN_PLAIN 20 +//#define TCP_HEADER_LEN_P 0x2e +//#define TCP_CHECKSUM_H_P 0x32 +//#define TCP_CHECKSUM_L_P 0x33 +//#define TCP_OPTIONS_P 0x36 +// + + +/** + * Ethernet/ARP header + */ + + +// The UDP and IP headers +typedef struct +{ + struct netIpHeader ip; + struct netUdpHeader udp; +} udpip_hdr; + +//@{ +//! Convert dot-notation IP address into 32-bit word. +/// Example: IPDOT(192l,168l,1l,1l) +#define IPDOT(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d)) + +//! Host-to-Network SHORT (16-bit) byte-order swap (macro). +#define HTONS(s) ((s<<8) | (s>>8)) +//! Host-to-Network LONG (32-bit) byte-order swap (macro). +#define HTONL(l) ((l<<24) | ((l&0x00FF0000l)>>8) | ((l&0x0000FF00l)<<8) | (l>>24)) + + +/** + * Host-to-Network SHORT (16-bit) byte-order swap (function). + */ +uint16_t htons(uint16_t val); + + +uint16_t ntohs(uint16_t val); + + +/** + * Host-to-Network LONG (32-bit) byte-order swap (function). + */ +uint32_t htonl(uint32_t val); + + +uint32_t ntohl(uint32_t val); + + +/** + * Calculate IP-style checksum from data. + */ +uint16_t netChecksum(uint8_t *data, uint16_t len); + +/** + * Print Ethernet address in XX:XX:XX:XX:XX:XX format. + */ +void netPrintEthAddr(FILE *stream, struct netEthAddr *ethaddr); + +/** + * Print IP address in dot notation. + * @param *stream - output stream + * @param ip_hdr - ipAddress stored in network order + */ +void netPrintIPAddr(FILE *stream, uint32_t ipaddr); + +/** + * Print Ethernet header information. + */ +void netPrintEthHeader(FILE *stream, struct netEthHeader* eth_hdr); + +/** + * Print IP header information. + */ +void netPrintIpHeader(FILE *stream, struct netIpHeader* ipheader); + +/** + * Print TCP header information. + */ +void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader); + +#endif +//@} + diff --git a/Lib/net/include/nic.h b/Lib/net/include/nic.h new file mode 100644 index 0000000..2310ee5 --- /dev/null +++ b/Lib/net/include/nic.h @@ -0,0 +1,138 @@ +/** + * @file nic.h + * @version 0.2 + * @brief Network Interface Card (NIC) software definition. + * @ingroup network + * @author Pascal Stang, Adam Kaliszan + * @defgroup nic Network Interface Card (NIC) software definition (nic.h) + * @code #include "net/nic.h" @endcode + * @par Description + * This is the software interface standard for network interface hardware + * as used by AVRlib. Drivers for network hardware must implement these + * functions to allow upper network layers to initialize the interface, + * and send and receive net traffic. + * + * Editor Tabs : 4 + * Target MCU : Atmel AVR series + * Created : 22.08.2004 + * Revised : 28.11.2010 + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ +//@{ + +#ifndef NIC_H +#define NIC_H + +#include +#include +#include +#include + +#include "net.h" +#include +#include "hardwareConfig.h" +#include "softwareConfig.h" + +typedef struct +{ + uint16_t bufferSize; /// rozmiar tablicy pamiÄ™ci z buforem + struct netEthAddr mac; + + union + { + uint8_t *buf; + struct netEthHeader *ethHeader; + } layer2; + + union + { + struct netArpHeader *arp; + struct netIpHeader *ip; + #if IPV6_SUPPORT + struct uip_ipv6_hdr *ipv6; + uint8_t *buf; //Pointer on layer3 + #endif + } layer3; + + union + { + struct netIcmpHeader *icmp; + struct netTcpHeader *tcp; + struct netUdpHeader *udp; + //#if IPV6_SUPPORT + //struct uip_icmp6_hdr *icmpv6; //in ipv6 "header length" before icmp_header may varry - there may be extended header + //#endif + } layer4; +} nicState_t; + +nicState_t nicState; + +/** + * Create mac buffer and next call hardware specyfic function to initialize NIC + * @note For some hardware, this command will take a non-negligible amount of time (1-2 seconds). + */ +void nicInit(void); + +/** + * Initialize network interface hardware. + * Hardware specyfic function + * Reset and bring up network interface hardware. This function should leave + * the network interface ready to handle \c nicSend() and \c nicPoll() requests. + * @note For some hardware, this command will take a non-negligible amount of time (1-2 seconds). + */ +void nicMacInit(void) __attribute__ ((weak)); + + +/** Send packet on network interface. + * Function accepts the length (in bytes) of the data to be sent, and a pointer + * to the data. This send command may assume an ethernet-like 802.3 header is at the + * beginning of the packet, and contains the packet addressing information. + * See net.h documentation for ethernet header format. + * @param length - data length + */ +void nicSend(uint16_t len) __attribute__ ((weak)); + +/** + * Check network interface. + * Upper network layers may assume that an ethernet-like 802.3 header is at the beginning + * of the packet, and contains the packet addressing information, without the preamble + * See net.h documentation for ethernet header format + * received data are stored in global buffer nicBuffer + * @return number of received bytes + */ +unsigned int nicPoll(void) __attribute__ ((weak)); + +/** + * Gets mac address of the network interface. + * This function can return a MAC address read from the NIC hardware, if available. + * If the hardware does not provide a MAC address, a software-defined address may be + * returned. It may be acceptable to return an address that is less than 48-bits. + * @param [out] macaddr* - pointer to the mac address. + */ +void nicGetMacAddress(uint8_t* macaddr) __attribute__ ((weak)); + +/** + * Set the 48-bit hardware node (MAC) address of this network interface. + * This function may not be supported on all hardware. + * @param [in] macaddr* - pointer to the mac address. + */ +void nicSetMacAddress(uint8_t* macaddr) __attribute__ ((weak)); + +/** + * Print network interface hardware registers. + * Prints a formatted list of names and values of NIC registers for debugging purposes. + * @param stream - input stream + */ +void nicRegDump(FILE *stream) __attribute__ ((weak)); + +/** + * Save nic parameters like MAC + */ +void nicSaveConfig(void); + +void nicLoadConfig(void); + +#endif +//@} diff --git a/Lib/net/include/tcp.h b/Lib/net/include/tcp.h new file mode 100644 index 0000000..ea2fa79 --- /dev/null +++ b/Lib/net/include/tcp.h @@ -0,0 +1,156 @@ +/** + * @file tcp.h + * @author Adam Kaliszan + * @brief Enc28j60 TCP socket + * @ingroup network + * @version 0.1 + * Created: 13.10.2010 + * Revised: .12.2010 + * Editor Tabs: 2 + * + * @defgroup netstack Network Stack + * @code #include "net/Enc28j60socket.h" @endcode + * @par Description + * This library supports TCP Sockets. + * + * @note This is NOT a full-blown TCP/IP stack. It merely handles lower + * level stack functions so that TCP packets can be sent and received easily. + * End-to-end TCP functionality may be added in a future version. + * Until then, I can recommend using other embedded TCP/IP stacks like Adam Dunkel's uIP. + * + */ +//@{ + +#ifndef TCP_H +#define TCP_H + +#include +#include +#include +#include +#include + +#include "hardwareConfig.h" +#include "softwareConfig.h" +#include "memory_x.h" + +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "queue.h" + +#include "net.h" +#include "ip.h" + +#if TCP_DEBUG +FILE *tcpDebugStream; +uint8_t tcpDebugLevel; + +extern uint8_t timer100Hz; +extern nicState_t nicState; + +/** + * Enables TCP protocol debuging + * @param *stream - pointer to output debug stream + * @param level - debug intensity 0 - debug sidabled, 1 - basic short info, 2 - short info about all ewents, 3 - basic detailed info + short info about all ewents, 4 - detailed info about everything + */ +void setTcpDebug(FILE *stream, uint8_t level); +#endif + +typedef enum +{ + CLOSED, + LISTEN, + SYN_RECEIVED, + ESTABILISHED, + CLOSE_WAIT, + LAST_ACK, + SYN_SENT, + FIN_WAIT1, + FIN_WAIT2, + CLOSING, + TIMED_WAIT +} socket_state_t; + +struct TcpIpSocket +{ + socket_state_t state; + uint32_t RemoteIpAddr; /// Stored in network order +#if IPV6_SUPPORT + uip_ip6addr_t RemoteIpAddr6; +#endif /*IPV6_SUPPORT*/ + + uint16_t localPort; /// Stored in network order + uint16_t remotePort; /// Stored in network order + + uint32_t seqNoLastReceived; /// Sequence number of last received packet + uint32_t seqNoLastSent; /// Sequence number of last sent packet + uint16_t noOfNotAckBytes; /// Number of received bytes without ack + + uint16_t windowSize; + uint8_t timer; + + xQueueHandle Rx; + xQueueHandle Tx; + + //struct packetBackup packetBackupBuffer[4]; + uint8_t packetBackupBufferNotConfirmedPacketIdx; + uint8_t packetBackupBufferWriteIdx; +}; + +struct TcpIpSocket *sockets; + +/** + * Initialize socket structs + */ +void socketInit(void); + + +/** + * put received data into the matching socket, + * if theare is matching sockets, creates new connection + * @param packet - IP packet + * @return 0 - OK, 1 - socket is ocupied by another connection + */ +uint8_t processTcpPacket(void); + +/** + * Reads number of bytes that are queued in Tx buffer + * @param socketNo - globals socket descriptor + * @return number of bytes in TCP buffer + */ +uint8_t getTxBufferState(uint8_t socketNo); + + +/** + * Sends data from Tx buffer + * @param socketNo - socket number + * @return 0 - all OK + */ +uint8_t sendTcpBuffer(uint8_t socketNo); + +/** + * Calculates TCP checksum according to data in ENC Tx buffer + * @param TCP data length + */ +void calculateTcpChecksun(uint16_t tcpLen); + +/** + * Close TCP socket + * @param socketNo - socket number to be closed + * @return 0 - all OK + */ +uint8_t closeSocket(uint8_t socketNo); + + +void netstackTCPIPProcess(void); + +/** + * Flush all UDP queues + */ +void flushTcpQueues(void); + +void httpProcess(void); + +#endif /*TCP_H*/ +//@} diff --git a/Lib/net/include/tcp6.h b/Lib/net/include/tcp6.h new file mode 100644 index 0000000..ebf17c1 --- /dev/null +++ b/Lib/net/include/tcp6.h @@ -0,0 +1,111 @@ +/** + * @file tcp.h //tcp6.h + * @author Adam Kaliszan + * @brief Enc28j60 TCP socket + * @ingroup network + * @version 0.1 + * Created: 13.10.2010 + * Revised: .12.2010 + * Editor Tabs: 2 + * + * @defgroup netstack Network Stack + * @code #include "net/Enc28j60socket.h" @endcode + * @par Description + * This library supports TCP Sockets (over ipv6). + * + * @note This is NOT a full-blown TCP/IP stack. It merely handles lower + * level stack functions so that TCP packets can be sent and received easily. + * End-to-end TCP functionality may be added in a future version. + * Until then, I can recommend using other embedded TCP/IP stacks like Adam Dunkel's uIP. + * + */ +//@{ + +#ifndef SOCKET_V6_H +#define SOCKET_V6_H + +#include +#include +#include +#include +#include + + +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "queue.h" + +#include "ipv6.h" +#include "../../freeRtos/Lib/net/include/ipv6.h" +#include "tcp.h" + +#if TCP_DEBUG +FILE *tcpDebugStream; +uint8_t tcpDebugLevel; + +extern uint8_t timer100Hz; +extern nicState_t nicState; + +/** + * Enables TCP protocol debuging + * @param *stream - pointer to output debug stream + * @param level - debug intensity 0 - debug sidabled, 1 - basic short info, 2 - short info about all ewents, 3 - basic detailed info + short info about all ewents, 4 - detailed info about everything + */ +void setTcpDebug6(FILE *stream, uint8_t level); +#endif + +/** + * Initialize socket structs + */ +void socketInit6(void); + + +/** + * put received data into the matching socket, + * if theare is matching sockets, creates new connection + * @param packet - IP packet + * @return 0 - OK, 1 - socket is ocupied by another connection + */ +uint8_t processTcpPacket6(void); + +/** + * Reads number of bytes that are queued in Tx buffer + * @param socketNo - globals socket descriptor + * @return number of bytes in TCP buffer + */ +uint8_t getTxBufferState6(uint8_t socketNo); + + +/** + * Sends data from Tx buffer + * @param socketNo - socket number + * @return 0 - all OK + */ +uint8_t sendTcpBuffer6(uint8_t socketNo); + +/** + * Calculates TCP checksum according to data in ENC Tx buffer + * @param TCP data length + */ +void calculateTcpChecksum6(uint16_t tcpLen); + +/** + * Close TCP socket + * @param socketNo - socket number to be closed + * @return 0 - all OK + */ +uint8_t closeSocket(uint8_t socketNo); + + +void netstackTCPIPProcess6(void); + +/** + * Flush all UDP queues + */ +void flushTcpQueues6(void); + +void httpProcess6(void); + +#endif /*SOCKET_V6_H*/ +//@} diff --git a/Lib/net/include/udp.h b/Lib/net/include/udp.h new file mode 100644 index 0000000..a988919 --- /dev/null +++ b/Lib/net/include/udp.h @@ -0,0 +1,78 @@ +#ifndef UDP_H +#define UDP_H + +#include +#include +#include "ip.h" +#include "nic.h" +#include "FreeRTOS.h" +#include "queue.h" +#include "softwareConfig.h" +#include "hardwareConfig.h" +#include "memory_x.h" +#include +#include + +#if UDP_DEBUG +#endif + +extern uint32_t udpIpDst_eep __attribute__((section (".eeprom"))); +extern uint16_t udpPortDstEep __attribute__((section (".eeprom"))); +extern uint16_t udpPortSrcEep __attribute__((section (".eeprom"))); + +extern struct ipConfig IpMyConfig; +extern nicState_t nicState; + +typedef struct +{ + uint16_t dstPortDef; //stored in network order + uint16_t dstPort; //stored in network order + uint16_t srcPort; + uint32_t dstIp; + + xQueueHandle Rx; + xQueueHandle Tx; +} UdpSocket_t; + +UdpSocket_t *udpSocket;//[NUMBER_OF_UDP_SOCK]; + +#if UDP_DEBUG +FILE *udpDbgStream; +uint8_t udpDbgLevel; + +/** + * Enable or disable debug stream + * @param *stream - output stream. Do not use network stream. NULL value disable debug stream + * @param level - debug detail's level + */ +void setUdpDebug(FILE *stream, uint8_t level); +#endif + + +void udpLoadConfig(void); + +/** + * Initialize UDP protocol. + * Creates UDP socket + * Invoke this function on the very begining + */ +void udpInit_0(void); + + +/** + * Send a UDP/IP packet. + * Packet data has to be written in Ethernet buffer. + * Function fills the IP addresses and ports according to UDP settings + * @param len - udp packet length (with header) + */ +void udpSend(uint16_t len); + + +void netstackUDPIPProcess(void); + +void flushUdpQueues(void); + +void udpSaveConfig(void); +void udpPrintStatus(FILE *stream); + +#endif diff --git a/Lib/net/include/uip-neighbor.h b/Lib/net/include/uip-neighbor.h new file mode 100644 index 0000000..d894469 --- /dev/null +++ b/Lib/net/include/uip-neighbor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uip-neighbor.h,v 1.2 2006/08/09 16:13:40 bg- Exp $ + */ + +/** + * \file + * Header file for database of link-local neighbors, used by + * IPv6 code and to be used by future ARP code. + * \author + * Adam Dunkels + */ + +#ifndef __UIP_NEIGHBOR_H__ +#define __UIP_NEIGHBOR_H__ + +#include "net/uip.h" + +struct uip_neighbor_addr { +#if UIP_NEIGHBOR_CONF_ADDRTYPE + UIP_NEIGHBOR_CONF_ADDRTYPE addr; +#else + struct uip_eth_addr addr; +#endif +}; + +void uip_neighbor_init(void); +void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr); +void uip_neighbor_update(uip_ipaddr_t *ipaddr); +struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t *ipaddr); +void uip_neighbor_periodic(void); + +#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/Lib/net/include/uip-netif.h b/Lib/net/include/uip-netif.h new file mode 100644 index 0000000..ac5f5ce --- /dev/null +++ b/Lib/net/include/uip-netif.h @@ -0,0 +1,105 @@ + +#ifndef __UIP_NETIF_H__ +#define __UIP_NETIF_H__ + + +#ifndef UIP_CONF_NETIF_MAX_ADDRESSES +#define UIP_CONF_NETIF_MAX_ADDRESSES 2 +#endif /*UIP_CONF_NETIF_MAX_ADDRESSES*/ + +#include "ipv6.h" +#include "ipv6-nd.h" + +/** + * \brief Possible states for the address of an interface (RFC 4862 autoconf + + * NOT_USED + INFINITE) + */ +typedef enum { + NOT_USED = -1, + TENTATIVE = 0, + PREFERRED = 1, + DEPRECATED = 2, /* not needed if we don't use pliffetime in prefix struct */ +} uip_netif_state; + +/** + * \brief How the address was acquired: Autoconf, DHCP or manually + * + */ +typedef enum { + AUTOCONF = 1, + DHCP = 2, + MANUAL = 3 +} uip_netif_type; + +/** + * \brief An address structure for an interface + * + * Contains an ip address assigned to the interface, and its state. + */ +struct uip_netif_addr { + uip_ipaddr_t ipaddr; + uip_netif_state state; + //struct timer vlifetime; + uint8_t is_infinite; + uip_netif_type type; +}; + +/** \brief Interface structure (contains all the interface variables) */ +struct uip_netif { + uint32_t link_mtu; + uint8_t cur_hop_limit; + uint32_t base_reachable_time; /* in msec */ + uint32_t reachable_time; /* in msec */ + uint32_t retrans_timer; /* in msec */ + uint8_t dup_addr_detect_transmit; + /** Note: the link-local address is at position 0 */ + struct uip_netif_addr addresses[UIP_CONF_NETIF_MAX_ADDRESSES]; + uip_ipaddr_t solicited_node_mcastaddr; +}; + + +/*---------------------------------------------------------------------------*/ +/** \brief The single physical interface */ +struct uip_netif *uip_netif_physical_if; +//extern struct etimer uip_netif_timer_dad; +//extern struct etimer uip_netif_timer_rs; +//extern struct etimer uip_netif_timer_periodic; + +/*---------------------------------------------------------------------------*/ +/** \brief Initialize the network interfac and run stateless autoconf */ +void uip_netif_init(void); + +/** + * \brief Check if an unicast address is attached to my interface + * \param ipaddr an IP address to be checked + * \return 1 if address is attached to my interface (otherwise false) + */ +#define uip_netif_is_addr_my_unicast(a) (uip_netif_addr_lookup(a, 128, 0) != NULL) + +/** + * \brief Set the 8 last bytes of the IP address + * based on the L2 identifier using autoconf + * \param *ipaddr the IP address to be completed with layer 2 info + * \param *lladdr the L2 address + */ +void uip_netif_addr_autoconf_set(uip_ipaddr_t *ipaddr, struct netEthAddr *lladdr); + +/** + * \brief Lookup an address + * \param ipaddr the prefix if we are looking for an autoconf address, the address otherwise + * \param length the prefix length if we are looking for autoconf address, 128 otherwise + * \param type AUTOCONF or MANUAL or DHCP or 0 + * + * + * If we are looking for an AUTOCONFIGURED address, ipaddr is a prefix + * length is its length, type is AUTOCONF. + * Otherwise ipaddr is a full address, length must be 128, type is MANUAL + * or DHCP. + * Note: if we do not care about the type, type MUST be 0 + */ +struct uip_netif_addr *uip_netif_addr_lookup(uip_ipaddr_t *ipaddr, uint8_t length, uip_netif_type type); + +#endif + +/** @} */ + diff --git a/Lib/net/ip.c b/Lib/net/ip.c new file mode 100644 index 0000000..5ec3f01 --- /dev/null +++ b/Lib/net/ip.c @@ -0,0 +1,216 @@ +/** + * @file ip.c + * @brief IP (Internet Protocol) Library. + */ +//***************************************************************************** +// +// File Name : 'ip.c' +// Title : IP (Internet Protocol) Library +// Author : Pascal Stang +// Created : 8/30/2004 +// Revised : 7/3/2005 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 2 +// +//***************************************************************************** + +#include "ip.h" + +static uint32_t myip_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_IP4 << 24) + ((uint32_t)MY_IP3 <<16) + ((uint32_t)MY_IP2 <<8) + MY_IP1; +static uint32_t mask_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_MASK4 << 24) + ((uint32_t)MY_MASK3 <<16) + ((uint32_t)MY_MASK2 <<8) + MY_MASK1; +static uint32_t defGw_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_GW4 << 24) + ((uint32_t)MY_GW3 <<16) + ((uint32_t)MY_GW2 <<8) + MY_GW1; + +void ipInit() +{ + +} + +void ipLoadConfig(void) +{ + IpMyConfig.ip = eeprom_read_dword(&myip_eep); + IpMyConfig.netmask = eeprom_read_dword(&mask_eep); + IpMyConfig.gateway = eeprom_read_dword(&defGw_eep); +#if IP_DEBUG + IpMyConfig.dbgLevel = 0; + IpMyConfig.dbgStream = NULL; +#endif +} + +void ipSaveConfig(void) +{ + eeprom_update_dword(&myip_eep, IpMyConfig.ip); + eeprom_update_dword(&mask_eep, IpMyConfig.netmask); + eeprom_update_dword(&defGw_eep, IpMyConfig.gateway); +} + +inline void netstackIPv4Process(void) +{ +// check IP addressing, stop processing if not for me and not a broadcast + if( (nicState.layer3.ip->destipaddr != ipGetConfig()->ip) && //Różne adresy IP + (nicState.layer3.ip->destipaddr != (ipGetConfig()->ip | (~ipGetConfig()->netmask))) && //Nie jest to adres rozgÅ‚oszeniowy sieci + (nicState.layer3.ip->destipaddr != 0xFFFFFFFF)) //Nie jest to brodcast + return; + +// handle ICMP packet + if(nicState.layer3.ip->proto == IP_PROTO_ICMP) + { +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: ICMP/IP packet\r\n")); + if (IpMyConfig.dbgLevel > 2) + icmpPrintHeader(IpMyConfig.dbgStream, nicState.layer3.ip, nicState.layer4.icmp); + } +#endif /*IP_DEBUG*/ + icmpIpIn(); + return; + } + if( nicState.layer3.ip->proto == IP_PROTO_UDP ) + { +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: UDP/IP packet\r\n")); + } +#endif /*IP_DEBUG*/ + netstackUDPIPProcess(); + return; + } +#ifdef TCP_H + if( nicState.layer3.ip->proto == IP_PROTO_TCP ) + { +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: TCP/IP packet\r\n")); + } +#endif /*IP_DEBUG*/ + netstackTCPIPProcess(); + return; + } +#endif +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + } +#endif /*IP_DEBUG*/ +} + +#if IP_DEBUG +void setIpDebug(FILE *stream, uint8_t level) +{ + IpMyConfig.dbgStream = stream; + IpMyConfig.dbgLevel = level; + if (level == 0) + IpMyConfig.dbgStream = NULL; +} +#endif + +void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp) +{ + // set local addressing + IpMyConfig.ip = myIp; + IpMyConfig.netmask = netmask; + IpMyConfig.gateway = gatewayIp; +} + +void ipSetConfigIp(uint32_t myIp) +{ + // set local addressing + IpMyConfig.ip = myIp; +} + +void ipSetConfigMask(uint32_t netmask) +{ + IpMyConfig.netmask = netmask; +} + +void ipSetConfigGw(uint32_t gatewayIp) +{ + IpMyConfig.gateway = gatewayIp; +} + + +struct ipConfig* ipGetConfig(void) +{ + return &IpMyConfig; +} + +void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len) +{ +// make pointer to ethernet/IP header +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 2) + fprintf_P(IpMyConfig.dbgStream, "Sending Ip packet\r\n"); + } +#endif + +// adjust length to add IP header + len += IP_HEADER_LEN; + +// fill IP header + nicState.layer3.ip->destipaddr = dstIp; + nicState.layer3.ip->srcipaddr = IpMyConfig.ip; + nicState.layer3.ip->proto = protocol; + nicState.layer3.ip->len = htons(len); + nicState.layer3.ip->vhl = 0x45; + nicState.layer3.ip->tos = 0; + nicState.layer3.ip->ipid = 0; + nicState.layer3.ip->ipoffset = 0; + nicState.layer3.ip->ttl = IP_TIME_TO_LIVE; + nicState.layer3.ip->ipchksum = 0; + +// calculate and apply IP checksum +// DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER + nicState.layer3.ip->ipchksum = netChecksum((uint8_t *)(nicState.layer3.ip), IP_HEADER_LEN); + +// add ethernet routing +// check if we need to send to gateway + if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) + { + arpIpOut(0); // local send +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet on local net\r\n")); +#endif + } + else + { + arpIpOut(IpMyConfig.gateway); // gateway send +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet to gateway\r\n")); +#endif + } + +// adjust length to add ethernet header + len += ETH_HEADER_LEN; + +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + { + if (IpMyConfig.dbgLevel > 3) + { + fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(ETH_HEADER_LEN, &data[0]);")); + fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]);")); + } + } +#endif +// send it + nicSend(len); +} + +void ipPrintConfig(FILE *stream, struct ipConfig* config) +{ + fprintf_P(stream, PSTR("IP Addr : ")); netPrintIPAddr(stream, config->ip); fprintf_P(stream, PSTR("\r\n")); + fprintf_P(stream, PSTR("Netmask : ")); netPrintIPAddr(stream, config->netmask); fprintf_P(stream, PSTR("\r\n")); + fprintf_P(stream, PSTR("Gateway : ")); netPrintIPAddr(stream, config->gateway); fprintf_P(stream, PSTR("\r\n")); +} diff --git a/Lib/net/ip.lst b/Lib/net/ip.lst new file mode 100644 index 0000000..ec25a02 --- /dev/null +++ b/Lib/net/ip.lst @@ -0,0 +1,1109 @@ + 1 .file "ip.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 160 .global ipInit + 162 ipInit: + 163 .stabd 46,0,0 + 1:../../../../Lib/net/ip.c **** /** + 2:../../../../Lib/net/ip.c **** * @file ip.c + 3:../../../../Lib/net/ip.c **** * @brief IP (Internet Protocol) Library. + 4:../../../../Lib/net/ip.c **** */ + 5:../../../../Lib/net/ip.c **** //***************************************************************************** + 6:../../../../Lib/net/ip.c **** // + 7:../../../../Lib/net/ip.c **** // File Name : 'ip.c' + 8:../../../../Lib/net/ip.c **** // Title : IP (Internet Protocol) Library + 9:../../../../Lib/net/ip.c **** // Author : Pascal Stang + 10:../../../../Lib/net/ip.c **** // Created : 8/30/2004 + 11:../../../../Lib/net/ip.c **** // Revised : 7/3/2005 + 12:../../../../Lib/net/ip.c **** // Version : 0.1 + 13:../../../../Lib/net/ip.c **** // Target MCU : Atmel AVR series + 14:../../../../Lib/net/ip.c **** // Editor Tabs : 2 + 15:../../../../Lib/net/ip.c **** // + 16:../../../../Lib/net/ip.c **** //***************************************************************************** + 17:../../../../Lib/net/ip.c **** + 18:../../../../Lib/net/ip.c **** #include "ip.h" + 19:../../../../Lib/net/ip.c **** + 20:../../../../Lib/net/ip.c **** static uint32_t myip_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_IP4 << 24) + ((u + 21:../../../../Lib/net/ip.c **** static uint32_t mask_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_MASK4 << 24) + ((u + 22:../../../../Lib/net/ip.c **** static uint32_t defGw_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_GW4 << 24) + ((u + 23:../../../../Lib/net/ip.c **** + 24:../../../../Lib/net/ip.c **** void ipInit() + 25:../../../../Lib/net/ip.c **** { + 165 .LM0: + 166 .LFBB1: + 167 /* prologue: function */ + 168 /* frame size = 0 */ + 169 /* stack size = 0 */ + 170 .L__stack_usage = 0 + 171 0000 0895 ret + 173 .Lscope1: + 175 .stabd 78,0,0 + 177 .global ipLoadConfig + 179 ipLoadConfig: + 180 .stabd 46,0,0 + 26:../../../../Lib/net/ip.c **** + 27:../../../../Lib/net/ip.c **** } + 28:../../../../Lib/net/ip.c **** + 29:../../../../Lib/net/ip.c **** void ipLoadConfig(void) + 30:../../../../Lib/net/ip.c **** { + 182 .LM1: + 183 .LFBB2: + 185 .LM2: + 186 0002 CF93 push r28 + 187 0004 DF93 push r29 + 188 /* prologue: function */ + 189 /* frame size = 0 */ + 190 /* stack size = 2 */ + 191 .L__stack_usage = 2 + 31:../../../../Lib/net/ip.c **** IpMyConfig.ip = eeprom_read_dword(&myip_eep); + 193 .LM3: + 194 0006 80E0 ldi r24,lo8(myip_eep) + 195 0008 90E0 ldi r25,hi8(myip_eep) + 196 000a 0E94 0000 call eeprom_read_dword + 197 000e C0E0 ldi r28,lo8(IpMyConfig) + 198 0010 D0E0 ldi r29,hi8(IpMyConfig) + 199 0012 6883 st Y,r22 + 200 0014 7983 std Y+1,r23 + 201 0016 8A83 std Y+2,r24 + 202 0018 9B83 std Y+3,r25 + 32:../../../../Lib/net/ip.c **** IpMyConfig.netmask = eeprom_read_dword(&mask_eep); + 204 .LM4: + 205 001a 80E0 ldi r24,lo8(mask_eep) + 206 001c 90E0 ldi r25,hi8(mask_eep) + 207 001e 0E94 0000 call eeprom_read_dword + 208 0022 6C83 std Y+4,r22 + 209 0024 7D83 std Y+5,r23 + 210 0026 8E83 std Y+6,r24 + 211 0028 9F83 std Y+7,r25 + 33:../../../../Lib/net/ip.c **** IpMyConfig.gateway = eeprom_read_dword(&defGw_eep); + 213 .LM5: + 214 002a 80E0 ldi r24,lo8(defGw_eep) + 215 002c 90E0 ldi r25,hi8(defGw_eep) + 216 002e 0E94 0000 call eeprom_read_dword + 217 0032 6887 std Y+8,r22 + 218 0034 7987 std Y+9,r23 + 219 0036 8A87 std Y+10,r24 + 220 0038 9B87 std Y+11,r25 + 34:../../../../Lib/net/ip.c **** #if IP_DEBUG + 35:../../../../Lib/net/ip.c **** IpMyConfig.dbgLevel = 0; + 222 .LM6: + 223 003a 1E86 std Y+14,__zero_reg__ + 36:../../../../Lib/net/ip.c **** IpMyConfig.dbgStream = NULL; + 225 .LM7: + 226 003c 1D86 std Y+13,__zero_reg__ + 227 003e 1C86 std Y+12,__zero_reg__ + 228 /* epilogue start */ + 37:../../../../Lib/net/ip.c **** #endif + 38:../../../../Lib/net/ip.c **** } + 230 .LM8: + 231 0040 DF91 pop r29 + 232 0042 CF91 pop r28 + 233 0044 0895 ret + 235 .Lscope2: + 237 .stabd 78,0,0 + 239 .global ipSaveConfig + 241 ipSaveConfig: + 242 .stabd 46,0,0 + 39:../../../../Lib/net/ip.c **** + 40:../../../../Lib/net/ip.c **** void ipSaveConfig(void) + 41:../../../../Lib/net/ip.c **** { + 244 .LM9: + 245 .LFBB3: + 246 0046 CF93 push r28 + 247 0048 DF93 push r29 + 248 /* prologue: function */ + 249 /* frame size = 0 */ + 250 /* stack size = 2 */ + 251 .L__stack_usage = 2 + 42:../../../../Lib/net/ip.c **** eeprom_update_dword(&myip_eep, IpMyConfig.ip); + 253 .LM10: + 254 004a C0E0 ldi r28,lo8(IpMyConfig) + 255 004c D0E0 ldi r29,hi8(IpMyConfig) + 256 004e 4881 ld r20,Y + 257 0050 5981 ldd r21,Y+1 + 258 0052 6A81 ldd r22,Y+2 + 259 0054 7B81 ldd r23,Y+3 + 260 0056 80E0 ldi r24,lo8(myip_eep) + 261 0058 90E0 ldi r25,hi8(myip_eep) + 262 005a 0E94 0000 call eeprom_update_dword + 43:../../../../Lib/net/ip.c **** eeprom_update_dword(&mask_eep, IpMyConfig.netmask); + 264 .LM11: + 265 005e 4C81 ldd r20,Y+4 + 266 0060 5D81 ldd r21,Y+5 + 267 0062 6E81 ldd r22,Y+6 + 268 0064 7F81 ldd r23,Y+7 + 269 0066 80E0 ldi r24,lo8(mask_eep) + 270 0068 90E0 ldi r25,hi8(mask_eep) + 271 006a 0E94 0000 call eeprom_update_dword + 44:../../../../Lib/net/ip.c **** eeprom_update_dword(&defGw_eep, IpMyConfig.gateway); + 273 .LM12: + 274 006e 4885 ldd r20,Y+8 + 275 0070 5985 ldd r21,Y+9 + 276 0072 6A85 ldd r22,Y+10 + 277 0074 7B85 ldd r23,Y+11 + 278 0076 80E0 ldi r24,lo8(defGw_eep) + 279 0078 90E0 ldi r25,hi8(defGw_eep) + 280 /* epilogue start */ + 45:../../../../Lib/net/ip.c **** } + 282 .LM13: + 283 007a DF91 pop r29 + 284 007c CF91 pop r28 + 44:../../../../Lib/net/ip.c **** eeprom_update_dword(&defGw_eep, IpMyConfig.gateway); + 286 .LM14: + 287 007e 0C94 0000 jmp eeprom_update_dword + 289 .Lscope3: + 291 .stabd 78,0,0 + 293 .global netstackIPv4Process + 295 netstackIPv4Process: + 296 .stabd 46,0,0 + 46:../../../../Lib/net/ip.c **** + 47:../../../../Lib/net/ip.c **** inline void netstackIPv4Process(void) + 48:../../../../Lib/net/ip.c **** { + 298 .LM15: + 299 .LFBB4: + 300 0082 0F93 push r16 + 301 0084 1F93 push r17 + 302 /* prologue: function */ + 303 /* frame size = 0 */ + 304 /* stack size = 2 */ + 305 .L__stack_usage = 2 + 49:../../../../Lib/net/ip.c **** // check IP addressing, stop processing if not for me and not a broadcast + 50:../../../../Lib/net/ip.c **** if( (nicState.layer3.ip->destipaddr != ipGetConfig()->ip) && // + 307 .LM16: + 308 0086 E091 0000 lds r30,nicState+10 + 309 008a F091 0000 lds r31,nicState+10+1 + 310 008e 4089 ldd r20,Z+16 + 311 0090 5189 ldd r21,Z+17 + 312 0092 6289 ldd r22,Z+18 + 313 0094 7389 ldd r23,Z+19 + 314 0096 8091 0000 lds r24,IpMyConfig + 315 009a 9091 0000 lds r25,IpMyConfig+1 + 316 009e A091 0000 lds r26,IpMyConfig+2 + 317 00a2 B091 0000 lds r27,IpMyConfig+3 + 318 00a6 4817 cp r20,r24 + 319 00a8 5907 cpc r21,r25 + 320 00aa 6A07 cpc r22,r26 + 321 00ac 7B07 cpc r23,r27 + 322 00ae 01F0 breq .L5 + 51:../../../../Lib/net/ip.c **** (nicState.layer3.ip->destipaddr != (ipGetConfig()->ip | (~ipGetConfig()->netmask))) && // + 324 .LM17: + 325 00b0 0091 0000 lds r16,IpMyConfig+4 + 326 00b4 1091 0000 lds r17,IpMyConfig+4+1 + 327 00b8 2091 0000 lds r18,IpMyConfig+4+2 + 328 00bc 3091 0000 lds r19,IpMyConfig+4+3 + 329 00c0 0095 com r16 + 330 00c2 1095 com r17 + 331 00c4 2095 com r18 + 332 00c6 3095 com r19 + 333 00c8 802B or r24,r16 + 334 00ca 912B or r25,r17 + 335 00cc A22B or r26,r18 + 336 00ce B32B or r27,r19 + 50:../../../../Lib/net/ip.c **** (nicState.layer3.ip->destipaddr != (ipGetConfig()->ip | (~ipGetConfig()->netmask))) && // + 338 .LM18: + 339 00d0 4817 cp r20,r24 + 340 00d2 5907 cpc r21,r25 + 341 00d4 6A07 cpc r22,r26 + 342 00d6 7B07 cpc r23,r27 + 343 00d8 01F0 breq .L5 + 345 .LM19: + 346 00da 4F3F cpi r20,-1 + 347 00dc 5F4F sbci r21,-1 + 348 00de 6F4F sbci r22,-1 + 349 00e0 7F4F sbci r23,-1 + 350 00e2 01F0 breq .+2 + 351 00e4 00C0 rjmp .L4 + 352 .L5: + 52:../../../../Lib/net/ip.c **** (nicState.layer3.ip->destipaddr != 0xFFFFFFFF)) // + 53:../../../../Lib/net/ip.c **** return; + 54:../../../../Lib/net/ip.c **** + 55:../../../../Lib/net/ip.c **** // handle ICMP packet + 56:../../../../Lib/net/ip.c **** if(nicState.layer3.ip->proto == IP_PROTO_ICMP) + 354 .LM20: + 355 00e6 2185 ldd r18,Z+9 + 356 00e8 8091 0000 lds r24,IpMyConfig+12 + 357 00ec 9091 0000 lds r25,IpMyConfig+12+1 + 358 00f0 2130 cpi r18,lo8(1) + 359 00f2 01F4 brne .L7 + 57:../../../../Lib/net/ip.c **** { + 58:../../../../Lib/net/ip.c **** #if IP_DEBUG + 59:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 361 .LM21: + 362 00f4 0097 sbiw r24,0 + 363 00f6 01F0 breq .L9 + 60:../../../../Lib/net/ip.c **** { + 61:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 0) + 365 .LM22: + 366 00f8 2091 0000 lds r18,IpMyConfig+14 + 367 00fc 2223 tst r18 + 368 00fe 01F0 breq .L10 + 62:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: ICMP/IP packet\r\n")); + 370 .LM23: + 371 0100 20E0 ldi r18,lo8(__c.2488) + 372 0102 30E0 ldi r19,hi8(__c.2488) + 373 0104 3F93 push r19 + 374 0106 2F93 push r18 + 375 0108 9F93 push r25 + 376 010a 8F93 push r24 + 377 010c 0E94 0000 call fprintf_P + 378 0110 0F90 pop __tmp_reg__ + 379 0112 0F90 pop __tmp_reg__ + 380 0114 0F90 pop __tmp_reg__ + 381 0116 0F90 pop __tmp_reg__ + 382 .L10: + 63:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 2) + 384 .LM24: + 385 0118 8091 0000 lds r24,IpMyConfig+14 + 386 011c 8330 cpi r24,lo8(3) + 387 011e 00F0 brlo .L9 + 64:../../../../Lib/net/ip.c **** icmpPrintHeader(IpMyConfig.dbgStream, nicState.layer3.ip, nicState.layer4.icmp); + 389 .LM25: + 390 0120 4091 0000 lds r20,nicState+12 + 391 0124 5091 0000 lds r21,nicState+12+1 + 392 0128 6091 0000 lds r22,nicState+10 + 393 012c 7091 0000 lds r23,nicState+10+1 + 394 0130 8091 0000 lds r24,IpMyConfig+12 + 395 0134 9091 0000 lds r25,IpMyConfig+12+1 + 396 0138 0E94 0000 call icmpPrintHeader + 397 .L9: + 398 /* epilogue start */ + 65:../../../../Lib/net/ip.c **** } + 66:../../../../Lib/net/ip.c **** #endif /*IP_DEBUG*/ + 67:../../../../Lib/net/ip.c **** icmpIpIn(); + 68:../../../../Lib/net/ip.c **** return; + 69:../../../../Lib/net/ip.c **** } + 70:../../../../Lib/net/ip.c **** if( nicState.layer3.ip->proto == IP_PROTO_UDP ) + 71:../../../../Lib/net/ip.c **** { + 72:../../../../Lib/net/ip.c **** #if IP_DEBUG + 73:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 74:../../../../Lib/net/ip.c **** { + 75:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 0) + 76:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: UDP/IP packet\r\n")); + 77:../../../../Lib/net/ip.c **** } + 78:../../../../Lib/net/ip.c **** #endif /*IP_DEBUG*/ + 79:../../../../Lib/net/ip.c **** netstackUDPIPProcess(); + 80:../../../../Lib/net/ip.c **** return; + 81:../../../../Lib/net/ip.c **** } + 82:../../../../Lib/net/ip.c **** #ifdef TCP_H + 83:../../../../Lib/net/ip.c **** if( nicState.layer3.ip->proto == IP_PROTO_TCP ) + 84:../../../../Lib/net/ip.c **** { + 85:../../../../Lib/net/ip.c **** #if IP_DEBUG + 86:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 87:../../../../Lib/net/ip.c **** { + 88:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 0) + 89:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: TCP/IP packet\r\n")); + 90:../../../../Lib/net/ip.c **** } + 91:../../../../Lib/net/ip.c **** #endif /*IP_DEBUG*/ + 92:../../../../Lib/net/ip.c **** netstackTCPIPProcess(); + 93:../../../../Lib/net/ip.c **** return; + 94:../../../../Lib/net/ip.c **** } + 95:../../../../Lib/net/ip.c **** #endif + 96:../../../../Lib/net/ip.c **** #if IP_DEBUG + 97:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 98:../../../../Lib/net/ip.c **** { + 99:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 0) + 100:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + 101:../../../../Lib/net/ip.c **** } + 102:../../../../Lib/net/ip.c **** #endif /*IP_DEBUG*/ + 103:../../../../Lib/net/ip.c **** } + 400 .LM26: + 401 013c 1F91 pop r17 + 402 013e 0F91 pop r16 + 67:../../../../Lib/net/ip.c **** return; + 404 .LM27: + 405 0140 0C94 0000 jmp icmpIpIn + 406 .L7: + 70:../../../../Lib/net/ip.c **** { + 408 .LM28: + 409 0144 2131 cpi r18,lo8(17) + 410 0146 01F4 brne .L12 + 73:../../../../Lib/net/ip.c **** { + 412 .LM29: + 413 0148 0097 sbiw r24,0 + 414 014a 01F0 breq .L13 + 75:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: UDP/IP packet\r\n")); + 416 .LM30: + 417 014c 2091 0000 lds r18,IpMyConfig+14 + 418 0150 2223 tst r18 + 419 0152 01F0 breq .L13 + 76:../../../../Lib/net/ip.c **** } + 421 .LM31: + 422 0154 20E0 ldi r18,lo8(__c.2490) + 423 0156 30E0 ldi r19,hi8(__c.2490) + 424 0158 3F93 push r19 + 425 015a 2F93 push r18 + 426 015c 9F93 push r25 + 427 015e 8F93 push r24 + 428 0160 0E94 0000 call fprintf_P + 429 0164 0F90 pop __tmp_reg__ + 430 0166 0F90 pop __tmp_reg__ + 431 0168 0F90 pop __tmp_reg__ + 432 016a 0F90 pop __tmp_reg__ + 433 .L13: + 434 /* epilogue start */ + 436 .LM32: + 437 016c 1F91 pop r17 + 438 016e 0F91 pop r16 + 79:../../../../Lib/net/ip.c **** return; + 440 .LM33: + 441 0170 0C94 0000 jmp netstackUDPIPProcess + 442 .L12: + 97:../../../../Lib/net/ip.c **** { + 444 .LM34: + 445 0174 0097 sbiw r24,0 + 446 0176 01F0 breq .L4 + 99:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + 448 .LM35: + 449 0178 2091 0000 lds r18,IpMyConfig+14 + 450 017c 2223 tst r18 + 451 017e 01F0 breq .L4 + 100:../../../../Lib/net/ip.c **** } + 453 .LM36: + 454 0180 20E0 ldi r18,lo8(__c.2492) + 455 0182 30E0 ldi r19,hi8(__c.2492) + 456 0184 3F93 push r19 + 457 0186 2F93 push r18 + 458 0188 9F93 push r25 + 459 018a 8F93 push r24 + 460 018c 0E94 0000 call fprintf_P + 461 0190 0F90 pop __tmp_reg__ + 462 0192 0F90 pop __tmp_reg__ + 463 0194 0F90 pop __tmp_reg__ + 464 0196 0F90 pop __tmp_reg__ + 465 .L4: + 466 /* epilogue start */ + 468 .LM37: + 469 0198 1F91 pop r17 + 470 019a 0F91 pop r16 + 471 019c 0895 ret + 473 .Lscope4: + 475 .stabd 78,0,0 + 479 .global setIpDebug + 481 setIpDebug: + 482 .stabd 46,0,0 + 104:../../../../Lib/net/ip.c **** + 105:../../../../Lib/net/ip.c **** #if IP_DEBUG + 106:../../../../Lib/net/ip.c **** void setIpDebug(FILE *stream, uint8_t level) + 107:../../../../Lib/net/ip.c **** { + 484 .LM38: + 485 .LFBB5: + 486 /* prologue: function */ + 487 /* frame size = 0 */ + 488 /* stack size = 0 */ + 489 .L__stack_usage = 0 + 108:../../../../Lib/net/ip.c **** IpMyConfig.dbgStream = stream; + 491 .LM39: + 492 019e 9093 0000 sts IpMyConfig+12+1,r25 + 493 01a2 8093 0000 sts IpMyConfig+12,r24 + 109:../../../../Lib/net/ip.c **** IpMyConfig.dbgLevel = level; + 495 .LM40: + 496 01a6 6093 0000 sts IpMyConfig+14,r22 + 110:../../../../Lib/net/ip.c **** if (level == 0) + 498 .LM41: + 499 01aa 6111 cpse r22,__zero_reg__ + 500 01ac 00C0 rjmp .L30 + 111:../../../../Lib/net/ip.c **** IpMyConfig.dbgStream = NULL; + 502 .LM42: + 503 01ae 1092 0000 sts IpMyConfig+12+1,__zero_reg__ + 504 01b2 1092 0000 sts IpMyConfig+12,__zero_reg__ + 505 .L30: + 506 01b6 0895 ret + 508 .Lscope5: + 510 .stabd 78,0,0 + 515 .global ipSetConfig + 517 ipSetConfig: + 518 .stabd 46,0,0 + 112:../../../../Lib/net/ip.c **** } + 113:../../../../Lib/net/ip.c **** #endif + 114:../../../../Lib/net/ip.c **** + 115:../../../../Lib/net/ip.c **** void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp) + 116:../../../../Lib/net/ip.c **** { + 520 .LM43: + 521 .LFBB6: + 522 01b8 EF92 push r14 + 523 01ba FF92 push r15 + 524 01bc 0F93 push r16 + 525 01be 1F93 push r17 + 526 /* prologue: function */ + 527 /* frame size = 0 */ + 528 /* stack size = 4 */ + 529 .L__stack_usage = 4 + 117:../../../../Lib/net/ip.c **** // set local addressing + 118:../../../../Lib/net/ip.c **** IpMyConfig.ip = myIp; + 531 .LM44: + 532 01c0 E0E0 ldi r30,lo8(IpMyConfig) + 533 01c2 F0E0 ldi r31,hi8(IpMyConfig) + 534 01c4 6083 st Z,r22 + 535 01c6 7183 std Z+1,r23 + 536 01c8 8283 std Z+2,r24 + 537 01ca 9383 std Z+3,r25 + 119:../../../../Lib/net/ip.c **** IpMyConfig.netmask = netmask; + 539 .LM45: + 540 01cc 2483 std Z+4,r18 + 541 01ce 3583 std Z+5,r19 + 542 01d0 4683 std Z+6,r20 + 543 01d2 5783 std Z+7,r21 + 120:../../../../Lib/net/ip.c **** IpMyConfig.gateway = gatewayIp; + 545 .LM46: + 546 01d4 E086 std Z+8,r14 + 547 01d6 F186 std Z+9,r15 + 548 01d8 0287 std Z+10,r16 + 549 01da 1387 std Z+11,r17 + 550 /* epilogue start */ + 121:../../../../Lib/net/ip.c **** } + 552 .LM47: + 553 01dc 1F91 pop r17 + 554 01de 0F91 pop r16 + 555 01e0 FF90 pop r15 + 556 01e2 EF90 pop r14 + 557 01e4 0895 ret + 559 .Lscope6: + 561 .stabd 78,0,0 + 564 .global ipSetConfigIp + 566 ipSetConfigIp: + 567 .stabd 46,0,0 + 122:../../../../Lib/net/ip.c **** + 123:../../../../Lib/net/ip.c **** void ipSetConfigIp(uint32_t myIp) + 124:../../../../Lib/net/ip.c **** { + 569 .LM48: + 570 .LFBB7: + 571 /* prologue: function */ + 572 /* frame size = 0 */ + 573 /* stack size = 0 */ + 574 .L__stack_usage = 0 + 125:../../../../Lib/net/ip.c **** // set local addressing + 126:../../../../Lib/net/ip.c **** IpMyConfig.ip = myIp; + 576 .LM49: + 577 01e6 6093 0000 sts IpMyConfig,r22 + 578 01ea 7093 0000 sts IpMyConfig+1,r23 + 579 01ee 8093 0000 sts IpMyConfig+2,r24 + 580 01f2 9093 0000 sts IpMyConfig+3,r25 + 581 01f6 0895 ret + 583 .Lscope7: + 585 .stabd 78,0,0 + 588 .global ipSetConfigMask + 590 ipSetConfigMask: + 591 .stabd 46,0,0 + 127:../../../../Lib/net/ip.c **** } + 128:../../../../Lib/net/ip.c **** + 129:../../../../Lib/net/ip.c **** void ipSetConfigMask(uint32_t netmask) + 130:../../../../Lib/net/ip.c **** { + 593 .LM50: + 594 .LFBB8: + 595 /* prologue: function */ + 596 /* frame size = 0 */ + 597 /* stack size = 0 */ + 598 .L__stack_usage = 0 + 131:../../../../Lib/net/ip.c **** IpMyConfig.netmask = netmask; + 600 .LM51: + 601 01f8 6093 0000 sts IpMyConfig+4,r22 + 602 01fc 7093 0000 sts IpMyConfig+4+1,r23 + 603 0200 8093 0000 sts IpMyConfig+4+2,r24 + 604 0204 9093 0000 sts IpMyConfig+4+3,r25 + 605 0208 0895 ret + 607 .Lscope8: + 609 .stabd 78,0,0 + 612 .global ipSetConfigGw + 614 ipSetConfigGw: + 615 .stabd 46,0,0 + 132:../../../../Lib/net/ip.c **** } + 133:../../../../Lib/net/ip.c **** + 134:../../../../Lib/net/ip.c **** void ipSetConfigGw(uint32_t gatewayIp) + 135:../../../../Lib/net/ip.c **** { + 617 .LM52: + 618 .LFBB9: + 619 /* prologue: function */ + 620 /* frame size = 0 */ + 621 /* stack size = 0 */ + 622 .L__stack_usage = 0 + 136:../../../../Lib/net/ip.c **** IpMyConfig.gateway = gatewayIp; + 624 .LM53: + 625 020a 6093 0000 sts IpMyConfig+8,r22 + 626 020e 7093 0000 sts IpMyConfig+8+1,r23 + 627 0212 8093 0000 sts IpMyConfig+8+2,r24 + 628 0216 9093 0000 sts IpMyConfig+8+3,r25 + 629 021a 0895 ret + 631 .Lscope9: + 633 .stabd 78,0,0 + 635 .global ipGetConfig + 637 ipGetConfig: + 638 .stabd 46,0,0 + 137:../../../../Lib/net/ip.c **** } + 138:../../../../Lib/net/ip.c **** + 139:../../../../Lib/net/ip.c **** + 140:../../../../Lib/net/ip.c **** struct ipConfig* ipGetConfig(void) + 141:../../../../Lib/net/ip.c **** { + 640 .LM54: + 641 .LFBB10: + 642 /* prologue: function */ + 643 /* frame size = 0 */ + 644 /* stack size = 0 */ + 645 .L__stack_usage = 0 + 142:../../../../Lib/net/ip.c **** return &IpMyConfig; + 143:../../../../Lib/net/ip.c **** } + 647 .LM55: + 648 021c 80E0 ldi r24,lo8(IpMyConfig) + 649 021e 90E0 ldi r25,hi8(IpMyConfig) + 650 0220 0895 ret + 652 .Lscope10: + 654 .stabd 78,0,0 + 655 .section .rodata.str1.1,"aMS",@progbits,1 + 656 .LC0: + 657 0000 5365 6E64 .string "Sending Ip packet\r\n" + 657 696E 6720 + 657 4970 2070 + 657 6163 6B65 + 657 740D 0A00 + 658 .text + 663 .global ipSend + 665 ipSend: + 666 .stabd 46,0,0 + 144:../../../../Lib/net/ip.c **** + 145:../../../../Lib/net/ip.c **** void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len) + 146:../../../../Lib/net/ip.c **** { + 668 .LM56: + 669 .LFBB11: + 670 0222 AF92 push r10 + 671 0224 BF92 push r11 + 672 0226 CF92 push r12 + 673 0228 DF92 push r13 + 674 022a EF92 push r14 + 675 022c FF92 push r15 + 676 022e 0F93 push r16 + 677 0230 1F93 push r17 + 678 0232 CF93 push r28 + 679 0234 DF93 push r29 + 680 0236 1F92 push __zero_reg__ + 681 0238 CDB7 in r28,__SP_L__ + 682 023a DEB7 in r29,__SP_H__ + 683 /* prologue: function */ + 684 /* frame size = 1 */ + 685 /* stack size = 11 */ + 686 .L__stack_usage = 11 + 687 023c 6B01 movw r12,r22 + 688 023e 7C01 movw r14,r24 + 689 0240 8901 movw r16,r18 + 147:../../../../Lib/net/ip.c **** // make pointer to ethernet/IP header + 148:../../../../Lib/net/ip.c **** #if IP_DEBUG + 149:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 691 .LM57: + 692 0242 2091 0000 lds r18,IpMyConfig+12 + 693 0246 3091 0000 lds r19,IpMyConfig+12+1 + 694 024a 2115 cp r18,__zero_reg__ + 695 024c 3105 cpc r19,__zero_reg__ + 696 024e 01F0 breq .L38 + 150:../../../../Lib/net/ip.c **** { + 151:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 2) + 698 .LM58: + 699 0250 8091 0000 lds r24,IpMyConfig+14 + 700 0254 8330 cpi r24,lo8(3) + 701 0256 00F0 brlo .L38 + 152:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, "Sending Ip packet\r\n"); + 703 .LM59: + 704 0258 80E0 ldi r24,lo8(.LC0) + 705 025a 90E0 ldi r25,hi8(.LC0) + 706 025c 9F93 push r25 + 707 025e 8F93 push r24 + 708 0260 3F93 push r19 + 709 0262 2F93 push r18 + 710 0264 4983 std Y+1,r20 + 711 0266 0E94 0000 call fprintf_P + 712 026a 0F90 pop __tmp_reg__ + 713 026c 0F90 pop __tmp_reg__ + 714 026e 0F90 pop __tmp_reg__ + 715 0270 0F90 pop __tmp_reg__ + 716 0272 4981 ldd r20,Y+1 + 717 .L38: + 153:../../../../Lib/net/ip.c **** } + 154:../../../../Lib/net/ip.c **** #endif + 155:../../../../Lib/net/ip.c **** + 156:../../../../Lib/net/ip.c **** // adjust length to add IP header + 157:../../../../Lib/net/ip.c **** len += IP_HEADER_LEN; + 158:../../../../Lib/net/ip.c **** + 159:../../../../Lib/net/ip.c **** // fill IP header + 160:../../../../Lib/net/ip.c **** nicState.layer3.ip->destipaddr = dstIp; + 719 .LM60: + 720 0274 A090 0000 lds r10,nicState+10 + 721 0278 B090 0000 lds r11,nicState+10+1 + 722 027c F501 movw r30,r10 + 723 027e C08A std Z+16,r12 + 724 0280 D18A std Z+17,r13 + 725 0282 E28A std Z+18,r14 + 726 0284 F38A std Z+19,r15 + 161:../../../../Lib/net/ip.c **** nicState.layer3.ip->srcipaddr = IpMyConfig.ip; + 728 .LM61: + 729 0286 8091 0000 lds r24,IpMyConfig + 730 028a 9091 0000 lds r25,IpMyConfig+1 + 731 028e A091 0000 lds r26,IpMyConfig+2 + 732 0292 B091 0000 lds r27,IpMyConfig+3 + 733 0296 8487 std Z+12,r24 + 734 0298 9587 std Z+13,r25 + 735 029a A687 std Z+14,r26 + 736 029c B787 std Z+15,r27 + 162:../../../../Lib/net/ip.c **** nicState.layer3.ip->proto = protocol; + 738 .LM62: + 739 029e 4187 std Z+9,r20 + 163:../../../../Lib/net/ip.c **** nicState.layer3.ip->len = htons(len); + 741 .LM63: + 742 02a0 C801 movw r24,r16 + 743 02a2 4496 adiw r24,20 + 744 02a4 0E94 0000 call htons + 745 02a8 F501 movw r30,r10 + 746 02aa 9383 std Z+3,r25 + 747 02ac 8283 std Z+2,r24 + 164:../../../../Lib/net/ip.c **** nicState.layer3.ip->vhl = 0x45; + 749 .LM64: + 750 02ae A090 0000 lds r10,nicState+10 + 751 02b2 B090 0000 lds r11,nicState+10+1 + 752 02b6 85E4 ldi r24,lo8(69) + 753 02b8 F501 movw r30,r10 + 754 02ba 8083 st Z,r24 + 165:../../../../Lib/net/ip.c **** nicState.layer3.ip->tos = 0; + 756 .LM65: + 757 02bc 1182 std Z+1,__zero_reg__ + 166:../../../../Lib/net/ip.c **** nicState.layer3.ip->ipid = 0; + 759 .LM66: + 760 02be 1582 std Z+5,__zero_reg__ + 761 02c0 1482 std Z+4,__zero_reg__ + 167:../../../../Lib/net/ip.c **** nicState.layer3.ip->ipoffset = 0; + 763 .LM67: + 764 02c2 1782 std Z+7,__zero_reg__ + 765 02c4 1682 std Z+6,__zero_reg__ + 168:../../../../Lib/net/ip.c **** nicState.layer3.ip->ttl = IP_TIME_TO_LIVE; + 767 .LM68: + 768 02c6 80E8 ldi r24,lo8(-128) + 769 02c8 8087 std Z+8,r24 + 169:../../../../Lib/net/ip.c **** nicState.layer3.ip->ipchksum = 0; + 771 .LM69: + 772 02ca 1386 std Z+11,__zero_reg__ + 773 02cc 1286 std Z+10,__zero_reg__ + 170:../../../../Lib/net/ip.c **** + 171:../../../../Lib/net/ip.c **** // calculate and apply IP checksum + 172:../../../../Lib/net/ip.c **** // DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER + 173:../../../../Lib/net/ip.c **** nicState.layer3.ip->ipchksum = netChecksum((uint8_t *)(nicState.layer3.ip), IP_HEADER_LEN); + 775 .LM70: + 776 02ce 64E1 ldi r22,lo8(20) + 777 02d0 70E0 ldi r23,0 + 778 02d2 C501 movw r24,r10 + 779 02d4 0E94 0000 call netChecksum + 780 02d8 F501 movw r30,r10 + 781 02da 9387 std Z+11,r25 + 782 02dc 8287 std Z+10,r24 + 174:../../../../Lib/net/ip.c **** + 175:../../../../Lib/net/ip.c **** // add ethernet routing + 176:../../../../Lib/net/ip.c **** // check if we need to send to gateway + 177:../../../../Lib/net/ip.c **** if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) + 784 .LM71: + 785 02de 8091 0000 lds r24,IpMyConfig + 786 02e2 9091 0000 lds r25,IpMyConfig+1 + 787 02e6 A091 0000 lds r26,IpMyConfig+2 + 788 02ea B091 0000 lds r27,IpMyConfig+3 + 789 02ee 8C25 eor r24,r12 + 790 02f0 9D25 eor r25,r13 + 791 02f2 AE25 eor r26,r14 + 792 02f4 BF25 eor r27,r15 + 793 02f6 4091 0000 lds r20,IpMyConfig+4 + 794 02fa 5091 0000 lds r21,IpMyConfig+4+1 + 795 02fe 6091 0000 lds r22,IpMyConfig+4+2 + 796 0302 7091 0000 lds r23,IpMyConfig+4+3 + 797 0306 8423 and r24,r20 + 798 0308 9523 and r25,r21 + 799 030a A623 and r26,r22 + 800 030c B723 and r27,r23 + 801 030e 892B or r24,r25 + 802 0310 8A2B or r24,r26 + 803 0312 8B2B or r24,r27 + 804 0314 01F4 brne .L39 + 178:../../../../Lib/net/ip.c **** { + 179:../../../../Lib/net/ip.c **** arpIpOut(0); // local send + 806 .LM72: + 807 0316 60E0 ldi r22,0 + 808 0318 70E0 ldi r23,0 + 809 031a CB01 movw r24,r22 + 810 031c 0E94 0000 call arpIpOut + 180:../../../../Lib/net/ip.c **** #if IP_DEBUG + 181:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 812 .LM73: + 813 0320 8091 0000 lds r24,IpMyConfig+12 + 814 0324 9091 0000 lds r25,IpMyConfig+12+1 + 815 0328 0097 sbiw r24,0 + 816 032a 01F0 breq .L41 + 182:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet on local net\r\n")); + 818 .LM74: + 819 032c 20E0 ldi r18,lo8(__c.2520) + 820 032e 30E0 ldi r19,hi8(__c.2520) + 821 0330 00C0 rjmp .L53 + 822 .L39: + 183:../../../../Lib/net/ip.c **** #endif + 184:../../../../Lib/net/ip.c **** } + 185:../../../../Lib/net/ip.c **** else + 186:../../../../Lib/net/ip.c **** { + 187:../../../../Lib/net/ip.c **** arpIpOut(IpMyConfig.gateway); // gateway send + 824 .LM75: + 825 0332 6091 0000 lds r22,IpMyConfig+8 + 826 0336 7091 0000 lds r23,IpMyConfig+8+1 + 827 033a 8091 0000 lds r24,IpMyConfig+8+2 + 828 033e 9091 0000 lds r25,IpMyConfig+8+3 + 829 0342 0E94 0000 call arpIpOut + 188:../../../../Lib/net/ip.c **** #if IP_DEBUG + 189:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 831 .LM76: + 832 0346 8091 0000 lds r24,IpMyConfig+12 + 833 034a 9091 0000 lds r25,IpMyConfig+12+1 + 834 034e 0097 sbiw r24,0 + 835 0350 01F0 breq .L41 + 190:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet to gateway\r\n")); + 837 .LM77: + 838 0352 20E0 ldi r18,lo8(__c.2522) + 839 0354 30E0 ldi r19,hi8(__c.2522) + 840 .L53: + 841 0356 3F93 push r19 + 842 0358 2F93 push r18 + 843 035a 9F93 push r25 + 844 035c 8F93 push r24 + 845 035e 0E94 0000 call fprintf_P + 846 0362 0F90 pop __tmp_reg__ + 847 0364 0F90 pop __tmp_reg__ + 848 0366 0F90 pop __tmp_reg__ + 849 0368 0F90 pop __tmp_reg__ + 850 .L41: + 191:../../../../Lib/net/ip.c **** #endif + 192:../../../../Lib/net/ip.c **** } + 193:../../../../Lib/net/ip.c **** + 194:../../../../Lib/net/ip.c **** // adjust length to add ethernet header + 195:../../../../Lib/net/ip.c **** len += ETH_HEADER_LEN; + 852 .LM78: + 853 036a 0E5D subi r16,-34 + 854 036c 1F4F sbci r17,-1 + 196:../../../../Lib/net/ip.c **** + 197:../../../../Lib/net/ip.c **** #if IP_DEBUG + 198:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgStream != NULL) + 856 .LM79: + 857 036e 8091 0000 lds r24,IpMyConfig+12 + 858 0372 9091 0000 lds r25,IpMyConfig+12+1 + 859 0376 0097 sbiw r24,0 + 860 0378 01F0 breq .L43 + 199:../../../../Lib/net/ip.c **** { + 200:../../../../Lib/net/ip.c **** if (IpMyConfig.dbgLevel > 3) + 862 .LM80: + 863 037a 2091 0000 lds r18,IpMyConfig+14 + 864 037e 2430 cpi r18,lo8(4) + 865 0380 00F0 brlo .L43 + 201:../../../../Lib/net/ip.c **** { + 202:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(ETH_HEADER_LEN, &data[0]);")); + 867 .LM81: + 868 0382 20E0 ldi r18,lo8(__c.2524) + 869 0384 30E0 ldi r19,hi8(__c.2524) + 870 0386 3F93 push r19 + 871 0388 2F93 push r18 + 872 038a 9F93 push r25 + 873 038c 8F93 push r24 + 874 038e 0E94 0000 call fprintf_P + 203:../../../../Lib/net/ip.c **** fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER + 876 .LM82: + 877 0392 80E0 ldi r24,lo8(__c.2526) + 878 0394 90E0 ldi r25,hi8(__c.2526) + 879 0396 9F93 push r25 + 880 0398 8F93 push r24 + 881 039a 8091 0000 lds r24,IpMyConfig+13 + 882 039e 8F93 push r24 + 883 03a0 8091 0000 lds r24,IpMyConfig+12 + 884 03a4 8F93 push r24 + 885 03a6 0E94 0000 call fprintf_P + 886 03aa 0FB6 in __tmp_reg__,__SREG__ + 887 03ac F894 cli + 888 03ae DEBF out __SP_H__,r29 + 889 03b0 0FBE out __SREG__,__tmp_reg__ + 890 03b2 CDBF out __SP_L__,r28 + 891 .L43: + 204:../../../../Lib/net/ip.c **** } + 205:../../../../Lib/net/ip.c **** } + 206:../../../../Lib/net/ip.c **** #endif + 207:../../../../Lib/net/ip.c **** // send it + 208:../../../../Lib/net/ip.c **** nicSend(len); + 893 .LM83: + 894 03b4 C801 movw r24,r16 + 895 /* epilogue start */ + 209:../../../../Lib/net/ip.c **** } + 897 .LM84: + 898 03b6 0F90 pop __tmp_reg__ + 899 03b8 DF91 pop r29 + 900 03ba CF91 pop r28 + 901 03bc 1F91 pop r17 + 902 03be 0F91 pop r16 + 903 03c0 FF90 pop r15 + 904 03c2 EF90 pop r14 + 905 03c4 DF90 pop r13 + 906 03c6 CF90 pop r12 + 907 03c8 BF90 pop r11 + 908 03ca AF90 pop r10 + 208:../../../../Lib/net/ip.c **** } + 910 .LM85: + 911 03cc 0C94 0000 jmp nicSend + 913 .Lscope11: + 915 .stabd 78,0,0 + 918 .global ipPrintConfig + 920 ipPrintConfig: + 921 .stabd 46,0,0 + 210:../../../../Lib/net/ip.c **** + 211:../../../../Lib/net/ip.c **** void ipPrintConfig(FILE *stream, struct ipConfig* config) + 212:../../../../Lib/net/ip.c **** { + 923 .LM86: + 924 .LFBB12: + 925 03d0 0F93 push r16 + 926 03d2 1F93 push r17 + 927 03d4 CF93 push r28 + 928 03d6 DF93 push r29 + 929 /* prologue: function */ + 930 /* frame size = 0 */ + 931 /* stack size = 4 */ + 932 .L__stack_usage = 4 + 933 03d8 EC01 movw r28,r24 + 934 03da 8B01 movw r16,r22 + 213:../../../../Lib/net/ip.c **** fprintf_P(stream, PSTR("IP Addr : ")); netPrintIPAddr(stream, config->ip); fprintf_P(strea + 936 .LM87: + 937 03dc 80E0 ldi r24,lo8(__c.2532) + 938 03de 90E0 ldi r25,hi8(__c.2532) + 939 03e0 9F93 push r25 + 940 03e2 8F93 push r24 + 941 03e4 DF93 push r29 + 942 03e6 CF93 push r28 + 943 03e8 0E94 0000 call fprintf_P + 944 03ec F801 movw r30,r16 + 945 03ee 4081 ld r20,Z + 946 03f0 5181 ldd r21,Z+1 + 947 03f2 6281 ldd r22,Z+2 + 948 03f4 7381 ldd r23,Z+3 + 949 03f6 CE01 movw r24,r28 + 950 03f8 0E94 0000 call netPrintIPAddr + 951 03fc 80E0 ldi r24,lo8(__c.2534) + 952 03fe 90E0 ldi r25,hi8(__c.2534) + 953 0400 9F93 push r25 + 954 0402 8F93 push r24 + 955 0404 DF93 push r29 + 956 0406 CF93 push r28 + 957 0408 0E94 0000 call fprintf_P + 214:../../../../Lib/net/ip.c **** fprintf_P(stream, PSTR("Netmask : ")); netPrintIPAddr(stream, config->netmask); fprintf_P(strea + 959 .LM88: + 960 040c 80E0 ldi r24,lo8(__c.2536) + 961 040e 90E0 ldi r25,hi8(__c.2536) + 962 0410 9F93 push r25 + 963 0412 8F93 push r24 + 964 0414 DF93 push r29 + 965 0416 CF93 push r28 + 966 0418 0E94 0000 call fprintf_P + 967 041c F801 movw r30,r16 + 968 041e 4481 ldd r20,Z+4 + 969 0420 5581 ldd r21,Z+5 + 970 0422 6681 ldd r22,Z+6 + 971 0424 7781 ldd r23,Z+7 + 972 0426 CE01 movw r24,r28 + 973 0428 0E94 0000 call netPrintIPAddr + 974 042c 80E0 ldi r24,lo8(__c.2538) + 975 042e 90E0 ldi r25,hi8(__c.2538) + 976 0430 9F93 push r25 + 977 0432 8F93 push r24 + 978 0434 DF93 push r29 + 979 0436 CF93 push r28 + 980 0438 0E94 0000 call fprintf_P + 215:../../../../Lib/net/ip.c **** fprintf_P(stream, PSTR("Gateway : ")); netPrintIPAddr(stream, config->gateway); fprintf_P(strea + 982 .LM89: + 983 043c 80E0 ldi r24,lo8(__c.2540) + 984 043e 90E0 ldi r25,hi8(__c.2540) + 985 0440 9F93 push r25 + 986 0442 8F93 push r24 + 987 0444 DF93 push r29 + 988 0446 CF93 push r28 + 989 0448 0E94 0000 call fprintf_P + 990 044c F801 movw r30,r16 + 991 044e 4085 ldd r20,Z+8 + 992 0450 5185 ldd r21,Z+9 + 993 0452 6285 ldd r22,Z+10 + 994 0454 7385 ldd r23,Z+11 + 995 0456 CE01 movw r24,r28 + 996 0458 0E94 0000 call netPrintIPAddr + 997 045c 80E0 ldi r24,lo8(__c.2542) + 998 045e 90E0 ldi r25,hi8(__c.2542) + 999 0460 9F93 push r25 + 1000 0462 8F93 push r24 + 1001 0464 DF93 push r29 + 1002 0466 CF93 push r28 + 1003 0468 0E94 0000 call fprintf_P + 1004 046c 8DB7 in r24,__SP_L__ + 1005 046e 9EB7 in r25,__SP_H__ + 1006 0470 4896 adiw r24,24 + 1007 0472 0FB6 in __tmp_reg__,__SREG__ + 1008 0474 F894 cli + 1009 0476 9EBF out __SP_H__,r25 + 1010 0478 0FBE out __SREG__,__tmp_reg__ + 1011 047a 8DBF out __SP_L__,r24 + 1012 /* epilogue start */ + 216:../../../../Lib/net/ip.c **** } + 1014 .LM90: + 1015 047c DF91 pop r29 + 1016 047e CF91 pop r28 + 1017 0480 1F91 pop r17 + 1018 0482 0F91 pop r16 + 1019 0484 0895 ret + 1021 .Lscope12: + 1023 .stabd 78,0,0 + 1024 .section .progmem.data,"a",@progbits + 1027 __c.2542: + 1028 0000 0D0A 00 .string "\r\n" + 1031 __c.2540: + 1032 0003 4761 7465 .string "Gateway : " + 1032 7761 7920 + 1032 3A20 00 + 1035 __c.2538: + 1036 000e 0D0A 00 .string "\r\n" + 1039 __c.2536: + 1040 0011 4E65 746D .string "Netmask : " + 1040 6173 6B20 + 1040 3A20 00 + 1043 __c.2534: + 1044 001c 0D0A 00 .string "\r\n" + 1047 __c.2532: + 1048 001f 4950 2041 .string "IP Addr : " + 1048 6464 7220 + 1048 3A20 00 + 1051 __c.2526: + 1052 002a 6465 6275 .string "debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]);" + 1052 6750 7269 + 1052 6E74 4865 + 1052 7854 6162 + 1052 6C65 286C + 1055 __c.2524: + 1056 0069 6465 6275 .string "debugPrintHexTable(ETH_HEADER_LEN, &data[0]);" + 1056 6750 7269 + 1056 6E74 4865 + 1056 7854 6162 + 1056 6C65 2845 + 1059 __c.2522: + 1060 0097 5365 6E64 .string "Sending IP packet to gateway\r\n" + 1060 696E 6720 + 1060 4950 2070 + 1060 6163 6B65 + 1060 7420 746F + 1063 __c.2520: + 1064 00b6 5365 6E64 .string "Sending IP packet on local net\r\n" + 1064 696E 6720 + 1064 4950 2070 + 1064 6163 6B65 + 1064 7420 6F6E + 1067 __c.2492: + 1068 00d7 4E45 5420 .string "NET Rx: Unknown IP packet\r\n" + 1068 5278 3A20 + 1068 556E 6B6E + 1068 6F77 6E20 + 1068 4950 2070 + 1071 __c.2490: + 1072 00f3 4E45 5420 .string "NET Rx: UDP/IP packet\r\n" + 1072 5278 3A20 + 1072 5544 502F + 1072 4950 2070 + 1072 6163 6B65 + 1075 __c.2488: + 1076 010b 4E45 5420 .string "NET Rx: ICMP/IP packet\r\n" + 1076 5278 3A20 + 1076 4943 4D50 + 1076 2F49 5020 + 1076 7061 636B + 1077 .section .eeprom,"aw",@progbits + 1080 defGw_eep: + 1081 0000 C0 .byte -64 + 1082 0001 A8 .byte -88 + 1083 0002 00 .byte 0 + 1084 0003 01 .byte 1 + 1087 mask_eep: + 1088 0004 FF .byte -1 + 1089 0005 FF .byte -1 + 1090 0006 FF .byte -1 + 1091 0007 00 .byte 0 + 1094 myip_eep: + 1095 0008 C0 .byte -64 + 1096 0009 A8 .byte -88 + 1097 000a 00 .byte 0 + 1098 000b 02 .byte 2 + 1099 .comm IpMyConfig,15,1 + 1100 .comm udpDbgLevel,1,1 + 1101 .comm udpDbgStream,2,1 + 1102 .comm udpSocket,2,1 + 1103 .comm icmpDebugLevel,1,1 + 1104 .comm icmpDebug,2,1 + 1105 .comm arpDebugLevel,1,1 + 1106 .comm arpDebug,2,1 + 1107 .comm nicState,14,1 + 1108 .comm wwwport,1,1 + 1122 .weak nicSend + 1123 .text + 1125 .Letext0: + 1126 .ident "GCC: (GNU) 4.9.2" + 1127 .global __do_copy_data + 1128 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 ip.c + /tmp/cchyldcg.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cchyldcg.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cchyldcg.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cchyldcg.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cchyldcg.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cchyldcg.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cchyldcg.s:162 .text:0000000000000000 ipInit + /tmp/cchyldcg.s:179 .text:0000000000000002 ipLoadConfig + /tmp/cchyldcg.s:1094 .eeprom:0000000000000008 myip_eep + *COM*:000000000000000f IpMyConfig + /tmp/cchyldcg.s:1087 .eeprom:0000000000000004 mask_eep + /tmp/cchyldcg.s:1080 .eeprom:0000000000000000 defGw_eep + /tmp/cchyldcg.s:241 .text:0000000000000046 ipSaveConfig + /tmp/cchyldcg.s:295 .text:0000000000000082 netstackIPv4Process + *COM*:000000000000000e nicState + /tmp/cchyldcg.s:1075 .progmem.data:000000000000010b __c.2488 + /tmp/cchyldcg.s:1071 .progmem.data:00000000000000f3 __c.2490 + /tmp/cchyldcg.s:1067 .progmem.data:00000000000000d7 __c.2492 + /tmp/cchyldcg.s:481 .text:000000000000019e setIpDebug + /tmp/cchyldcg.s:517 .text:00000000000001b8 ipSetConfig + /tmp/cchyldcg.s:566 .text:00000000000001e6 ipSetConfigIp + /tmp/cchyldcg.s:590 .text:00000000000001f8 ipSetConfigMask + /tmp/cchyldcg.s:614 .text:000000000000020a ipSetConfigGw + /tmp/cchyldcg.s:637 .text:000000000000021c ipGetConfig + /tmp/cchyldcg.s:665 .text:0000000000000222 ipSend + /tmp/cchyldcg.s:1063 .progmem.data:00000000000000b6 __c.2520 + /tmp/cchyldcg.s:1059 .progmem.data:0000000000000097 __c.2522 + /tmp/cchyldcg.s:1055 .progmem.data:0000000000000069 __c.2524 + /tmp/cchyldcg.s:1051 .progmem.data:000000000000002a __c.2526 + /tmp/cchyldcg.s:920 .text:00000000000003d0 ipPrintConfig + /tmp/cchyldcg.s:1047 .progmem.data:000000000000001f __c.2532 + /tmp/cchyldcg.s:1043 .progmem.data:000000000000001c __c.2534 + /tmp/cchyldcg.s:1039 .progmem.data:0000000000000011 __c.2536 + /tmp/cchyldcg.s:1035 .progmem.data:000000000000000e __c.2538 + /tmp/cchyldcg.s:1031 .progmem.data:0000000000000003 __c.2540 + /tmp/cchyldcg.s:1027 .progmem.data:0000000000000000 __c.2542 + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +eeprom_read_dword +eeprom_update_dword +fprintf_P +icmpPrintHeader +icmpIpIn +netstackUDPIPProcess +htons +netChecksum +arpIpOut +nicSend +netPrintIPAddr +__do_copy_data +__do_clear_bss diff --git a/Lib/net/ipv6-nd.c b/Lib/net/ipv6-nd.c new file mode 100644 index 0000000..2e2ac34 --- /dev/null +++ b/Lib/net/ipv6-nd.c @@ -0,0 +1,410 @@ +/** + * @file ipv6-nd.c + * @brief IP Network Discovery + * + * Please Notice, that we do have a fwe strategies - Router Discovery/Solicitation, Neighbour Discovery/Solicitation + * For now, only Neighbour Discovery is implemented + */ + +#include "ipv6-nd.h" +#include "include/ipv6-nd.h" + +/** \brief Offset from the end of the icmpv6 header to the option in uip_buf*/ +static u8_t nd6_opt_offset; +/** \brief Pointer to llao option in uip_buf */ +static struct uip_nd6_opt_llao *nd6_opt_llao; +/** \brief Pointer to an interface address */ +static struct uip_netif_addr *ifaddr; + +void vNDinit(void) +{ + entries = xmalloc( ENTRIES * sizeof(neighbor_entry)); + #if IP_DEBUG + fprintf_P(debugStream, PSTR("ENTRIES %d %d:"), ENTRIES, sizeof(neighbor_entry)); + #endif/**IP_DEBUG*/ + + for(uint8_t i = 0; i < ENTRIES; ++i) { + entries[i].time = 0; + } +} + +#if IP_DEBUG +void vNDDebugInit(FILE *stream) +{ + debugStream = stream; +} +#endif/**IP_DEBUG*/ + +#if JM +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_add(uip_ipaddr_t *ipaddr, struct netEthAddr *addr) +{ + uint8_t i, insertPos; + uint32_t oldestTime = 0xFFFFFFFF; + + //#if IP_DEBUG + fprintf_P(debugStream, PSTR("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n\r"), + addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], + addr->addr[4], addr->addr[5]); + + + fprintf_P(debugStream, PSTR("SizeofInt %d %d \n\r"), + sizeof(int), xTaskGetTickCount()); + //#endif/**IP_DEBUG*/ + + insertPos = 0; + /* Find the first unused entry or the oldest used entry. */ + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time == 0) { + insertPos = i; + break; + } + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { + insertPos = i; + break; + } + if(entries[i].time < oldestTime) { + oldestTime = entries[i].time; + insertPos =i; + } + } + + fprintf_P(debugStream, PSTR("oldestTime %d \n\r"),oldestTime); + + /* Use the oldest or first free entry (either pointed to by the + "oldestTime" variable). */ + entries[insertPos].time = (uint32_t)xTaskGetTickCount(); + uip_ipaddr_copy(&entries[insertPos].ipaddr, ipaddr); + memcpy(&entries[insertPos].addr, addr, sizeof(struct netEthAddr)); + + //#if IP_DEBUG + fprintf_P(debugStream, PSTR("EntryPacket[0]:\r\n")); + for (i =0; i < sizeof(neighbor_entry); i++) + fprintf_P(debugStream, PSTR("%02x:"), ((uint8_t *)entries)[i]); + fprintf_P(debugStream, PSTR("\n\r")); + + fprintf_P(debugStream, PSTR("link address %02x:%02x:%02x:%02x:%02x:%02x\n\r"), + entries[0].addr.addr[0], entries[0].addr.addr[1], entries[0].addr.addr[2], entries[0].addr.addr[3], + entries[0].addr.addr[4], entries[0].addr.addr[5]); + + fprintf_P(debugStream, PSTR("IP address:\r\n")); + fprintf_P(debugStream, PSTR("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"), + entries[0].ipaddr.u8[0], entries[0].ipaddr.u8[1], + entries[0].ipaddr.u8[2], entries[0].ipaddr.u8[3], + entries[0].ipaddr.u8[4], entries[0].ipaddr.u8[5], + entries[0].ipaddr.u8[6], entries[0].ipaddr.u8[7], + entries[0].ipaddr.u8[8], entries[0].ipaddr.u8[9], + entries[0].ipaddr.u8[10], entries[0].ipaddr.u8[11], + entries[0].ipaddr.u8[12], entries[0].ipaddr.u8[13], + entries[0].ipaddr.u8[14], entries[0].ipaddr.u8[15]); + fprintf_P(debugStream, PSTR("\r\n")); + //#endif/**IP_DEBUG*/ +} +/*---------------------------------------------------------------------------*/ +neighbor_entry * +find_entry(uip_ipaddr_t *ipaddr) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { + return &entries[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +#endif /*JM*/ + +void uip_nd6_io_ns_input(uint16_t packetLenght) +{ + + fprintf_P(debugStream, PSTR("Received NS from\n\r")); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->srcipaddr); + fprintf_P(debugStream, PSTR("to\n\r")); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->destipaddr); + ///Adres z icmpv6 header'a + PRINTF2(debugStream,"with target address\n\r"); + PRINT6ADDR(debugStream, (&UIP_ND6_NS_BUF->tgtipaddr)); + /* + PRINTF2(debugStream,"with target address\n\r"); + fprintf_P(debugStream, PSTR("to (l2 %04x)\n\r"), &nicState.layer2.buf[14+40+4]); + fprintf_P(debugStream, PSTR("to (l4 %04x)\n\r"), nicState.layer4.buf); + fprintf_P(debugStream, PSTR("to (l4 %04x)\n\r"), &((struct uip_nd6_ns *)&nicState.layer2.buf[14+40+4])->tgtipaddr); + PRINT6ADDR(debugStream, &((struct uip_nd6_ns *)&nicState.layer2.buf[14+40+4])->tgtipaddr ); + PRINT6ADDR(debugStream, &((struct uip_nd6_ns *) (nicState.layer4.buf + 4))->tgtipaddr ); + */ + + u8_t flags; + + + /* Options reading: we handle only SLLAO for now */ + nd6_opt_llao = NULL; + nd6_opt_offset = UIP_ND6_NS_LEN; + + fprintf_P(debugStream, PSTR("uip_l2_l3_icmp_hdr_len %04x; packetLenght %04x ; UIP_ND6_OPT_HDR_BUF %04x, nd6_opt_offset %04x\r\n"), + uip_l2_l3_icmp_hdr_len, packetLenght, + UIP_ND6_OPT_HDR_BUF, nd6_opt_offset ); + fprintf_P(debugStream, PSTR("ICMPv6 payload: \r\n")); + for (uint8_t i=UIP_ND6_NS_LEN + UIP_ICMPH_LEN; i < 32; i++) ///Tu dlugosc ICMP + { + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer3.buf[i+UIP_IPH_LEN]); + } + fprintf_P(debugStream, PSTR("\r\n")); + + + while(uip_l2_l3_icmp_hdr_len + nd6_opt_offset < packetLenght) { +#if UIP_CONF_IPV6_CHECKS + if(UIP_ND6_OPT_HDR_BUF->len == 0) { + goto badpkt; + } +#endif /* UIP_CONF_IPV6_CHECKS */ + switch(UIP_ND6_OPT_HDR_BUF->type) { + case UIP_ND6_OPT_SLLAO: + nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; + break; + default: + PRINTF2(debugStream,"ND option not supported in NS"); + break; + } + nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); + } + + + + + /* Options processing: only SLLAO */ + if(nd6_opt_llao != NULL) { +#if UIP_CONF_IPV6_CHECKS + /* There must be NO option in a DAD NS */ + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { + goto badpkt; + } else { +#endif /*UIP_CONF_IPV6_CHECKS*/ +/* + neighbor = uip_nd6_nbrcache_lookup(&UIP_IP_BUF->srcipaddr); + if(neighbor == NULL) { + /* we need to add the neighbor* + uip_nd6_nbrcache_add(&UIP_IP_BUF->srcipaddr, + &nd6_opt_llao->addr, 0, STALE); + } else { + /* If LL address changed, set neighbor state to stale * + if(memcmp(&nd6_opt_llao->addr, &neighbor->lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); + neighbor->state = STALE; + } else { + /* If neighbor state is INCOMPLETE, set to STALE * + if(neighbor->state == INCOMPLETE) { + neighbor->state = STALE; + } + } + } +*/ +#if UIP_CONF_IPV6_CHECKS + } +#endif /*UIP_CONF_IPV6_CHECKS*/ + } + + /* + * Rest of NS processing: Depends on the purpose of the NS: NUD or DAD or + * Address Resolution + */ + ifaddr = xmalloc(sizeof(struct uip_netif_addr)); + /** \note we use ifaddr to remember the target address */ + memcpy(&ifaddr->ipaddr, &UIP_ND6_NS_BUF->tgtipaddr, sizeof(uip_ip6addr_t)); + + fprintf_P(debugStream, PSTR("ifaddr: ** %04x \r\n"), &ifaddr->ipaddr); + PRINT6ADDR(debugStream, &ifaddr->ipaddr); + PRINT6ADDR(debugStream, &UIP_ND6_NS_BUF->tgtipaddr); + //ifaddr = uip_netif_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr, 128, 0); //Sprawdza czy to nasz adres, narazie wylaczone + if(ifaddr != NULL) + { +#if JM + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){ + /* DAD CASE */ +//#if UIP_CONF_IPV6_CHECKS + /* Dst address must be solicited node mcast address */ + if(!uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){ + goto badpkt; + } +//#endif /* UIP_CONF_IPV6_CHECKS */ + /* + * If my address is not tentative, then send a NA to all nodes with + * TLLAO flags are: override = yes. + */ + if(ifaddr->state!=TENTATIVE) { + /* + * we need to send a NA, we set the src, dest, flags. tgt remains the + * same and the rest is done at "create_na" + */ + uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); + uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + flags = UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } else { + /** \todo if I sent a NS before him, I win */ + uip_netif_dad_failed(&UIP_ND6_NS_BUF->tgtipaddr); + goto discard; + } + } +#endif //JM + +#if UIP_CONF_IPV6_CHECKS + /* Duplicate check */ ///Tego narazie tez nie robie + if(uip_netif_is_addr_my_unicast(&UIP_IP_BUF->srcipaddr)) { + /** + * \NOTE do we do something here? we both are using the same address. + * If we are doing dad, we could cancel it, though we should receive a + * NA in response of DAD NS we sent, hence DAD will fail anyway. If we + * were not doing DAD, it means there is a duplicate in the network! + */ + goto badpkt; + } +#endif /*UIP_CONF_IPV6_CHECKS*/ + + ///Bez tego powinno dzialac + /* Address resolution case */ + if(0){ + //if(uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){ + /* + * we need to send a NA, we set the src, dest, flags. The rest is + * set at the "create_na" label. + */ + ///uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); + ///uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); + ///flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } + + /* + * NUD CASE. at this point the packet must be for us! we check this, + * and at the same time if target == dest + */ + ///Tu wyszukiwanie adresu jest nie tak - narazie przepuszcze dla tesotwego pakietu na staÅ‚e + //if(uip_netif_addr_lookup(&UIP_IP_BUF->destipaddr, 128, 0) == ifaddr){ + if(1) + { + /* + * we need to send a NA, we set the src, dest, flags. The rest is set + * at the "create_na" label. + */ + fprintf_P(debugStream, PSTR("uip_netif_addr_lookup: \r\n")); + + fprintf_P(debugStream, PSTR("ORG addr: \r\n")); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->destipaddr); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->srcipaddr); + + + memcpy(&nicState.layer3.ipv6->destipaddr, &nicState.layer3.ipv6->srcipaddr, sizeof(uip_ip6addr_t)); + memcpy(&nicState.layer3.ipv6->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr, sizeof(uip_ip6addr_t)); + + fprintf_P(debugStream, PSTR("MOD addr: \r\n")); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->destipaddr); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->srcipaddr); + + + + ///uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); + ///uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); + flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } else { +#if UIP_CONF_IPV6_CHECKS + goto badpkt; +#endif /* UIP_CONF_IPV6_CHECKS */ + } + } else { + goto discard; + } + + + create_na: + /* + * Fill the part of the NA which is common to all NAs. If the NS contained + * extension headers, we must set the target address properly + */ + uip_ext_len = 0; + +#ifdef DEBUG_PRINT_NET_PACKET + fprintf_P(debugStream, PSTR("NS packet before:\r\n")); + for (uint8_t i=0; i < packetLenght; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); +#endif + + + /* IP header */ + //UIP_IP_BUF->vtc = 0x60; + nicState.layer3.ipv6->vtc = 0x60; + nicState.layer3.ipv6->tcflow = 0; + nicState.layer3.ipv6->flow = 0; + nicState.layer3.ipv6->len[0] = 0; /* length will not be more than 255 */ + nicState.layer3.ipv6->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; + nicState.layer3.ipv6->proto = UIP_PROTO_ICMP6; + nicState.layer3.ipv6->ttl = UIP_ND6_HOP_LIMIT; + + /* ICMP header */ + UIP_ICMP_BUF->type = ICMP6_NA; + UIP_ICMP_BUF->icode = 0; + + /* NA static part */ + UIP_ND6_NA_BUF->flagsreserved = flags; + memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &ifaddr->ipaddr, sizeof(uip_ipaddr_t)); ///////////////////// + + /* NA option: TLLAO. note that length field is in unit of 8 bytes */ + packetLenght = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN + ETH_HEADER_LEN; + nd6_opt_llao = (struct uip_nd6_opt_llao *)&nicState.layer2.buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN]; + nd6_opt_llao->type = UIP_ND6_OPT_TLLAO; + nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; + + fprintf_P(debugStream, PSTR("&nicState.mac.addr %02x \n\r"), &nicState.mac.addr); + + memcpy(&(nd6_opt_llao->addr.addr), &nicState.mac.addr, ETH_HEADER_LEN); + /* padding if needed */ + memset((void *)(&nd6_opt_llao->addr.addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); + + /*ICMP checksum*/ + fprintf_P(debugStream, PSTR("nicState.layer4.icmp->icmpchksum %04x\n\r"), UIP_ICMP_BUF->icmpchksum ); + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + ///nicState.layer4.icmpv6->icmpchksum = 0; + ///nicState.layer4.icmpv6->icmpchksum = ~uip_icmp6chksum(); + //netChecksum((uint8_t*)(&nicState.layer4.icmpv6 + 4), 28 );// htons(nicState.layer3.ip->len)-IP_HEADER_LEN); + fprintf_P(debugStream, PSTR("nicState.layer4.icmp->icmpchksum %04x\n\r"), UIP_ICMP_BUF->icmpchksum ); + //nicState.layer4.icmpv6->icmpchksum = 0x923b; + + #ifdef DEBUG_PRINT_NET_PACKET + fprintf_P(debugStream, PSTR("NS packet AFTER:\r\n")); + for (uint8_t i=0; i < packetLenght; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); +#endif + + PRINTF2(debugStream,"Sending NA to\n\r"); + PRINT6ADDR(debugStream,&UIP_IP_BUF->destipaddr); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->destipaddr); + PRINTF2(debugStream,"from\n\r"); + PRINT6ADDR(debugStream,&UIP_IP_BUF->srcipaddr); + PRINT6ADDR(debugStream, &nicState.layer3.ipv6->srcipaddr); + PRINTF2(debugStream,"with target address\n\r"); + PRINT6ADDR(debugStream,&UIP_ND6_NA_BUF->tgtipaddr); + return; + +#if UIP_CONF_IPV6_CHECKS + badpkt: + PRINTF2(debugStream,"NS received is bad\n\r"); +#endif /* UIP_CONF_IPV6_CHECKS */ + + discard: + packetLenght = 0; + return; + +} + diff --git a/Lib/net/ipv6.c b/Lib/net/ipv6.c new file mode 100644 index 0000000..17693b9 --- /dev/null +++ b/Lib/net/ipv6.c @@ -0,0 +1,232 @@ +/** + * Deklaracje glownych funkcji ipv6 + */ + +#include "ipv6.h" +#include "../../freeRtos/Lib/net/include/ipv6.h" + +void ipv6Init(void) +{ + //Ipv6MyConfig.ip = xmalloc(sizeof(uip_ip6addr_t)); + //Ipv6MyConfig.prefix= 64; + //Ipv6MyConfig.gateway = xmalloc(sizeof(uip_ip6addr_t)); +} + +void netstackIPv6Process(void) +{ + //uip_ip6addr_t *ipv6addr; + #if IP_DEBUG + fprintf_P(debugStream, PSTR("*IPv6 packet in. Length: %d\r\n"), plen); + netPrintIpv6Header(debugStream); + //netPrintIpv6HeaderRAW(debugStream); + netPrintIpv6PayloadRAW(debugStream); + ipv6PrintConfig(debugStream, uip_netif_physical_if); + #endif /*IP_DEBUG*/ + + if(checkPacketLen() == 1) + { + + + // if(!uip_netif_is_addr_my_unicast(&UIP_IP_BUF->destipaddr) && + // !uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr) && + // !uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr)){ + // UIP_STAT(++uip_stat.ip.drop); + // goto drop; + + + if(UIP_ICMP_BUF->type==ICMP6_ECHO_REQUEST) + { + //reply + uip_icmp6_echo_request_input(); + swithEthAddresses(); + nicSend(plen); + } + if(UIP_ICMP_BUF->type==ICMP6_NS) + { + //reply ICMP6_NA + fprintf_P(debugStream, PSTR("NS, length=%d, \r\n"), plen); + for (uint8_t i=0; i < plen; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); + uip_nd6_io_ns_input(plen); + swithEthAddresses(); + fprintf_P(debugStream, PSTR("Packet out, length=%d, \r\n"), plen); + for (uint8_t i=0; i < plen; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); + nicSend(86); + } + if(UIP_IP_BUF->proto==IP_PROTO_TCP) + { + fprintf_P(debugStream, PSTR("TCP packet in, \r\n")); + netstackTCPIPProcess6(); + } + } + else + { + #if IP_DEBUG + fprintf_P(debugStream, PSTR("ip: packet shorter than reported in IP header.\n\r")); + #endif /*IP_DEBUG*/ + } + +} + +void swithEthAddresses(void) +{ + /* fprintf_P(debugStream, PSTR("Packet out, length=%d, \r\n"), plen); + for (uint8_t i=0; i < plen; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); + */ + memcpy(&nicState.layer2.ethHeader->dest, &nicState.layer2.ethHeader->src, 6); + memcpy(&nicState.layer2.ethHeader->src, &nicState.mac, 6); + nicState.layer2.ethHeader->type = 0xdd86; + /* + fprintf_P(debugStream, PSTR("Packet out, length=%d, \r\n"), plen); + for (uint8_t i=0; i < plen; i++) + { + if (i!=0 && i%16==0) fprintf_P(debugStream, PSTR("\r\n")); + fprintf_P(debugStream, PSTR("%02x:"), nicState.layer2.buf[i]); + } + fprintf_P(debugStream, PSTR("\r\n")); + */ +} + +void ipv6DebugInit(FILE* inDebugStream) +{ + debugStream = inDebugStream; +} + +uint8_t checkPacketLen() +{ + // 1 - packet ok, 0 - wrong length + if(plen <= (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1]) + return 0; + else + return 1; + +} + +void netPrintIpv6HeaderRAW(FILE *stream) +{ + fprintf_P(stream, PSTR("*IPv6 Header RAW:\r\n")); + fprintf_P(stream, PSTR("\t")); + for (uint8_t i=0; i < UIP_IPv6H_LEN; i++) + { + if (i!=0 && i%16==0) + { + fprintf_P(stream, PSTR("\r\n")); + fprintf_P(stream, PSTR("\t")); + } + fprintf_P(stream, PSTR("%02x:"), nicState.layer3.buf[i]); + } + fprintf_P(stream, PSTR("\r\n")); +} + +void netPrintIpv6Header(FILE *stream) +{ + fprintf_P(stream, PSTR("*IPv6 Header:\r\n")); + fprintf_P(stream, PSTR("\tVersion: \t\t")); + fprintf_P(stream, PSTR("\t%d \n\r"), (nicState.layer3.ipv6->vtc >> 4)); + fprintf_P(stream, PSTR("\tTraffic Class: \t\t")); + fprintf_P(stream, PSTR("\t%d \n\r"), nicState.layer3.ipv6->vtc & 0x0F + (nicState.layer3.ipv6->tcflow >> 4)); + fprintf_P(stream, PSTR("\tFlow Label: \t\t")); + fprintf_P(stream, PSTR("\t%d \n\r"), nicState.layer3.ipv6->tcflow & 0x0F + (nicState.layer3.ipv6->flow << 4)); + fprintf_P(stream, PSTR("\tPayload Length: \t")); + fprintf_P(stream, PSTR("\t%d \n\r"), nicState.layer3.ipv6->len[1] + (nicState.layer3.ipv6->len[0] << 8)); + fprintf_P(stream, PSTR("\tSource address: \t")); + PRINT6ADDR(stream, &nicState.layer3.ipv6->srcipaddr); + fprintf_P(stream, PSTR("\tDestination address: \t")); + PRINT6ADDR(stream, &nicState.layer3.ipv6->destipaddr); +} + +void netPrintIpv6PayloadRAW(FILE *stream) +{ + uint16_t payloadLen=nicState.layer3.ipv6->len[1] + (nicState.layer3.ipv6->len[0] << 8); + fprintf_P(stream, PSTR("*IPv6 Payload RAW:\r\n")); + fprintf_P(stream, PSTR("\t")); + for (uint8_t i=0; i < payloadLen; i++) + { + if (i!=0 && i%16==0) + { + fprintf_P(stream, PSTR("\r\n")); + fprintf_P(stream, PSTR("\t")); + } + fprintf_P(stream, PSTR("%02x:"), nicState.layer3.buf[i + UIP_IPv6H_LEN]); + } + fprintf_P(stream, PSTR("\r\n")); +} + +void ipv6PrintConfig(FILE *stream, struct uip_netif* config) +{ + //Currently not all settings are printed + fprintf_P(stream, PSTR("*Interface IPv6 config:\n\r")); + uint8_t i; + fprintf_P(stream, PSTR("\tAddresses:\n\r")); + for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) + if(config->addresses[i].state != NOT_USED) + { + fprintf_P(stream, PSTR("\tAddress %d:\t\t"), i); + PRINT6ADDR(stream, &config->addresses[i].ipaddr); + } + fprintf_P(stream, PSTR("\tSolicited node mcast address:")); + PRINT6ADDR(stream, &config->solicited_node_mcastaddr); +} + +void ipv6Send(uint8_t protocol, uint16_t len) +{ +// make pointer to ethernet/IP header +//#if IP_DEBUG + //if (debugStream != NULL) + { + //if (IpMyConfig.dbgLevel > 2) + fprintf_P(debugStream, PSTR("Sending Ip packet\r\n")); + } +//#endif + + //Exchange eth addresses + swithEthAddresses(); + + // adjust length to add IP header + //len += IP_HEADER_LEN; + + // fill IP header + + uip_ip6addr_t *tmp_ipaddr; + tmp_ipaddr = xmalloc(sizeof(uip_ip6addr_t)); + memcpy(tmp_ipaddr, &UIP_IP_BUF->srcipaddr, sizeof(uip_ip6addr_t)); + memcpy(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr, sizeof(uip_ip6addr_t)); + memcpy(&UIP_IP_BUF->destipaddr, tmp_ipaddr, sizeof(uip_ip6addr_t)); + + + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->len[0] = (len & 0xFF00); /* more than 255 */ + UIP_IP_BUF->len[1] = (len & 0x00FF); + UIP_IP_BUF->proto = protocol; + UIP_IP_BUF->ttl = IP_TIME_TO_LIVE; + + + ///UIP_TCP_BUF->tcpchksum = 0; + ///UIP_TCP_BUF->tcpchksum = 0; + +// adjust length to add ethernet and IPv6 header + len += ETH_HEADER_LEN + UIP_IPH_LEN; + +// send it + nicSend(len); +} + +//void ipv6Send(uint32_t dstIpv6, uint8_t protocol, uint16_t len); +//void netPrintIpv6Header(FILE *stream, struct netIpv6Header* ipheader); +//void ipSetConfigIpv6(uint32_t myIp); \ No newline at end of file diff --git a/Lib/net/net.c b/Lib/net/net.c new file mode 100644 index 0000000..1502e09 --- /dev/null +++ b/Lib/net/net.c @@ -0,0 +1,117 @@ +/** + * @file net.c + * @author Pascal Stang, Adam Kaliszan + * @brief Network support library. + * @version 0.1 + * Created 30.08.2004 + * Revised 25.11.2010 + * Editor Tabs 2 + */ + +#include "net.h" + + +uint16_t ntohs(uint16_t val) +{ + return (val<<8) | (val>>8); +} + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); +} + +uint32_t htonl(uint32_t val) +{ + return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); +} + +uint32_t ntohl(uint32_t val) +{ + return (ntohs(val>>16) | (uint32_t)ntohs(val&0x0000FFFF)<<16); +} + + +uint16_t netChecksum(uint8_t *data, uint16_t len) +{ + register uint32_t sum = 0; + + for (;;) + { + if (len < 2) + break; +//sum += *((uint16_t *)data)++; + sum += *((uint16_t *)data); + data+=2; + len -= 2; + } + if (len) + sum += *(uint8_t *) data; + + while ((len = (uint16_t) (sum >> 16)) != 0) + sum = (uint16_t) sum + len; + + return (uint16_t) sum ^ 0xFFFF; +} + +void netPrintEthAddr(FILE *stream, struct netEthAddr* ethaddr) +{ + fprintf_P(stream, PSTR("%02x:%02x:%02x:%02x:%02x:%02x"), ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]); +} + +void netPrintIPAddr(FILE *stream, uint32_t ipaddr) +{ + fprintf_P(stream, PSTR("%d.%d.%d.%d"), ((unsigned char*)&ipaddr)[0], ((unsigned char*)&ipaddr)[1], ((unsigned char*)&ipaddr)[2], ((unsigned char*)&ipaddr)[3]); +} + +void netPrintEthHeader(FILE *stream, struct netEthHeader* eth_hdr) +{ + fprintf_P(stream, PSTR("Eth Packet Type: 0x%x"), eth_hdr->type); + fprintf_P(stream, PSTR(" SRC:")); + netPrintEthAddr(stream, ð_hdr->src); + fprintf_P(stream, PSTR("->DST:")); + netPrintEthAddr(stream, ð_hdr->dest); +} + +void netPrintIpHeader(FILE *stream, struct netIpHeader* ipheader) +{ + fprintf_P(stream, PSTR("IP Header\r\n")); + fprintf_P(stream, PSTR("Ver : %d\r\n"), (ipheader->vhl)>>4); + fprintf_P(stream, PSTR("Length : %d\r\n"), htons(ipheader->len)); + if(ipheader->proto == IP_PROTO_ICMP) + fprintf_P(stream, PSTR("Protocol: ICMP\r\n")); + else if(ipheader->proto == IP_PROTO_TCP) + fprintf_P(stream, PSTR("Protocol: TCP\r\n")); + else if(ipheader->proto == IP_PROTO_UDP) + fprintf_P(stream, PSTR("Protocol: UDP\r\n")); + else + fprintf_P(stream, PSTR("Protocol: %d\r\n"), ipheader->proto); + + fprintf_P(stream, PSTR("SourceIP: ")); netPrintIPAddr(stream, htonl(ipheader->srcipaddr)); fprintf_P(stream, PSTR("\r\n")); + fprintf_P(stream, PSTR("Dest IP: ")); netPrintIPAddr(stream, htonl(ipheader->destipaddr)); fprintf_P(stream, PSTR("\r\n")); +} + +void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader) +{ + fprintf_P(stream, PSTR("TCP Header\r\n")); + fprintf_P(stream, PSTR("Src Port: %d\r\n"), htons(tcpheader->srcport)); + fprintf_P(stream, PSTR("Dst Port: %d\r\n"), htons(tcpheader->destport)); + fprintf_P(stream, PSTR("Seq Num : 0x%x"), htonl(tcpheader->seqno)); + fprintf_P(stream, PSTR("Ack Num : 0x%x\r\n"), htonl(tcpheader->ackno)); + fprintf_P(stream, PSTR("Flags : ")); + if(tcpheader->flags & TCP_FLAGS_FIN) + fprintf_P(stream, PSTR("FIN ")); + if(tcpheader->flags & TCP_FLAGS_SYN) + fprintf_P(stream, PSTR("SYN ")); + if(tcpheader->flags & TCP_FLAGS_RST) + fprintf_P(stream, PSTR("RST ")); + if(tcpheader->flags & TCP_FLAGS_PSH) + fprintf_P(stream, PSTR("PSH ")); + if(tcpheader->flags & TCP_FLAGS_ACK) + fprintf_P(stream, PSTR("ACK ")); + if(tcpheader->flags & TCP_FLAGS_URG) + fprintf_P(stream, PSTR("URG ")); + fprintf_P(stream, PSTR("\r\n")); +} + + diff --git a/Lib/net/net.lst b/Lib/net/net.lst new file mode 100644 index 0000000..aac8698 --- /dev/null +++ b/Lib/net/net.lst @@ -0,0 +1,1056 @@ + 1 .file "net.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 125 .global ntohs + 127 ntohs: + 128 .stabd 46,0,0 + 1:../../../../Lib/net/net.c **** /** + 2:../../../../Lib/net/net.c **** * @file net.c + 3:../../../../Lib/net/net.c **** * @author Pascal Stang, Adam Kaliszan + 4:../../../../Lib/net/net.c **** * @brief Network support library. + 5:../../../../Lib/net/net.c **** * @version 0.1 + 6:../../../../Lib/net/net.c **** * Created 30.08.2004 + 7:../../../../Lib/net/net.c **** * Revised 25.11.2010 + 8:../../../../Lib/net/net.c **** * Editor Tabs 2 + 9:../../../../Lib/net/net.c **** */ + 10:../../../../Lib/net/net.c **** + 11:../../../../Lib/net/net.c **** #include "net.h" + 12:../../../../Lib/net/net.c **** + 13:../../../../Lib/net/net.c **** + 14:../../../../Lib/net/net.c **** uint16_t ntohs(uint16_t val) + 15:../../../../Lib/net/net.c **** { + 130 .LM0: + 131 .LFBB1: + 132 /* prologue: function */ + 133 /* frame size = 0 */ + 134 /* stack size = 0 */ + 135 .L__stack_usage = 0 + 16:../../../../Lib/net/net.c **** return (val<<8) | (val>>8); + 17:../../../../Lib/net/net.c **** } + 137 .LM1: + 138 0000 9827 eor r25,r24 + 139 0002 8927 eor r24,r25 + 140 0004 9827 eor r25,r24 + 141 0006 0895 ret + 143 .Lscope1: + 145 .stabd 78,0,0 + 148 .global htons + 150 htons: + 151 .stabd 46,0,0 + 18:../../../../Lib/net/net.c **** + 19:../../../../Lib/net/net.c **** uint16_t htons(uint16_t val) + 20:../../../../Lib/net/net.c **** { + 153 .LM2: + 154 .LFBB2: + 155 /* prologue: function */ + 156 /* frame size = 0 */ + 157 /* stack size = 0 */ + 158 .L__stack_usage = 0 + 21:../../../../Lib/net/net.c **** return (val<<8) | (val>>8); + 22:../../../../Lib/net/net.c **** } + 160 .LM3: + 161 0008 9827 eor r25,r24 + 162 000a 8927 eor r24,r25 + 163 000c 9827 eor r25,r24 + 164 000e 0895 ret + 166 .Lscope2: + 168 .stabd 78,0,0 + 171 .global htonl + 173 htonl: + 174 .stabd 46,0,0 + 23:../../../../Lib/net/net.c **** + 24:../../../../Lib/net/net.c **** uint32_t htonl(uint32_t val) + 25:../../../../Lib/net/net.c **** { + 176 .LM4: + 177 .LFBB3: + 178 /* prologue: function */ + 179 /* frame size = 0 */ + 180 /* stack size = 0 */ + 181 .L__stack_usage = 0 + 182 0010 0E94 0000 call __bswapsi2 + 26:../../../../Lib/net/net.c **** return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); + 27:../../../../Lib/net/net.c **** } + 184 .LM5: + 185 0014 0895 ret + 187 .Lscope3: + 189 .stabd 78,0,0 + 192 .global ntohl + 194 ntohl: + 195 .stabd 46,0,0 + 28:../../../../Lib/net/net.c **** + 29:../../../../Lib/net/net.c **** uint32_t ntohl(uint32_t val) + 30:../../../../Lib/net/net.c **** { + 197 .LM6: + 198 .LFBB4: + 199 /* prologue: function */ + 200 /* frame size = 0 */ + 201 /* stack size = 0 */ + 202 .L__stack_usage = 0 + 203 0016 0E94 0000 call __bswapsi2 + 31:../../../../Lib/net/net.c **** return (ntohs(val>>16) | (uint32_t)ntohs(val&0x0000FFFF)<<16); + 32:../../../../Lib/net/net.c **** } + 205 .LM7: + 206 001a 0895 ret + 208 .Lscope4: + 210 .stabd 78,0,0 + 214 .global netChecksum + 216 netChecksum: + 217 .stabd 46,0,0 + 33:../../../../Lib/net/net.c **** + 34:../../../../Lib/net/net.c **** + 35:../../../../Lib/net/net.c **** uint16_t netChecksum(uint8_t *data, uint16_t len) + 36:../../../../Lib/net/net.c **** { + 219 .LM8: + 220 .LFBB5: + 221 001c CF93 push r28 + 222 001e DF93 push r29 + 223 /* prologue: function */ + 224 /* frame size = 0 */ + 225 /* stack size = 2 */ + 226 .L__stack_usage = 2 + 227 0020 DB01 movw r26,r22 + 229 .LM9: + 230 0022 9B01 movw r18,r22 + 231 0024 FC01 movw r30,r24 + 37:../../../../Lib/net/net.c **** register uint32_t sum = 0; + 233 .LM10: + 234 0026 40E0 ldi r20,0 + 235 0028 50E0 ldi r21,0 + 236 002a BA01 movw r22,r20 + 237 .L7: + 38:../../../../Lib/net/net.c **** + 39:../../../../Lib/net/net.c **** for (;;) + 40:../../../../Lib/net/net.c **** { + 41:../../../../Lib/net/net.c **** if (len < 2) + 239 .LM11: + 240 002c 2230 cpi r18,2 + 241 002e 3105 cpc r19,__zero_reg__ + 242 0030 00F0 brlo .L6 + 42:../../../../Lib/net/net.c **** break; + 43:../../../../Lib/net/net.c **** //sum += *((uint16_t *)data)++; + 44:../../../../Lib/net/net.c **** sum += *((uint16_t *)data); + 244 .LM12: + 245 0032 C191 ld r28,Z+ + 246 0034 D191 ld r29,Z+ + 247 0036 4C0F add r20,r28 + 248 0038 5D1F adc r21,r29 + 249 003a 611D adc r22,__zero_reg__ + 250 003c 711D adc r23,__zero_reg__ + 45:../../../../Lib/net/net.c **** data+=2; + 46:../../../../Lib/net/net.c **** len -= 2; + 252 .LM13: + 253 003e 2250 subi r18,2 + 254 0040 3109 sbc r19,__zero_reg__ + 47:../../../../Lib/net/net.c **** } + 256 .LM14: + 257 0042 00C0 rjmp .L7 + 258 .L6: + 259 0044 9D01 movw r18,r26 + 260 0046 2E7F andi r18,254 + 261 0048 FC01 movw r30,r24 + 262 004a E20F add r30,r18 + 263 004c F31F adc r31,r19 + 48:../../../../Lib/net/net.c **** if (len) + 265 .LM15: + 266 004e A0FF sbrs r26,0 + 267 0050 00C0 rjmp .L9 + 49:../../../../Lib/net/net.c **** sum += *(uint8_t *) data; + 269 .LM16: + 270 0052 8081 ld r24,Z + 271 0054 480F add r20,r24 + 272 0056 511D adc r21,__zero_reg__ + 273 0058 611D adc r22,__zero_reg__ + 274 005a 711D adc r23,__zero_reg__ + 275 .L9: + 50:../../../../Lib/net/net.c **** + 51:../../../../Lib/net/net.c **** while ((len = (uint16_t) (sum >> 16)) != 0) + 277 .LM17: + 278 005c CB01 movw r24,r22 + 279 005e AA27 clr r26 + 280 0060 BB27 clr r27 + 281 0062 0097 sbiw r24,0 + 282 0064 01F0 breq .L15 + 52:../../../../Lib/net/net.c **** sum = (uint16_t) sum + len; + 284 .LM18: + 285 0066 480F add r20,r24 + 286 0068 591F adc r21,r25 + 287 006a 60E0 ldi r22,0 + 288 006c 70E0 ldi r23,0 + 289 006e 00C0 rjmp .L9 + 290 .L15: + 53:../../../../Lib/net/net.c **** + 54:../../../../Lib/net/net.c **** return (uint16_t) sum ^ 0xFFFF; + 292 .LM19: + 293 0070 CA01 movw r24,r20 + 294 0072 8095 com r24 + 295 0074 9095 com r25 + 296 /* epilogue start */ + 55:../../../../Lib/net/net.c **** } + 298 .LM20: + 299 0076 DF91 pop r29 + 300 0078 CF91 pop r28 + 301 007a 0895 ret + 303 .Lscope5: + 305 .stabd 78,0,0 + 308 .global netPrintEthAddr + 310 netPrintEthAddr: + 311 .stabd 46,0,0 + 56:../../../../Lib/net/net.c **** + 57:../../../../Lib/net/net.c **** void netPrintEthAddr(FILE *stream, struct netEthAddr* ethaddr) + 58:../../../../Lib/net/net.c **** { + 313 .LM21: + 314 .LFBB6: + 315 /* prologue: function */ + 316 /* frame size = 0 */ + 317 /* stack size = 0 */ + 318 .L__stack_usage = 0 + 319 007c FB01 movw r30,r22 + 59:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("%02x:%02x:%02x:%02x:%02x:%02x"), ethaddr->addr[0], ethaddr->addr[1], etha + 321 .LM22: + 322 007e 2581 ldd r18,Z+5 + 323 0080 1F92 push __zero_reg__ + 324 0082 2F93 push r18 + 325 0084 2481 ldd r18,Z+4 + 326 0086 1F92 push __zero_reg__ + 327 0088 2F93 push r18 + 328 008a 2381 ldd r18,Z+3 + 329 008c 1F92 push __zero_reg__ + 330 008e 2F93 push r18 + 331 0090 2281 ldd r18,Z+2 + 332 0092 1F92 push __zero_reg__ + 333 0094 2F93 push r18 + 334 0096 2181 ldd r18,Z+1 + 335 0098 1F92 push __zero_reg__ + 336 009a 2F93 push r18 + 337 009c 2081 ld r18,Z + 338 009e 1F92 push __zero_reg__ + 339 00a0 2F93 push r18 + 340 00a2 20E0 ldi r18,lo8(__c.1932) + 341 00a4 30E0 ldi r19,hi8(__c.1932) + 342 00a6 3F93 push r19 + 343 00a8 2F93 push r18 + 344 00aa 9F93 push r25 + 345 00ac 8F93 push r24 + 346 00ae 0E94 0000 call fprintf_P + 347 00b2 8DB7 in r24,__SP_L__ + 348 00b4 9EB7 in r25,__SP_H__ + 349 00b6 4096 adiw r24,16 + 350 00b8 0FB6 in __tmp_reg__,__SREG__ + 351 00ba F894 cli + 352 00bc 9EBF out __SP_H__,r25 + 353 00be 0FBE out __SREG__,__tmp_reg__ + 354 00c0 8DBF out __SP_L__,r24 + 355 00c2 0895 ret + 357 .Lscope6: + 359 .stabd 78,0,0 + 362 .global netPrintIPAddr + 364 netPrintIPAddr: + 365 .stabd 46,0,0 + 60:../../../../Lib/net/net.c **** } + 61:../../../../Lib/net/net.c **** + 62:../../../../Lib/net/net.c **** void netPrintIPAddr(FILE *stream, uint32_t ipaddr) + 63:../../../../Lib/net/net.c **** { + 367 .LM23: + 368 .LFBB7: + 369 00c4 CF93 push r28 + 370 00c6 DF93 push r29 + 371 00c8 00D0 rcall . + 372 00ca 00D0 rcall . + 373 00cc CDB7 in r28,__SP_L__ + 374 00ce DEB7 in r29,__SP_H__ + 375 /* prologue: function */ + 376 /* frame size = 4 */ + 377 /* stack size = 6 */ + 378 .L__stack_usage = 6 + 379 00d0 4983 std Y+1,r20 + 380 00d2 5A83 std Y+2,r21 + 381 00d4 6B83 std Y+3,r22 + 382 00d6 7C83 std Y+4,r23 + 64:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("%d.%d.%d.%d"), ((unsigned char*)&ipaddr)[0], ((unsigned char*)&ipaddr)[1] + 384 .LM24: + 385 00d8 2C81 ldd r18,Y+4 + 386 00da 1F92 push __zero_reg__ + 387 00dc 2F93 push r18 + 388 00de 2B81 ldd r18,Y+3 + 389 00e0 1F92 push __zero_reg__ + 390 00e2 2F93 push r18 + 391 00e4 2A81 ldd r18,Y+2 + 392 00e6 1F92 push __zero_reg__ + 393 00e8 2F93 push r18 + 394 00ea 2981 ldd r18,Y+1 + 395 00ec 1F92 push __zero_reg__ + 396 00ee 2F93 push r18 + 397 00f0 20E0 ldi r18,lo8(__c.1938) + 398 00f2 30E0 ldi r19,hi8(__c.1938) + 399 00f4 3F93 push r19 + 400 00f6 2F93 push r18 + 401 00f8 9F93 push r25 + 402 00fa 8F93 push r24 + 403 00fc 0E94 0000 call fprintf_P + 404 0100 0FB6 in __tmp_reg__,__SREG__ + 405 0102 F894 cli + 406 0104 DEBF out __SP_H__,r29 + 407 0106 0FBE out __SREG__,__tmp_reg__ + 408 0108 CDBF out __SP_L__,r28 + 409 /* epilogue start */ + 65:../../../../Lib/net/net.c **** } + 411 .LM25: + 412 010a 0F90 pop __tmp_reg__ + 413 010c 0F90 pop __tmp_reg__ + 414 010e 0F90 pop __tmp_reg__ + 415 0110 0F90 pop __tmp_reg__ + 416 0112 DF91 pop r29 + 417 0114 CF91 pop r28 + 418 0116 0895 ret + 420 .Lscope7: + 422 .stabd 78,0,0 + 425 .global netPrintEthHeader + 427 netPrintEthHeader: + 428 .stabd 46,0,0 + 66:../../../../Lib/net/net.c **** + 67:../../../../Lib/net/net.c **** void netPrintEthHeader(FILE *stream, struct netEthHeader* eth_hdr) + 68:../../../../Lib/net/net.c **** { + 430 .LM26: + 431 .LFBB8: + 432 0118 0F93 push r16 + 433 011a 1F93 push r17 + 434 011c CF93 push r28 + 435 011e DF93 push r29 + 436 /* prologue: function */ + 437 /* frame size = 0 */ + 438 /* stack size = 4 */ + 439 .L__stack_usage = 4 + 440 0120 D82F mov r29,r24 + 441 0122 C92F mov r28,r25 + 442 0124 8B01 movw r16,r22 + 69:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Eth Packet Type: 0x%x"), eth_hdr->type); + 444 .LM27: + 445 0126 FB01 movw r30,r22 + 446 0128 8585 ldd r24,Z+13 + 447 012a 8F93 push r24 + 448 012c 8485 ldd r24,Z+12 + 449 012e 8F93 push r24 + 450 0130 80E0 ldi r24,lo8(__c.1944) + 451 0132 90E0 ldi r25,hi8(__c.1944) + 452 0134 9F93 push r25 + 453 0136 8F93 push r24 + 454 0138 CF93 push r28 + 455 013a DF93 push r29 + 456 013c 0E94 0000 call fprintf_P + 70:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR(" SRC:")); + 458 .LM28: + 459 0140 80E0 ldi r24,lo8(__c.1946) + 460 0142 90E0 ldi r25,hi8(__c.1946) + 461 0144 9F93 push r25 + 462 0146 8F93 push r24 + 463 0148 CF93 push r28 + 464 014a DF93 push r29 + 465 014c 0E94 0000 call fprintf_P + 71:../../../../Lib/net/net.c **** netPrintEthAddr(stream, ð_hdr->src); + 467 .LM29: + 468 0150 B801 movw r22,r16 + 469 0152 6A5F subi r22,-6 + 470 0154 7F4F sbci r23,-1 + 471 0156 8D2F mov r24,r29 + 472 0158 9C2F mov r25,r28 + 473 015a 0E94 0000 call netPrintEthAddr + 72:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("->DST:")); + 475 .LM30: + 476 015e 80E0 ldi r24,lo8(__c.1948) + 477 0160 90E0 ldi r25,hi8(__c.1948) + 478 0162 9F93 push r25 + 479 0164 8F93 push r24 + 480 0166 CF93 push r28 + 481 0168 DF93 push r29 + 482 016a 0E94 0000 call fprintf_P + 73:../../../../Lib/net/net.c **** netPrintEthAddr(stream, ð_hdr->dest); + 484 .LM31: + 485 016e 8DB7 in r24,__SP_L__ + 486 0170 9EB7 in r25,__SP_H__ + 487 0172 0E96 adiw r24,14 + 488 0174 0FB6 in __tmp_reg__,__SREG__ + 489 0176 F894 cli + 490 0178 9EBF out __SP_H__,r25 + 491 017a 0FBE out __SREG__,__tmp_reg__ + 492 017c 8DBF out __SP_L__,r24 + 493 017e B801 movw r22,r16 + 494 0180 8D2F mov r24,r29 + 495 0182 9C2F mov r25,r28 + 496 /* epilogue start */ + 74:../../../../Lib/net/net.c **** } + 498 .LM32: + 499 0184 DF91 pop r29 + 500 0186 CF91 pop r28 + 501 0188 1F91 pop r17 + 502 018a 0F91 pop r16 + 73:../../../../Lib/net/net.c **** netPrintEthAddr(stream, ð_hdr->dest); + 504 .LM33: + 505 018c 0C94 0000 jmp netPrintEthAddr + 507 .Lscope8: + 509 .stabd 78,0,0 + 512 .global netPrintIpHeader + 514 netPrintIpHeader: + 515 .stabd 46,0,0 + 75:../../../../Lib/net/net.c **** + 76:../../../../Lib/net/net.c **** void netPrintIpHeader(FILE *stream, struct netIpHeader* ipheader) + 77:../../../../Lib/net/net.c **** { + 517 .LM34: + 518 .LFBB9: + 519 0190 0F93 push r16 + 520 0192 1F93 push r17 + 521 0194 CF93 push r28 + 522 0196 DF93 push r29 + 523 /* prologue: function */ + 524 /* frame size = 0 */ + 525 /* stack size = 4 */ + 526 .L__stack_usage = 4 + 527 0198 EC01 movw r28,r24 + 528 019a 8B01 movw r16,r22 + 78:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("IP Header\r\n")); + 530 .LM35: + 531 019c 80E0 ldi r24,lo8(__c.1954) + 532 019e 90E0 ldi r25,hi8(__c.1954) + 533 01a0 9F93 push r25 + 534 01a2 8F93 push r24 + 535 01a4 DF93 push r29 + 536 01a6 CF93 push r28 + 537 01a8 0E94 0000 call fprintf_P + 79:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Ver : %d\r\n"), (ipheader->vhl)>>4); + 539 .LM36: + 540 01ac F801 movw r30,r16 + 541 01ae 8081 ld r24,Z + 542 01b0 8295 swap r24 + 543 01b2 8F70 andi r24,lo8(15) + 544 01b4 1F92 push __zero_reg__ + 545 01b6 8F93 push r24 + 546 01b8 80E0 ldi r24,lo8(__c.1956) + 547 01ba 90E0 ldi r25,hi8(__c.1956) + 548 01bc 9F93 push r25 + 549 01be 8F93 push r24 + 550 01c0 DF93 push r29 + 551 01c2 CF93 push r28 + 552 01c4 0E94 0000 call fprintf_P + 553 .LBB40: + 554 .LBB41: + 21:../../../../Lib/net/net.c **** } + 556 .LM37: + 557 01c8 F801 movw r30,r16 + 558 01ca 8281 ldd r24,Z+2 + 559 01cc 9381 ldd r25,Z+3 + 560 01ce 9827 eor r25,r24 + 561 01d0 8927 eor r24,r25 + 562 01d2 9827 eor r25,r24 + 563 .LBE41: + 564 .LBE40: + 80:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Length : %d\r\n"), htons(ipheader->len)); + 566 .LM38: + 567 01d4 9F93 push r25 + 568 01d6 8F93 push r24 + 569 01d8 80E0 ldi r24,lo8(__c.1958) + 570 01da 90E0 ldi r25,hi8(__c.1958) + 571 01dc 9F93 push r25 + 572 01de 8F93 push r24 + 573 01e0 DF93 push r29 + 574 01e2 CF93 push r28 + 575 01e4 0E94 0000 call fprintf_P + 81:../../../../Lib/net/net.c **** if(ipheader->proto == IP_PROTO_ICMP) + 577 .LM39: + 578 01e8 F801 movw r30,r16 + 579 01ea 8185 ldd r24,Z+9 + 580 01ec 2DB7 in r18,__SP_L__ + 581 01ee 3EB7 in r19,__SP_H__ + 582 01f0 205F subi r18,-16 + 583 01f2 3F4F sbci r19,-1 + 584 01f4 0FB6 in __tmp_reg__,__SREG__ + 585 01f6 F894 cli + 586 01f8 3EBF out __SP_H__,r19 + 587 01fa 0FBE out __SREG__,__tmp_reg__ + 588 01fc 2DBF out __SP_L__,r18 + 589 01fe 8130 cpi r24,lo8(1) + 590 0200 01F4 brne .L20 + 82:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Protocol: ICMP\r\n")); + 592 .LM40: + 593 0202 80E0 ldi r24,lo8(__c.1960) + 594 0204 90E0 ldi r25,hi8(__c.1960) + 595 0206 00C0 rjmp .L24 + 596 .L20: + 83:../../../../Lib/net/net.c **** else if(ipheader->proto == IP_PROTO_TCP) + 598 .LM41: + 599 0208 8630 cpi r24,lo8(6) + 600 020a 01F4 brne .L22 + 84:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Protocol: TCP\r\n")); + 602 .LM42: + 603 020c 80E0 ldi r24,lo8(__c.1962) + 604 020e 90E0 ldi r25,hi8(__c.1962) + 605 .L24: + 606 0210 9F93 push r25 + 607 0212 8F93 push r24 + 608 0214 DF93 push r29 + 609 0216 CF93 push r28 + 610 0218 0E94 0000 call fprintf_P + 611 021c 0F90 pop __tmp_reg__ + 612 021e 0F90 pop __tmp_reg__ + 613 0220 0F90 pop __tmp_reg__ + 614 0222 0F90 pop __tmp_reg__ + 615 0224 00C0 rjmp .L21 + 616 .L22: + 85:../../../../Lib/net/net.c **** else if(ipheader->proto == IP_PROTO_UDP) + 618 .LM43: + 619 0226 8131 cpi r24,lo8(17) + 620 0228 01F4 brne .L23 + 86:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Protocol: UDP\r\n")); + 622 .LM44: + 623 022a 80E0 ldi r24,lo8(__c.1964) + 624 022c 90E0 ldi r25,hi8(__c.1964) + 625 022e 00C0 rjmp .L24 + 626 .L23: + 87:../../../../Lib/net/net.c **** else + 88:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Protocol: %d\r\n"), ipheader->proto); + 628 .LM45: + 629 0230 1F92 push __zero_reg__ + 630 0232 8F93 push r24 + 631 0234 80E0 ldi r24,lo8(__c.1966) + 632 0236 90E0 ldi r25,hi8(__c.1966) + 633 0238 9F93 push r25 + 634 023a 8F93 push r24 + 635 023c DF93 push r29 + 636 023e CF93 push r28 + 637 0240 0E94 0000 call fprintf_P + 638 0244 0F90 pop __tmp_reg__ + 639 0246 0F90 pop __tmp_reg__ + 640 0248 0F90 pop __tmp_reg__ + 641 024a 0F90 pop __tmp_reg__ + 642 024c 0F90 pop __tmp_reg__ + 643 024e 0F90 pop __tmp_reg__ + 644 .L21: + 89:../../../../Lib/net/net.c **** + 90:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("SourceIP: ")); netPrintIPAddr(stream, htonl(ipheader->srcipaddr)); fpri + 646 .LM46: + 647 0250 80E0 ldi r24,lo8(__c.1968) + 648 0252 90E0 ldi r25,hi8(__c.1968) + 649 0254 9F93 push r25 + 650 0256 8F93 push r24 + 651 0258 DF93 push r29 + 652 025a CF93 push r28 + 653 025c 0E94 0000 call fprintf_P + 654 0260 F801 movw r30,r16 + 655 0262 6485 ldd r22,Z+12 + 656 0264 7585 ldd r23,Z+13 + 657 0266 8685 ldd r24,Z+14 + 658 0268 9785 ldd r25,Z+15 + 659 026a 0E94 0000 call htonl + 660 026e AB01 movw r20,r22 + 661 0270 BC01 movw r22,r24 + 662 0272 CE01 movw r24,r28 + 663 0274 0E94 0000 call netPrintIPAddr + 664 0278 80E0 ldi r24,lo8(__c.1970) + 665 027a 90E0 ldi r25,hi8(__c.1970) + 666 027c 9F93 push r25 + 667 027e 8F93 push r24 + 668 0280 DF93 push r29 + 669 0282 CF93 push r28 + 670 0284 0E94 0000 call fprintf_P + 91:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Dest IP: ")); netPrintIPAddr(stream, htonl(ipheader->destipaddr)); fpri + 672 .LM47: + 673 0288 80E0 ldi r24,lo8(__c.1972) + 674 028a 90E0 ldi r25,hi8(__c.1972) + 675 028c 9F93 push r25 + 676 028e 8F93 push r24 + 677 0290 DF93 push r29 + 678 0292 CF93 push r28 + 679 0294 0E94 0000 call fprintf_P + 680 0298 F801 movw r30,r16 + 681 029a 6089 ldd r22,Z+16 + 682 029c 7189 ldd r23,Z+17 + 683 029e 8289 ldd r24,Z+18 + 684 02a0 9389 ldd r25,Z+19 + 685 02a2 0E94 0000 call htonl + 686 02a6 AB01 movw r20,r22 + 687 02a8 BC01 movw r22,r24 + 688 02aa CE01 movw r24,r28 + 689 02ac 0E94 0000 call netPrintIPAddr + 690 02b0 80E0 ldi r24,lo8(__c.1974) + 691 02b2 90E0 ldi r25,hi8(__c.1974) + 692 02b4 9F93 push r25 + 693 02b6 8F93 push r24 + 694 02b8 DF93 push r29 + 695 02ba CF93 push r28 + 696 02bc 0E94 0000 call fprintf_P + 697 02c0 2DB7 in r18,__SP_L__ + 698 02c2 3EB7 in r19,__SP_H__ + 699 02c4 205F subi r18,-16 + 700 02c6 3F4F sbci r19,-1 + 701 02c8 0FB6 in __tmp_reg__,__SREG__ + 702 02ca F894 cli + 703 02cc 3EBF out __SP_H__,r19 + 704 02ce 0FBE out __SREG__,__tmp_reg__ + 705 02d0 2DBF out __SP_L__,r18 + 706 /* epilogue start */ + 92:../../../../Lib/net/net.c **** } + 708 .LM48: + 709 02d2 DF91 pop r29 + 710 02d4 CF91 pop r28 + 711 02d6 1F91 pop r17 + 712 02d8 0F91 pop r16 + 713 02da 0895 ret + 715 .Lscope9: + 717 .stabd 78,0,0 + 720 .global netPrintTcpHeader + 722 netPrintTcpHeader: + 723 .stabd 46,0,0 + 93:../../../../Lib/net/net.c **** + 94:../../../../Lib/net/net.c **** void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader) + 95:../../../../Lib/net/net.c **** { + 725 .LM49: + 726 .LFBB10: + 727 02dc 0F93 push r16 + 728 02de 1F93 push r17 + 729 02e0 CF93 push r28 + 730 02e2 DF93 push r29 + 731 /* prologue: function */ + 732 /* frame size = 0 */ + 733 /* stack size = 4 */ + 734 .L__stack_usage = 4 + 735 02e4 EC01 movw r28,r24 + 736 02e6 8B01 movw r16,r22 + 96:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("TCP Header\r\n")); + 738 .LM50: + 739 02e8 80E0 ldi r24,lo8(__c.1980) + 740 02ea 90E0 ldi r25,hi8(__c.1980) + 741 02ec 9F93 push r25 + 742 02ee 8F93 push r24 + 743 02f0 DF93 push r29 + 744 02f2 CF93 push r28 + 745 02f4 0E94 0000 call fprintf_P + 746 .LBB42: + 747 .LBB43: + 21:../../../../Lib/net/net.c **** } + 749 .LM51: + 750 02f8 F801 movw r30,r16 + 751 02fa 8081 ld r24,Z + 752 02fc 9181 ldd r25,Z+1 + 753 02fe 9827 eor r25,r24 + 754 0300 8927 eor r24,r25 + 755 0302 9827 eor r25,r24 + 756 .LBE43: + 757 .LBE42: + 97:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Src Port: %d\r\n"), htons(tcpheader->srcport)); + 759 .LM52: + 760 0304 9F93 push r25 + 761 0306 8F93 push r24 + 762 0308 80E0 ldi r24,lo8(__c.1982) + 763 030a 90E0 ldi r25,hi8(__c.1982) + 764 030c 9F93 push r25 + 765 030e 8F93 push r24 + 766 0310 DF93 push r29 + 767 0312 CF93 push r28 + 768 0314 0E94 0000 call fprintf_P + 769 .LBB44: + 770 .LBB45: + 21:../../../../Lib/net/net.c **** } + 772 .LM53: + 773 0318 F801 movw r30,r16 + 774 031a 8281 ldd r24,Z+2 + 775 031c 9381 ldd r25,Z+3 + 776 031e 9827 eor r25,r24 + 777 0320 8927 eor r24,r25 + 778 0322 9827 eor r25,r24 + 779 .LBE45: + 780 .LBE44: + 98:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Dst Port: %d\r\n"), htons(tcpheader->destport)); + 782 .LM54: + 783 0324 9F93 push r25 + 784 0326 8F93 push r24 + 785 0328 80E0 ldi r24,lo8(__c.1984) + 786 032a 90E0 ldi r25,hi8(__c.1984) + 787 032c 9F93 push r25 + 788 032e 8F93 push r24 + 789 0330 DF93 push r29 + 790 0332 CF93 push r28 + 791 0334 0E94 0000 call fprintf_P + 99:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Seq Num : 0x%x"), htonl(tcpheader->seqno)); + 793 .LM55: + 794 0338 F801 movw r30,r16 + 795 033a 6481 ldd r22,Z+4 + 796 033c 7581 ldd r23,Z+5 + 797 033e 8681 ldd r24,Z+6 + 798 0340 9781 ldd r25,Z+7 + 799 0342 0E94 0000 call htonl + 800 0346 9F93 push r25 + 801 0348 8F93 push r24 + 802 034a 7F93 push r23 + 803 034c 6F93 push r22 + 804 034e 80E0 ldi r24,lo8(__c.1986) + 805 0350 90E0 ldi r25,hi8(__c.1986) + 806 0352 9F93 push r25 + 807 0354 8F93 push r24 + 808 0356 DF93 push r29 + 809 0358 CF93 push r28 + 810 035a 0E94 0000 call fprintf_P + 100:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Ack Num : 0x%x\r\n"), htonl(tcpheader->ackno)); + 812 .LM56: + 813 035e F801 movw r30,r16 + 814 0360 6085 ldd r22,Z+8 + 815 0362 7185 ldd r23,Z+9 + 816 0364 8285 ldd r24,Z+10 + 817 0366 9385 ldd r25,Z+11 + 818 0368 0E94 0000 call htonl + 819 036c 9F93 push r25 + 820 036e 8F93 push r24 + 821 0370 7F93 push r23 + 822 0372 6F93 push r22 + 823 0374 80E0 ldi r24,lo8(__c.1988) + 824 0376 90E0 ldi r25,hi8(__c.1988) + 825 0378 9F93 push r25 + 826 037a 8F93 push r24 + 827 037c DF93 push r29 + 828 037e CF93 push r28 + 829 0380 0E94 0000 call fprintf_P + 101:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("Flags : ")); + 831 .LM57: + 832 0384 8DB7 in r24,__SP_L__ + 833 0386 9EB7 in r25,__SP_H__ + 834 0388 8096 adiw r24,32 + 835 038a 0FB6 in __tmp_reg__,__SREG__ + 836 038c F894 cli + 837 038e 9EBF out __SP_H__,r25 + 838 0390 0FBE out __SREG__,__tmp_reg__ + 839 0392 8DBF out __SP_L__,r24 + 840 0394 80E0 ldi r24,lo8(__c.1990) + 841 0396 90E0 ldi r25,hi8(__c.1990) + 842 0398 9F93 push r25 + 843 039a 8F93 push r24 + 844 039c DF93 push r29 + 845 039e CF93 push r28 + 846 03a0 0E94 0000 call fprintf_P + 102:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_FIN) + 848 .LM58: + 849 03a4 F801 movw r30,r16 + 850 03a6 8585 ldd r24,Z+13 + 851 03a8 0F90 pop __tmp_reg__ + 852 03aa 0F90 pop __tmp_reg__ + 853 03ac 0F90 pop __tmp_reg__ + 854 03ae 0F90 pop __tmp_reg__ + 855 03b0 80FF sbrs r24,0 + 856 03b2 00C0 rjmp .L26 + 103:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("FIN ")); + 858 .LM59: + 859 03b4 80E0 ldi r24,lo8(__c.1992) + 860 03b6 90E0 ldi r25,hi8(__c.1992) + 861 03b8 9F93 push r25 + 862 03ba 8F93 push r24 + 863 03bc DF93 push r29 + 864 03be CF93 push r28 + 865 03c0 0E94 0000 call fprintf_P + 866 03c4 0F90 pop __tmp_reg__ + 867 03c6 0F90 pop __tmp_reg__ + 868 03c8 0F90 pop __tmp_reg__ + 869 03ca 0F90 pop __tmp_reg__ + 870 .L26: + 104:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_SYN) + 872 .LM60: + 873 03cc F801 movw r30,r16 + 874 03ce 8585 ldd r24,Z+13 + 875 03d0 81FF sbrs r24,1 + 876 03d2 00C0 rjmp .L27 + 105:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("SYN ")); + 878 .LM61: + 879 03d4 80E0 ldi r24,lo8(__c.1994) + 880 03d6 90E0 ldi r25,hi8(__c.1994) + 881 03d8 9F93 push r25 + 882 03da 8F93 push r24 + 883 03dc DF93 push r29 + 884 03de CF93 push r28 + 885 03e0 0E94 0000 call fprintf_P + 886 03e4 0F90 pop __tmp_reg__ + 887 03e6 0F90 pop __tmp_reg__ + 888 03e8 0F90 pop __tmp_reg__ + 889 03ea 0F90 pop __tmp_reg__ + 890 .L27: + 106:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_RST) + 892 .LM62: + 893 03ec F801 movw r30,r16 + 894 03ee 8585 ldd r24,Z+13 + 895 03f0 82FF sbrs r24,2 + 896 03f2 00C0 rjmp .L28 + 107:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("RST ")); + 898 .LM63: + 899 03f4 80E0 ldi r24,lo8(__c.1996) + 900 03f6 90E0 ldi r25,hi8(__c.1996) + 901 03f8 9F93 push r25 + 902 03fa 8F93 push r24 + 903 03fc DF93 push r29 + 904 03fe CF93 push r28 + 905 0400 0E94 0000 call fprintf_P + 906 0404 0F90 pop __tmp_reg__ + 907 0406 0F90 pop __tmp_reg__ + 908 0408 0F90 pop __tmp_reg__ + 909 040a 0F90 pop __tmp_reg__ + 910 .L28: + 108:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_PSH) + 912 .LM64: + 913 040c F801 movw r30,r16 + 914 040e 8585 ldd r24,Z+13 + 915 0410 83FF sbrs r24,3 + 916 0412 00C0 rjmp .L29 + 109:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("PSH ")); + 918 .LM65: + 919 0414 80E0 ldi r24,lo8(__c.1998) + 920 0416 90E0 ldi r25,hi8(__c.1998) + 921 0418 9F93 push r25 + 922 041a 8F93 push r24 + 923 041c DF93 push r29 + 924 041e CF93 push r28 + 925 0420 0E94 0000 call fprintf_P + 926 0424 0F90 pop __tmp_reg__ + 927 0426 0F90 pop __tmp_reg__ + 928 0428 0F90 pop __tmp_reg__ + 929 042a 0F90 pop __tmp_reg__ + 930 .L29: + 110:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_ACK) + 932 .LM66: + 933 042c F801 movw r30,r16 + 934 042e 8585 ldd r24,Z+13 + 935 0430 84FF sbrs r24,4 + 936 0432 00C0 rjmp .L30 + 111:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("ACK ")); + 938 .LM67: + 939 0434 80E0 ldi r24,lo8(__c.2000) + 940 0436 90E0 ldi r25,hi8(__c.2000) + 941 0438 9F93 push r25 + 942 043a 8F93 push r24 + 943 043c DF93 push r29 + 944 043e CF93 push r28 + 945 0440 0E94 0000 call fprintf_P + 946 0444 0F90 pop __tmp_reg__ + 947 0446 0F90 pop __tmp_reg__ + 948 0448 0F90 pop __tmp_reg__ + 949 044a 0F90 pop __tmp_reg__ + 950 .L30: + 112:../../../../Lib/net/net.c **** if(tcpheader->flags & TCP_FLAGS_URG) + 952 .LM68: + 953 044c F801 movw r30,r16 + 954 044e 8585 ldd r24,Z+13 + 955 0450 85FF sbrs r24,5 + 956 0452 00C0 rjmp .L31 + 113:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("URG ")); + 958 .LM69: + 959 0454 80E0 ldi r24,lo8(__c.2002) + 960 0456 90E0 ldi r25,hi8(__c.2002) + 961 0458 9F93 push r25 + 962 045a 8F93 push r24 + 963 045c DF93 push r29 + 964 045e CF93 push r28 + 965 0460 0E94 0000 call fprintf_P + 966 0464 0F90 pop __tmp_reg__ + 967 0466 0F90 pop __tmp_reg__ + 968 0468 0F90 pop __tmp_reg__ + 969 046a 0F90 pop __tmp_reg__ + 970 .L31: + 114:../../../../Lib/net/net.c **** fprintf_P(stream, PSTR("\r\n")); + 972 .LM70: + 973 046c 80E0 ldi r24,lo8(__c.2004) + 974 046e 90E0 ldi r25,hi8(__c.2004) + 975 0470 9F93 push r25 + 976 0472 8F93 push r24 + 977 0474 DF93 push r29 + 978 0476 CF93 push r28 + 979 0478 0E94 0000 call fprintf_P + 980 047c 0F90 pop __tmp_reg__ + 981 047e 0F90 pop __tmp_reg__ + 982 0480 0F90 pop __tmp_reg__ + 983 0482 0F90 pop __tmp_reg__ + 984 /* epilogue start */ + 115:../../../../Lib/net/net.c **** } + 986 .LM71: + 987 0484 DF91 pop r29 + 988 0486 CF91 pop r28 + 989 0488 1F91 pop r17 + 990 048a 0F91 pop r16 + 991 048c 0895 ret + 993 .Lscope10: + 995 .stabd 78,0,0 + 996 .section .progmem.data,"a",@progbits + 999 __c.2004: + 1000 0000 0D0A 00 .string "\r\n" + 1003 __c.2002: + 1004 0003 5552 4720 .string "URG " + 1004 00 + 1007 __c.2000: + 1008 0008 4143 4B20 .string "ACK " + 1008 00 + 1011 __c.1998: + 1012 000d 5053 4820 .string "PSH " + 1012 00 + 1015 __c.1996: + 1016 0012 5253 5420 .string "RST " + 1016 00 + 1019 __c.1994: + 1020 0017 5359 4E20 .string "SYN " + 1020 00 + 1023 __c.1992: + 1024 001c 4649 4E20 .string "FIN " + 1024 00 + 1027 __c.1990: + 1028 0021 466C 6167 .string "Flags : " + 1028 7320 2020 + 1028 3A20 00 + 1031 __c.1988: + 1032 002c 4163 6B20 .string "Ack Num : 0x%x\r\n" + 1032 4E75 6D20 + 1032 3A20 3078 + 1032 2578 0D0A + 1032 00 + 1035 __c.1986: + 1036 003d 5365 7120 .string "Seq Num : 0x%x" + 1036 4E75 6D20 + 1036 3A20 3078 + 1036 2578 00 + 1039 __c.1984: + 1040 004c 4473 7420 .string "Dst Port: %d\r\n" + 1040 506F 7274 + 1040 3A20 2564 + 1040 0D0A 00 + 1043 __c.1982: + 1044 005b 5372 6320 .string "Src Port: %d\r\n" + 1044 506F 7274 + 1044 3A20 2564 + 1044 0D0A 00 + 1047 __c.1980: + 1048 006a 5443 5020 .string "TCP Header\r\n" + 1048 4865 6164 + 1048 6572 0D0A + 1048 00 + 1051 __c.1974: + 1052 0077 0D0A 00 .string "\r\n" + 1055 __c.1972: + 1056 007a 4465 7374 .string "Dest IP: " + 1056 2020 4950 + 1056 3A20 00 + 1059 __c.1970: + 1060 0085 0D0A 00 .string "\r\n" + 1063 __c.1968: + 1064 0088 536F 7572 .string "SourceIP: " + 1064 6365 4950 + 1064 3A20 00 + 1067 __c.1966: + 1068 0093 5072 6F74 .string "Protocol: %d\r\n" + 1068 6F63 6F6C + 1068 3A20 2564 + 1068 0D0A 00 + 1071 __c.1964: + 1072 00a2 5072 6F74 .string "Protocol: UDP\r\n" + 1072 6F63 6F6C + 1072 3A20 5544 + 1072 500D 0A00 + 1075 __c.1962: + 1076 00b2 5072 6F74 .string "Protocol: TCP\r\n" + 1076 6F63 6F6C + 1076 3A20 5443 + 1076 500D 0A00 + 1079 __c.1960: + 1080 00c2 5072 6F74 .string "Protocol: ICMP\r\n" + 1080 6F63 6F6C + 1080 3A20 4943 + 1080 4D50 0D0A + 1080 00 + 1083 __c.1958: + 1084 00d3 4C65 6E67 .string "Length : %d\r\n" + 1084 7468 2020 + 1084 3A20 2564 + 1084 0D0A 00 + 1087 __c.1956: + 1088 00e2 5665 7220 .string "Ver : %d\r\n" + 1088 2020 2020 + 1088 3A20 2564 + 1088 0D0A 00 + 1091 __c.1954: + 1092 00f1 4950 2048 .string "IP Header\r\n" + 1092 6561 6465 + 1092 720D 0A00 + 1095 __c.1948: + 1096 00fd 2D3E 4453 .string "->DST:" + 1096 543A 00 + 1099 __c.1946: + 1100 0104 2053 5243 .string " SRC:" + 1100 3A00 + 1103 __c.1944: + 1104 010a 4574 6820 .string "Eth Packet Type: 0x%x" + 1104 5061 636B + 1104 6574 2054 + 1104 7970 653A + 1104 2030 7825 + 1107 __c.1938: + 1108 0120 2564 2E25 .string "%d.%d.%d.%d" + 1108 642E 2564 + 1108 2E25 6400 + 1111 __c.1932: + 1112 012c 2530 3278 .string "%02x:%02x:%02x:%02x:%02x:%02x" + 1112 3A25 3032 + 1112 783A 2530 + 1112 3278 3A25 + 1112 3032 783A + 1113 .comm wwwport,1,1 + 1115 .text + 1117 .Letext0: + 1118 .ident "GCC: (GNU) 4.9.2" + 1119 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 net.c + /tmp/cclkRqCa.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cclkRqCa.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cclkRqCa.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cclkRqCa.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cclkRqCa.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cclkRqCa.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cclkRqCa.s:127 .text:0000000000000000 ntohs + /tmp/cclkRqCa.s:150 .text:0000000000000008 htons + /tmp/cclkRqCa.s:173 .text:0000000000000010 htonl + /tmp/cclkRqCa.s:194 .text:0000000000000016 ntohl + /tmp/cclkRqCa.s:216 .text:000000000000001c netChecksum + /tmp/cclkRqCa.s:310 .text:000000000000007c netPrintEthAddr + /tmp/cclkRqCa.s:1111 .progmem.data:000000000000012c __c.1932 + /tmp/cclkRqCa.s:364 .text:00000000000000c4 netPrintIPAddr + /tmp/cclkRqCa.s:1107 .progmem.data:0000000000000120 __c.1938 + /tmp/cclkRqCa.s:427 .text:0000000000000118 netPrintEthHeader + /tmp/cclkRqCa.s:1103 .progmem.data:000000000000010a __c.1944 + /tmp/cclkRqCa.s:1099 .progmem.data:0000000000000104 __c.1946 + /tmp/cclkRqCa.s:1095 .progmem.data:00000000000000fd __c.1948 + /tmp/cclkRqCa.s:514 .text:0000000000000190 netPrintIpHeader + /tmp/cclkRqCa.s:1091 .progmem.data:00000000000000f1 __c.1954 + /tmp/cclkRqCa.s:1087 .progmem.data:00000000000000e2 __c.1956 + /tmp/cclkRqCa.s:1083 .progmem.data:00000000000000d3 __c.1958 + /tmp/cclkRqCa.s:1079 .progmem.data:00000000000000c2 __c.1960 + /tmp/cclkRqCa.s:1075 .progmem.data:00000000000000b2 __c.1962 + /tmp/cclkRqCa.s:1071 .progmem.data:00000000000000a2 __c.1964 + /tmp/cclkRqCa.s:1067 .progmem.data:0000000000000093 __c.1966 + /tmp/cclkRqCa.s:1063 .progmem.data:0000000000000088 __c.1968 + /tmp/cclkRqCa.s:1059 .progmem.data:0000000000000085 __c.1970 + /tmp/cclkRqCa.s:1055 .progmem.data:000000000000007a __c.1972 + /tmp/cclkRqCa.s:1051 .progmem.data:0000000000000077 __c.1974 + /tmp/cclkRqCa.s:722 .text:00000000000002dc netPrintTcpHeader + /tmp/cclkRqCa.s:1047 .progmem.data:000000000000006a __c.1980 + /tmp/cclkRqCa.s:1043 .progmem.data:000000000000005b __c.1982 + /tmp/cclkRqCa.s:1039 .progmem.data:000000000000004c __c.1984 + /tmp/cclkRqCa.s:1035 .progmem.data:000000000000003d __c.1986 + /tmp/cclkRqCa.s:1031 .progmem.data:000000000000002c __c.1988 + /tmp/cclkRqCa.s:1027 .progmem.data:0000000000000021 __c.1990 + /tmp/cclkRqCa.s:1023 .progmem.data:000000000000001c __c.1992 + /tmp/cclkRqCa.s:1019 .progmem.data:0000000000000017 __c.1994 + /tmp/cclkRqCa.s:1015 .progmem.data:0000000000000012 __c.1996 + /tmp/cclkRqCa.s:1011 .progmem.data:000000000000000d __c.1998 + /tmp/cclkRqCa.s:1007 .progmem.data:0000000000000008 __c.2000 + /tmp/cclkRqCa.s:1003 .progmem.data:0000000000000003 __c.2002 + /tmp/cclkRqCa.s:999 .progmem.data:0000000000000000 __c.2004 + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +__bswapsi2 +fprintf_P +__do_clear_bss diff --git a/Lib/net/nic.c b/Lib/net/nic.c new file mode 100644 index 0000000..8357742 --- /dev/null +++ b/Lib/net/nic.c @@ -0,0 +1,88 @@ +/** + * @file nic.h + * @version 0.2 + * @brief Network Interface Card (NIC) software definition. + * @ingroup network + * @author Pascal Stang, Adam Kaliszan + * @defgroup nic Network Interface Card (NIC) software definition (nic.h) + * @code #include "net/nic.h" @endcode + * @par Description + * This is the software interface standard for network interface hardware + * as used by AVRlib. Drivers for network hardware must implement these + * functions to allow upper network layers to initialize the interface, + * and send and receive net traffic. + * + * Editor Tabs : 4 + * Target MCU : Atmel AVR series + * Created : 22.08.2004 + * Revised : 28.11.2010 + * + * This code is distributed under the GNU Public License + * which can be found at http://www.gnu.org/licenses/gpl.txt + */ +//@{ + +#include "nic.h" + + +#include "softwareConfig.h" +static uint8_t mymac_eep[6] __attribute__((section (".eeprom"))) = {MAC_ADR1, MAC_ADR2, MAC_ADR3, MAC_ADR4, MAC_ADR5, MAC_ADR6}; + + +/* Weak functions, that hast to be overriden in hardware specyfic driver implementation i.e. in enc28j60 */ +void nicMacInit(void) { } +void nicSend(uint16_t len) { (void) len; } +unsigned int nicPoll(void) { return 0; } + + + + + +static void nicBufferInit(void) +{ + nicState.bufferSize = NETWORK_STACK_BUF_SIZE; + nicState.layer2.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR); + nicState.layer3.ip = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te wartosci beda ustawiane w czasie analizy pakietu + nicState.layer4.icmp = (struct netIcmpHeader *)(NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN + IP_HEADER_LEN); + #if IPV6_SUPPORT + nicState.layer3.ipv6 = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + nicState.layer3.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + //nicState.layer4.icmpv6 = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te wartosci beda ustawiane w czasie analizy pakietu + #endif /*IPV6_SUPPORT*/ + memset(nicState.layer2.buf, 0, nicState.bufferSize); + nicLoadConfig(); +} + +void nicLoadConfig(void) +{ + eeprom_read_block(&nicState.mac.addr, mymac_eep, 6); +} + +void nicSaveConfig(void) +{ + eeprom_update_block(&nicState.mac.addr, mymac_eep, 6); +} + +void nicInit() +{ + nicBufferInit(); + nicMacInit(); +} + +void nicGetMacAddress(uint8_t* macaddr) +{ + strncpy((void *)(macaddr), (void *)(nicState.mac.addr), 6); +} + +void nicSetMacAddress(uint8_t* macaddr) +{ + strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); + nicMacInit(); +} + +void nicRegDump(FILE *stream) +{ + fprintf_P(stream, PSTR("NIC reg dump not implemented\r\n")); +} + +//@} diff --git a/Lib/net/nic.lst b/Lib/net/nic.lst new file mode 100644 index 0000000..27b382d --- /dev/null +++ b/Lib/net/nic.lst @@ -0,0 +1,336 @@ + 1 .file "nic.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 131 .weak nicMacInit + 133 nicMacInit: + 134 .stabd 46,0,0 + 1:../../../../Lib/net/nic.c **** /** + 2:../../../../Lib/net/nic.c **** * @file nic.h + 3:../../../../Lib/net/nic.c **** * @version 0.2 + 4:../../../../Lib/net/nic.c **** * @brief Network Interface Card (NIC) software definition. + 5:../../../../Lib/net/nic.c **** * @ingroup network + 6:../../../../Lib/net/nic.c **** * @author Pascal Stang, Adam Kaliszan + 7:../../../../Lib/net/nic.c **** * @defgroup nic Network Interface Card (NIC) software definition (nic.h) + 8:../../../../Lib/net/nic.c **** * @code #include "net/nic.h" @endcode + 9:../../../../Lib/net/nic.c **** * @par Description + 10:../../../../Lib/net/nic.c **** * This is the software interface standard for network interface hardware + 11:../../../../Lib/net/nic.c **** * as used by AVRlib. Drivers for network hardware must implement these + 12:../../../../Lib/net/nic.c **** * functions to allow upper network layers to initialize the interface, + 13:../../../../Lib/net/nic.c **** * and send and receive net traffic. + 14:../../../../Lib/net/nic.c **** * + 15:../../../../Lib/net/nic.c **** * Editor Tabs : 4 + 16:../../../../Lib/net/nic.c **** * Target MCU : Atmel AVR series + 17:../../../../Lib/net/nic.c **** * Created : 22.08.2004 + 18:../../../../Lib/net/nic.c **** * Revised : 28.11.2010 + 19:../../../../Lib/net/nic.c **** * + 20:../../../../Lib/net/nic.c **** * This code is distributed under the GNU Public License + 21:../../../../Lib/net/nic.c **** * which can be found at http://www.gnu.org/licenses/gpl.txt + 22:../../../../Lib/net/nic.c **** */ + 23:../../../../Lib/net/nic.c **** //@{ + 24:../../../../Lib/net/nic.c **** + 25:../../../../Lib/net/nic.c **** #include "nic.h" + 26:../../../../Lib/net/nic.c **** + 27:../../../../Lib/net/nic.c **** + 28:../../../../Lib/net/nic.c **** #include "softwareConfig.h" + 29:../../../../Lib/net/nic.c **** static uint8_t mymac_eep[6] __attribute__((section (".eeprom"))) = {MAC_ADR1, MAC_ADR2, MAC_ADR3, + 30:../../../../Lib/net/nic.c **** + 31:../../../../Lib/net/nic.c **** + 32:../../../../Lib/net/nic.c **** /* Weak functions, that hast to be overriden in hardware specyfic driver implementation i.e. in enc + 33:../../../../Lib/net/nic.c **** void nicMacInit(void) { } + 136 .LM0: + 137 .LFBB1: + 138 /* prologue: function */ + 139 /* frame size = 0 */ + 140 /* stack size = 0 */ + 141 .L__stack_usage = 0 + 142 0000 0895 ret + 144 .Lscope1: + 146 .stabd 78,0,0 + 149 .weak nicSend + 151 nicSend: + 152 .stabd 46,0,0 + 34:../../../../Lib/net/nic.c **** void nicSend(uint16_t len) { (void) len; } + 154 .LM1: + 155 .LFBB2: + 156 /* prologue: function */ + 157 /* frame size = 0 */ + 158 /* stack size = 0 */ + 159 .L__stack_usage = 0 + 160 0002 0895 ret + 162 .Lscope2: + 164 .stabd 78,0,0 + 166 .weak nicPoll + 168 nicPoll: + 169 .stabd 46,0,0 + 35:../../../../Lib/net/nic.c **** unsigned int nicPoll(void) { return 0; } + 171 .LM2: + 172 .LFBB3: + 173 /* prologue: function */ + 174 /* frame size = 0 */ + 175 /* stack size = 0 */ + 176 .L__stack_usage = 0 + 178 .LM3: + 179 0004 80E0 ldi r24,0 + 180 0006 90E0 ldi r25,0 + 181 0008 0895 ret + 183 .Lscope3: + 185 .stabd 78,0,0 + 187 .global nicLoadConfig + 189 nicLoadConfig: + 190 .stabd 46,0,0 + 36:../../../../Lib/net/nic.c **** + 37:../../../../Lib/net/nic.c **** + 38:../../../../Lib/net/nic.c **** + 39:../../../../Lib/net/nic.c **** + 40:../../../../Lib/net/nic.c **** + 41:../../../../Lib/net/nic.c **** static void nicBufferInit(void) + 42:../../../../Lib/net/nic.c **** { + 43:../../../../Lib/net/nic.c **** nicState.bufferSize = NETWORK_STACK_BUF_SIZE; + 44:../../../../Lib/net/nic.c **** nicState.layer2.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR); + 45:../../../../Lib/net/nic.c **** nicState.layer3.ip = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te w + 46:../../../../Lib/net/nic.c **** nicState.layer4.icmp = (struct netIcmpHeader *)(NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN + IP_HEA + 47:../../../../Lib/net/nic.c **** #if IPV6_SUPPORT + 48:../../../../Lib/net/nic.c **** nicState.layer3.ipv6 = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + 49:../../../../Lib/net/nic.c **** nicState.layer3.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + 50:../../../../Lib/net/nic.c **** //nicState.layer4.icmpv6 = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); / + 51:../../../../Lib/net/nic.c **** #endif /*IPV6_SUPPORT*/ + 52:../../../../Lib/net/nic.c **** memset(nicState.layer2.buf, 0, nicState.bufferSize); + 53:../../../../Lib/net/nic.c **** nicLoadConfig(); + 54:../../../../Lib/net/nic.c **** } + 55:../../../../Lib/net/nic.c **** + 56:../../../../Lib/net/nic.c **** void nicLoadConfig(void) + 57:../../../../Lib/net/nic.c **** { + 192 .LM4: + 193 .LFBB4: + 194 /* prologue: function */ + 195 /* frame size = 0 */ + 196 /* stack size = 0 */ + 197 .L__stack_usage = 0 + 58:../../../../Lib/net/nic.c **** eeprom_read_block(&nicState.mac.addr, mymac_eep, 6); + 199 .LM5: + 200 000a 46E0 ldi r20,lo8(6) + 201 000c 50E0 ldi r21,0 + 202 000e 60E0 ldi r22,lo8(mymac_eep) + 203 0010 70E0 ldi r23,hi8(mymac_eep) + 204 0012 80E0 ldi r24,lo8(nicState+2) + 205 0014 90E0 ldi r25,hi8(nicState+2) + 206 0016 0C94 0000 jmp eeprom_read_block + 208 .Lscope4: + 210 .stabd 78,0,0 + 212 .global nicSaveConfig + 214 nicSaveConfig: + 215 .stabd 46,0,0 + 59:../../../../Lib/net/nic.c **** } + 60:../../../../Lib/net/nic.c **** + 61:../../../../Lib/net/nic.c **** void nicSaveConfig(void) + 62:../../../../Lib/net/nic.c **** { + 217 .LM6: + 218 .LFBB5: + 219 /* prologue: function */ + 220 /* frame size = 0 */ + 221 /* stack size = 0 */ + 222 .L__stack_usage = 0 + 63:../../../../Lib/net/nic.c **** eeprom_update_block(&nicState.mac.addr, mymac_eep, 6); + 224 .LM7: + 225 001a 46E0 ldi r20,lo8(6) + 226 001c 50E0 ldi r21,0 + 227 001e 60E0 ldi r22,lo8(mymac_eep) + 228 0020 70E0 ldi r23,hi8(mymac_eep) + 229 0022 80E0 ldi r24,lo8(nicState+2) + 230 0024 90E0 ldi r25,hi8(nicState+2) + 231 0026 0C94 0000 jmp eeprom_update_block + 233 .Lscope5: + 235 .stabd 78,0,0 + 237 .global nicInit + 239 nicInit: + 240 .stabd 46,0,0 + 64:../../../../Lib/net/nic.c **** } + 65:../../../../Lib/net/nic.c **** + 66:../../../../Lib/net/nic.c **** void nicInit() + 67:../../../../Lib/net/nic.c **** { + 242 .LM8: + 243 .LFBB6: + 244 /* prologue: function */ + 245 /* frame size = 0 */ + 246 /* stack size = 0 */ + 247 .L__stack_usage = 0 + 248 .LBB4: + 249 .LBB5: + 43:../../../../Lib/net/nic.c **** nicState.layer2.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR); + 251 .LM9: + 252 002a E0E0 ldi r30,lo8(nicState) + 253 002c F0E0 ldi r31,hi8(nicState) + 254 002e 80E0 ldi r24,0 + 255 0030 96E0 ldi r25,lo8(6) + 256 0032 9183 std Z+1,r25 + 257 0034 8083 st Z,r24 + 44:../../../../Lib/net/nic.c **** nicState.layer3.ip = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te w + 259 .LM10: + 260 0036 A0E0 ldi r26,0 + 261 0038 BAE7 ldi r27,lo8(122) + 262 003a B187 std Z+9,r27 + 263 003c A087 std Z+8,r26 + 45:../../../../Lib/net/nic.c **** nicState.layer4.icmp = (struct netIcmpHeader *)(NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN + IP_HEA + 265 .LM11: + 266 003e 2EE0 ldi r18,lo8(14) + 267 0040 3AE7 ldi r19,lo8(122) + 268 0042 3387 std Z+11,r19 + 269 0044 2287 std Z+10,r18 + 46:../../../../Lib/net/nic.c **** #if IPV6_SUPPORT + 271 .LM12: + 272 0046 22E2 ldi r18,lo8(34) + 273 0048 3AE7 ldi r19,lo8(122) + 274 004a 3587 std Z+13,r19 + 275 004c 2487 std Z+12,r18 + 52:../../../../Lib/net/nic.c **** nicLoadConfig(); + 277 .LM13: + 278 004e FD01 movw r30,r26 + 279 0050 9C01 movw r18,r24 + 280 0: + 281 0052 1192 st Z+,__zero_reg__ + 282 0054 2150 subi r18,1 + 283 0056 3040 sbci r19,0 + 284 0058 01F4 brne 0b + 53:../../../../Lib/net/nic.c **** } + 286 .LM14: + 287 005a 0E94 0000 call nicLoadConfig + 288 .LBE5: + 289 .LBE4: + 68:../../../../Lib/net/nic.c **** nicBufferInit(); + 69:../../../../Lib/net/nic.c **** nicMacInit(); + 291 .LM15: + 292 005e 0C94 0000 jmp nicMacInit + 294 .Lscope6: + 296 .stabd 78,0,0 + 299 .weak nicGetMacAddress + 301 nicGetMacAddress: + 302 .stabd 46,0,0 + 70:../../../../Lib/net/nic.c **** } + 71:../../../../Lib/net/nic.c **** + 72:../../../../Lib/net/nic.c **** void nicGetMacAddress(uint8_t* macaddr) + 73:../../../../Lib/net/nic.c **** { + 304 .LM16: + 305 .LFBB7: + 306 /* prologue: function */ + 307 /* frame size = 0 */ + 308 /* stack size = 0 */ + 309 .L__stack_usage = 0 + 74:../../../../Lib/net/nic.c **** strncpy((void *)(macaddr), (void *)(nicState.mac.addr), 6); + 311 .LM17: + 312 0062 46E0 ldi r20,lo8(6) + 313 0064 50E0 ldi r21,0 + 314 0066 60E0 ldi r22,lo8(nicState+2) + 315 0068 70E0 ldi r23,hi8(nicState+2) + 316 006a 0C94 0000 jmp strncpy + 318 .Lscope7: + 320 .stabd 78,0,0 + 323 .weak nicSetMacAddress + 325 nicSetMacAddress: + 326 .stabd 46,0,0 + 75:../../../../Lib/net/nic.c **** } + 76:../../../../Lib/net/nic.c **** + 77:../../../../Lib/net/nic.c **** void nicSetMacAddress(uint8_t* macaddr) + 78:../../../../Lib/net/nic.c **** { + 328 .LM18: + 329 .LFBB8: + 330 /* prologue: function */ + 331 /* frame size = 0 */ + 332 /* stack size = 0 */ + 333 .L__stack_usage = 0 + 79:../../../../Lib/net/nic.c **** strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); + 335 .LM19: + 336 006e 46E0 ldi r20,lo8(6) + 337 0070 50E0 ldi r21,0 + 338 0072 BC01 movw r22,r24 + 339 0074 80E0 ldi r24,lo8(nicState+2) + 340 0076 90E0 ldi r25,hi8(nicState+2) + 341 0078 0E94 0000 call strncpy + 80:../../../../Lib/net/nic.c **** nicMacInit(); + 343 .LM20: + 344 007c 0C94 0000 jmp nicMacInit + 346 .Lscope8: + 348 .stabd 78,0,0 + 350 .weak nicRegDump + 352 nicRegDump: + 353 .stabd 46,0,0 + 81:../../../../Lib/net/nic.c **** } + 82:../../../../Lib/net/nic.c **** + 83:../../../../Lib/net/nic.c **** void nicRegDump(FILE *stream) + 84:../../../../Lib/net/nic.c **** { + 355 .LM21: + 356 .LFBB9: + 357 /* prologue: function */ + 358 /* frame size = 0 */ + 359 /* stack size = 0 */ + 360 .L__stack_usage = 0 + 85:../../../../Lib/net/nic.c **** fprintf_P(stream, PSTR("NIC reg dump not implemented\r\n")); + 362 .LM22: + 363 0080 20E0 ldi r18,lo8(__c.2141) + 364 0082 30E0 ldi r19,hi8(__c.2141) + 365 0084 3F93 push r19 + 366 0086 2F93 push r18 + 367 0088 9F93 push r25 + 368 008a 8F93 push r24 + 369 008c 0E94 0000 call fprintf_P + 370 0090 0F90 pop __tmp_reg__ + 371 0092 0F90 pop __tmp_reg__ + 372 0094 0F90 pop __tmp_reg__ + 373 0096 0F90 pop __tmp_reg__ + 374 0098 0895 ret + 376 .Lscope9: + 378 .stabd 78,0,0 + 379 .section .progmem.data,"a",@progbits + 382 __c.2141: + 383 0000 4E49 4320 .string "NIC reg dump not implemented\r\n" + 383 7265 6720 + 383 6475 6D70 + 383 206E 6F74 + 383 2069 6D70 + 384 .section .eeprom,"aw",@progbits + 387 mymac_eep: + 388 0000 12 .byte 18 + 389 0001 34 .byte 52 + 390 0002 56 .byte 86 + 391 0003 78 .byte 120 + 392 0004 9A .byte -102 + 393 0005 BC .byte -68 + 394 .comm nicState,14,1 + 395 .comm wwwport,1,1 + 399 .text + 401 .Letext0: + 402 .ident "GCC: (GNU) 4.9.2" + 403 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 nic.c + /tmp/ccETGQcc.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccETGQcc.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccETGQcc.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccETGQcc.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccETGQcc.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccETGQcc.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccETGQcc.s:133 .text:0000000000000000 nicMacInit + /tmp/ccETGQcc.s:151 .text:0000000000000002 nicSend + /tmp/ccETGQcc.s:168 .text:0000000000000004 nicPoll + /tmp/ccETGQcc.s:189 .text:000000000000000a nicLoadConfig + /tmp/ccETGQcc.s:387 .eeprom:0000000000000000 mymac_eep + *COM*:000000000000000e nicState + /tmp/ccETGQcc.s:214 .text:000000000000001a nicSaveConfig + /tmp/ccETGQcc.s:239 .text:000000000000002a nicInit + /tmp/ccETGQcc.s:301 .text:0000000000000062 nicGetMacAddress + /tmp/ccETGQcc.s:325 .text:000000000000006e nicSetMacAddress + /tmp/ccETGQcc.s:352 .text:0000000000000080 nicRegDump + /tmp/ccETGQcc.s:382 .progmem.data:0000000000000000 __c.2141 + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +eeprom_read_block +eeprom_update_block +strncpy +fprintf_P +__do_clear_bss diff --git a/Lib/net/tcp.c b/Lib/net/tcp.c new file mode 100644 index 0000000..df2c0ff --- /dev/null +++ b/Lib/net/tcp.c @@ -0,0 +1,353 @@ +/** + * @file tcp.c + * @author Adam Kaliszan + * @brief TCP socket + * @ingroup network + * @defgroup netstack Network Stack + * @version 0.2 + * Created: 13.10.2010 + * Revised: 05.10.2010 + * Editor Tabs: 2 + * + */ + +#include "tcp.h" + + +static struct TcpIpSocket* findConnectedSocket(void); + +/** + * @param *sck socket + */ +static inline void tcpAcceptConn(struct TcpIpSocket *sck); + +inline void socketInit(void) +{ + sockets = xmalloc(NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + memset(sockets, 0, NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + + uint8_t i; + uint8_t *ptr = (uint8_t *)RTOS_TCP_BUF_BASE_ADDR; + + struct TcpIpSocket *sck = sockets; + for (i=0; i < NUMBER_OF_SOCKETS; i++) + { +// sck->Rx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; +// sck->Tx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; + + sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + sck->seqNoLastSent = HTONL(0xFF112233); + sck->state = LISTEN; + sck++; + } +} + +struct TcpIpSocket* findConnectedSocket(void) +{ + struct TcpIpSocket *result = sockets; + uint8_t i; + for (i=0; istate != LISTEN) && (result->state != CLOSED)) + && (result->RemoteIpAddr == nicState.layer3.ip->srcipaddr) && (result->localPort == nicState.layer4.tcp->destport) && (result->remotePort == nicState.layer4.tcp->srcport)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Found TCP socket state %d\r\n"), result->state); +#endif + return result; + } + result++; + } + + result = sockets; + for (i=0; istate == LISTEN) && (result->localPort == nicState.layer4.tcp->destport)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Found TCP socket no %d state LISTEN\r\n"), i); +#endif + return &sockets[i]; + } + result++; + } +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Can't find TCP socket with localPort %d\r\n"), htons(nicState.layer4.tcp->destport)); +#endif + return NULL; +} + +static inline void tcpAcceptConn(struct TcpIpSocket *sck) +{ + sck->state = SYN_RECEIVED; + sck->remotePort = nicState.layer4.tcp->srcport; + sck->RemoteIpAddr = nicState.layer3.ip->srcipaddr; +} + +inline uint8_t processTcpPacket(void) +{ + struct TcpIpSocket *socket = findConnectedSocket(); + + if (socket == NULL) + return 1; + + + socket->seqNoLastReceived = htonl(nicState.layer4.tcp->seqno); + + if (socket->state == LISTEN) + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_SYN) + { +// uint16_t len = nicState.layer4.tcp->tcpoffset>>4; +// len *=4; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RECEIVED\r\n")); +#endif + tcpAcceptConn(socket); + //Preparing response + nicState.layer4.tcp->srcport = socket->localPort; + nicState.layer4.tcp->destport = socket->remotePort; + nicState.layer4.tcp->seqno = htonl(socket->seqNoLastSent); + nicState.layer4.tcp->ackno = htonl(socket->seqNoLastReceived+1); + nicState.layer4.tcp->tcpoffset = 5<<4; + nicState.layer4.tcp->flags = TCP_FLAGS_ACK+TCP_FLAGS_SYN; + nicState.layer4.tcp->wnd = htons(100); + nicState.layer4.tcp->tcpchksum = 0; + nicState.layer4.tcp->urgp = 0; + calculateTcpChecksun(TCP_HEADER_LEN); + + socket->seqNoLastSent++; + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + } +#if TCP_DEBUG + else + { + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 1) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: syn flag wasn't set\r\n")); + } +#endif + return 0; + } + + if (socket->state == SYN_RECEIVED) + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_ACK) + { + socket->state = ESTABILISHED; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change SYN_RECEIVED->ESTABILISHED\r\n")); +#endif + + } + else + { + socket->state = LISTEN; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 1) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: ack flag wasn't set\r\n")); +#endif + } + return 0; + } + + + if (socket->state == ESTABILISHED) + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_FIN) //ESTABILISHED -> CLOSE_WAIT -> closed + { + socket->timer = timer100Hz; + nicState.layer4.tcp->flags = TCP_FLAGS_ACK; + + uint8_t dataFromBufLen = 0; + uint8_t *dataPtr = (uint8_t *)(nicState.layer4.tcp+1); + while (xQueueReceive(socket->Tx, dataPtr, 0) == pdTRUE) + { + dataFromBufLen++; + dataPtr++; + } + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN + dataFromBufLen); + socket->state = CLOSE_WAIT; + + + nicState.layer4.tcp->flags = TCP_FLAGS_FIN; + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + socket->state = LAST_ACK; + } + return 0; + } + + //Read data and put into the queue + + return 0; +} + +void calculateTcpChecksun(uint16_t tcpLen) +{ + nicState.layer4.tcp->tcpchksum = 0; + nicState.layer4.tcp->tcpchksum = netChecksum((uint8_t *)nicState.layer4.tcp, tcpLen); //TODO finish it +} + + + +uint8_t sendTcpBuffer(uint8_t socketNo) +{ + (void) socketNo; + //struct TcpIpSocket *sck = &sockets[socketNo]; + return 0; +} + +void netstackTCPIPProcess(void) +{ + if (nicState.layer4.tcp->destport == htons(80)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + fprintf_P(tcpDebugStream, PSTR("HTTP not implemented\r\n")); +#endif + ; + } + else + { + processTcpPacket(); + } +} + +#if TCP_DEBUG +void setTcpDebug(FILE *stream, uint8_t level) +{ + tcpDebugStream = stream; + tcpDebugLevel = level; +} +#endif /* TCP_DEBUG */ + +void flushTcpQueues() +{ + uint8_t sckNo = 0; + struct TcpIpSocket *sck = sockets; + for (sckNo = 0; sckNo < NUMBER_OF_SOCKETS; sckNo++) + { + + sck++; + } +} + + +inline void httpProcess() +{ +#if 0 + // TCP WWW tcp port www start, compare only the lower byte + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_L_P]==MYWWWPORT ) + { + if ( Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V ) + { + make_tcp_synack_from_syn (Enc28j60_global.buf ); + // make_tcp_synack_from_syn does already send the syn,ack + continue; + } + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) + { + init_len_info (Enc28j60_global.buf ); // init some data structures + // we can possibly have no data, just ack: + dat_p=get_tcp_data_pointer(); + if ( dat_p==0 ) + { + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V ) + { + // finack, answer with ack + make_tcp_ack_from_any (Enc28j60_global.buf ); + } + // just an ack with no data, wait for next packet + continue; + } + if ( strncmp ( "GET ", ( char * )(&Enc28j60_global.buf[dat_p]), 4) !=0 ) + { + // head, post and other methods: + // + // for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=fill_tcp_data_p (Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + if ( strncmp ( "/ ", ( char * ) & (Enc28j60_global.buf[dat_p+4] ),2 ) ==0) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Usage: http://host_or_ip/filename or http://host_or_ip/sd/filename

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + + cmd = analyse_get_url (( char * )(&Enc28j60_global.buf[dat_p+5]), filename); + + if (cmd == URLramDysk) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + + //Open the filen + struct ramPlikFd fd; + if (ramDyskOtworzPlik(filename, &fd) != 0) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Nie mozna otworzyc pliku o nazwie: " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " umieszczonego w ram dysku

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Zawartosc pliku " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " zapisanego w ram dysku:
" ) ); + + char c; + while (plen < Enc28j60_global.bufferSize - 30) + { + if (ramDyskCzytajBajtZPliku(&fd , &c) != 0) + break; + plen = add_tcp_byte(Enc28j60_global.buf, plen, c); + } + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

\n")); + ramDyskZamknijPlik(&fd); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + + continue; + } + + if (cmd == URLsdDysk) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Do zaimpelentowania wyswietlenie pliku o nazwie " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " z karty SD

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + if (cmd == URLstatus) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=printHTMLstatus(Enc28j60_global.buf, plen, Enc28j60_global.bufferSize); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + } + +#endif +} diff --git a/Lib/net/tcp.lst b/Lib/net/tcp.lst new file mode 100644 index 0000000..96afb18 --- /dev/null +++ b/Lib/net/tcp.lst @@ -0,0 +1,1260 @@ + 1 .file "tcp.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 184 .global socketInit + 186 socketInit: + 187 .stabd 46,0,0 + 1:../../../../Lib/net/tcp.c **** /** + 2:../../../../Lib/net/tcp.c **** * @file tcp.c + 3:../../../../Lib/net/tcp.c **** * @author Adam Kaliszan + 4:../../../../Lib/net/tcp.c **** * @brief TCP socket + 5:../../../../Lib/net/tcp.c **** * @ingroup network + 6:../../../../Lib/net/tcp.c **** * @defgroup netstack Network Stack + 7:../../../../Lib/net/tcp.c **** * @version 0.2 + 8:../../../../Lib/net/tcp.c **** * Created: 13.10.2010 + 9:../../../../Lib/net/tcp.c **** * Revised: 05.10.2010 + 10:../../../../Lib/net/tcp.c **** * Editor Tabs: 2 + 11:../../../../Lib/net/tcp.c **** * + 12:../../../../Lib/net/tcp.c **** */ + 13:../../../../Lib/net/tcp.c **** + 14:../../../../Lib/net/tcp.c **** #include "tcp.h" + 15:../../../../Lib/net/tcp.c **** + 16:../../../../Lib/net/tcp.c **** + 17:../../../../Lib/net/tcp.c **** static struct TcpIpSocket* findConnectedSocket(void); + 18:../../../../Lib/net/tcp.c **** + 19:../../../../Lib/net/tcp.c **** /** + 20:../../../../Lib/net/tcp.c **** * @param *sck socket + 21:../../../../Lib/net/tcp.c **** */ + 22:../../../../Lib/net/tcp.c **** static inline void tcpAcceptConn(struct TcpIpSocket *sck); + 23:../../../../Lib/net/tcp.c **** + 24:../../../../Lib/net/tcp.c **** inline void socketInit(void) + 25:../../../../Lib/net/tcp.c **** { + 189 .LM0: + 190 .LFBB1: + 191 0000 8F92 push r8 + 192 0002 9F92 push r9 + 193 0004 AF92 push r10 + 194 0006 BF92 push r11 + 195 0008 FF92 push r15 + 196 000a 0F93 push r16 + 197 000c 1F93 push r17 + 198 000e CF93 push r28 + 199 0010 DF93 push r29 + 200 /* prologue: function */ + 201 /* frame size = 0 */ + 202 /* stack size = 9 */ + 203 .L__stack_usage = 9 + 26:../../../../Lib/net/tcp.c **** sockets = xmalloc(NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + 205 .LM1: + 206 0012 80E3 ldi r24,lo8(48) + 207 0014 92E0 ldi r25,lo8(2) + 208 0016 0E94 0000 call xmalloc + 209 001a 9093 0000 sts sockets+1,r25 + 210 001e 8093 0000 sts sockets,r24 + 27:../../../../Lib/net/tcp.c **** memset(sockets, 0, NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + 212 .LM2: + 213 0022 20E3 ldi r18,lo8(48) + 214 0024 32E0 ldi r19,lo8(2) + 215 0026 FC01 movw r30,r24 + 216 0028 A901 movw r20,r18 + 217 0: + 218 002a 1192 st Z+,__zero_reg__ + 219 002c 4150 subi r20,1 + 220 002e 5040 sbci r21,0 + 221 0030 01F4 brne 0b + 28:../../../../Lib/net/tcp.c **** + 29:../../../../Lib/net/tcp.c **** uint8_t i; + 30:../../../../Lib/net/tcp.c **** uint8_t *ptr = (uint8_t *)RTOS_TCP_BUF_BASE_ADDR; + 31:../../../../Lib/net/tcp.c **** + 32:../../../../Lib/net/tcp.c **** struct TcpIpSocket *sck = sockets; + 223 .LM3: + 224 0032 0091 0000 lds r16,sockets + 225 0036 1091 0000 lds r17,sockets+1 + 226 003a C8EA ldi r28,lo8(-88) + 227 003c D1E6 ldi r29,lo8(97) + 33:../../../../Lib/net/tcp.c **** for (i=0; i < NUMBER_OF_SOCKETS; i++) + 34:../../../../Lib/net/tcp.c **** { + 35:../../../../Lib/net/tcp.c **** // sck->Rx = xQueueCreateExternal(255, 1, (void *)(ptr)); + 36:../../../../Lib/net/tcp.c **** ptr+=256; + 37:../../../../Lib/net/tcp.c **** // sck->Tx = xQueueCreateExternal(255, 1, (void *)(ptr)); + 38:../../../../Lib/net/tcp.c **** ptr+=256; + 39:../../../../Lib/net/tcp.c **** + 40:../../../../Lib/net/tcp.c **** sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + 41:../../../../Lib/net/tcp.c **** sck->seqNoLastSent = HTONL(0xFF112233); + 229 .LM4: + 230 003e 8824 clr r8 + 231 0040 8A94 dec r8 + 232 0042 81E1 ldi r24,lo8(17) + 233 0044 982E mov r9,r24 + 234 0046 82E2 ldi r24,lo8(34) + 235 0048 A82E mov r10,r24 + 236 004a 83E3 ldi r24,lo8(51) + 237 004c B82E mov r11,r24 + 42:../../../../Lib/net/tcp.c **** sck->state = LISTEN; + 239 .LM5: + 240 004e FF24 clr r15 + 241 0050 F394 inc r15 + 242 .L3: + 243 0052 8C2F mov r24,r28 + 244 0054 885A subi r24,lo8(-(88)) + 40:../../../../Lib/net/tcp.c **** sck->seqNoLastSent = HTONL(0xFF112233); + 246 .LM6: + 247 0056 8031 cpi r24,lo8(16) + 248 0058 00F4 brsh .L4 + 40:../../../../Lib/net/tcp.c **** sck->seqNoLastSent = HTONL(0xFF112233); + 250 .LM7: + 251 005a CE01 movw r24,r28 + 252 005c 0E94 0000 call htons + 253 0060 00C0 rjmp .L2 + 254 .L4: + 40:../../../../Lib/net/tcp.c **** sck->seqNoLastSent = HTONL(0xFF112233); + 256 .LM8: + 257 0062 88EB ldi r24,lo8(-72) + 258 0064 91E6 ldi r25,lo8(97) + 259 .L2: + 40:../../../../Lib/net/tcp.c **** sck->seqNoLastSent = HTONL(0xFF112233); + 261 .LM9: + 262 0066 F801 movw r30,r16 + 263 0068 9683 std Z+6,r25 + 264 006a 8583 std Z+5,r24 + 41:../../../../Lib/net/tcp.c **** sck->state = LISTEN; + 266 .LM10: + 267 006c 8586 std Z+13,r8 + 268 006e 9686 std Z+14,r9 + 269 0070 A786 std Z+15,r10 + 270 0072 B08A std Z+16,r11 + 272 .LM11: + 273 0074 F082 st Z,r15 + 43:../../../../Lib/net/tcp.c **** sck++; + 275 .LM12: + 276 0076 045E subi r16,-28 + 277 0078 1F4F sbci r17,-1 + 278 007a 2196 adiw r28,1 + 33:../../../../Lib/net/tcp.c **** { + 280 .LM13: + 281 007c CC3B cpi r28,-68 + 282 007e F1E6 ldi r31,97 + 283 0080 DF07 cpc r29,r31 + 284 0082 01F4 brne .L3 + 285 /* epilogue start */ + 44:../../../../Lib/net/tcp.c **** } + 45:../../../../Lib/net/tcp.c **** } + 287 .LM14: + 288 0084 DF91 pop r29 + 289 0086 CF91 pop r28 + 290 0088 1F91 pop r17 + 291 008a 0F91 pop r16 + 292 008c FF90 pop r15 + 293 008e BF90 pop r11 + 294 0090 AF90 pop r10 + 295 0092 9F90 pop r9 + 296 0094 8F90 pop r8 + 297 0096 0895 ret + 302 .Lscope1: + 304 .stabd 78,0,0 + 307 .global calculateTcpChecksun + 309 calculateTcpChecksun: + 310 .stabd 46,0,0 + 46:../../../../Lib/net/tcp.c **** + 47:../../../../Lib/net/tcp.c **** struct TcpIpSocket* findConnectedSocket(void) + 48:../../../../Lib/net/tcp.c **** { + 49:../../../../Lib/net/tcp.c **** struct TcpIpSocket *result = sockets; + 50:../../../../Lib/net/tcp.c **** uint8_t i; + 51:../../../../Lib/net/tcp.c **** for (i=0; istate != LISTEN) && (result->state != CLOSED)) + 54:../../../../Lib/net/tcp.c **** && (result->RemoteIpAddr == nicState.layer3.ip->srcipaddr) && (result->localPort == nicState. + 55:../../../../Lib/net/tcp.c **** { + 56:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 57:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 58:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 59:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Found TCP socket state %d\r\n"), result->state); + 60:../../../../Lib/net/tcp.c **** #endif + 61:../../../../Lib/net/tcp.c **** return result; + 62:../../../../Lib/net/tcp.c **** } + 63:../../../../Lib/net/tcp.c **** result++; + 64:../../../../Lib/net/tcp.c **** } + 65:../../../../Lib/net/tcp.c **** + 66:../../../../Lib/net/tcp.c **** result = sockets; + 67:../../../../Lib/net/tcp.c **** for (i=0; istate == LISTEN) && (result->localPort == nicState.layer4.tcp->destport)) + 70:../../../../Lib/net/tcp.c **** { + 71:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 72:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 73:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 74:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Found TCP socket no %d state LISTEN\r\n"), i); + 75:../../../../Lib/net/tcp.c **** #endif + 76:../../../../Lib/net/tcp.c **** return &sockets[i]; + 77:../../../../Lib/net/tcp.c **** } + 78:../../../../Lib/net/tcp.c **** result++; + 79:../../../../Lib/net/tcp.c **** } + 80:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 81:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 82:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 83:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Can't find TCP socket with localPort %d\r\n"), htons(nicState + 84:../../../../Lib/net/tcp.c **** #endif + 85:../../../../Lib/net/tcp.c **** return NULL; + 86:../../../../Lib/net/tcp.c **** } + 87:../../../../Lib/net/tcp.c **** + 88:../../../../Lib/net/tcp.c **** static inline void tcpAcceptConn(struct TcpIpSocket *sck) + 89:../../../../Lib/net/tcp.c **** { + 90:../../../../Lib/net/tcp.c **** sck->state = SYN_RECEIVED; + 91:../../../../Lib/net/tcp.c **** sck->remotePort = nicState.layer4.tcp->srcport; + 92:../../../../Lib/net/tcp.c **** sck->RemoteIpAddr = nicState.layer3.ip->srcipaddr; + 93:../../../../Lib/net/tcp.c **** } + 94:../../../../Lib/net/tcp.c **** + 95:../../../../Lib/net/tcp.c **** inline uint8_t processTcpPacket(void) + 96:../../../../Lib/net/tcp.c **** { + 97:../../../../Lib/net/tcp.c **** struct TcpIpSocket *socket = findConnectedSocket(); + 98:../../../../Lib/net/tcp.c **** + 99:../../../../Lib/net/tcp.c **** if (socket == NULL) + 100:../../../../Lib/net/tcp.c **** return 1; + 101:../../../../Lib/net/tcp.c **** + 102:../../../../Lib/net/tcp.c **** + 103:../../../../Lib/net/tcp.c **** socket->seqNoLastReceived = htonl(nicState.layer4.tcp->seqno); + 104:../../../../Lib/net/tcp.c **** + 105:../../../../Lib/net/tcp.c **** if (socket->state == LISTEN) + 106:../../../../Lib/net/tcp.c **** { + 107:../../../../Lib/net/tcp.c **** if (nicState.layer4.tcp->flags & TCP_FLAGS_SYN) + 108:../../../../Lib/net/tcp.c **** { + 109:../../../../Lib/net/tcp.c **** // uint16_t len = nicState.layer4.tcp->tcpoffset>>4; + 110:../../../../Lib/net/tcp.c **** // len *=4; + 111:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 112:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 113:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 114:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RE + 115:../../../../Lib/net/tcp.c **** #endif + 116:../../../../Lib/net/tcp.c **** tcpAcceptConn(socket); + 117:../../../../Lib/net/tcp.c **** //Preparing response + 118:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->srcport = socket->localPort; + 119:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->destport = socket->remotePort; + 120:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->seqno = htonl(socket->seqNoLastSent); + 121:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->ackno = htonl(socket->seqNoLastReceived+1); + 122:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpoffset = 5<<4; + 123:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->flags = TCP_FLAGS_ACK+TCP_FLAGS_SYN; + 124:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->wnd = htons(100); + 125:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpchksum = 0; + 126:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->urgp = 0; + 127:../../../../Lib/net/tcp.c **** calculateTcpChecksun(TCP_HEADER_LEN); + 128:../../../../Lib/net/tcp.c **** + 129:../../../../Lib/net/tcp.c **** socket->seqNoLastSent++; + 130:../../../../Lib/net/tcp.c **** ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 131:../../../../Lib/net/tcp.c **** } + 132:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 133:../../../../Lib/net/tcp.c **** else + 134:../../../../Lib/net/tcp.c **** { + 135:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 136:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 1) + 137:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: syn flag wasn't set\r\n")); + 138:../../../../Lib/net/tcp.c **** } + 139:../../../../Lib/net/tcp.c **** #endif + 140:../../../../Lib/net/tcp.c **** return 0; + 141:../../../../Lib/net/tcp.c **** } + 142:../../../../Lib/net/tcp.c **** + 143:../../../../Lib/net/tcp.c **** if (socket->state == SYN_RECEIVED) + 144:../../../../Lib/net/tcp.c **** { + 145:../../../../Lib/net/tcp.c **** if (nicState.layer4.tcp->flags & TCP_FLAGS_ACK) + 146:../../../../Lib/net/tcp.c **** { + 147:../../../../Lib/net/tcp.c **** socket->state = ESTABILISHED; + 148:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 149:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 150:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 151:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change SYN_RECEIVED->ES + 152:../../../../Lib/net/tcp.c **** #endif + 153:../../../../Lib/net/tcp.c **** + 154:../../../../Lib/net/tcp.c **** } + 155:../../../../Lib/net/tcp.c **** else + 156:../../../../Lib/net/tcp.c **** { + 157:../../../../Lib/net/tcp.c **** socket->state = LISTEN; + 158:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 159:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 160:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 1) + 161:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: ack flag wasn't set\r\n")); + 162:../../../../Lib/net/tcp.c **** #endif + 163:../../../../Lib/net/tcp.c **** } + 164:../../../../Lib/net/tcp.c **** return 0; + 165:../../../../Lib/net/tcp.c **** } + 166:../../../../Lib/net/tcp.c **** + 167:../../../../Lib/net/tcp.c **** + 168:../../../../Lib/net/tcp.c **** if (socket->state == ESTABILISHED) + 169:../../../../Lib/net/tcp.c **** { + 170:../../../../Lib/net/tcp.c **** if (nicState.layer4.tcp->flags & TCP_FLAGS_FIN) //ESTABILISHED -> CLOSE_WAIT -> closed + 171:../../../../Lib/net/tcp.c **** { + 172:../../../../Lib/net/tcp.c **** socket->timer = timer100Hz; + 173:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->flags = TCP_FLAGS_ACK; + 174:../../../../Lib/net/tcp.c **** + 175:../../../../Lib/net/tcp.c **** uint8_t dataFromBufLen = 0; + 176:../../../../Lib/net/tcp.c **** uint8_t *dataPtr = (uint8_t *)(nicState.layer4.tcp+1); + 177:../../../../Lib/net/tcp.c **** while (xQueueReceive(socket->Tx, dataPtr, 0) == pdTRUE) + 178:../../../../Lib/net/tcp.c **** { + 179:../../../../Lib/net/tcp.c **** dataFromBufLen++; + 180:../../../../Lib/net/tcp.c **** dataPtr++; + 181:../../../../Lib/net/tcp.c **** } + 182:../../../../Lib/net/tcp.c **** ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN + dataFromBufLen); + 183:../../../../Lib/net/tcp.c **** socket->state = CLOSE_WAIT; + 184:../../../../Lib/net/tcp.c **** + 185:../../../../Lib/net/tcp.c **** + 186:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->flags = TCP_FLAGS_FIN; + 187:../../../../Lib/net/tcp.c **** ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 188:../../../../Lib/net/tcp.c **** socket->state = LAST_ACK; + 189:../../../../Lib/net/tcp.c **** } + 190:../../../../Lib/net/tcp.c **** return 0; + 191:../../../../Lib/net/tcp.c **** } + 192:../../../../Lib/net/tcp.c **** + 193:../../../../Lib/net/tcp.c **** //Read data and put into the queue + 194:../../../../Lib/net/tcp.c **** + 195:../../../../Lib/net/tcp.c **** return 0; + 196:../../../../Lib/net/tcp.c **** } + 197:../../../../Lib/net/tcp.c **** + 198:../../../../Lib/net/tcp.c **** void calculateTcpChecksun(uint16_t tcpLen) + 199:../../../../Lib/net/tcp.c **** { + 312 .LM15: + 313 .LFBB2: + 314 0098 CF93 push r28 + 315 009a DF93 push r29 + 316 /* prologue: function */ + 317 /* frame size = 0 */ + 318 /* stack size = 2 */ + 319 .L__stack_usage = 2 + 200:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpchksum = 0; + 321 .LM16: + 322 009c C091 0000 lds r28,nicState+12 + 323 00a0 D091 0000 lds r29,nicState+12+1 + 324 00a4 198A std Y+17,__zero_reg__ + 325 00a6 188A std Y+16,__zero_reg__ + 201:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpchksum = netChecksum((uint8_t *)nicState.layer4.tcp, tcpLen); //TODO fini + 327 .LM17: + 328 00a8 BC01 movw r22,r24 + 329 00aa CE01 movw r24,r28 + 330 00ac 0E94 0000 call netChecksum + 331 00b0 998B std Y+17,r25 + 332 00b2 888B std Y+16,r24 + 333 /* epilogue start */ + 202:../../../../Lib/net/tcp.c **** } + 335 .LM18: + 336 00b4 DF91 pop r29 + 337 00b6 CF91 pop r28 + 338 00b8 0895 ret + 340 .Lscope2: + 342 .stabd 78,0,0 + 344 .global processTcpPacket + 346 processTcpPacket: + 347 .stabd 46,0,0 + 96:../../../../Lib/net/tcp.c **** struct TcpIpSocket *socket = findConnectedSocket(); + 349 .LM19: + 350 .LFBB3: + 351 00ba 6F92 push r6 + 352 00bc 7F92 push r7 + 353 00be 8F92 push r8 + 354 00c0 9F92 push r9 + 355 00c2 AF92 push r10 + 356 00c4 BF92 push r11 + 357 00c6 CF92 push r12 + 358 00c8 DF92 push r13 + 359 00ca EF92 push r14 + 360 00cc FF92 push r15 + 361 00ce 0F93 push r16 + 362 00d0 1F93 push r17 + 363 00d2 CF93 push r28 + 364 00d4 DF93 push r29 + 365 /* prologue: function */ + 366 /* frame size = 0 */ + 367 /* stack size = 14 */ + 368 .L__stack_usage = 14 + 369 .LBB25: + 370 .LBB26: + 49:../../../../Lib/net/tcp.c **** uint8_t i; + 372 .LM20: + 373 00d6 E091 0000 lds r30,sockets + 374 00da F091 0000 lds r31,sockets+1 + 54:../../../../Lib/net/tcp.c **** { + 376 .LM21: + 377 00de 4091 0000 lds r20,nicState+10 + 378 00e2 5091 0000 lds r21,nicState+10+1 + 379 00e6 6090 0000 lds r6,nicState+12 + 380 00ea 7090 0000 lds r7,nicState+12+1 + 381 00ee CF01 movw r24,r30 + 382 00f0 805D subi r24,-48 + 383 00f2 9D4F sbci r25,-3 + 49:../../../../Lib/net/tcp.c **** uint8_t i; + 385 .LM22: + 386 00f4 EF01 movw r28,r30 + 387 .L12: + 53:../../../../Lib/net/tcp.c **** && (result->RemoteIpAddr == nicState.layer3.ip->srcipaddr) && (result->localPort == nicState. + 389 .LM23: + 390 00f6 2881 ld r18,Y + 391 00f8 2230 cpi r18,lo8(2) + 392 00fa 00F0 brlo .L9 + 54:../../../../Lib/net/tcp.c **** { + 394 .LM24: + 395 00fc 8980 ldd r8,Y+1 + 396 00fe 9A80 ldd r9,Y+2 + 397 0100 AB80 ldd r10,Y+3 + 398 0102 BC80 ldd r11,Y+4 + 399 0104 DA01 movw r26,r20 + 400 0106 1C96 adiw r26,12 + 401 0108 CD90 ld r12,X+ + 402 010a DD90 ld r13,X+ + 403 010c ED90 ld r14,X+ + 404 010e FC90 ld r15,X + 405 0110 1F97 sbiw r26,12+3 + 406 0112 8C14 cp r8,r12 + 407 0114 9D04 cpc r9,r13 + 408 0116 AE04 cpc r10,r14 + 409 0118 BF04 cpc r11,r15 + 410 011a 01F4 brne .L9 + 411 011c 0D81 ldd r16,Y+5 + 412 011e 1E81 ldd r17,Y+6 + 413 0120 D301 movw r26,r6 + 414 0122 1296 adiw r26,2 + 415 0124 6D91 ld r22,X+ + 416 0126 7C91 ld r23,X + 417 0128 1397 sbiw r26,2+1 + 418 012a 0617 cp r16,r22 + 419 012c 1707 cpc r17,r23 + 420 012e 01F4 brne .L9 + 421 0130 0F81 ldd r16,Y+7 + 422 0132 1885 ldd r17,Y+8 + 423 0134 6D91 ld r22,X+ + 424 0136 7C91 ld r23,X + 425 0138 0617 cp r16,r22 + 426 013a 1707 cpc r17,r23 + 427 013c 01F4 brne .L9 + 57:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 429 .LM25: + 430 013e 8091 0000 lds r24,tcpDebugStream + 431 0142 9091 0000 lds r25,tcpDebugStream+1 + 432 0146 0097 sbiw r24,0 + 433 0148 01F4 brne .+2 + 434 014a 00C0 rjmp .L11 + 58:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Found TCP socket state %d\r\n"), result->state); + 436 .LM26: + 437 014c 3091 0000 lds r19,tcpDebugLevel + 438 0150 3330 cpi r19,lo8(3) + 439 0152 00F4 brsh .+2 + 440 0154 00C0 rjmp .L11 + 59:../../../../Lib/net/tcp.c **** #endif + 442 .LM27: + 443 0156 1F92 push __zero_reg__ + 444 0158 2F93 push r18 + 445 015a 20E0 ldi r18,lo8(__c.2682) + 446 015c 30E0 ldi r19,hi8(__c.2682) + 447 015e 3F93 push r19 + 448 0160 2F93 push r18 + 449 0162 9F93 push r25 + 450 0164 8F93 push r24 + 451 0166 0E94 0000 call fprintf_P + 452 016a 0F90 pop __tmp_reg__ + 453 016c 0F90 pop __tmp_reg__ + 454 016e 0F90 pop __tmp_reg__ + 455 0170 0F90 pop __tmp_reg__ + 456 0172 0F90 pop __tmp_reg__ + 457 0174 0F90 pop __tmp_reg__ + 458 0176 00C0 rjmp .L11 + 459 .L9: + 63:../../../../Lib/net/tcp.c **** } + 461 .LM28: + 462 0178 6C96 adiw r28,28 + 51:../../../../Lib/net/tcp.c **** { + 464 .LM29: + 465 017a C817 cp r28,r24 + 466 017c D907 cpc r29,r25 + 467 017e 01F0 breq .+2 + 468 0180 00C0 rjmp .L12 + 469 0182 D0E0 ldi r29,0 + 470 .L15: + 69:../../../../Lib/net/tcp.c **** { + 472 .LM30: + 473 0184 8081 ld r24,Z + 474 0186 8130 cpi r24,lo8(1) + 475 0188 01F4 brne .L13 + 476 018a 2581 ldd r18,Z+5 + 477 018c 3681 ldd r19,Z+6 + 478 018e D301 movw r26,r6 + 479 0190 1296 adiw r26,2 + 480 0192 8D91 ld r24,X+ + 481 0194 9C91 ld r25,X + 482 0196 1397 sbiw r26,2+1 + 483 0198 2817 cp r18,r24 + 484 019a 3907 cpc r19,r25 + 485 019c 01F4 brne .L13 + 72:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 487 .LM31: + 488 019e 8091 0000 lds r24,tcpDebugStream + 489 01a2 9091 0000 lds r25,tcpDebugStream+1 + 490 01a6 0097 sbiw r24,0 + 491 01a8 01F0 breq .L14 + 73:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Found TCP socket no %d state LISTEN\r\n"), i); + 493 .LM32: + 494 01aa 2091 0000 lds r18,tcpDebugLevel + 495 01ae 2330 cpi r18,lo8(3) + 496 01b0 00F0 brlo .L14 + 74:../../../../Lib/net/tcp.c **** #endif + 498 .LM33: + 499 01b2 1F92 push __zero_reg__ + 500 01b4 DF93 push r29 + 501 01b6 20E0 ldi r18,lo8(__c.2687) + 502 01b8 30E0 ldi r19,hi8(__c.2687) + 503 01ba 3F93 push r19 + 504 01bc 2F93 push r18 + 505 01be 9F93 push r25 + 506 01c0 8F93 push r24 + 507 01c2 0E94 0000 call fprintf_P + 508 01c6 0F90 pop __tmp_reg__ + 509 01c8 0F90 pop __tmp_reg__ + 510 01ca 0F90 pop __tmp_reg__ + 511 01cc 0F90 pop __tmp_reg__ + 512 01ce 0F90 pop __tmp_reg__ + 513 01d0 0F90 pop __tmp_reg__ + 514 .L14: + 76:../../../../Lib/net/tcp.c **** } + 516 .LM34: + 517 01d2 8091 0000 lds r24,sockets + 518 01d6 9091 0000 lds r25,sockets+1 + 519 01da FC01 movw r30,r24 + 520 01dc 2CE1 ldi r18,lo8(28) + 521 01de D29F mul r29,r18 + 522 01e0 E00D add r30,r0 + 523 01e2 F11D adc r31,r1 + 524 01e4 1124 clr __zero_reg__ + 525 01e6 EF01 movw r28,r30 + 526 01e8 00C0 rjmp .L11 + 527 .L13: + 78:../../../../Lib/net/tcp.c **** } + 529 .LM35: + 530 01ea 7C96 adiw r30,28 + 67:../../../../Lib/net/tcp.c **** { + 532 .LM36: + 533 01ec DF5F subi r29,lo8(-(1)) + 534 01ee D431 cpi r29,lo8(20) + 535 01f0 01F4 brne .L15 + 81:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 537 .LM37: + 538 01f2 8091 0000 lds r24,tcpDebugStream + 539 01f6 9091 0000 lds r25,tcpDebugStream+1 + 540 01fa 892B or r24,r25 + 541 01fc 01F4 brne .+2 + 542 01fe 00C0 rjmp .L16 + 82:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Can't find TCP socket with localPort %d\r\n"), htons(nicState + 544 .LM38: + 545 0200 8091 0000 lds r24,tcpDebugLevel + 546 0204 8330 cpi r24,lo8(3) + 547 0206 00F4 brsh .+2 + 548 0208 00C0 rjmp .L16 + 83:../../../../Lib/net/tcp.c **** #endif + 550 .LM39: + 551 020a D301 movw r26,r6 + 552 020c 1296 adiw r26,2 + 553 020e 8D91 ld r24,X+ + 554 0210 9C91 ld r25,X + 555 0212 1397 sbiw r26,2+1 + 556 0214 0E94 0000 call htons + 557 0218 9F93 push r25 + 558 021a 8F93 push r24 + 559 021c 80E0 ldi r24,lo8(__c.2692) + 560 021e 90E0 ldi r25,hi8(__c.2692) + 561 0220 9F93 push r25 + 562 0222 8F93 push r24 + 563 0224 8091 0000 lds r24,tcpDebugStream+1 + 564 0228 8F93 push r24 + 565 022a 8091 0000 lds r24,tcpDebugStream + 566 022e 8F93 push r24 + 567 0230 0E94 0000 call fprintf_P + 568 0234 0F90 pop __tmp_reg__ + 569 0236 0F90 pop __tmp_reg__ + 570 0238 0F90 pop __tmp_reg__ + 571 023a 0F90 pop __tmp_reg__ + 572 023c 0F90 pop __tmp_reg__ + 573 023e 0F90 pop __tmp_reg__ + 574 0240 00C0 rjmp .L16 + 575 .L11: + 576 .LBE26: + 577 .LBE25: + 99:../../../../Lib/net/tcp.c **** return 1; + 579 .LM40: + 580 0242 2097 sbiw r28,0 + 581 0244 01F4 brne .+2 + 582 0246 00C0 rjmp .L16 + 103:../../../../Lib/net/tcp.c **** + 584 .LM41: + 585 0248 E091 0000 lds r30,nicState+12 + 586 024c F091 0000 lds r31,nicState+12+1 + 587 0250 6481 ldd r22,Z+4 + 588 0252 7581 ldd r23,Z+5 + 589 0254 8681 ldd r24,Z+6 + 590 0256 9781 ldd r25,Z+7 + 591 0258 0E94 0000 call htonl + 592 025c 6987 std Y+9,r22 + 593 025e 7A87 std Y+10,r23 + 594 0260 8B87 std Y+11,r24 + 595 0262 9C87 std Y+12,r25 + 105:../../../../Lib/net/tcp.c **** { + 597 .LM42: + 598 0264 8881 ld r24,Y + 599 0266 8130 cpi r24,lo8(1) + 600 0268 01F0 breq .+2 + 601 026a 00C0 rjmp .L18 + 107:../../../../Lib/net/tcp.c **** { + 603 .LM43: + 604 026c E091 0000 lds r30,nicState+12 + 605 0270 F091 0000 lds r31,nicState+12+1 + 606 0274 2585 ldd r18,Z+13 + 607 0276 8091 0000 lds r24,tcpDebugStream + 608 027a 9091 0000 lds r25,tcpDebugStream+1 + 609 027e 122F mov r17,r18 + 610 0280 1270 andi r17,lo8(2) + 611 0282 21FF sbrs r18,1 + 612 0284 00C0 rjmp .L19 + 112:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 614 .LM44: + 615 0286 0097 sbiw r24,0 + 616 0288 01F0 breq .L20 + 113:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RE + 618 .LM45: + 619 028a 2091 0000 lds r18,tcpDebugLevel + 620 028e 2330 cpi r18,lo8(3) + 621 0290 00F0 brlo .L20 + 114:../../../../Lib/net/tcp.c **** #endif + 623 .LM46: + 624 0292 20E0 ldi r18,lo8(__c.2701) + 625 0294 30E0 ldi r19,hi8(__c.2701) + 626 0296 3F93 push r19 + 627 0298 2F93 push r18 + 628 029a 9F93 push r25 + 629 029c 8F93 push r24 + 630 029e 0E94 0000 call fprintf_P + 631 02a2 0F90 pop __tmp_reg__ + 632 02a4 0F90 pop __tmp_reg__ + 633 02a6 0F90 pop __tmp_reg__ + 634 02a8 0F90 pop __tmp_reg__ + 635 .L20: + 636 .LBB27: + 637 .LBB28: + 90:../../../../Lib/net/tcp.c **** sck->remotePort = nicState.layer4.tcp->srcport; + 639 .LM47: + 640 02aa 82E0 ldi r24,lo8(2) + 641 02ac 8883 st Y,r24 + 91:../../../../Lib/net/tcp.c **** sck->RemoteIpAddr = nicState.layer3.ip->srcipaddr; + 643 .LM48: + 644 02ae 0091 0000 lds r16,nicState+12 + 645 02b2 1091 0000 lds r17,nicState+12+1 + 646 02b6 F801 movw r30,r16 + 647 02b8 8081 ld r24,Z + 648 02ba 9181 ldd r25,Z+1 + 649 02bc 9887 std Y+8,r25 + 650 02be 8F83 std Y+7,r24 + 92:../../../../Lib/net/tcp.c **** } + 652 .LM49: + 653 02c0 E091 0000 lds r30,nicState+10 + 654 02c4 F091 0000 lds r31,nicState+10+1 + 655 02c8 4485 ldd r20,Z+12 + 656 02ca 5585 ldd r21,Z+13 + 657 02cc 6685 ldd r22,Z+14 + 658 02ce 7785 ldd r23,Z+15 + 659 02d0 4983 std Y+1,r20 + 660 02d2 5A83 std Y+2,r21 + 661 02d4 6B83 std Y+3,r22 + 662 02d6 7C83 std Y+4,r23 + 663 .LBE28: + 664 .LBE27: + 118:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->destport = socket->remotePort; + 666 .LM50: + 667 02d8 2D81 ldd r18,Y+5 + 668 02da 3E81 ldd r19,Y+6 + 669 02dc D801 movw r26,r16 + 670 02de 1196 adiw r26,1 + 671 02e0 3C93 st X,r19 + 672 02e2 2E93 st -X,r18 + 119:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->seqno = htonl(socket->seqNoLastSent); + 674 .LM51: + 675 02e4 1396 adiw r26,2+1 + 676 02e6 9C93 st X,r25 + 677 02e8 8E93 st -X,r24 + 678 02ea 1297 sbiw r26,2 + 120:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->ackno = htonl(socket->seqNoLastReceived+1); + 680 .LM52: + 681 02ec 6D85 ldd r22,Y+13 + 682 02ee 7E85 ldd r23,Y+14 + 683 02f0 8F85 ldd r24,Y+15 + 684 02f2 9889 ldd r25,Y+16 + 685 02f4 0E94 0000 call htonl + 686 02f8 F801 movw r30,r16 + 687 02fa 6483 std Z+4,r22 + 688 02fc 7583 std Z+5,r23 + 689 02fe 8683 std Z+6,r24 + 690 0300 9783 std Z+7,r25 + 121:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpoffset = 5<<4; + 692 .LM53: + 693 0302 0091 0000 lds r16,nicState+12 + 694 0306 1091 0000 lds r17,nicState+12+1 + 695 030a 8985 ldd r24,Y+9 + 696 030c 9A85 ldd r25,Y+10 + 697 030e AB85 ldd r26,Y+11 + 698 0310 BC85 ldd r27,Y+12 + 699 0312 BC01 movw r22,r24 + 700 0314 CD01 movw r24,r26 + 701 0316 6F5F subi r22,-1 + 702 0318 7F4F sbci r23,-1 + 703 031a 8F4F sbci r24,-1 + 704 031c 9F4F sbci r25,-1 + 705 031e 0E94 0000 call htonl + 706 0322 D801 movw r26,r16 + 707 0324 1896 adiw r26,8 + 708 0326 6D93 st X+,r22 + 709 0328 7D93 st X+,r23 + 710 032a 8D93 st X+,r24 + 711 032c 9C93 st X,r25 + 712 032e 1B97 sbiw r26,8+3 + 122:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->flags = TCP_FLAGS_ACK+TCP_FLAGS_SYN; + 714 .LM54: + 715 0330 0091 0000 lds r16,nicState+12 + 716 0334 1091 0000 lds r17,nicState+12+1 + 717 0338 80E5 ldi r24,lo8(80) + 718 033a F801 movw r30,r16 + 719 033c 8487 std Z+12,r24 + 123:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->wnd = htons(100); + 721 .LM55: + 722 033e 82E1 ldi r24,lo8(18) + 723 0340 8587 std Z+13,r24 + 124:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->tcpchksum = 0; + 725 .LM56: + 726 0342 84E6 ldi r24,lo8(100) + 727 0344 90E0 ldi r25,0 + 728 0346 0E94 0000 call htons + 729 034a D801 movw r26,r16 + 730 034c 1F96 adiw r26,14+1 + 731 034e 9C93 st X,r25 + 732 0350 8E93 st -X,r24 + 733 0352 1E97 sbiw r26,14 + 125:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->urgp = 0; + 735 .LM57: + 736 0354 E091 0000 lds r30,nicState+12 + 737 0358 F091 0000 lds r31,nicState+12+1 + 738 035c 118A std Z+17,__zero_reg__ + 739 035e 108A std Z+16,__zero_reg__ + 126:../../../../Lib/net/tcp.c **** calculateTcpChecksun(TCP_HEADER_LEN); + 741 .LM58: + 742 0360 138A std Z+19,__zero_reg__ + 743 0362 128A std Z+18,__zero_reg__ + 127:../../../../Lib/net/tcp.c **** + 745 .LM59: + 746 0364 84E1 ldi r24,lo8(20) + 747 0366 90E0 ldi r25,0 + 748 0368 0E94 0000 call calculateTcpChecksun + 129:../../../../Lib/net/tcp.c **** ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 750 .LM60: + 751 036c 8D85 ldd r24,Y+13 + 752 036e 9E85 ldd r25,Y+14 + 753 0370 AF85 ldd r26,Y+15 + 754 0372 B889 ldd r27,Y+16 + 755 0374 0196 adiw r24,1 + 756 0376 A11D adc r26,__zero_reg__ + 757 0378 B11D adc r27,__zero_reg__ + 758 037a 8D87 std Y+13,r24 + 759 037c 9E87 std Y+14,r25 + 760 037e AF87 std Y+15,r26 + 761 0380 B88B std Y+16,r27 + 130:../../../../Lib/net/tcp.c **** } + 763 .LM61: + 764 0382 6981 ldd r22,Y+1 + 765 0384 7A81 ldd r23,Y+2 + 766 0386 8B81 ldd r24,Y+3 + 767 0388 9C81 ldd r25,Y+4 + 768 038a 24E1 ldi r18,lo8(20) + 769 038c 30E0 ldi r19,0 + 770 038e 46E0 ldi r20,lo8(6) + 771 0390 0E94 0000 call ipSend + 772 0394 00C0 rjmp .L52 + 773 .L19: + 774 .LBB29: + 775 .LBB30: + 135:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 1) + 777 .LM62: + 778 0396 0097 sbiw r24,0 + 779 0398 01F4 brne .+2 + 780 039a 00C0 rjmp .L52 + 136:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: syn flag wasn't set\r\n")); + 782 .LM63: + 783 039c 2091 0000 lds r18,tcpDebugLevel + 784 03a0 2230 cpi r18,lo8(2) + 785 03a2 00F4 brsh .+2 + 786 03a4 00C0 rjmp .L52 + 137:../../../../Lib/net/tcp.c **** } + 788 .LM64: + 789 03a6 20E0 ldi r18,lo8(__c.2703) + 790 03a8 30E0 ldi r19,hi8(__c.2703) + 791 03aa 00C0 rjmp .L53 + 792 .L18: + 793 .LBE30: + 794 .LBE29: + 143:../../../../Lib/net/tcp.c **** { + 796 .LM65: + 797 03ac 8230 cpi r24,lo8(2) + 798 03ae 01F4 brne .L23 + 145:../../../../Lib/net/tcp.c **** { + 800 .LM66: + 801 03b0 E091 0000 lds r30,nicState+12 + 802 03b4 F091 0000 lds r31,nicState+12+1 + 803 03b8 2585 ldd r18,Z+13 + 804 03ba 8091 0000 lds r24,tcpDebugStream + 805 03be 9091 0000 lds r25,tcpDebugStream+1 + 806 03c2 122F mov r17,r18 + 807 03c4 1071 andi r17,lo8(16) + 808 03c6 24FF sbrs r18,4 + 809 03c8 00C0 rjmp .L24 + 147:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 811 .LM67: + 812 03ca 23E0 ldi r18,lo8(3) + 813 03cc 2883 st Y,r18 + 149:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 2) + 815 .LM68: + 816 03ce 0097 sbiw r24,0 + 817 03d0 01F4 brne .+2 + 818 03d2 00C0 rjmp .L52 + 150:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change SYN_RECEIVED->ES + 820 .LM69: + 821 03d4 2091 0000 lds r18,tcpDebugLevel + 822 03d8 2330 cpi r18,lo8(3) + 823 03da 00F4 brsh .+2 + 824 03dc 00C0 rjmp .L52 + 151:../../../../Lib/net/tcp.c **** #endif + 826 .LM70: + 827 03de 20E0 ldi r18,lo8(__c.2705) + 828 03e0 30E0 ldi r19,hi8(__c.2705) + 829 03e2 3F93 push r19 + 830 03e4 2F93 push r18 + 831 03e6 9F93 push r25 + 832 03e8 8F93 push r24 + 833 03ea 0E94 0000 call fprintf_P + 834 03ee 0F90 pop __tmp_reg__ + 835 03f0 0F90 pop __tmp_reg__ + 836 03f2 0F90 pop __tmp_reg__ + 837 03f4 0F90 pop __tmp_reg__ + 838 03f6 00C0 rjmp .L52 + 839 .L24: + 157:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 841 .LM71: + 842 03f8 21E0 ldi r18,lo8(1) + 843 03fa 2883 st Y,r18 + 159:../../../../Lib/net/tcp.c **** if (tcpDebugLevel > 1) + 845 .LM72: + 846 03fc 0097 sbiw r24,0 + 847 03fe 01F4 brne .+2 + 848 0400 00C0 rjmp .L52 + 160:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: ack flag wasn't set\r\n")); + 850 .LM73: + 851 0402 2091 0000 lds r18,tcpDebugLevel + 852 0406 2230 cpi r18,lo8(2) + 853 0408 00F4 brsh .+2 + 854 040a 00C0 rjmp .L52 + 161:../../../../Lib/net/tcp.c **** #endif + 856 .LM74: + 857 040c 20E0 ldi r18,lo8(__c.2707) + 858 040e 30E0 ldi r19,hi8(__c.2707) + 859 .L53: + 860 0410 3F93 push r19 + 861 0412 2F93 push r18 + 862 0414 9F93 push r25 + 863 0416 8F93 push r24 + 864 0418 0E94 0000 call fprintf_P + 865 041c 0F90 pop __tmp_reg__ + 866 041e 0F90 pop __tmp_reg__ + 867 0420 0F90 pop __tmp_reg__ + 868 0422 0F90 pop __tmp_reg__ + 869 0424 00C0 rjmp .L51 + 870 .L23: + 168:../../../../Lib/net/tcp.c **** { + 872 .LM75: + 873 0426 8330 cpi r24,lo8(3) + 874 0428 01F4 brne .L52 + 170:../../../../Lib/net/tcp.c **** { + 876 .LM76: + 877 042a E091 0000 lds r30,nicState+12 + 878 042e F091 0000 lds r31,nicState+12+1 + 879 0432 8585 ldd r24,Z+13 + 880 0434 80FF sbrs r24,0 + 881 0436 00C0 rjmp .L52 + 882 .LBB31: + 172:../../../../Lib/net/tcp.c **** nicState.layer4.tcp->flags = TCP_FLAGS_ACK; + 884 .LM77: + 885 0438 8091 0000 lds r24,timer100Hz + 886 043c 8D8B std Y+21,r24 + 173:../../../../Lib/net/tcp.c **** + 888 .LM78: + 889 043e 80E1 ldi r24,lo8(16) + 890 0440 8587 std Z+13,r24 + 176:../../../../Lib/net/tcp.c **** while (xQueueReceive(socket->Tx, dataPtr, 0) == pdTRUE) + 892 .LM79: + 893 0442 8F01 movw r16,r30 + 894 0444 0C5E subi r16,-20 + 895 0446 1F4F sbci r17,-1 + 896 0448 6801 movw r12,r16 + 897 .L25: + 898 044a FC2C mov r15,r12 + 899 044c F01A sub r15,r16 + 177:../../../../Lib/net/tcp.c **** { + 901 .LM80: + 902 044e 20E0 ldi r18,0 + 903 0450 40E0 ldi r20,0 + 904 0452 50E0 ldi r21,0 + 905 0454 B601 movw r22,r12 + 906 0456 888D ldd r24,Y+24 + 907 0458 998D ldd r25,Y+25 + 908 045a 0E94 0000 call xQueueGenericReceive + 909 045e 8130 cpi r24,lo8(1) + 910 0460 01F4 brne .L54 + 180:../../../../Lib/net/tcp.c **** } + 912 .LM81: + 913 0462 BFEF ldi r27,-1 + 914 0464 CB1A sub r12,r27 + 915 0466 DB0A sbc r13,r27 + 916 0468 00C0 rjmp .L25 + 917 .L54: + 182:../../../../Lib/net/tcp.c **** socket->state = CLOSE_WAIT; + 919 .LM82: + 920 046a 2F2D mov r18,r15 + 921 046c 30E0 ldi r19,0 + 922 046e 2C5E subi r18,-20 + 923 0470 3F4F sbci r19,-1 + 924 0472 6981 ldd r22,Y+1 + 925 0474 7A81 ldd r23,Y+2 + 926 0476 8B81 ldd r24,Y+3 + 927 0478 9C81 ldd r25,Y+4 + 928 047a 46E0 ldi r20,lo8(6) + 929 047c 0E94 0000 call ipSend + 183:../../../../Lib/net/tcp.c **** + 931 .LM83: + 932 0480 84E0 ldi r24,lo8(4) + 933 0482 8883 st Y,r24 + 186:../../../../Lib/net/tcp.c **** ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 935 .LM84: + 936 0484 E091 0000 lds r30,nicState+12 + 937 0488 F091 0000 lds r31,nicState+12+1 + 938 048c 81E0 ldi r24,lo8(1) + 939 048e 8587 std Z+13,r24 + 187:../../../../Lib/net/tcp.c **** socket->state = LAST_ACK; + 941 .LM85: + 942 0490 6981 ldd r22,Y+1 + 943 0492 7A81 ldd r23,Y+2 + 944 0494 8B81 ldd r24,Y+3 + 945 0496 9C81 ldd r25,Y+4 + 946 0498 24E1 ldi r18,lo8(20) + 947 049a 30E0 ldi r19,0 + 948 049c 46E0 ldi r20,lo8(6) + 949 049e 0E94 0000 call ipSend + 188:../../../../Lib/net/tcp.c **** } + 951 .LM86: + 952 04a2 85E0 ldi r24,lo8(5) + 953 04a4 8883 st Y,r24 + 954 .L52: + 955 .LBE31: + 190:../../../../Lib/net/tcp.c **** } + 957 .LM87: + 958 04a6 10E0 ldi r17,0 + 959 04a8 00C0 rjmp .L51 + 960 .L16: + 100:../../../../Lib/net/tcp.c **** + 962 .LM88: + 963 04aa 11E0 ldi r17,lo8(1) + 964 .L51: + 196:../../../../Lib/net/tcp.c **** + 966 .LM89: + 967 04ac 812F mov r24,r17 + 968 /* epilogue start */ + 969 04ae DF91 pop r29 + 970 04b0 CF91 pop r28 + 971 04b2 1F91 pop r17 + 972 04b4 0F91 pop r16 + 973 04b6 FF90 pop r15 + 974 04b8 EF90 pop r14 + 975 04ba DF90 pop r13 + 976 04bc CF90 pop r12 + 977 04be BF90 pop r11 + 978 04c0 AF90 pop r10 + 979 04c2 9F90 pop r9 + 980 04c4 8F90 pop r8 + 981 04c6 7F90 pop r7 + 982 04c8 6F90 pop r6 + 983 04ca 0895 ret + 991 .Lscope3: + 993 .stabd 78,0,0 + 996 .global sendTcpBuffer + 998 sendTcpBuffer: + 999 .stabd 46,0,0 + 203:../../../../Lib/net/tcp.c **** + 204:../../../../Lib/net/tcp.c **** + 205:../../../../Lib/net/tcp.c **** + 206:../../../../Lib/net/tcp.c **** uint8_t sendTcpBuffer(uint8_t socketNo) + 207:../../../../Lib/net/tcp.c **** { + 1001 .LM90: + 1002 .LFBB4: + 1003 /* prologue: function */ + 1004 /* frame size = 0 */ + 1005 /* stack size = 0 */ + 1006 .L__stack_usage = 0 + 208:../../../../Lib/net/tcp.c **** (void) socketNo; + 209:../../../../Lib/net/tcp.c **** //struct TcpIpSocket *sck = &sockets[socketNo]; + 210:../../../../Lib/net/tcp.c **** return 0; + 211:../../../../Lib/net/tcp.c **** } + 1008 .LM91: + 1009 04cc 80E0 ldi r24,0 + 1010 04ce 0895 ret + 1012 .Lscope4: + 1014 .stabd 78,0,0 + 1016 .global netstackTCPIPProcess + 1018 netstackTCPIPProcess: + 1019 .stabd 46,0,0 + 212:../../../../Lib/net/tcp.c **** + 213:../../../../Lib/net/tcp.c **** void netstackTCPIPProcess(void) + 214:../../../../Lib/net/tcp.c **** { + 1021 .LM92: + 1022 .LFBB5: + 1023 04d0 CF93 push r28 + 1024 04d2 DF93 push r29 + 1025 /* prologue: function */ + 1026 /* frame size = 0 */ + 1027 /* stack size = 2 */ + 1028 .L__stack_usage = 2 + 215:../../../../Lib/net/tcp.c **** if (nicState.layer4.tcp->destport == htons(80)) + 1030 .LM93: + 1031 04d4 E091 0000 lds r30,nicState+12 + 1032 04d8 F091 0000 lds r31,nicState+12+1 + 1033 04dc C281 ldd r28,Z+2 + 1034 04de D381 ldd r29,Z+3 + 1035 04e0 80E5 ldi r24,lo8(80) + 1036 04e2 90E0 ldi r25,0 + 1037 04e4 0E94 0000 call htons + 1038 04e8 C817 cp r28,r24 + 1039 04ea D907 cpc r29,r25 + 1040 04ec 01F4 brne .L57 + 216:../../../../Lib/net/tcp.c **** { + 217:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 218:../../../../Lib/net/tcp.c **** if (tcpDebugStream != NULL) + 1042 .LM94: + 1043 04ee 8091 0000 lds r24,tcpDebugStream + 1044 04f2 9091 0000 lds r25,tcpDebugStream+1 + 1045 04f6 0097 sbiw r24,0 + 1046 04f8 01F0 breq .L56 + 219:../../../../Lib/net/tcp.c **** fprintf_P(tcpDebugStream, PSTR("HTTP not implemented\r\n")); + 1048 .LM95: + 1049 04fa 20E0 ldi r18,lo8(__c.2723) + 1050 04fc 30E0 ldi r19,hi8(__c.2723) + 1051 04fe 3F93 push r19 + 1052 0500 2F93 push r18 + 1053 0502 9F93 push r25 + 1054 0504 8F93 push r24 + 1055 0506 0E94 0000 call fprintf_P + 1056 050a 0F90 pop __tmp_reg__ + 1057 050c 0F90 pop __tmp_reg__ + 1058 050e 0F90 pop __tmp_reg__ + 1059 0510 0F90 pop __tmp_reg__ + 1060 0512 00C0 rjmp .L56 + 1061 .L57: + 1062 /* epilogue start */ + 220:../../../../Lib/net/tcp.c **** #endif + 221:../../../../Lib/net/tcp.c **** ; + 222:../../../../Lib/net/tcp.c **** } + 223:../../../../Lib/net/tcp.c **** else + 224:../../../../Lib/net/tcp.c **** { + 225:../../../../Lib/net/tcp.c **** processTcpPacket(); + 226:../../../../Lib/net/tcp.c **** } + 227:../../../../Lib/net/tcp.c **** } + 1064 .LM96: + 1065 0514 DF91 pop r29 + 1066 0516 CF91 pop r28 + 225:../../../../Lib/net/tcp.c **** } + 1068 .LM97: + 1069 0518 0C94 0000 jmp processTcpPacket + 1070 .L56: + 1071 /* epilogue start */ + 1073 .LM98: + 1074 051c DF91 pop r29 + 1075 051e CF91 pop r28 + 1076 0520 0895 ret + 1078 .Lscope5: + 1080 .stabd 78,0,0 + 1084 .global setTcpDebug + 1086 setTcpDebug: + 1087 .stabd 46,0,0 + 228:../../../../Lib/net/tcp.c **** + 229:../../../../Lib/net/tcp.c **** #if TCP_DEBUG + 230:../../../../Lib/net/tcp.c **** void setTcpDebug(FILE *stream, uint8_t level) + 231:../../../../Lib/net/tcp.c **** { + 1089 .LM99: + 1090 .LFBB6: + 1091 /* prologue: function */ + 1092 /* frame size = 0 */ + 1093 /* stack size = 0 */ + 1094 .L__stack_usage = 0 + 232:../../../../Lib/net/tcp.c **** tcpDebugStream = stream; + 1096 .LM100: + 1097 0522 9093 0000 sts tcpDebugStream+1,r25 + 1098 0526 8093 0000 sts tcpDebugStream,r24 + 233:../../../../Lib/net/tcp.c **** tcpDebugLevel = level; + 1100 .LM101: + 1101 052a 6093 0000 sts tcpDebugLevel,r22 + 1102 052e 0895 ret + 1104 .Lscope6: + 1106 .stabd 78,0,0 + 1108 .global flushTcpQueues + 1110 flushTcpQueues: + 1111 .stabd 46,0,0 + 234:../../../../Lib/net/tcp.c **** } + 235:../../../../Lib/net/tcp.c **** #endif /* TCP_DEBUG */ + 236:../../../../Lib/net/tcp.c **** + 237:../../../../Lib/net/tcp.c **** void flushTcpQueues() + 238:../../../../Lib/net/tcp.c **** { + 1113 .LM102: + 1114 .LFBB7: + 1115 /* prologue: function */ + 1116 /* frame size = 0 */ + 1117 /* stack size = 0 */ + 1118 .L__stack_usage = 0 + 1119 0530 0895 ret + 1121 .Lscope7: + 1123 .stabd 78,0,0 + 1125 .global httpProcess + 1127 httpProcess: + 1128 .stabd 46,0,0 + 239:../../../../Lib/net/tcp.c **** uint8_t sckNo = 0; + 240:../../../../Lib/net/tcp.c **** struct TcpIpSocket *sck = sockets; + 241:../../../../Lib/net/tcp.c **** for (sckNo = 0; sckNo < NUMBER_OF_SOCKETS; sckNo++) + 242:../../../../Lib/net/tcp.c **** { + 243:../../../../Lib/net/tcp.c **** + 244:../../../../Lib/net/tcp.c **** sck++; + 245:../../../../Lib/net/tcp.c **** } + 246:../../../../Lib/net/tcp.c **** } + 247:../../../../Lib/net/tcp.c **** + 248:../../../../Lib/net/tcp.c **** + 249:../../../../Lib/net/tcp.c **** inline void httpProcess() + 250:../../../../Lib/net/tcp.c **** { + 1130 .LM103: + 1131 .LFBB8: + 1132 /* prologue: function */ + 1133 /* frame size = 0 */ + 1134 /* stack size = 0 */ + 1135 .L__stack_usage = 0 + 1136 0532 0895 ret + 1138 .Lscope8: + 1140 .stabd 78,0,0 + 1141 .section .progmem.data,"a",@progbits + 1144 __c.2723: + 1145 0000 4854 5450 .string "HTTP not implemented\r\n" + 1145 206E 6F74 + 1145 2069 6D70 + 1145 6C65 6D65 + 1145 6E74 6564 + 1148 __c.2692: + 1149 0017 4361 6E27 .string "Can't find TCP socket with localPort %d\r\n" + 1149 7420 6669 + 1149 6E64 2054 + 1149 4350 2073 + 1149 6F63 6B65 + 1152 __c.2687: + 1153 0041 466F 756E .string "Found TCP socket no %d state LISTEN\r\n" + 1153 6420 5443 + 1153 5020 736F + 1153 636B 6574 + 1153 206E 6F20 + 1156 __c.2682: + 1157 0067 466F 756E .string "Found TCP socket state %d\r\n" + 1157 6420 5443 + 1157 5020 736F + 1157 636B 6574 + 1157 2073 7461 + 1160 __c.2707: + 1161 0083 4F70 656E .string "Opening TCP connection ERROR: ack flag wasn't set\r\n" + 1161 696E 6720 + 1161 5443 5020 + 1161 636F 6E6E + 1161 6563 7469 + 1164 __c.2705: + 1165 00b7 4F70 656E .string "Opening TCP connection socket state change SYN_RECEIVED->ESTABILISHED\r\n" + 1165 696E 6720 + 1165 5443 5020 + 1165 636F 6E6E + 1165 6563 7469 + 1168 __c.2703: + 1169 00ff 4F70 656E .string "Opening TCP connection ERROR: syn flag wasn't set\r\n" + 1169 696E 6720 + 1169 5443 5020 + 1169 636F 6E6E + 1169 6563 7469 + 1172 __c.2701: + 1173 0133 4F70 656E .string "Opening TCP connection socket state change LISTEN->SYN_RECEIVED\r\n" + 1173 696E 6720 + 1173 5443 5020 + 1173 636F 6E6E + 1173 6563 7469 + 1174 .comm sockets,2,1 + 1175 .comm tcpDebugLevel,1,1 + 1176 .comm tcpDebugStream,2,1 + 1177 .comm IpMyConfig,15,1 + 1178 .comm udpDbgLevel,1,1 + 1179 .comm udpDbgStream,2,1 + 1180 .comm udpSocket,2,1 + 1181 .comm icmpDebugLevel,1,1 + 1182 .comm icmpDebug,2,1 + 1183 .comm arpDebugLevel,1,1 + 1184 .comm arpDebug,2,1 + 1185 .comm nicState,14,1 + 1186 .comm wwwport,1,1 + 1200 .text + 1202 .Letext0: + 1203 .ident "GCC: (GNU) 4.9.2" + 1204 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 tcp.c + /tmp/ccRv3TNe.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccRv3TNe.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccRv3TNe.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccRv3TNe.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccRv3TNe.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccRv3TNe.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccRv3TNe.s:186 .text:0000000000000000 socketInit + *COM*:0000000000000002 sockets + /tmp/ccRv3TNe.s:309 .text:0000000000000098 calculateTcpChecksun + *COM*:000000000000000e nicState + /tmp/ccRv3TNe.s:346 .text:00000000000000ba processTcpPacket + *COM*:0000000000000002 tcpDebugStream + *COM*:0000000000000001 tcpDebugLevel + /tmp/ccRv3TNe.s:1156 .progmem.data:0000000000000067 __c.2682 + /tmp/ccRv3TNe.s:1152 .progmem.data:0000000000000041 __c.2687 + /tmp/ccRv3TNe.s:1148 .progmem.data:0000000000000017 __c.2692 + /tmp/ccRv3TNe.s:1172 .progmem.data:0000000000000133 __c.2701 + /tmp/ccRv3TNe.s:1168 .progmem.data:00000000000000ff __c.2703 + /tmp/ccRv3TNe.s:1164 .progmem.data:00000000000000b7 __c.2705 + /tmp/ccRv3TNe.s:1160 .progmem.data:0000000000000083 __c.2707 + /tmp/ccRv3TNe.s:998 .text:00000000000004cc sendTcpBuffer + /tmp/ccRv3TNe.s:1018 .text:00000000000004d0 netstackTCPIPProcess + /tmp/ccRv3TNe.s:1144 .progmem.data:0000000000000000 __c.2723 + /tmp/ccRv3TNe.s:1086 .text:0000000000000522 setTcpDebug + /tmp/ccRv3TNe.s:1110 .text:0000000000000530 flushTcpQueues + /tmp/ccRv3TNe.s:1127 .text:0000000000000532 httpProcess + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +xmalloc +htons +netChecksum +fprintf_P +htonl +ipSend +timer100Hz +xQueueGenericReceive +__do_clear_bss diff --git a/Lib/net/tcp6.c b/Lib/net/tcp6.c new file mode 100644 index 0000000..aceb0fb --- /dev/null +++ b/Lib/net/tcp6.c @@ -0,0 +1,367 @@ +/** + * @file tcp.c + * @author Adam Kaliszan + * @brief TCP socket + * @ingroup network + * @defgroup netstack Network Stack + * @version 0.2 + * Created: 13.10.2010 + * Revised: 05.10.2010 + * Editor Tabs: 2 + * + */ + +#include "tcp6.h" +#include "include/ipv6.h" + + +static struct TcpIpSocket* findConnectedSocket(void); + +/** + * @param *sck socket + */ +static inline void tcpAcceptConn6(struct TcpIpSocket *sck); + +inline void socketInit6(void) +{ + sockets = xmalloc(NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + memset(sockets, 0, NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + + uint8_t i; + uint8_t *ptr = (uint8_t *)RTOS_TCP_BUF_BASE_ADDR; + + struct TcpIpSocket *sck = sockets; + for (i=0; i < NUMBER_OF_SOCKETS; i++) + { + sck->Rx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; + sck->Tx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; + + sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + sck->seqNoLastSent = HTONL(0xFF112233); + sck->state = LISTEN; + sck++; + } +} + +struct TcpIpSocket* findConnectedSocket6(void) +{ + struct TcpIpSocket *result = sockets; + //UIP_TCP_BUF-> + uint8_t i; + for (i=0; istate != LISTEN) && (result->state != CLOSED)) + && memcmp(&result->RemoteIpAddr6,&nicState.layer3.ipv6->srcipaddr, 128) && (result->localPort == UIP_TCP_BUF->destport) && (result->remotePort == UIP_TCP_BUF->srcport)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Found TCP socket state %d\r\n"), result->state); +#endif + return result; + } + result++; + } + + result = sockets; + for (i=0; istate == LISTEN) && (result->localPort == UIP_TCP_BUF->destport)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Found TCP socket no %d state LISTEN\r\n"), i); +#endif + return &sockets[i]; + } + result++; + } +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Can't find TCP socket with localPort %d\r\n"), htons(UIP_TCP_BUF->destport)); +#endif + return NULL; +} + +static inline void tcpAcceptConn6(struct TcpIpSocket *sck) +{ + //UIP_TCP_BUF-> + sck->state = SYN_RECEIVED; + fprintf_P(tcpDebugStream, PSTR("TCP PORTS src %04x ; dest %04x\r\n"), UIP_TCP_BUF->srcport, UIP_TCP_BUF->destport); + uint16_t tempPort = UIP_TCP_BUF->destport; + sck->remotePort = UIP_TCP_BUF->srcport; + sck->localPort = tempPort; + //memcpy(&sck->RemoteIpAddr6, &nicState.layer3.ip->srcipaddr, 128) + sck->RemoteIpAddr6 = nicState.layer3.ipv6->srcipaddr; +} + +inline uint8_t processTcpPacket6(void) +{ + ///struct TcpIpSocket *socket = findConnectedSocket6(); + //UIP_TCP_BUF-> + + ///if (socket == NULL) + ///return 1; + + struct TcpIpSocket *socket = &sockets[0]; + + socket->seqNoLastReceived = htonl( (struct netTcpHeader *)UIP_TCP_BUF->seqno); + + if (socket->state == LISTEN) + { + if (UIP_TCP_BUF->flags & TCP_FLAGS_SYN) + { +// uint16_t len = UIP_TCP_BUF->tcpoffset>>4; +// len *=4; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RECEIVED\r\n")); +#endif + tcpAcceptConn6(socket); + //Preparing response + UIP_TCP_BUF->srcport = socket->localPort; + UIP_TCP_BUF->destport = socket->remotePort; + UIP_TCP_BUF->seqno = htonl(socket->seqNoLastSent); + UIP_TCP_BUF->ackno = htonl(socket->seqNoLastReceived+1); + UIP_TCP_BUF->tcpoffset = 5<<4; + UIP_TCP_BUF->flags = TCP_FLAGS_ACK+TCP_FLAGS_SYN; + UIP_TCP_BUF->wnd = htons(100); + UIP_TCP_BUF->tcpchksum = 0; + UIP_TCP_BUF->urgp = 0; + calculateTcpChecksum6(TCP_HEADER_LEN); + + socket->seqNoLastSent++; + fprintf_P(tcpDebugStream, PSTR("Sending SYN_ACK\r\n")); + ipv6Send(IP_PROTO_TCP, TCP_HEADER_LEN); + fprintf_P(tcpDebugStream, PSTR("Sent SYN_ACK\r\n")); + } +#if TCP_DEBUG + else + { + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 1) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: syn flag wasn't set\r\n")); + } +#endif + return 0; + } + + if (socket->state == SYN_RECEIVED) + { + fprintf_P(tcpDebugStream, PSTR("SYN_RECEIVED\r\n")); + if (UIP_TCP_BUF->flags & TCP_FLAGS_ACK) + { + socket->state = ESTABILISHED; + fprintf_P(tcpDebugStream, PSTR("ESTABILISHED\r\n")); +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change SYN_RECEIVED->ESTABILISHED\r\n")); +#endif + + } + else + { + socket->state = LISTEN; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + if (tcpDebugLevel > 1) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: ack flag wasn't set\r\n")); +#endif + } + return 0; + } + + + if (socket->state == ESTABILISHED) + { + if (UIP_TCP_BUF->flags & TCP_FLAGS_FIN) //ESTABILISHED -> CLOSE_WAIT -> closed + { + socket->timer = timer100Hz; + UIP_TCP_BUF->flags = TCP_FLAGS_ACK; + + uint8_t dataFromBufLen; + uint8_t *dataPtr = (uint8_t *)(UIP_TCP_BUF+1); +// while (xQueueReceive(socket->Tx, dataPtr, 0) == pdTRUE) +// { +// dataFromBufLen++; +// dataPtr++; +// } + calculateTcpChecksum6(TCP_HEADER_LEN); + ipv6Send(IP_PROTO_TCP, TCP_HEADER_LEN + dataFromBufLen); + socket->state = CLOSE_WAIT; + + + UIP_TCP_BUF->flags = TCP_FLAGS_FIN; + calculateTcpChecksum6(TCP_HEADER_LEN); + ipv6Send(IP_PROTO_TCP, TCP_HEADER_LEN); + socket->state = LAST_ACK; + } + return 0; + } + + //Read data and put into the queue + + return 0; +} + +void calculateTcpChecksum6(uint16_t tcpLen) +{ + UIP_TCP_BUF->tcpchksum = 0; + UIP_TCP_BUF->tcpchksum = netChecksum(UIP_TCP_BUF, tcpLen); //TODO finish it +} + + + +uint8_t sendTcBuffer6(uint8_t socketNo) +{ + struct TcpIpSocket *sck = &sockets[socketNo]; + return 0; +} + +void netstackTCPIPProcess6(void) +{ + if (UIP_TCP_BUF->destport == htons(80)) + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + fprintf_P(tcpDebugStream, PSTR("HTTP not implemented\r\n")); +#endif + ; + } + else + { + processTcpPacket6(); + } +} + +#if TCP_DEBUG +void setTcpDebug6(FILE *stream, uint8_t level) +{ + tcpDebugStream = stream; + tcpDebugLevel = level; +} +#endif /* TCP_DEBUG */ + +void flushTcpQueues6() +{ + uint8_t sckNo = 0; + struct TcpIpSocket *sck = sockets; + for (sckNo = 0; sckNo < NUMBER_OF_SOCKETS; sckNo++) + { + + sck++; + } +} + + +inline void httpProcess6() +{ +#if 0 + // TCP WWW tcp port www start, compare only the lower byte + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_L_P]==MYWWWPORT ) + { + if ( Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V ) + { + make_tcp_synack_from_syn (Enc28j60_global.buf ); + // make_tcp_synack_from_syn does already send the syn,ack + continue; + } + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) + { + init_len_info (Enc28j60_global.buf ); // init some data structures + // we can possibly have no data, just ack: + dat_p=get_tcp_data_pointer(); + if ( dat_p==0 ) + { + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V ) + { + // finack, answer with ack + make_tcp_ack_from_any (Enc28j60_global.buf ); + } + // just an ack with no data, wait for next packet + continue; + } + if ( strncmp ( "GET ", ( char * )(&Enc28j60_global.buf[dat_p]), 4) !=0 ) + { + // head, post and other methods: + // + // for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=fill_tcp_data_p (Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + if ( strncmp ( "/ ", ( char * ) & (Enc28j60_global.buf[dat_p+4] ),2 ) ==0) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Usage: http://host_or_ip/filename or http://host_or_ip/sd/filename

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + + cmd = analyse_get_url (( char * )(&Enc28j60_global.buf[dat_p+5]), filename); + + if (cmd == URLramDysk) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + + //Open the filen + struct ramPlikFd fd; + if (ramDyskOtworzPlik(filename, &fd) != 0) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Nie mozna otworzyc pliku o nazwie: " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " umieszczonego w ram dysku

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Zawartosc pliku " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " zapisanego w ram dysku:
" ) ); + + char c; + while (plen < Enc28j60_global.bufferSize - 30) + { + if (ramDyskCzytajBajtZPliku(&fd , &c) != 0) + break; + plen = add_tcp_byte(Enc28j60_global.buf, plen, c); + } + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

\n")); + ramDyskZamknijPlik(&fd); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + + continue; + } + + if (cmd == URLsdDysk) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Do zaimpelentowania wyswietlenie pliku o nazwie " ) ); + plen=fill_tcp_data(Enc28j60_global.buf, plen, filename); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( " z karty SD

\n" ) ); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + if (cmd == URLstatus) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=printHTMLstatus(Enc28j60_global.buf, plen, Enc28j60_global.bufferSize); + make_tcp_ack_from_any(Enc28j60_global.buf); // send ack for http get + make_tcp_ack_with_data(Enc28j60_global.buf, plen); // send data + continue; + } + } + +#endif +} \ No newline at end of file diff --git a/Lib/net/udp.c b/Lib/net/udp.c new file mode 100644 index 0000000..690358c --- /dev/null +++ b/Lib/net/udp.c @@ -0,0 +1,141 @@ +#include "udp.h" + +void udpLoadConfig() +{ + udpSocket->dstIp = eeprom_read_dword(&udpIpDst_eep); + udpSocket->dstPortDef = eeprom_read_word(&udpPortDstEep); + udpSocket->srcPort = eeprom_read_word(&udpPortSrcEep); +} + +void udpInit_0(void) +{ +#if UDP_DEBUG + udpDbgStream = NULL; + udpDbgLevel = 0; +#endif + udpSocket = xmalloc(sizeof(UdpSocket_t)); + + udpSocket->Rx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_RX_BUF_ADDR)); + udpSocket->Tx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_TX_BUF_ADDR)); +} + +#if UDP_DEBUG +void setUdpDebug(FILE *stream, uint8_t level) +{ + udpDbgStream = stream; + udpDbgLevel = level; +} +#endif + +inline void udpSend(uint16_t len) +{ +// make pointer to UDP header + nicState.layer4.udp->srcport = udpSocket->srcPort; + nicState.layer4.udp->destport = (udpSocket->dstPortDef == 0)? udpSocket->dstPort : udpSocket->dstPortDef; //data in udpSocket are stored in network order + + nicState.layer4.udp->udplen = htons(len + UDP_HEADER_LEN); + nicState.layer4.udp->udpchksum = 0; + +#if UDP_DEBUG + if (udpDbgStream != NULL) + if (udpDbgLevel > 1) + fprintf_P(udpDbgStream, PSTR("Sending UDP packet (data length %d)\r\n"), len); +#endif + ipSend(udpSocket->dstIp, IP_PROTO_UDP, len + UDP_HEADER_LEN); + + if(udpDbgStream != NULL) + fprintf_P(udpDbgStream, PSTR("UDP tx %d bytes\r\n"), len); +} + +inline void netstackUDPIPProcess(void) +{ + uint16_t len = (uint16_t) htons(nicState.layer4.udp->udplen); + uint8_t i; + + #if UDP_DEBUG + if(udpDbgStream != NULL) + if (udpDbgLevel > 5) + fprintf_P(udpDbgStream, PSTR("Proc. UDP packet (data length %d)"), len-UDP_HEADER_LEN); +#endif + + if ((udpSocket->srcPort != nicState.layer4.udp->destport) || + ((udpSocket->dstPortDef != HTONS(0)) && (udpSocket->dstPort == nicState.layer4.udp->srcport))) + { +#if UDP_DEBUG + if(udpDbgStream != NULL) + if (udpDbgLevel > 5) + fprintf_P(udpDbgStream, PSTR("Skipping, wrong ports %d %d\r\n"), nicState.layer4.udp->destport, nicState.layer4.udp->srcport ); +#endif + return; + } + + if (udpSocket->dstPortDef == HTONS(0)) + udpSocket->dstPort = nicState.layer4.udp->srcport; + uint8_t *tmp = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; +#if UDP_DEBUG + if(udpDbgStream != NULL) + if (udpDbgLevel > 4) + fprintf_P(udpDbgStream, PSTR("Received UDP data:")); +#endif + + for (i=UDP_HEADER_LEN; i 4) + fprintf_P(udpDbgStream, PSTR(" 0x%2x"), *tmp); +#else + xQueueSend(udpSocket->Rx, tmp, 0); +#endif +#if UDP_DEBUG + if (xQueueSend(udpSocket->Rx, tmp, 10) == 0) + if(udpDbgStream != NULL) + if (udpDbgLevel > 0) + fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); +#endif + tmp++; + } +#if UDP_DEBUG + if(udpDbgStream != NULL) + { + if (udpDbgLevel > 4) + fprintf_P(udpDbgStream, PSTR("\r\n")); + else if (udpDbgLevel > 0) + fprintf_P(udpDbgStream, PSTR("Received UDP packet (len %d)\r\n"), len); + + } +#endif +} + +inline void flushUdpQueues(void) +{ + if (uxQueueMessagesWaiting(udpSocket->Tx) > 0) + { + uint16_t len = 0; + uint8_t *data = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + while (xQueueReceive(udpSocket->Tx, data, 0) == pdTRUE) + { + data++; + len++; + } + udpSend(len); + } +} + +void udpSaveConfig(void) +{ + eeprom_update_dword(&udpIpDst_eep, udpSocket->dstIp); + eeprom_update_word(&udpPortDstEep, udpSocket->dstPortDef); + eeprom_update_word(&udpPortSrcEep, udpSocket->srcPort); +} + +void udpPrintStatus(FILE *stream) +{ + fprintf_P(stream, PSTR("UDP config:")); + fprintf_P(stream, PSTR("\r\n IP : ")); netPrintIPAddr(stream, udpSocket->dstIp); + fprintf_P(stream, PSTR("\r\n src port : %d\r\n dst port : "), htons(udpSocket->srcPort)); + if (udpSocket->dstPortDef == HTONS(0)) + fprintf_P(stream, PSTR("ANY\r\n")); + else + fprintf_P(stream, PSTR("%d\r\n"), htons(udpSocket->dstPortDef)); +} diff --git a/Lib/net/udp.lst b/Lib/net/udp.lst new file mode 100644 index 0000000..026c141 --- /dev/null +++ b/Lib/net/udp.lst @@ -0,0 +1,1041 @@ + 1 .file "udp.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 160 .global udpLoadConfig + 162 udpLoadConfig: + 163 .stabd 46,0,0 + 1:../../../../Lib/net/udp.c **** #include "udp.h" + 2:../../../../Lib/net/udp.c **** + 3:../../../../Lib/net/udp.c **** void udpLoadConfig() + 4:../../../../Lib/net/udp.c **** { + 165 .LM0: + 166 .LFBB1: + 167 0000 CF93 push r28 + 168 0002 DF93 push r29 + 169 /* prologue: function */ + 170 /* frame size = 0 */ + 171 /* stack size = 2 */ + 172 .L__stack_usage = 2 + 5:../../../../Lib/net/udp.c **** udpSocket->dstIp = eeprom_read_dword(&udpIpDst_eep); + 174 .LM1: + 175 0004 C091 0000 lds r28,udpSocket + 176 0008 D091 0000 lds r29,udpSocket+1 + 177 000c 80E0 ldi r24,lo8(udpIpDst_eep) + 178 000e 90E0 ldi r25,hi8(udpIpDst_eep) + 179 0010 0E94 0000 call eeprom_read_dword + 180 0014 6E83 std Y+6,r22 + 181 0016 7F83 std Y+7,r23 + 182 0018 8887 std Y+8,r24 + 183 001a 9987 std Y+9,r25 + 6:../../../../Lib/net/udp.c **** udpSocket->dstPortDef = eeprom_read_word(&udpPortDstEep); + 185 .LM2: + 186 001c 80E0 ldi r24,lo8(udpPortDstEep) + 187 001e 90E0 ldi r25,hi8(udpPortDstEep) + 188 0020 0E94 0000 call eeprom_read_word + 189 0024 9983 std Y+1,r25 + 190 0026 8883 st Y,r24 + 7:../../../../Lib/net/udp.c **** udpSocket->srcPort = eeprom_read_word(&udpPortSrcEep); + 192 .LM3: + 193 0028 80E0 ldi r24,lo8(udpPortSrcEep) + 194 002a 90E0 ldi r25,hi8(udpPortSrcEep) + 195 002c 0E94 0000 call eeprom_read_word + 196 0030 9D83 std Y+5,r25 + 197 0032 8C83 std Y+4,r24 + 198 /* epilogue start */ + 8:../../../../Lib/net/udp.c **** } + 200 .LM4: + 201 0034 DF91 pop r29 + 202 0036 CF91 pop r28 + 203 0038 0895 ret + 205 .Lscope1: + 207 .stabd 78,0,0 + 209 .global udpInit_0 + 211 udpInit_0: + 212 .stabd 46,0,0 + 9:../../../../Lib/net/udp.c **** + 10:../../../../Lib/net/udp.c **** void udpInit_0(void) + 11:../../../../Lib/net/udp.c **** { + 214 .LM5: + 215 .LFBB2: + 216 003a CF93 push r28 + 217 003c DF93 push r29 + 218 /* prologue: function */ + 219 /* frame size = 0 */ + 220 /* stack size = 2 */ + 221 .L__stack_usage = 2 + 12:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 13:../../../../Lib/net/udp.c **** udpDbgStream = NULL; + 223 .LM6: + 224 003e 1092 0000 sts udpDbgStream+1,__zero_reg__ + 225 0042 1092 0000 sts udpDbgStream,__zero_reg__ + 14:../../../../Lib/net/udp.c **** udpDbgLevel = 0; + 227 .LM7: + 228 0046 1092 0000 sts udpDbgLevel,__zero_reg__ + 15:../../../../Lib/net/udp.c **** #endif + 16:../../../../Lib/net/udp.c **** udpSocket = xmalloc(sizeof(UdpSocket_t)); + 230 .LM8: + 231 004a 8EE0 ldi r24,lo8(14) + 232 004c 90E0 ldi r25,0 + 233 004e 0E94 0000 call xmalloc + 234 0052 EC01 movw r28,r24 + 235 0054 9093 0000 sts udpSocket+1,r25 + 236 0058 8093 0000 sts udpSocket,r24 + 17:../../../../Lib/net/udp.c **** + 18:../../../../Lib/net/udp.c **** udpSocket->Rx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_RX_BUF_ADDR)); + 238 .LM9: + 239 005c 40E0 ldi r20,0 + 240 005e 59E7 ldi r21,lo8(121) + 241 0060 61E0 ldi r22,lo8(1) + 242 0062 8FEF ldi r24,lo8(-1) + 243 0064 0E94 0000 call xQueueCreateExternal + 244 0068 9B87 std Y+11,r25 + 245 006a 8A87 std Y+10,r24 + 19:../../../../Lib/net/udp.c **** udpSocket->Tx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_TX_BUF_ADDR)); + 247 .LM10: + 248 006c C091 0000 lds r28,udpSocket + 249 0070 D091 0000 lds r29,udpSocket+1 + 250 0074 40E0 ldi r20,0 + 251 0076 58E7 ldi r21,lo8(120) + 252 0078 61E0 ldi r22,lo8(1) + 253 007a 8FEF ldi r24,lo8(-1) + 254 007c 0E94 0000 call xQueueCreateExternal + 255 0080 9D87 std Y+13,r25 + 256 0082 8C87 std Y+12,r24 + 257 /* epilogue start */ + 20:../../../../Lib/net/udp.c **** } + 259 .LM11: + 260 0084 DF91 pop r29 + 261 0086 CF91 pop r28 + 262 0088 0895 ret + 264 .Lscope2: + 266 .stabd 78,0,0 + 270 .global setUdpDebug + 272 setUdpDebug: + 273 .stabd 46,0,0 + 21:../../../../Lib/net/udp.c **** + 22:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 23:../../../../Lib/net/udp.c **** void setUdpDebug(FILE *stream, uint8_t level) + 24:../../../../Lib/net/udp.c **** { + 275 .LM12: + 276 .LFBB3: + 277 /* prologue: function */ + 278 /* frame size = 0 */ + 279 /* stack size = 0 */ + 280 .L__stack_usage = 0 + 25:../../../../Lib/net/udp.c **** udpDbgStream = stream; + 282 .LM13: + 283 008a 9093 0000 sts udpDbgStream+1,r25 + 284 008e 8093 0000 sts udpDbgStream,r24 + 26:../../../../Lib/net/udp.c **** udpDbgLevel = level; + 286 .LM14: + 287 0092 6093 0000 sts udpDbgLevel,r22 + 288 0096 0895 ret + 290 .Lscope3: + 292 .stabd 78,0,0 + 295 .global udpSend + 297 udpSend: + 298 .stabd 46,0,0 + 27:../../../../Lib/net/udp.c **** } + 28:../../../../Lib/net/udp.c **** #endif + 29:../../../../Lib/net/udp.c **** + 30:../../../../Lib/net/udp.c **** inline void udpSend(uint16_t len) + 31:../../../../Lib/net/udp.c **** { + 300 .LM15: + 301 .LFBB4: + 302 0098 EF92 push r14 + 303 009a FF92 push r15 + 304 009c 0F93 push r16 + 305 009e 1F93 push r17 + 306 00a0 CF93 push r28 + 307 00a2 DF93 push r29 + 308 /* prologue: function */ + 309 /* frame size = 0 */ + 310 /* stack size = 6 */ + 311 .L__stack_usage = 6 + 312 00a4 EC01 movw r28,r24 + 32:../../../../Lib/net/udp.c **** // make pointer to UDP header + 33:../../../../Lib/net/udp.c **** nicState.layer4.udp->srcport = udpSocket->srcPort; + 314 .LM16: + 315 00a6 A091 0000 lds r26,nicState+12 + 316 00aa B091 0000 lds r27,nicState+12+1 + 317 00ae E091 0000 lds r30,udpSocket + 318 00b2 F091 0000 lds r31,udpSocket+1 + 319 00b6 8481 ldd r24,Z+4 + 320 00b8 9581 ldd r25,Z+5 + 321 00ba 8D93 st X+,r24 + 322 00bc 9C93 st X,r25 + 34:../../../../Lib/net/udp.c **** nicState.layer4.udp->destport = (udpSocket->dstPortDef == 0)? udpSocket->dstPort : udpSocket->dst + 324 .LM17: + 325 00be A091 0000 lds r26,nicState+12 + 326 00c2 B091 0000 lds r27,nicState+12+1 + 327 00c6 8081 ld r24,Z + 328 00c8 9181 ldd r25,Z+1 + 329 00ca 0097 sbiw r24,0 + 330 00cc 01F4 brne .L5 + 332 .LM18: + 333 00ce 8281 ldd r24,Z+2 + 334 00d0 9381 ldd r25,Z+3 + 335 .L5: + 337 .LM19: + 338 00d2 1396 adiw r26,2+1 + 339 00d4 9C93 st X,r25 + 340 00d6 8E93 st -X,r24 + 341 00d8 1297 sbiw r26,2 + 35:../../../../Lib/net/udp.c **** + 36:../../../../Lib/net/udp.c **** nicState.layer4.udp->udplen = htons(len + UDP_HEADER_LEN); + 343 .LM20: + 344 00da E090 0000 lds r14,nicState+12 + 345 00de F090 0000 lds r15,nicState+12+1 + 346 00e2 8E01 movw r16,r28 + 347 00e4 085F subi r16,-8 + 348 00e6 1F4F sbci r17,-1 + 349 00e8 C801 movw r24,r16 + 350 00ea 0E94 0000 call htons + 351 00ee F701 movw r30,r14 + 352 00f0 9583 std Z+5,r25 + 353 00f2 8483 std Z+4,r24 + 37:../../../../Lib/net/udp.c **** nicState.layer4.udp->udpchksum = 0; + 355 .LM21: + 356 00f4 E091 0000 lds r30,nicState+12 + 357 00f8 F091 0000 lds r31,nicState+12+1 + 358 00fc 1782 std Z+7,__zero_reg__ + 359 00fe 1682 std Z+6,__zero_reg__ + 38:../../../../Lib/net/udp.c **** + 39:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 40:../../../../Lib/net/udp.c **** if (udpDbgStream != NULL) + 361 .LM22: + 362 0100 4091 0000 lds r20,udpDbgStream + 363 0104 5091 0000 lds r21,udpDbgStream+1 + 364 0108 4115 cp r20,__zero_reg__ + 365 010a 5105 cpc r21,__zero_reg__ + 366 010c 01F0 breq .L6 + 41:../../../../Lib/net/udp.c **** if (udpDbgLevel > 1) + 368 .LM23: + 369 010e 8091 0000 lds r24,udpDbgLevel + 370 0112 8230 cpi r24,lo8(2) + 371 0114 00F0 brlo .L6 + 42:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("Sending UDP packet (data length %d)\r\n"), len); + 373 .LM24: + 374 0116 DF93 push r29 + 375 0118 CF93 push r28 + 376 011a 80E0 ldi r24,lo8(__c.2486) + 377 011c 90E0 ldi r25,hi8(__c.2486) + 378 011e 9F93 push r25 + 379 0120 8F93 push r24 + 380 0122 5F93 push r21 + 381 0124 4F93 push r20 + 382 0126 0E94 0000 call fprintf_P + 383 012a 0F90 pop __tmp_reg__ + 384 012c 0F90 pop __tmp_reg__ + 385 012e 0F90 pop __tmp_reg__ + 386 0130 0F90 pop __tmp_reg__ + 387 0132 0F90 pop __tmp_reg__ + 388 0134 0F90 pop __tmp_reg__ + 389 .L6: + 43:../../../../Lib/net/udp.c **** #endif + 44:../../../../Lib/net/udp.c **** ipSend(udpSocket->dstIp, IP_PROTO_UDP, len + UDP_HEADER_LEN); + 391 .LM25: + 392 0136 E091 0000 lds r30,udpSocket + 393 013a F091 0000 lds r31,udpSocket+1 + 394 013e 6681 ldd r22,Z+6 + 395 0140 7781 ldd r23,Z+7 + 396 0142 8085 ldd r24,Z+8 + 397 0144 9185 ldd r25,Z+9 + 398 0146 9801 movw r18,r16 + 399 0148 41E1 ldi r20,lo8(17) + 400 014a 0E94 0000 call ipSend + 45:../../../../Lib/net/udp.c **** + 46:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 402 .LM26: + 403 014e 8091 0000 lds r24,udpDbgStream + 404 0152 9091 0000 lds r25,udpDbgStream+1 + 405 0156 0097 sbiw r24,0 + 406 0158 01F0 breq .L4 + 47:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("UDP tx %d bytes\r\n"), len); + 408 .LM27: + 409 015a DF93 push r29 + 410 015c CF93 push r28 + 411 015e 20E0 ldi r18,lo8(__c.2488) + 412 0160 30E0 ldi r19,hi8(__c.2488) + 413 0162 3F93 push r19 + 414 0164 2F93 push r18 + 415 0166 9F93 push r25 + 416 0168 8F93 push r24 + 417 016a 0E94 0000 call fprintf_P + 418 016e 0F90 pop __tmp_reg__ + 419 0170 0F90 pop __tmp_reg__ + 420 0172 0F90 pop __tmp_reg__ + 421 0174 0F90 pop __tmp_reg__ + 422 0176 0F90 pop __tmp_reg__ + 423 0178 0F90 pop __tmp_reg__ + 424 .L4: + 425 /* epilogue start */ + 48:../../../../Lib/net/udp.c **** } + 427 .LM28: + 428 017a DF91 pop r29 + 429 017c CF91 pop r28 + 430 017e 1F91 pop r17 + 431 0180 0F91 pop r16 + 432 0182 FF90 pop r15 + 433 0184 EF90 pop r14 + 434 0186 0895 ret + 436 .Lscope4: + 438 .stabd 78,0,0 + 440 .global netstackUDPIPProcess + 442 netstackUDPIPProcess: + 443 .stabd 46,0,0 + 49:../../../../Lib/net/udp.c **** + 50:../../../../Lib/net/udp.c **** inline void netstackUDPIPProcess(void) + 51:../../../../Lib/net/udp.c **** { + 445 .LM29: + 446 .LFBB5: + 447 0188 BF92 push r11 + 448 018a CF92 push r12 + 449 018c DF92 push r13 + 450 018e EF92 push r14 + 451 0190 FF92 push r15 + 452 0192 0F93 push r16 + 453 0194 1F93 push r17 + 454 0196 CF93 push r28 + 455 0198 DF93 push r29 + 456 /* prologue: function */ + 457 /* frame size = 0 */ + 458 /* stack size = 9 */ + 459 .L__stack_usage = 9 + 52:../../../../Lib/net/udp.c **** uint16_t len = (uint16_t) htons(nicState.layer4.udp->udplen); + 461 .LM30: + 462 019a E091 0000 lds r30,nicState+12 + 463 019e F091 0000 lds r31,nicState+12+1 + 464 01a2 8481 ldd r24,Z+4 + 465 01a4 9581 ldd r25,Z+5 + 466 01a6 0E94 0000 call htons + 467 01aa 8C01 movw r16,r24 + 53:../../../../Lib/net/udp.c **** uint8_t i; + 54:../../../../Lib/net/udp.c **** + 55:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 56:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 469 .LM31: + 470 01ac 8091 0000 lds r24,udpDbgStream + 471 01b0 9091 0000 lds r25,udpDbgStream+1 + 472 01b4 0097 sbiw r24,0 + 473 01b6 01F0 breq .L16 + 57:../../../../Lib/net/udp.c **** if (udpDbgLevel > 5) + 475 .LM32: + 476 01b8 2091 0000 lds r18,udpDbgLevel + 477 01bc 2630 cpi r18,lo8(6) + 478 01be 00F0 brlo .L16 + 58:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("Proc. UDP packet (data length %d)"), len-UDP_HEADER_LEN); + 480 .LM33: + 481 01c0 9801 movw r18,r16 + 482 01c2 2850 subi r18,8 + 483 01c4 3109 sbc r19,__zero_reg__ + 484 01c6 3F93 push r19 + 485 01c8 2F93 push r18 + 486 01ca 20E0 ldi r18,lo8(__c.2495) + 487 01cc 30E0 ldi r19,hi8(__c.2495) + 488 01ce 3F93 push r19 + 489 01d0 2F93 push r18 + 490 01d2 9F93 push r25 + 491 01d4 8F93 push r24 + 492 01d6 0E94 0000 call fprintf_P + 493 01da 0F90 pop __tmp_reg__ + 494 01dc 0F90 pop __tmp_reg__ + 495 01de 0F90 pop __tmp_reg__ + 496 01e0 0F90 pop __tmp_reg__ + 497 01e2 0F90 pop __tmp_reg__ + 498 01e4 0F90 pop __tmp_reg__ + 499 .L16: + 59:../../../../Lib/net/udp.c **** #endif + 60:../../../../Lib/net/udp.c **** + 61:../../../../Lib/net/udp.c **** if ((udpSocket->srcPort != nicState.layer4.udp->destport) || + 501 .LM34: + 502 01e6 E091 0000 lds r30,udpSocket + 503 01ea F091 0000 lds r31,udpSocket+1 + 504 01ee A091 0000 lds r26,nicState+12 + 505 01f2 B091 0000 lds r27,nicState+12+1 + 506 01f6 1296 adiw r26,2 + 507 01f8 8D91 ld r24,X+ + 508 01fa 9C91 ld r25,X + 509 01fc 1397 sbiw r26,2+1 + 510 01fe 4481 ldd r20,Z+4 + 511 0200 5581 ldd r21,Z+5 + 512 0202 2091 0000 lds r18,udpDbgStream + 513 0206 3091 0000 lds r19,udpDbgStream+1 + 514 020a 4817 cp r20,r24 + 515 020c 5907 cpc r21,r25 + 516 020e 01F4 brne .L17 + 518 .LM35: + 519 0210 6081 ld r22,Z + 520 0212 7181 ldd r23,Z+1 + 521 0214 4D91 ld r20,X+ + 522 0216 5C91 ld r21,X + 523 0218 1197 sbiw r26,1 + 524 021a 672B or r22,r23 + 525 021c 01F0 breq .L18 + 62:../../../../Lib/net/udp.c **** ((udpSocket->dstPortDef != HTONS(0)) && (udpSocket->dstPort == nicState.layer4.udp->srcport))) + 527 .LM36: + 528 021e 6281 ldd r22,Z+2 + 529 0220 7381 ldd r23,Z+3 + 530 0222 6417 cp r22,r20 + 531 0224 7507 cpc r23,r21 + 532 0226 01F4 brne .L19 + 533 .L17: + 63:../../../../Lib/net/udp.c **** { + 64:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 65:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 535 .LM37: + 536 0228 2115 cp r18,__zero_reg__ + 537 022a 3105 cpc r19,__zero_reg__ + 538 022c 01F4 brne .+2 + 539 022e 00C0 rjmp .L15 + 66:../../../../Lib/net/udp.c **** if (udpDbgLevel > 5) + 541 .LM38: + 542 0230 4091 0000 lds r20,udpDbgLevel + 543 0234 4630 cpi r20,lo8(6) + 544 0236 00F4 brsh .+2 + 545 0238 00C0 rjmp .L15 + 67:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("Skipping, wrong ports %d %d\r\n"), nicState.layer4.udp->des + 547 .LM39: + 548 023a 1196 adiw r26,1 + 549 023c 4C91 ld r20,X + 550 023e 1197 sbiw r26,1 + 551 0240 4F93 push r20 + 552 0242 4C91 ld r20,X + 553 0244 4F93 push r20 + 554 0246 9F93 push r25 + 555 0248 8F93 push r24 + 556 024a 80E0 ldi r24,lo8(__c.2497) + 557 024c 90E0 ldi r25,hi8(__c.2497) + 558 024e 9F93 push r25 + 559 0250 8F93 push r24 + 560 0252 3F93 push r19 + 561 0254 2F93 push r18 + 562 0256 0E94 0000 call fprintf_P + 563 025a 8DB7 in r24,__SP_L__ + 564 025c 9EB7 in r25,__SP_H__ + 565 025e 0896 adiw r24,8 + 566 0260 0FB6 in __tmp_reg__,__SREG__ + 567 0262 F894 cli + 568 0264 9EBF out __SP_H__,r25 + 569 0266 0FBE out __SREG__,__tmp_reg__ + 570 0268 8DBF out __SP_L__,r24 + 571 026a 00C0 rjmp .L15 + 572 .L18: + 68:../../../../Lib/net/udp.c **** #endif + 69:../../../../Lib/net/udp.c **** return; + 70:../../../../Lib/net/udp.c **** } + 71:../../../../Lib/net/udp.c **** + 72:../../../../Lib/net/udp.c **** if (udpSocket->dstPortDef == HTONS(0)) + 73:../../../../Lib/net/udp.c **** udpSocket->dstPort = nicState.layer4.udp->srcport; + 574 .LM40: + 575 026c 5383 std Z+3,r21 + 576 026e 4283 std Z+2,r20 + 577 .L19: + 74:../../../../Lib/net/udp.c **** uint8_t *tmp = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + 579 .LM41: + 580 0270 C091 0000 lds r28,nicState+12 + 581 0274 D091 0000 lds r29,nicState+12+1 + 582 0278 2896 adiw r28,8 + 75:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 76:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 584 .LM42: + 585 027a 2115 cp r18,__zero_reg__ + 586 027c 3105 cpc r19,__zero_reg__ + 587 027e 01F0 breq .L23 + 77:../../../../Lib/net/udp.c **** if (udpDbgLevel > 4) + 589 .LM43: + 590 0280 8091 0000 lds r24,udpDbgLevel + 591 0284 8530 cpi r24,lo8(5) + 592 0286 00F0 brlo .L23 + 78:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("Received UDP data:")); + 594 .LM44: + 595 0288 80E0 ldi r24,lo8(__c.2500) + 596 028a 90E0 ldi r25,hi8(__c.2500) + 597 028c 9F93 push r25 + 598 028e 8F93 push r24 + 599 0290 3F93 push r19 + 600 0292 2F93 push r18 + 601 0294 0E94 0000 call fprintf_P + 602 0298 0F90 pop __tmp_reg__ + 603 029a 0F90 pop __tmp_reg__ + 604 029c 0F90 pop __tmp_reg__ + 605 029e 0F90 pop __tmp_reg__ + 606 .L23: + 51:../../../../Lib/net/udp.c **** uint16_t len = (uint16_t) htons(nicState.layer4.udp->udplen); + 608 .LM45: + 609 02a0 88E0 ldi r24,lo8(8) + 610 02a2 B82E mov r11,r24 + 79:../../../../Lib/net/udp.c **** #endif + 80:../../../../Lib/net/udp.c **** + 81:../../../../Lib/net/udp.c **** for (i=UDP_HEADER_LEN; i 4) + 86:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR(" 0x%2x"), *tmp); + 612 .LM46: + 613 02a4 90E0 ldi r25,lo8(__c.2502) + 614 02a6 E92E mov r14,r25 + 615 02a8 90E0 ldi r25,hi8(__c.2502) + 616 02aa F92E mov r15,r25 + 87:../../../../Lib/net/udp.c **** #else + 88:../../../../Lib/net/udp.c **** xQueueSend(udpSocket->Rx, tmp, 0); + 89:../../../../Lib/net/udp.c **** #endif + 90:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 91:../../../../Lib/net/udp.c **** if (xQueueSend(udpSocket->Rx, tmp, 10) == 0) + 92:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 93:../../../../Lib/net/udp.c **** if (udpDbgLevel > 0) + 94:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); + 618 .LM47: + 619 02ac 20E0 ldi r18,lo8(__c.2504) + 620 02ae C22E mov r12,r18 + 621 02b0 20E0 ldi r18,hi8(__c.2504) + 622 02b2 D22E mov r13,r18 + 623 .L24: + 81:../../../../Lib/net/udp.c **** { + 625 .LM48: + 626 02b4 8B2D mov r24,r11 + 627 02b6 90E0 ldi r25,0 + 628 02b8 2091 0000 lds r18,udpDbgStream + 629 02bc 3091 0000 lds r19,udpDbgStream+1 + 630 02c0 8017 cp r24,r16 + 631 02c2 9107 cpc r25,r17 + 632 02c4 00F4 brsh .L50 + 84:../../../../Lib/net/udp.c **** if (udpDbgLevel > 4) + 634 .LM49: + 635 02c6 2115 cp r18,__zero_reg__ + 636 02c8 3105 cpc r19,__zero_reg__ + 637 02ca 01F0 breq .L25 + 85:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR(" 0x%2x"), *tmp); + 639 .LM50: + 640 02cc 8091 0000 lds r24,udpDbgLevel + 641 02d0 8530 cpi r24,lo8(5) + 642 02d2 00F0 brlo .L25 + 86:../../../../Lib/net/udp.c **** #else + 644 .LM51: + 645 02d4 8881 ld r24,Y + 646 02d6 1F92 push __zero_reg__ + 647 02d8 8F93 push r24 + 648 02da FF92 push r15 + 649 02dc EF92 push r14 + 650 02de 3F93 push r19 + 651 02e0 2F93 push r18 + 652 02e2 0E94 0000 call fprintf_P + 653 02e6 0F90 pop __tmp_reg__ + 654 02e8 0F90 pop __tmp_reg__ + 655 02ea 0F90 pop __tmp_reg__ + 656 02ec 0F90 pop __tmp_reg__ + 657 02ee 0F90 pop __tmp_reg__ + 658 02f0 0F90 pop __tmp_reg__ + 659 .L25: + 91:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 661 .LM52: + 662 02f2 E091 0000 lds r30,udpSocket + 663 02f6 F091 0000 lds r31,udpSocket+1 + 664 02fa 20E0 ldi r18,0 + 665 02fc 4AE0 ldi r20,lo8(10) + 666 02fe 50E0 ldi r21,0 + 667 0300 BE01 movw r22,r28 + 668 0302 8285 ldd r24,Z+10 + 669 0304 9385 ldd r25,Z+11 + 670 0306 0E94 0000 call xQueueGenericSend + 671 030a 8111 cpse r24,__zero_reg__ + 672 030c 00C0 rjmp .L26 + 92:../../../../Lib/net/udp.c **** if (udpDbgLevel > 0) + 674 .LM53: + 675 030e 8091 0000 lds r24,udpDbgStream + 676 0312 9091 0000 lds r25,udpDbgStream+1 + 677 0316 0097 sbiw r24,0 + 678 0318 01F0 breq .L26 + 93:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); + 680 .LM54: + 681 031a 2091 0000 lds r18,udpDbgLevel + 682 031e 2223 tst r18 + 683 0320 01F0 breq .L26 + 685 .LM55: + 686 0322 DF92 push r13 + 687 0324 CF92 push r12 + 688 0326 9F93 push r25 + 689 0328 8F93 push r24 + 690 032a 0E94 0000 call fprintf_P + 691 032e 0F90 pop __tmp_reg__ + 692 0330 0F90 pop __tmp_reg__ + 693 0332 0F90 pop __tmp_reg__ + 694 0334 0F90 pop __tmp_reg__ + 695 .L26: + 95:../../../../Lib/net/udp.c **** #endif + 96:../../../../Lib/net/udp.c **** tmp++; + 697 .LM56: + 698 0336 2196 adiw r28,1 + 81:../../../../Lib/net/udp.c **** { + 700 .LM57: + 701 0338 B394 inc r11 + 702 033a 00C0 rjmp .L24 + 703 .L50: + 97:../../../../Lib/net/udp.c **** } + 98:../../../../Lib/net/udp.c **** #if UDP_DEBUG + 99:../../../../Lib/net/udp.c **** if(udpDbgStream != NULL) + 705 .LM58: + 706 033c 2115 cp r18,__zero_reg__ + 707 033e 3105 cpc r19,__zero_reg__ + 708 0340 01F0 breq .L15 + 100:../../../../Lib/net/udp.c **** { + 101:../../../../Lib/net/udp.c **** if (udpDbgLevel > 4) + 710 .LM59: + 711 0342 8091 0000 lds r24,udpDbgLevel + 712 0346 8530 cpi r24,lo8(5) + 713 0348 00F0 brlo .L28 + 102:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("\r\n")); + 715 .LM60: + 716 034a 80E0 ldi r24,lo8(__c.2509) + 717 034c 90E0 ldi r25,hi8(__c.2509) + 718 034e 9F93 push r25 + 719 0350 8F93 push r24 + 720 0352 3F93 push r19 + 721 0354 2F93 push r18 + 722 0356 0E94 0000 call fprintf_P + 723 035a 0F90 pop __tmp_reg__ + 724 035c 0F90 pop __tmp_reg__ + 725 035e 0F90 pop __tmp_reg__ + 726 0360 0F90 pop __tmp_reg__ + 727 0362 00C0 rjmp .L15 + 728 .L28: + 103:../../../../Lib/net/udp.c **** else if (udpDbgLevel > 0) + 730 .LM61: + 731 0364 8823 tst r24 + 732 0366 01F0 breq .L15 + 104:../../../../Lib/net/udp.c **** fprintf_P(udpDbgStream, PSTR("Received UDP packet (len %d)\r\n"), len); + 734 .LM62: + 735 0368 1F93 push r17 + 736 036a 0F93 push r16 + 737 036c 80E0 ldi r24,lo8(__c.2511) + 738 036e 90E0 ldi r25,hi8(__c.2511) + 739 0370 9F93 push r25 + 740 0372 8F93 push r24 + 741 0374 3F93 push r19 + 742 0376 2F93 push r18 + 743 0378 0E94 0000 call fprintf_P + 744 037c 0F90 pop __tmp_reg__ + 745 037e 0F90 pop __tmp_reg__ + 746 0380 0F90 pop __tmp_reg__ + 747 0382 0F90 pop __tmp_reg__ + 748 0384 0F90 pop __tmp_reg__ + 749 0386 0F90 pop __tmp_reg__ + 750 .L15: + 751 /* epilogue start */ + 105:../../../../Lib/net/udp.c **** + 106:../../../../Lib/net/udp.c **** } + 107:../../../../Lib/net/udp.c **** #endif + 108:../../../../Lib/net/udp.c **** } + 753 .LM63: + 754 0388 DF91 pop r29 + 755 038a CF91 pop r28 + 756 038c 1F91 pop r17 + 757 038e 0F91 pop r16 + 758 0390 FF90 pop r15 + 759 0392 EF90 pop r14 + 760 0394 DF90 pop r13 + 761 0396 CF90 pop r12 + 762 0398 BF90 pop r11 + 763 039a 0895 ret + 770 .Lscope5: + 772 .stabd 78,0,0 + 774 .global flushUdpQueues + 776 flushUdpQueues: + 777 .stabd 46,0,0 + 109:../../../../Lib/net/udp.c **** + 110:../../../../Lib/net/udp.c **** inline void flushUdpQueues(void) + 111:../../../../Lib/net/udp.c **** { + 779 .LM64: + 780 .LFBB6: + 781 039c 0F93 push r16 + 782 039e 1F93 push r17 + 783 03a0 CF93 push r28 + 784 03a2 DF93 push r29 + 785 /* prologue: function */ + 786 /* frame size = 0 */ + 787 /* stack size = 4 */ + 788 .L__stack_usage = 4 + 112:../../../../Lib/net/udp.c **** if (uxQueueMessagesWaiting(udpSocket->Tx) > 0) + 790 .LM65: + 791 03a4 E091 0000 lds r30,udpSocket + 792 03a8 F091 0000 lds r31,udpSocket+1 + 793 03ac 8485 ldd r24,Z+12 + 794 03ae 9585 ldd r25,Z+13 + 795 03b0 0E94 0000 call uxQueueMessagesWaiting + 796 03b4 8823 tst r24 + 797 03b6 01F0 breq .L51 + 798 .LBB2: + 113:../../../../Lib/net/udp.c **** { + 114:../../../../Lib/net/udp.c **** uint16_t len = 0; + 115:../../../../Lib/net/udp.c **** uint8_t *data = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + 800 .LM66: + 801 03b8 C091 0000 lds r28,nicState+12 + 802 03bc D091 0000 lds r29,nicState+12+1 + 803 03c0 2896 adiw r28,8 + 114:../../../../Lib/net/udp.c **** uint8_t *data = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + 805 .LM67: + 806 03c2 00E0 ldi r16,0 + 807 03c4 10E0 ldi r17,0 + 808 .L53: + 116:../../../../Lib/net/udp.c **** while (xQueueReceive(udpSocket->Tx, data, 0) == pdTRUE) + 810 .LM68: + 811 03c6 E091 0000 lds r30,udpSocket + 812 03ca F091 0000 lds r31,udpSocket+1 + 813 03ce 20E0 ldi r18,0 + 814 03d0 40E0 ldi r20,0 + 815 03d2 50E0 ldi r21,0 + 816 03d4 BE01 movw r22,r28 + 817 03d6 8485 ldd r24,Z+12 + 818 03d8 9585 ldd r25,Z+13 + 819 03da 0E94 0000 call xQueueGenericReceive + 820 03de 8130 cpi r24,lo8(1) + 821 03e0 01F4 brne .L55 + 117:../../../../Lib/net/udp.c **** { + 118:../../../../Lib/net/udp.c **** data++; + 823 .LM69: + 824 03e2 2196 adiw r28,1 + 119:../../../../Lib/net/udp.c **** len++; + 826 .LM70: + 827 03e4 0F5F subi r16,-1 + 828 03e6 1F4F sbci r17,-1 + 829 03e8 00C0 rjmp .L53 + 830 .L55: + 120:../../../../Lib/net/udp.c **** } + 121:../../../../Lib/net/udp.c **** udpSend(len); + 832 .LM71: + 833 03ea C801 movw r24,r16 + 834 /* epilogue start */ + 835 .LBE2: + 122:../../../../Lib/net/udp.c **** } + 123:../../../../Lib/net/udp.c **** } + 837 .LM72: + 838 03ec DF91 pop r29 + 839 03ee CF91 pop r28 + 840 03f0 1F91 pop r17 + 841 03f2 0F91 pop r16 + 842 .LBB3: + 121:../../../../Lib/net/udp.c **** } + 844 .LM73: + 845 03f4 0C94 0000 jmp udpSend + 846 .L51: + 847 /* epilogue start */ + 848 .LBE3: + 850 .LM74: + 851 03f8 DF91 pop r29 + 852 03fa CF91 pop r28 + 853 03fc 1F91 pop r17 + 854 03fe 0F91 pop r16 + 855 0400 0895 ret + 865 .Lscope6: + 867 .stabd 78,0,0 + 869 .global udpSaveConfig + 871 udpSaveConfig: + 872 .stabd 46,0,0 + 124:../../../../Lib/net/udp.c **** + 125:../../../../Lib/net/udp.c **** void udpSaveConfig(void) + 126:../../../../Lib/net/udp.c **** { + 874 .LM75: + 875 .LFBB7: + 876 /* prologue: function */ + 877 /* frame size = 0 */ + 878 /* stack size = 0 */ + 879 .L__stack_usage = 0 + 127:../../../../Lib/net/udp.c **** eeprom_update_dword(&udpIpDst_eep, udpSocket->dstIp); + 881 .LM76: + 882 0402 E091 0000 lds r30,udpSocket + 883 0406 F091 0000 lds r31,udpSocket+1 + 884 040a 4681 ldd r20,Z+6 + 885 040c 5781 ldd r21,Z+7 + 886 040e 6085 ldd r22,Z+8 + 887 0410 7185 ldd r23,Z+9 + 888 0412 80E0 ldi r24,lo8(udpIpDst_eep) + 889 0414 90E0 ldi r25,hi8(udpIpDst_eep) + 890 0416 0E94 0000 call eeprom_update_dword + 128:../../../../Lib/net/udp.c **** eeprom_update_word(&udpPortDstEep, udpSocket->dstPortDef); + 892 .LM77: + 893 041a E091 0000 lds r30,udpSocket + 894 041e F091 0000 lds r31,udpSocket+1 + 895 0422 6081 ld r22,Z + 896 0424 7181 ldd r23,Z+1 + 897 0426 80E0 ldi r24,lo8(udpPortDstEep) + 898 0428 90E0 ldi r25,hi8(udpPortDstEep) + 899 042a 0E94 0000 call eeprom_update_word + 129:../../../../Lib/net/udp.c **** eeprom_update_word(&udpPortSrcEep, udpSocket->srcPort); + 901 .LM78: + 902 042e E091 0000 lds r30,udpSocket + 903 0432 F091 0000 lds r31,udpSocket+1 + 904 0436 6481 ldd r22,Z+4 + 905 0438 7581 ldd r23,Z+5 + 906 043a 80E0 ldi r24,lo8(udpPortSrcEep) + 907 043c 90E0 ldi r25,hi8(udpPortSrcEep) + 908 043e 0C94 0000 jmp eeprom_update_word + 910 .Lscope7: + 912 .stabd 78,0,0 + 914 .global udpPrintStatus + 916 udpPrintStatus: + 917 .stabd 46,0,0 + 130:../../../../Lib/net/udp.c **** } + 131:../../../../Lib/net/udp.c **** + 132:../../../../Lib/net/udp.c **** void udpPrintStatus(FILE *stream) + 133:../../../../Lib/net/udp.c **** { + 919 .LM79: + 920 .LFBB8: + 921 0442 CF93 push r28 + 922 0444 DF93 push r29 + 923 /* prologue: function */ + 924 /* frame size = 0 */ + 925 /* stack size = 2 */ + 926 .L__stack_usage = 2 + 927 0446 EC01 movw r28,r24 + 134:../../../../Lib/net/udp.c **** fprintf_P(stream, PSTR("UDP config:")); + 929 .LM80: + 930 0448 80E0 ldi r24,lo8(__c.2527) + 931 044a 90E0 ldi r25,hi8(__c.2527) + 932 044c 9F93 push r25 + 933 044e 8F93 push r24 + 934 0450 DF93 push r29 + 935 0452 CF93 push r28 + 936 0454 0E94 0000 call fprintf_P + 135:../../../../Lib/net/udp.c **** fprintf_P(stream, PSTR("\r\n IP : ")); netPrintIPAddr(stream, udpSocket->dstIp); + 938 .LM81: + 939 0458 80E0 ldi r24,lo8(__c.2529) + 940 045a 90E0 ldi r25,hi8(__c.2529) + 941 045c 9F93 push r25 + 942 045e 8F93 push r24 + 943 0460 DF93 push r29 + 944 0462 CF93 push r28 + 945 0464 0E94 0000 call fprintf_P + 946 0468 E091 0000 lds r30,udpSocket + 947 046c F091 0000 lds r31,udpSocket+1 + 948 0470 4681 ldd r20,Z+6 + 949 0472 5781 ldd r21,Z+7 + 950 0474 6085 ldd r22,Z+8 + 951 0476 7185 ldd r23,Z+9 + 952 0478 CE01 movw r24,r28 + 953 047a 0E94 0000 call netPrintIPAddr + 136:../../../../Lib/net/udp.c **** fprintf_P(stream, PSTR("\r\n src port : %d\r\n dst port : "), htons(udpSocket->srcPort)); + 955 .LM82: + 956 047e E091 0000 lds r30,udpSocket + 957 0482 F091 0000 lds r31,udpSocket+1 + 958 0486 8481 ldd r24,Z+4 + 959 0488 9581 ldd r25,Z+5 + 960 048a 0E94 0000 call htons + 961 048e 9F93 push r25 + 962 0490 8F93 push r24 + 963 0492 80E0 ldi r24,lo8(__c.2531) + 964 0494 90E0 ldi r25,hi8(__c.2531) + 965 0496 9F93 push r25 + 966 0498 8F93 push r24 + 967 049a DF93 push r29 + 968 049c CF93 push r28 + 969 049e 0E94 0000 call fprintf_P + 137:../../../../Lib/net/udp.c **** if (udpSocket->dstPortDef == HTONS(0)) + 971 .LM83: + 972 04a2 E091 0000 lds r30,udpSocket + 973 04a6 F091 0000 lds r31,udpSocket+1 + 974 04aa 8081 ld r24,Z + 975 04ac 9181 ldd r25,Z+1 + 976 04ae 2DB7 in r18,__SP_L__ + 977 04b0 3EB7 in r19,__SP_H__ + 978 04b2 225F subi r18,-14 + 979 04b4 3F4F sbci r19,-1 + 980 04b6 0FB6 in __tmp_reg__,__SREG__ + 981 04b8 F894 cli + 982 04ba 3EBF out __SP_H__,r19 + 983 04bc 0FBE out __SREG__,__tmp_reg__ + 984 04be 2DBF out __SP_L__,r18 + 985 04c0 0097 sbiw r24,0 + 986 04c2 01F4 brne .L58 + 138:../../../../Lib/net/udp.c **** fprintf_P(stream, PSTR("ANY\r\n")); + 988 .LM84: + 989 04c4 80E0 ldi r24,lo8(__c.2533) + 990 04c6 90E0 ldi r25,hi8(__c.2533) + 991 04c8 9F93 push r25 + 992 04ca 8F93 push r24 + 993 04cc DF93 push r29 + 994 04ce CF93 push r28 + 995 04d0 0E94 0000 call fprintf_P + 996 04d4 0F90 pop __tmp_reg__ + 997 04d6 0F90 pop __tmp_reg__ + 998 04d8 0F90 pop __tmp_reg__ + 999 04da 0F90 pop __tmp_reg__ + 1000 04dc 00C0 rjmp .L57 + 1001 .L58: + 139:../../../../Lib/net/udp.c **** else + 140:../../../../Lib/net/udp.c **** fprintf_P(stream, PSTR("%d\r\n"), htons(udpSocket->dstPortDef)); + 1003 .LM85: + 1004 04de 0E94 0000 call htons + 1005 04e2 9F93 push r25 + 1006 04e4 8F93 push r24 + 1007 04e6 80E0 ldi r24,lo8(__c.2535) + 1008 04e8 90E0 ldi r25,hi8(__c.2535) + 1009 04ea 9F93 push r25 + 1010 04ec 8F93 push r24 + 1011 04ee DF93 push r29 + 1012 04f0 CF93 push r28 + 1013 04f2 0E94 0000 call fprintf_P + 1014 04f6 0F90 pop __tmp_reg__ + 1015 04f8 0F90 pop __tmp_reg__ + 1016 04fa 0F90 pop __tmp_reg__ + 1017 04fc 0F90 pop __tmp_reg__ + 1018 04fe 0F90 pop __tmp_reg__ + 1019 0500 0F90 pop __tmp_reg__ + 1020 .L57: + 1021 /* epilogue start */ + 141:../../../../Lib/net/udp.c **** } + 1023 .LM86: + 1024 0502 DF91 pop r29 + 1025 0504 CF91 pop r28 + 1026 0506 0895 ret + 1028 .Lscope8: + 1030 .stabd 78,0,0 + 1031 .section .progmem.data,"a",@progbits + 1034 __c.2535: + 1035 0000 2564 0D0A .string "%d\r\n" + 1035 00 + 1038 __c.2533: + 1039 0005 414E 590D .string "ANY\r\n" + 1039 0A00 + 1042 __c.2531: + 1043 000b 0D0A 2020 .string "\r\n src port : %d\r\n dst port : " + 1043 7372 6320 + 1043 706F 7274 + 1043 2020 2020 + 1043 3A20 2564 + 1046 __c.2529: + 1047 0032 0D0A 2020 .string "\r\n IP : " + 1047 4950 2020 + 1047 2020 2020 + 1047 2020 2020 + 1047 3A20 00 + 1050 __c.2527: + 1051 0045 5544 5020 .string "UDP config:" + 1051 636F 6E66 + 1051 6967 3A00 + 1054 __c.2511: + 1055 0051 5265 6365 .string "Received UDP packet (len %d)\r\n" + 1055 6976 6564 + 1055 2055 4450 + 1055 2070 6163 + 1055 6B65 7420 + 1058 __c.2509: + 1059 0070 0D0A 00 .string "\r\n" + 1062 __c.2504: + 1063 0073 5544 5020 .string "UDP TX buffer busy\r\n" + 1063 5458 2062 + 1063 7566 6665 + 1063 7220 6275 + 1063 7379 0D0A + 1066 __c.2502: + 1067 0088 2030 7825 .string " 0x%2x" + 1067 3278 00 + 1070 __c.2500: + 1071 008f 5265 6365 .string "Received UDP data:" + 1071 6976 6564 + 1071 2055 4450 + 1071 2064 6174 + 1071 613A 00 + 1074 __c.2497: + 1075 00a2 536B 6970 .string "Skipping, wrong ports %d %d\r\n" + 1075 7069 6E67 + 1075 2C20 7772 + 1075 6F6E 6720 + 1075 706F 7274 + 1078 __c.2495: + 1079 00c0 5072 6F63 .string "Proc. UDP packet (data length %d)" + 1079 2E20 5544 + 1079 5020 7061 + 1079 636B 6574 + 1079 2028 6461 + 1082 __c.2488: + 1083 00e2 5544 5020 .string "UDP tx %d bytes\r\n" + 1083 7478 2025 + 1083 6420 6279 + 1083 7465 730D + 1083 0A00 + 1086 __c.2486: + 1087 00f4 5365 6E64 .string "Sending UDP packet (data length %d)\r\n" + 1087 696E 6720 + 1087 5544 5020 + 1087 7061 636B + 1087 6574 2028 + 1088 .comm udpDbgLevel,1,1 + 1089 .comm udpDbgStream,2,1 + 1090 .comm udpSocket,2,1 + 1091 .comm IpMyConfig,15,1 + 1092 .comm icmpDebugLevel,1,1 + 1093 .comm icmpDebug,2,1 + 1094 .comm arpDebugLevel,1,1 + 1095 .comm arpDebug,2,1 + 1096 .comm nicState,14,1 + 1097 .comm wwwport,1,1 + 1108 .text + 1110 .Letext0: + 1111 .ident "GCC: (GNU) 4.9.2" + 1112 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 udp.c + /tmp/ccp5nKFk.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccp5nKFk.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccp5nKFk.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccp5nKFk.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccp5nKFk.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccp5nKFk.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccp5nKFk.s:162 .text:0000000000000000 udpLoadConfig + *COM*:0000000000000002 udpSocket + /tmp/ccp5nKFk.s:211 .text:000000000000003a udpInit_0 + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000001 udpDbgLevel + /tmp/ccp5nKFk.s:272 .text:000000000000008a setUdpDebug + /tmp/ccp5nKFk.s:297 .text:0000000000000098 udpSend + *COM*:000000000000000e nicState + /tmp/ccp5nKFk.s:1086 .progmem.data:00000000000000f4 __c.2486 + /tmp/ccp5nKFk.s:1082 .progmem.data:00000000000000e2 __c.2488 + /tmp/ccp5nKFk.s:442 .text:0000000000000188 netstackUDPIPProcess + /tmp/ccp5nKFk.s:1078 .progmem.data:00000000000000c0 __c.2495 + /tmp/ccp5nKFk.s:1074 .progmem.data:00000000000000a2 __c.2497 + /tmp/ccp5nKFk.s:1070 .progmem.data:000000000000008f __c.2500 + /tmp/ccp5nKFk.s:1066 .progmem.data:0000000000000088 __c.2502 + /tmp/ccp5nKFk.s:1062 .progmem.data:0000000000000073 __c.2504 + /tmp/ccp5nKFk.s:1058 .progmem.data:0000000000000070 __c.2509 + /tmp/ccp5nKFk.s:1054 .progmem.data:0000000000000051 __c.2511 + /tmp/ccp5nKFk.s:776 .text:000000000000039c flushUdpQueues + /tmp/ccp5nKFk.s:871 .text:0000000000000402 udpSaveConfig + /tmp/ccp5nKFk.s:916 .text:0000000000000442 udpPrintStatus + /tmp/ccp5nKFk.s:1050 .progmem.data:0000000000000045 __c.2527 + /tmp/ccp5nKFk.s:1046 .progmem.data:0000000000000032 __c.2529 + /tmp/ccp5nKFk.s:1042 .progmem.data:000000000000000b __c.2531 + /tmp/ccp5nKFk.s:1038 .progmem.data:0000000000000005 __c.2533 + /tmp/ccp5nKFk.s:1034 .progmem.data:0000000000000000 __c.2535 + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +udpIpDst_eep +eeprom_read_dword +udpPortDstEep +eeprom_read_word +udpPortSrcEep +xmalloc +xQueueCreateExternal +htons +fprintf_P +ipSend +xQueueGenericSend +uxQueueMessagesWaiting +xQueueGenericReceive +eeprom_update_dword +eeprom_update_word +netPrintIPAddr +__do_clear_bss diff --git a/Lib/net/uip-neighbor.c b/Lib/net/uip-neighbor.c new file mode 100644 index 0000000..629b8e3 --- /dev/null +++ b/Lib/net/uip-neighbor.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uip-neighbor.c,v 1.2 2006/08/09 16:13:40 bg- Exp $ + */ + +/** + * \file + * Database of link-local neighbors, used by IPv6 code and + * to be used by a future ARP code rewrite. + * \author + * Adam Dunkels + */ + +#include "net/uip-neighbor.h" + +#include +#include + +#define MAX_TIME 128 + +#ifdef UIP_NEIGHBOR_CONF_ENTRIES +#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES +#else /* UIP_NEIGHBOR_CONF_ENTRIES */ +#define ENTRIES 8 +#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ + +struct neighbor_entry { + uip_ipaddr_t ipaddr; + struct uip_neighbor_addr addr; + u8_t time; +}; +static struct neighbor_entry entries[ENTRIES]; + +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_init(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + entries[i].time = MAX_TIME; + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_periodic(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time < MAX_TIME) { + entries[i].time++; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr) +{ + int i, oldest; + u8_t oldest_time; + + printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], + addr->addr.addr[4], addr->addr.addr[5]); + + /* Find the first unused entry or the oldest used entry. */ + oldest_time = 0; + oldest = 0; + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time == MAX_TIME) { + oldest = i; + break; + } + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { + oldest = i; + break; + } + if(entries[i].time > oldest_time) { + oldest = i; + oldest_time = entries[i].time; + } + } + + /* Use the oldest or first free entry (either pointed to by the + "oldest" variable). */ + entries[oldest].time = 0; + uip_ipaddr_copy(&entries[oldest].ipaddr, ipaddr); + memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); +} +/*---------------------------------------------------------------------------*/ +static struct neighbor_entry * +find_entry(uip_ipaddr_t *ipaddr) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { + return &entries[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_update(uip_ipaddr_t *ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + e->time = 0; + } +} +/*---------------------------------------------------------------------------*/ +struct uip_neighbor_addr * +uip_neighbor_lookup(uip_ipaddr_t *ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], + e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ + + return &e->addr; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/Lib/net/uip-netif.c b/Lib/net/uip-netif.c new file mode 100644 index 0000000..36bf7b3 --- /dev/null +++ b/Lib/net/uip-netif.c @@ -0,0 +1,117 @@ + +/** + * \file + * Network interface and configuration + */ + +/* + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + */ + +#include "uip-netif.h" +#include +#include +#include "include/uip-netif.h" + +/*---------------------------------------------------------------------------*/ + + +void uip_netif_init(void) +{ + uip_netif_physical_if = xmalloc(sizeof(struct uip_netif)); + /* INITIALIZE INTERFACE (default values for now) */ + uip_netif_physical_if->link_mtu = UIP_LINK_MTU; + uip_netif_physical_if->cur_hop_limit = UIP_TTL; + uip_netif_physical_if->base_reachable_time = UIP_ND6_REACHABLE_TIME; + uip_netif_physical_if->reachable_time = 0;//uip_netif_compute_reachable_time(); //to trzeba zmienić w przypadku potrowania caÅ‚Ä™go ND + uip_netif_physical_if->retrans_timer = UIP_ND6_RETRANS_TIMER; + uip_netif_physical_if->dup_addr_detect_transmit = 0; + + /* + * STATELESS AUTOCONFIGURATION of the link local address. We set it to + * infinite (this will become really true once DAD succeeds) + */ + uip_ip6addr(&(uip_netif_physical_if->addresses[0].ipaddr), + 0xfe80,0,0,0,0,0,0,0); + uip_netif_addr_autoconf_set(&(uip_netif_physical_if->addresses[0].ipaddr), &nicState.mac.addr); + uip_netif_physical_if->addresses[0].state = TENTATIVE; + uip_netif_physical_if->addresses[0].type = MANUAL; + uip_netif_physical_if->addresses[0].is_infinite = 1; + + /* set all other addresses to NOT_USED initialy */ + uint8_t i; + for(i = 1; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) + uip_netif_physical_if->addresses[i].state = NOT_USED; + + uip_ip6addr_u8(&(uip_netif_physical_if->solicited_node_mcastaddr), + 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, + nicState.mac.addr[3], + nicState.mac.addr[4], + nicState.mac.addr[5]); + /* Find router (send rs to all-routers multicast group)) */ + //uip_netif_sched_send_rs(); +} + +void uip_netif_addr_autoconf_set(uip_ipaddr_t *ipaddr, struct netEthAddr *lladdr) +{ + /* We consider only links with IEEE EUI-64 identifier or + IEEE 48-bit MAC addresses */ +#if (UIP_LLADDR_LEN == 8) + memcpy(ipaddr->u8 + 8, lladdr->addr, UIP_LLADDR_LEN); + ipaddr->u8[8] ^= 0x02; +#elif (UIP_LLADDR_LEN == 6) + memcpy(ipaddr->u8 + 8, lladdr->addr, 3); + ipaddr->u8[11] = 0xff; + ipaddr->u8[12] = 0xfe; + memcpy(ipaddr->u8 + 13, (u8_t*)lladdr->addr + 3, 3); + ipaddr->u8[8] ^= 0x02; +#else + //UIP_LOG("CAN NOT BUIL INTERFACE IDENTIFIER"); +#endif +} + +/*---------------------------------------------------------------------------*/ +struct uip_netif_addr *uip_netif_addr_lookup(uip_ipaddr_t *ipaddr, u8_t length, uip_netif_type type) +{ + uint8_t i; + for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) { + if((uip_netif_physical_if->addresses[i].state != NOT_USED) && + (uip_netif_physical_if->addresses[i].type == type || type == 0) && + (uip_ipaddr_prefixcmp(&(uip_netif_physical_if->addresses[i].ipaddr), ipaddr, length))) { + return &uip_netif_physical_if->addresses[i]; + } + } + //return NULL; + + return &uip_netif_physical_if->addresses[0]; + + return NULL; +} + + +/** @} */ diff --git a/Lib/queueStream.c b/Lib/queueStream.c new file mode 100644 index 0000000..27fe3f6 --- /dev/null +++ b/Lib/queueStream.c @@ -0,0 +1,33 @@ +#include "queueStream.h" + +static int streamQueueOutputFun(char c, FILE *ostream); +static int streamQueueInputFun(FILE *istream); + +void initQueueStream(FILE *stream, streamBuffers_t *buffer, xQueueHandle Rx, xQueueHandle Tx) +{ + fdev_setup_stream(stream, streamQueueOutputFun, streamQueueInputFun, _FDEV_SETUP_RW); + fdev_set_udata(stream, (void *)buffer); + buffer->Rx = Rx; + buffer->Tx = Tx; + return; +} + +static int streamQueueOutputFun(char c, FILE *ostream) +{ + streamBuffers_t *strBuf = (streamBuffers_t *) ostream->udata; +/* if (xQueueSend( strBuf->Tx, &c, strBuf->tx_timeout)) + { + return EOF; + } + else*/ + xQueueSend( strBuf->Tx, &c, portMAX_DELAY); + return 0; +} + +static int streamQueueInputFun(FILE *istream) +{ + char c; + streamBuffers_t *strBuf = (streamBuffers_t *) istream->udata; + xQueueReceive(strBuf->Rx, &c, portMAX_DELAY); + return c; +} diff --git a/Lib/queueStream.lst b/Lib/queueStream.lst new file mode 100644 index 0000000..b97d796 --- /dev/null +++ b/Lib/queueStream.lst @@ -0,0 +1,179 @@ + 1 .file "queueStream.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 136 streamQueueInputFun: + 137 .stabd 46,0,0 + 1:../../../../Lib/queueStream.c **** #include "queueStream.h" + 2:../../../../Lib/queueStream.c **** + 3:../../../../Lib/queueStream.c **** static int streamQueueOutputFun(char c, FILE *ostream); + 4:../../../../Lib/queueStream.c **** static int streamQueueInputFun(FILE *istream); + 5:../../../../Lib/queueStream.c **** + 6:../../../../Lib/queueStream.c **** void initQueueStream(FILE *stream, streamBuffers_t *buffer, xQueueHandle Rx, xQueueHandle Tx) + 7:../../../../Lib/queueStream.c **** { + 8:../../../../Lib/queueStream.c **** fdev_setup_stream(stream, streamQueueOutputFun, streamQueueInputFun, _FDEV_SETUP_RW); + 9:../../../../Lib/queueStream.c **** fdev_set_udata(stream, (void *)buffer); + 10:../../../../Lib/queueStream.c **** buffer->Rx = Rx; + 11:../../../../Lib/queueStream.c **** buffer->Tx = Tx; + 12:../../../../Lib/queueStream.c **** return; + 13:../../../../Lib/queueStream.c **** } + 14:../../../../Lib/queueStream.c **** + 15:../../../../Lib/queueStream.c **** static int streamQueueOutputFun(char c, FILE *ostream) + 16:../../../../Lib/queueStream.c **** { + 17:../../../../Lib/queueStream.c **** streamBuffers_t *strBuf = (streamBuffers_t *) ostream->udata; + 18:../../../../Lib/queueStream.c **** /* if (xQueueSend( strBuf->Tx, &c, strBuf->tx_timeout)) + 19:../../../../Lib/queueStream.c **** { + 20:../../../../Lib/queueStream.c **** return EOF; + 21:../../../../Lib/queueStream.c **** } + 22:../../../../Lib/queueStream.c **** else*/ + 23:../../../../Lib/queueStream.c **** xQueueSend( strBuf->Tx, &c, portMAX_DELAY); + 24:../../../../Lib/queueStream.c **** return 0; + 25:../../../../Lib/queueStream.c **** } + 26:../../../../Lib/queueStream.c **** + 27:../../../../Lib/queueStream.c **** static int streamQueueInputFun(FILE *istream) + 28:../../../../Lib/queueStream.c **** { + 139 .LM0: + 140 .LFBB1: + 141 0000 CF93 push r28 + 142 0002 DF93 push r29 + 143 0004 1F92 push __zero_reg__ + 144 0006 CDB7 in r28,__SP_L__ + 145 0008 DEB7 in r29,__SP_H__ + 146 /* prologue: function */ + 147 /* frame size = 1 */ + 148 /* stack size = 3 */ + 149 .L__stack_usage = 3 + 29:../../../../Lib/queueStream.c **** char c; + 30:../../../../Lib/queueStream.c **** streamBuffers_t *strBuf = (streamBuffers_t *) istream->udata; + 31:../../../../Lib/queueStream.c **** xQueueReceive(strBuf->Rx, &c, portMAX_DELAY); + 151 .LM1: + 152 000a DC01 movw r26,r24 + 153 000c 1C96 adiw r26,12 + 154 000e ED91 ld r30,X+ + 155 0010 FC91 ld r31,X + 156 0012 1D97 sbiw r26,12+1 + 157 0014 20E0 ldi r18,0 + 158 0016 4FEF ldi r20,lo8(-1) + 159 0018 5FEF ldi r21,lo8(-1) + 160 001a BE01 movw r22,r28 + 161 001c 6F5F subi r22,-1 + 162 001e 7F4F sbci r23,-1 + 163 0020 8081 ld r24,Z + 164 0022 9181 ldd r25,Z+1 + 165 0024 0E94 0000 call xQueueGenericReceive + 32:../../../../Lib/queueStream.c **** return c; + 167 .LM2: + 168 0028 8981 ldd r24,Y+1 + 33:../../../../Lib/queueStream.c **** } + 170 .LM3: + 171 002a 082E mov __tmp_reg__,r24 + 172 002c 000C lsl r0 + 173 002e 990B sbc r25,r25 + 174 /* epilogue start */ + 175 0030 0F90 pop __tmp_reg__ + 176 0032 DF91 pop r29 + 177 0034 CF91 pop r28 + 178 0036 0895 ret + 183 .Lscope1: + 185 .stabd 78,0,0 + 190 streamQueueOutputFun: + 191 .stabd 46,0,0 + 16:../../../../Lib/queueStream.c **** streamBuffers_t *strBuf = (streamBuffers_t *) ostream->udata; + 193 .LM4: + 194 .LFBB2: + 195 0038 CF93 push r28 + 196 003a DF93 push r29 + 197 003c 1F92 push __zero_reg__ + 198 003e CDB7 in r28,__SP_L__ + 199 0040 DEB7 in r29,__SP_H__ + 200 /* prologue: function */ + 201 /* frame size = 1 */ + 202 /* stack size = 3 */ + 203 .L__stack_usage = 3 + 204 0042 8983 std Y+1,r24 + 23:../../../../Lib/queueStream.c **** return 0; + 206 .LM5: + 207 0044 DB01 movw r26,r22 + 208 0046 1C96 adiw r26,12 + 209 0048 ED91 ld r30,X+ + 210 004a FC91 ld r31,X + 211 004c 1D97 sbiw r26,12+1 + 212 004e 20E0 ldi r18,0 + 213 0050 4FEF ldi r20,lo8(-1) + 214 0052 5FEF ldi r21,lo8(-1) + 215 0054 BE01 movw r22,r28 + 216 0056 6F5F subi r22,-1 + 217 0058 7F4F sbci r23,-1 + 218 005a 8281 ldd r24,Z+2 + 219 005c 9381 ldd r25,Z+3 + 220 005e 0E94 0000 call xQueueGenericSend + 25:../../../../Lib/queueStream.c **** + 222 .LM6: + 223 0062 80E0 ldi r24,0 + 224 0064 90E0 ldi r25,0 + 225 /* epilogue start */ + 226 0066 0F90 pop __tmp_reg__ + 227 0068 DF91 pop r29 + 228 006a CF91 pop r28 + 229 006c 0895 ret + 231 .Lscope2: + 233 .stabd 78,0,0 + 239 .global initQueueStream + 241 initQueueStream: + 242 .stabd 46,0,0 + 7:../../../../Lib/queueStream.c **** fdev_setup_stream(stream, streamQueueOutputFun, streamQueueInputFun, _FDEV_SETUP_RW); + 244 .LM7: + 245 .LFBB3: + 246 /* prologue: function */ + 247 /* frame size = 0 */ + 248 /* stack size = 0 */ + 249 .L__stack_usage = 0 + 250 006e FC01 movw r30,r24 + 8:../../../../Lib/queueStream.c **** fdev_set_udata(stream, (void *)buffer); + 252 .LM8: + 253 0070 80E0 ldi r24,lo8(gs(streamQueueOutputFun)) + 254 0072 90E0 ldi r25,hi8(gs(streamQueueOutputFun)) + 255 0074 9187 std Z+9,r25 + 256 0076 8087 std Z+8,r24 + 257 0078 80E0 ldi r24,lo8(gs(streamQueueInputFun)) + 258 007a 90E0 ldi r25,hi8(gs(streamQueueInputFun)) + 259 007c 9387 std Z+11,r25 + 260 007e 8287 std Z+10,r24 + 261 0080 83E0 ldi r24,lo8(3) + 262 0082 8383 std Z+3,r24 + 9:../../../../Lib/queueStream.c **** buffer->Rx = Rx; + 264 .LM9: + 265 0084 7587 std Z+13,r23 + 266 0086 6487 std Z+12,r22 + 10:../../../../Lib/queueStream.c **** buffer->Tx = Tx; + 268 .LM10: + 269 0088 FB01 movw r30,r22 + 270 008a 5183 std Z+1,r21 + 271 008c 4083 st Z,r20 + 11:../../../../Lib/queueStream.c **** return; + 273 .LM11: + 274 008e 3383 std Z+3,r19 + 275 0090 2283 std Z+2,r18 + 276 0092 0895 ret + 278 .Lscope3: + 280 .stabd 78,0,0 + 282 .Letext0: + 283 .ident "GCC: (GNU) 4.9.2" +DEFINED SYMBOLS + *ABS*:0000000000000000 queueStream.c + /tmp/ccDtVXmj.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccDtVXmj.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccDtVXmj.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccDtVXmj.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccDtVXmj.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccDtVXmj.s:136 .text:0000000000000000 streamQueueInputFun + /tmp/ccDtVXmj.s:190 .text:0000000000000038 streamQueueOutputFun + /tmp/ccDtVXmj.s:241 .text:000000000000006e initQueueStream + +UNDEFINED SYMBOLS +xQueueGenericReceive +xQueueGenericSend diff --git a/Lib/ramdysk.c b/Lib/ramdysk.c new file mode 100644 index 0000000..641c53c --- /dev/null +++ b/Lib/ramdysk.c @@ -0,0 +1,618 @@ +#include "ramdysk.h" +#include + +#define systemTime() 0; //Dodać w pliku hardware.h funkcje do odczytu czasu systemowego + +static uint8_t znajdzWolnyKlaster(void); +static uint8_t nastepnyKlaster(uint8_t nrKlastra); +static uint8_t znajdzKlasterN(uint8_t nrPierwszegoKlastra, uint8_t lPrzeskokow); +#if ( USUNKLASTER == 1) +static uint8_t usunKlaster(uint8_t nrKlastra); +#endif +static uint8_t wObrebiePliku(struct ramPlikFd *fd); +static void uaktualnijRozmiarPliku(struct ramPlikFd *fd); +static struct ramPlik* znajdzPlik(const char *nazwa); +static struct ramPlik* znajdzMiejsceNaWpis(void); +static void czyscKlaster(uint8_t nrKlastra); + +static void czyscKlaster(uint8_t nrKlastra) +{ + uint8_t *tmpPtr = dataPtr(nrKlastra, 0); + memset (tmpPtr, 0, 256); +} + +static uint8_t wObrebiePliku(struct ramPlikFd *fd) +{ + if (fd->wpis->rozmiarHi > fd->IndHi) + return 0; + + if ((fd->wpis->rozmiarHi == fd->IndHi) && (fd->wpis->rozmiarLo >= fd->IndLo)) + return 0; + + return 1; +} + +static void uaktualnijRozmiarPliku(struct ramPlikFd *fd) +{ + if (fd->wpis->rozmiarHi == fd->IndHi) + { + if (fd->wpis->rozmiarLo < fd->IndLo) + fd->wpis->rozmiarLo = fd->IndLo; + } + if (fd->wpis->rozmiarHi < fd->IndHi) + { + fd->wpis->rozmiarLo = fd->IndLo; + fd->wpis->rozmiarHi = fd->IndHi; + } +} + +static uint8_t znajdzWolnyKlaster(void) +{ + uint8_t i; + for (i=1; i 8) + dlNazwy = 8; + + + if (nazwa[dlNazwy-1] == 0) + dlNazwy--; //Nie sprawdzamy czy string koÅ„czy siÄ™ /0 + struct ramPlik *plik; + uint8_t temp; + uint8_t tempKlaster=0; + uint8_t tempKlaster2; + + for (temp=1; temp < dlNazwy; temp ++) + { + if (nazwa[temp] == ' ') //Pozbycie sie spacji + { + dlNazwy = temp; + break; + } + } + if (dlNazwy == 0) + return NULL; + + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + { + if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + return plik; + plik++; //PrzejÅ›cie do kolejnego wpisu (w tym samym klastrze) + } + tempKlaster2 = tempKlaster; + tempKlaster = klastry[tempKlaster]; + } + while (tempKlaster2 != tempKlaster); + return NULL; +} + +static struct ramPlik* znajdzMiejsceNaWpis(void) +{ + struct ramPlik *plik; + uint8_t temp; + uint8_t tempKlaster=0; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + uint8_t tempKlaster2; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + { + if (plik->nazwa[0] == 0) + return plik; + plik++; //PrzejÅ›cie do kolejnego wpisu (w tym samym klastrze) + } + tempKlaster2 = tempKlaster; + tempKlaster = klastry[tempKlaster]; + } + while (tempKlaster2 != tempKlaster); + + klastry[tempKlaster] = znajdzWolnyKlaster(); + plik = NULL; + if (klastry[tempKlaster] != 0) + plik = (struct ramPlik*) (dataPtr(klastry[tempKlaster], 0)); + + return plik; +} + + +void ramDyskInit(void) +{ + memset (klastry, 0, 128); //Czyszczenie tablicy klastrów (wszystkie sÄ… puste) + memset (dataPtr(0,0), 0, 256); //Czyszczenie zerowego klastra z tablicÄ… plików +} +uint8_t ramDyskUtworzPlik(const char *nazwa) +{ //Nowo utworzony plik nie zajmuje żadnego klastra + uint8_t dlNazwy = strlen(nazwa); + uint8_t i; + if (dlNazwy > 8) + dlNazwy = 8; + + for (i=0; inazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + return 0; + } + return 1; +} + +uint8_t ramDyskOtworzPlik(const char *nazwa, struct ramPlikFd *fd) +{ + uint8_t wynik = 1; + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) != NULL) + { + memset(fd, 0, 3); //Zerowanie struktury deskryptora pliku + fd->wpis = plik; //Ustawianie w deskryptorze wskaźnika na wpis pliku do katalogu głównego + plik->lAktOtw++; //Uaktualnienie licznika otwarć plików + wynik = 0; + } + return wynik; +} + +uint8_t ramDyskUsunPlik(const char *nazwa) +{ + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) == NULL) + return 1; //Nie znaleziono pliku + if (plik->lAktOtw != 0) + return 2; //Plik jest otwarty + + uint8_t usuwanyKlaster; + while(plik->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ okazać, że plik nie miaÅ‚ klastrów + { + usuwanyKlaster = plik->pierwszyKlaster; + if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostatniego klastra + plik->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwanie pliku + else + plik->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + } + + memset (plik, 0, 16); //Wpis katalogowy zostaje. Jest pusty. Inny plik może być tam wpisany +//relokacjaTablicyWpisow() + return 0; +} + +void ramDyskZamknijPlik(struct ramPlikFd *fd) +{ + if (fd -> wpis -> lAktOtw > 0) //Sprawdzanie, czy licznik otwarć jest poprawny + { + fd->wpis->lAktOtw--; //Zmniejszanie licznika otwarć pliku + memset(fd, 0, sizeof(struct ramPlikFd)); //CZyszczenie struktury deskryptora plików + } +} + +uint8_t ramDyskCzyscPlik(struct ramPlikFd *fd) +{ + uint8_t usuwanyKlaster; + while(fd->wpis->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ okazać, że plik nie miaÅ‚ klastrów + { + usuwanyKlaster = fd->wpis->pierwszyKlaster; + if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostatniego klastra + fd->wpis->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwanie pliku + else + fd->wpis->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + } + fd->wpis->rozmiarLo = 0; + fd->wpis->rozmiarHi = 0; + fd->wpis->dataMod = systemTime(); + memset (fd, 0, 4); + return 0; +} + +uint8_t ramDyskZapiszBajtDoPliku(struct ramPlikFd *fd, uint8_t znak) +{ + uint8_t tmpKlaster; + if (fd->wpis->pierwszyKlaster == 0) + { + if ((tmpKlaster = znajdzWolnyKlaster()) == 0) + return 1; //Nie można byÅ‚o przydzielić pierwszego klastra do pliku + fd->wpis->pierwszyKlaster = tmpKlaster; + } + if (fd->IndLo == 0) + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Wyszukanie lub dodanie nastÄ™pnego klastra. Na podstawie rozmiaru zostanie stwierdzone, czy klaster byÅ‚ dodany + if (tmpKlaster == 0) + { + return 2; //Nie można byÅ‚o przydzielić kolejnego klastra + } + fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek nowego klastra + } + + *(fd->Wsk) = znak; //Zapis bajtu do pliku + + fd->IndLo++; //ZwiÄ™kszanie indeksu odczytu/zapisu + if (fd->IndLo == 0) //JeÅ›li ma on wartość 0, to oznacza to, że czÅ‚y klaster jest zapisany + fd->IndHi++; //Należy zwiÄ™kszyć bardziej znaczÄ…cy bajt indeksu. Nie utworzono nowego klastra, zatem nie uaktualniamy wskaźnika + else //Wziąż dziaÅ‚amy na tym samym klastrze. + fd->Wsk++; //Można uaktualnić wskaźnik + + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru + return 0; +} + +uint8_t ramDyskCzytajBajtZPliku(struct ramPlikFd *fd, uint8_t *bajt) +{ + if (wObrebiePliku(fd) != 0) //Sprawdzanie, czy jesteÅ›my w obrÄ™bie pliku + return 1; //1 - eof + + if (fd->IndLo == 0) //Sprawdzanie, czy dziaÅ‚amy na poczÄ…tku nowego klastra + { + uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + fd->Wsk = dataPtr(nrKlastra, 0); //Ustawianie wskaźnika na poczÄ…tek nowego klastra + } + + *bajt = *(fd->Wsk); //Odczyt z pliku + fd->IndLo++; //ZwiÄ™kszenie indeksu o 1 + if (fd->IndLo == 0) //Sprawdzamy, czy przeszliÅ›my do nowego klastra + fd->IndHi++; //Tak: uaktualniamy liczbÄ™ przeskokół wzglÄ™dem pierwszego klastra (bardziej znaczÄ…cy bajt indeksu) + else //DziaÅ‚amy na tym samym klastrze + fd->Wsk++; //Uaktualniamy wskaźnik do tego klastra + return 0; +} + +uint8_t ramDyskZapiszBlokDoPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) +{ + if (fd->wpis->pierwszyKlaster == 0) + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + + uint16_t dlBloku = 256 - fd->IndLo; //Obliczanie liczby bajtów, jakÄ… da siÄ™ zapisać w aktualnym klastrze + uint16_t doZapisu = *dlugosc; + *dlugosc = 0; //Jak do tÄ…d jeszcze nic nie zapisano + uint8_t tmpKlaster = 0; + while (doZapisu > 0) + { + if (fd->IndLo == 0) //JeÅ›li indeks pokazuje na poczÄ…tek klastra, to należy odczytać jego numer oraz ustawić na niego wskaźnik + { + if (tmpKlaster == 0) //Pierwsza operacja zapisu, nie odczytano jeszcze numeru klastra + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Odczyt numeru klastra na podstawie informacji o liczbie przeskoków od pierwszego + else //Znamy poprzedni klaster + tmpKlaster = nastepnyKlaster(tmpKlaster); //Wystarczy przejść do nastÄ™pnego + if (tmpKlaster == 0) //Sprawdzanie, czy udaÅ‚o siÄ™ znaleźć klaster + return 1; //1 - Brak wolnego klastra + + fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek klastra. Teraz można do niego już pisać + } + if (doZapisu > dlBloku) //Sprawdzanie, czy wszystko uda siÄ™ zapisać w bieżącym klastrze + { //Nie uda siÄ™, teraz zapiszemy caÅ‚y klastr do koÅ„ca + memcpy(fd->Wsk, znaki, dlBloku); //Zapis do koÅ„ca aktualnego klastra + znaki +=dlBloku; + fd->IndLo = 0; //Mniej znaczÄ…cy bajt odczytu wskazuje na poczÄ…tek nowego klastra. Kolejna iteracja go utworzy + doZapisu -= dlBloku; //Uaktualnianie informacji o liczbie bajtów jaka pozostaÅ‚Ä… do zapisujemy + *dlugosc += dlBloku; //Uaktualnianie informacji o liczbie zapisanych danych + fd->IndHi++; //Ustawienie bardziej znaczÄ…cego bajtu indeksu. Oznacza to przejÅ›cie do kolejnego klastra + dlBloku = 256; //Do nastÄ™pnego klastra możemy zapisać do 256 bajtów + } + else //Jest to ostatni zapis. CaÅ‚e dane zostanÄ… skopiowane + { + memcpy(fd->Wsk, znaki, doZapisu); //Ostatnia operacja zapisu do klasrta. + fd->IndLo += doZapisu; //Uaktualnianie indeksu (wystarczy uaktualnić mneij znaczÄ…cy bajt). + *dlugosc += doZapisu; //Uaktualnianie informacji o liczbie zapisanych danych. + doZapisu = 0; //Równie dobrze można tutaj wstawić break; + fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce klastra. + } + } + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + return 0; +} + +uint8_t ramDyskCzytajBlokZPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) +{ + if (fd->wpis->pierwszyKlaster == 0) + { + *dlugosc = 0; + return 1; //1 - Plik jest pusty + } + if (wObrebiePliku(fd) != 0) + { + *dlugosc = 0; + return 2; //2 - Źle ustawiony indeks odczytu/zapisu (poza obszarem pliku) + } + + uint16_t lDanych = (fd->wpis->rozmiarHi - fd->IndHi); + lDanych +=fd->wpis->rozmiarLo; //Obliczanie liczby bajtów jaka zostaÅ‚Ä… zapisana jeszcze za wskaźnikiem. + lDanych -=fd->IndLo; //Na podstawie wczeÅ›niej sprawdzonych warunków jest to zawsze liczba dodatnia + + uint16_t doOdczytania = (lDanych < *dlugosc)? //Sprawdzenie liczby zapisanych bajtół w pliku i okreÅ›lenie ile bajtów zdoÅ‚a siÄ™ odczytać + lDanych : //W pliku jest mniej bajtów do odczytu niż chcemy odczytać + *dlugosc; //W pliku jest wiÄ™cej bajtów niż chcemy odczytać + *dlugosc = 0; //Jak do tÄ…d odczytano 0 bajtów + uint16_t dlBloku = 256 - fd->IndLo; //OkreÅ›lanie liczby bajtół jaka zostaÅ‚Ä… do koÅ„ca aktualnego klastra` + uint8_t tmpKlaster = 0; + while (doOdczytania > 0) + { + if (fd->IndLo == 0) //Indeks odczytu wskazuje na poczÄ…tek klastra. Oznacza to, że wskaźnik nie jest jeszcze ustawiony + { //Bardziej znaczÄ…cy bajt indeksu okreÅ›la o ile klastrów (od poczÄ…tkowego) należy siÄ™ przesunąć do przodu + if (tmpKlaster == 0) + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + else + tmpKlaster = nastepnyKlaster(tmpKlaster); + if (tmpKlaster != 0) //JeÅ›li znaleziono odpowiedni klaster, to + fd->Wsk = dataPtr(tmpKlaster, 0); //przestaw wskaźnik na poczÄ…tek tego klastra + else + return 3; //3 - Nie udaÅ‚o siÄ™ znaleźć odpowiedniego klastra + } + + if (doOdczytania > dlBloku) //Odczyt do koÅ„ca zawartoÅ›ci klastra + { //dlBloku okreÅ›la ile zostaÅ‚o jeszcze bajtów do koÅ„ca klasrta + memcpy(znaki, fd->Wsk, dlBloku); //Odczyt zawartoÅ›ci Klastra + znaki +=dlBloku; //Przestawienie wskaźnika do tablicy, w której zapisujemy odczytane bajty + fd->IndLo = 0; //Indeks wskazuje na poczÄ…tek nowego klastra + fd->IndHi++; //Bardziej znaczÄ…cy bajt okreÅ›la zmianÄ™ klastra. Teraz nie ma potrzeby ustawienia wskaźnika odczytu na jego poczÄ…tek + doOdczytania -= dlBloku; //Uaktualnienie liczby bajtół jakÄ… należy odczytać + *dlugosc += dlBloku; //Uaktualnienie + dlBloku = 256; //Kolejny dostÄ™pny blok do odczytania, to dÅ‚ugość caÅ‚ego klastra. + } + else //Ostatnia operacja odczytu + { + memcpy(znaki, fd->Wsk, doOdczytania); + fd->Wsk += doOdczytania; //Po zakoÅ„czeniu operacji odczytu nadal dziaÅ‚amy w tym samym klastrze, zatem trzeba teraz uaktualnić wzkaźnik + fd->IndLo += doOdczytania; //Uaktualnianie indeksu. JesteÅ›my w tym samym klastrze, zatem nie trzeba zmieniać IndHi + *dlugosc += doOdczytania; //Uaktualnianie liczby odczytanych bajtów + doOdczytania = 0; //Tutaj równie dobrze może być brake + } + } + return 0; +} + +uint8_t ramDyskUstawWskaznik(struct ramPlikFd *fd, uint16_t indeks) +{ + if (indeks == 0) //Sprawdzanie, czy wskaźnik nie pokazuje na poczÄ…tek pliku. + { //JeÅ›li tak, to nie ma potzeby tworzenia klastrów. Plik może nadal nei mieć żadnego klastra. + fd->IndLo = 0; //Ustawianie na 0 indeksów (mniej i bardziej znaczÄ…cego bajtu) + fd->IndHi = 0; + return 0; + } + indeks--; //Zmniejszamy indeks o 1, by odpowiednio ustawić rozmair pliku. + //JeÅ›li indeks jest wiÄ™kszy niż rozmiar pliku, to plik zostanie rozciÄ…gniÄ™ty do zadanej wartoÅ›ci indeksu -1 + + if (fd->wpis->pierwszyKlaster == 0) //Sprawdzanie, czy plik ma już przydzielony pierwszy klaster + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); //Przydzielanie pierwszego klastra dla pliku. Jest to konieczne, ponieważ klaster ma wartość niezerowÄ… + + uint8_t klasterN = indeks >> 8; //Obliczanie liczby klastrów, jakÄ… należy dodać do pierwszego klastra` + + fd->IndLo = indeks & 0xFF; //Obliczanie na podstawie wartoÅ›ci 16 mniej znaczÄ…cego bajtu indeksu pomniejszonej o 1 + fd->IndHi = klasterN; //oraz bardziej znaczÄ…cego bajtu indeksu w deskryptorze. + + uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, klasterN); + if (nrKlastra == 0) + return 1; //Brak klastrów + + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + + fd->IndLo++; //Powrót do zadanej wartoÅ›ci indeksu + if (fd->IndLo == 0) //JeÅ›li jesteÅ›my na poczÄ…tku klastra, to jeszcze on nie iestnieje + fd->IndHi++; //Uaktualniamy tylko bardziej znaczÄ…cy bajt indeksu + else //JesteÅ›my w obszarze utworzonego klastra, można uaktualnić wskaźnik + fd->Wsk=dataPtr(nrKlastra, fd->IndLo); //ustawić wskaźnik na odpowiednie miejsce klastra + + return 0; +} + +uint8_t ramDyskUstawWskaznikNaKoniec(struct ramPlikFd *fd) +{ + if (fd == NULL) + return 1; + fd->IndLo = fd->wpis->rozmiarLo; + fd->IndHi = fd->wpis->rozmiarHi; +// fd->IndLo++; + uint8_t tmpKlaster = 0; + if (fd->IndLo != 0) + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->wpis->rozmiarHi); + fd->Wsk=dataPtr(tmpKlaster, fd->IndLo); + } + return 0; +} + +uint8_t* ramDyskDodajBlokXmodem(struct ramPlikFd *fd, uint16_t nrBloku) +{ + if (nrBloku == 0) + return NULL; + nrBloku --; + + uint8_t indHi = (uint8_t)(nrBloku / 2); + //uint8_t indLo = 0; + uint8_t *wynik; + + if (fd->wpis->pierwszyKlaster == 0) + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + if (fd->wpis->pierwszyKlaster == 0) + return NULL; + + uint8_t tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster , indHi); + if (tmpKlaster == 0) + return NULL; + if ((nrBloku & 0x0001) == 0x0001) // Druga część klastra + { + //indLo = 128; + if (fd->wpis->rozmiarHi <= indHi) + { + fd->wpis->rozmiarHi = indHi+1; + fd->wpis->rozmiarLo = 0; + } + wynik=dataPtr(tmpKlaster, 128); + } + else + { + if (fd->wpis->rozmiarHi < indHi) + { + fd->wpis->rozmiarHi = indHi; + fd->wpis->rozmiarLo = 128; + } + else if ((fd->wpis->rozmiarHi == indHi) && (fd->wpis->rozmiarLo < 128)) + fd->wpis->rozmiarLo = 128; + + wynik=dataPtr(tmpKlaster, 0); + } + return wynik; +} + +void ramDyskDir(FILE *ostream) +{ + fprintf(ostream, "nazwa\t\trozmiar\totwarty\r\n"); + struct ramPlik *plik; + uint8_t tmpKlaster = 0; + uint8_t tmpKlaster2; + uint8_t tmp, tmp2, tmp3; + do + { + plik = (struct ramPlik *)(dataPtr(tmpKlaster, 0)); + for (tmp=0; tmp<16; tmp++) + { + tmp3=plik->nazwa[0]; + if (tmp3 == 0) + break; //Ten wpis jest pusty. + fputc(tmp3 , ostream); + for (tmp2=1; tmp2<8; tmp2++) + { + if (tmp3 != 0) + tmp3=plik->nazwa[tmp2]; + + if (tmp3 != 0) + fputc(tmp3 , ostream); + else + fputc(' ' , ostream); + } + fprintf(ostream, "\t%d\t%d\r\n", 256*plik->rozmiarHi+plik->rozmiarLo, plik->lAktOtw); + plik++; + } + tmpKlaster2 = tmpKlaster; + tmpKlaster = klastry[tmpKlaster]; + } + while (tmpKlaster != tmpKlaster2); +} + +uint8_t ramDyskLiczbaWolnychKlastrow(void) +{ + uint8_t wynik=0; + uint8_t temp; + for (temp = L_KLASTROW-1; temp > 0; temp--) + if (klastry[temp] == 0) + wynik++; + return wynik; +} + + +static int getSTD(FILE *stream) +{ + uint8_t wynik; + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + + if (ramDyskCzytajBajtZPliku(fd, &wynik) == 0) + return wynik; + return EOF; +} + +static int putSTD(char c, FILE *stream) +{ + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + return ramDyskZapiszBajtDoPliku(fd, c); +} + +uint8_t ramDyskOtworzPlikStdIo(const char *nazwa, struct ramPlikFd *fd, FILE *stream, uint8_t flags) +{ + uint8_t wynik = ramDyskOtworzPlik(nazwa, fd); + if (wynik != 0) + return wynik; + + fdev_setup_stream(stream, putSTD, getSTD, flags); + fdev_set_udata(stream, fd); + return 0; +} + +uint8_t ramDyskZamknijPlikStdIo(FILE *stream) +{ + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + ramDyskZamknijPlik(fd); + fclose(stream); + return fd->wpis->lAktOtw; +} diff --git a/Lib/ramdysk.lst b/Lib/ramdysk.lst new file mode 100644 index 0000000..78461ae --- /dev/null +++ b/Lib/ramdysk.lst @@ -0,0 +1,2917 @@ + 1 .file "ramdysk.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 uaktualnijRozmiarPliku: + 276 .stabd 46,0,0 + 1:../../../../Lib/ramdysk.c **** #include "ramdysk.h" + 2:../../../../Lib/ramdysk.c **** #include + 3:../../../../Lib/ramdysk.c **** + 4:../../../../Lib/ramdysk.c **** #define systemTime() 0; //Dodać w pliku hardware.h funkcje do odczytu czasu systemowego + 5:../../../../Lib/ramdysk.c **** + 6:../../../../Lib/ramdysk.c **** static uint8_t znajdzWolnyKlaster(void); + 7:../../../../Lib/ramdysk.c **** static uint8_t nastepnyKlaster(uint8_t nrKlastra); + 8:../../../../Lib/ramdysk.c **** static uint8_t znajdzKlasterN(uint8_t nrPierwszegoKlastra, uint8_t lPrzeskokow); + 9:../../../../Lib/ramdysk.c **** #if ( USUNKLASTER == 1) + 10:../../../../Lib/ramdysk.c **** static uint8_t usunKlaster(uint8_t nrKlastra); + 11:../../../../Lib/ramdysk.c **** #endif + 12:../../../../Lib/ramdysk.c **** static uint8_t wObrebiePliku(struct ramPlikFd *fd); + 13:../../../../Lib/ramdysk.c **** static void uaktualnijRozmiarPliku(struct ramPlikFd *fd); + 14:../../../../Lib/ramdysk.c **** static struct ramPlik* znajdzPlik(const char *nazwa); + 15:../../../../Lib/ramdysk.c **** static struct ramPlik* znajdzMiejsceNaWpis(void); + 16:../../../../Lib/ramdysk.c **** static void czyscKlaster(uint8_t nrKlastra); + 17:../../../../Lib/ramdysk.c **** + 18:../../../../Lib/ramdysk.c **** static void czyscKlaster(uint8_t nrKlastra) + 19:../../../../Lib/ramdysk.c **** { + 20:../../../../Lib/ramdysk.c **** uint8_t *tmpPtr = dataPtr(nrKlastra, 0); + 21:../../../../Lib/ramdysk.c **** memset (tmpPtr, 0, 256); + 22:../../../../Lib/ramdysk.c **** } + 23:../../../../Lib/ramdysk.c **** + 24:../../../../Lib/ramdysk.c **** static uint8_t wObrebiePliku(struct ramPlikFd *fd) + 25:../../../../Lib/ramdysk.c **** { + 26:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarHi > fd->IndHi) + 27:../../../../Lib/ramdysk.c **** return 0; + 28:../../../../Lib/ramdysk.c **** + 29:../../../../Lib/ramdysk.c **** if ((fd->wpis->rozmiarHi == fd->IndHi) && (fd->wpis->rozmiarLo >= fd->IndLo)) + 30:../../../../Lib/ramdysk.c **** return 0; + 31:../../../../Lib/ramdysk.c **** + 32:../../../../Lib/ramdysk.c **** return 1; + 33:../../../../Lib/ramdysk.c **** } + 34:../../../../Lib/ramdysk.c **** + 35:../../../../Lib/ramdysk.c **** static void uaktualnijRozmiarPliku(struct ramPlikFd *fd) + 36:../../../../Lib/ramdysk.c **** { + 278 .LM0: + 279 .LFBB1: + 280 /* prologue: function */ + 281 /* frame size = 0 */ + 282 /* stack size = 0 */ + 283 .L__stack_usage = 0 + 284 0000 FC01 movw r30,r24 + 37:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarHi == fd->IndHi) + 286 .LM1: + 287 0002 A481 ldd r26,Z+4 + 288 0004 B581 ldd r27,Z+5 + 289 0006 1296 adiw r26,2 + 290 0008 9C91 ld r25,X + 291 000a 1297 sbiw r26,2 + 292 000c 8381 ldd r24,Z+3 + 293 000e 9813 cpse r25,r24 + 294 0010 00C0 rjmp .L2 + 38:../../../../Lib/ramdysk.c **** { + 39:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarLo < fd->IndLo) + 296 .LM2: + 297 0012 8281 ldd r24,Z+2 + 298 0014 1196 adiw r26,1 + 299 0016 9C91 ld r25,X + 300 0018 1197 sbiw r26,1 + 301 001a 9817 cp r25,r24 + 302 001c 00F4 brsh .L2 + 40:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = fd->IndLo; + 304 .LM3: + 305 001e 1196 adiw r26,1 + 306 0020 8C93 st X,r24 + 307 .L2: + 41:../../../../Lib/ramdysk.c **** } + 42:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarHi < fd->IndHi) + 309 .LM4: + 310 0022 A481 ldd r26,Z+4 + 311 0024 B581 ldd r27,Z+5 + 312 0026 1296 adiw r26,2 + 313 0028 9C91 ld r25,X + 314 002a 1297 sbiw r26,2 + 315 002c 8381 ldd r24,Z+3 + 316 002e 9817 cp r25,r24 + 317 0030 00F4 brsh .L1 + 43:../../../../Lib/ramdysk.c **** { + 44:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = fd->IndLo; + 319 .LM5: + 320 0032 8281 ldd r24,Z+2 + 321 0034 1196 adiw r26,1 + 322 0036 8C93 st X,r24 + 45:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarHi = fd->IndHi; + 324 .LM6: + 325 0038 A481 ldd r26,Z+4 + 326 003a B581 ldd r27,Z+5 + 327 003c 8381 ldd r24,Z+3 + 328 003e 1296 adiw r26,2 + 329 0040 8C93 st X,r24 + 330 .L1: + 331 0042 0895 ret + 333 .Lscope1: + 335 .stabd 78,0,0 + 339 nastepnyKlaster: + 340 .stabd 46,0,0 + 46:../../../../Lib/ramdysk.c **** } + 47:../../../../Lib/ramdysk.c **** } + 48:../../../../Lib/ramdysk.c **** + 49:../../../../Lib/ramdysk.c **** static uint8_t znajdzWolnyKlaster(void) + 50:../../../../Lib/ramdysk.c **** { + 51:../../../../Lib/ramdysk.c **** uint8_t i; + 52:../../../../Lib/ramdysk.c **** for (i=1; i 8) + 121:../../../../Lib/ramdysk.c **** dlNazwy = 8; + 122:../../../../Lib/ramdysk.c **** + 123:../../../../Lib/ramdysk.c **** + 124:../../../../Lib/ramdysk.c **** if (nazwa[dlNazwy-1] == 0) + 512 .LM25: + 513 00e6 D701 movw r26,r14 + 514 00e8 AE0F add r26,r30 + 515 00ea B11D adc r27,__zero_reg__ + 516 00ec 1197 sbiw r26,1 + 517 00ee 8C91 ld r24,X + 518 00f0 8111 cpse r24,__zero_reg__ + 519 00f2 00C0 rjmp .L20 + 125:../../../../Lib/ramdysk.c **** dlNazwy--; //Nie sprawdzamy czy string koÅ„czy siÄ™ /0 + 521 .LM26: + 522 00f4 E150 subi r30,lo8(-(-1)) + 523 .L20: + 524 00f6 D701 movw r26,r14 + 525 00f8 1196 adiw r26,1 + 126:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 127:../../../../Lib/ramdysk.c **** uint8_t temp; + 128:../../../../Lib/ramdysk.c **** uint8_t tempKlaster=0; + 129:../../../../Lib/ramdysk.c **** uint8_t tempKlaster2; + 130:../../../../Lib/ramdysk.c **** + 131:../../../../Lib/ramdysk.c **** for (temp=1; temp < dlNazwy; temp ++) + 527 .LM27: + 528 00fa 81E0 ldi r24,lo8(1) + 529 .L21: + 531 .LM28: + 532 00fc 8E17 cp r24,r30 + 533 00fe 00F4 brsh .L32 + 132:../../../../Lib/ramdysk.c **** { + 133:../../../../Lib/ramdysk.c **** if (nazwa[temp] == ' ') //Pozbycie sie spacji + 535 .LM29: + 536 0100 9D91 ld r25,X+ + 537 0102 9032 cpi r25,lo8(32) + 538 0104 01F0 breq .L27 + 131:../../../../Lib/ramdysk.c **** { + 540 .LM30: + 541 0106 8F5F subi r24,lo8(-(1)) + 542 0108 00C0 rjmp .L21 + 543 .L32: + 134:../../../../Lib/ramdysk.c **** { + 135:../../../../Lib/ramdysk.c **** dlNazwy = temp; + 136:../../../../Lib/ramdysk.c **** break; + 137:../../../../Lib/ramdysk.c **** } + 138:../../../../Lib/ramdysk.c **** } + 139:../../../../Lib/ramdysk.c **** if (dlNazwy == 0) + 545 .LM31: + 546 010a E111 cpse r30,__zero_reg__ + 547 010c 00C0 rjmp .L22 + 548 010e 00C0 rjmp .L28 + 549 .L27: + 550 0110 E82F mov r30,r24 + 551 .L22: + 552 0112 B12C mov r11,__zero_reg__ + 140:../../../../Lib/ramdysk.c **** return NULL; + 141:../../../../Lib/ramdysk.c **** + 142:../../../../Lib/ramdysk.c **** do + 143:../../../../Lib/ramdysk.c **** { + 144:../../../../Lib/ramdysk.c **** plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w kla + 145:../../../../Lib/ramdysk.c **** for (temp=0; temp <16; temp++) + 146:../../../../Lib/ramdysk.c **** { + 147:../../../../Lib/ramdysk.c **** if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + 554 .LM32: + 555 0114 CE2F mov r28,r30 + 556 0116 D0E0 ldi r29,0 + 557 .L26: + 144:../../../../Lib/ramdysk.c **** for (temp=0; temp <16; temp++) + 559 .LM33: + 560 0118 CB2C mov r12,r11 + 561 011a D12C mov r13,__zero_reg__ + 562 011c 8601 movw r16,r12 + 563 011e 0058 subi r16,-128 + 564 0120 1F4F sbci r17,-1 + 565 0122 102F mov r17,r16 + 566 0124 0027 clr r16 + 567 0126 4801 movw r8,r16 + 568 0128 9394 inc r9 + 569 .L25: + 571 .LM34: + 572 012a AE01 movw r20,r28 + 573 012c B801 movw r22,r16 + 574 012e 6C5F subi r22,-4 + 575 0130 7F4F sbci r23,-1 + 576 0132 C701 movw r24,r14 + 577 0134 0E94 0000 call strncmp + 578 0138 892B or r24,r25 + 579 013a 01F0 breq .L29 + 148:../../../../Lib/ramdysk.c **** return plik; + 149:../../../../Lib/ramdysk.c **** plik++; //PrzejÅ›cie do kolejnego wpisu (w tym sam + 581 .LM35: + 582 013c 005F subi r16,-16 + 583 013e 1F4F sbci r17,-1 + 145:../../../../Lib/ramdysk.c **** { + 585 .LM36: + 586 0140 0815 cp r16,r8 + 587 0142 1905 cpc r17,r9 + 588 0144 01F4 brne .L25 + 150:../../../../Lib/ramdysk.c **** } + 151:../../../../Lib/ramdysk.c **** tempKlaster2 = tempKlaster; + 152:../../../../Lib/ramdysk.c **** tempKlaster = klastry[tempKlaster]; + 590 .LM37: + 591 0146 F601 movw r30,r12 + 592 0148 E050 subi r30,lo8(-(klastry)) + 593 014a F040 sbci r31,hi8(-(klastry)) + 594 014c 8081 ld r24,Z + 153:../../../../Lib/ramdysk.c **** } + 154:../../../../Lib/ramdysk.c **** while (tempKlaster2 != tempKlaster); + 596 .LM38: + 597 014e B816 cp r11,r24 + 598 0150 01F0 breq .L28 + 599 0152 B82E mov r11,r24 + 600 0154 00C0 rjmp .L26 + 601 .L28: + 140:../../../../Lib/ramdysk.c **** + 603 .LM39: + 604 0156 80E0 ldi r24,0 + 605 0158 90E0 ldi r25,0 + 606 015a 00C0 rjmp .L24 + 607 .L29: + 148:../../../../Lib/ramdysk.c **** plik++; //PrzejÅ›cie do kolejnego wpisu (w tym sam + 609 .LM40: + 610 015c C801 movw r24,r16 + 611 .L24: + 612 /* epilogue start */ + 155:../../../../Lib/ramdysk.c **** return NULL; + 156:../../../../Lib/ramdysk.c **** } + 614 .LM41: + 615 015e DF91 pop r29 + 616 0160 CF91 pop r28 + 617 0162 1F91 pop r17 + 618 0164 0F91 pop r16 + 619 0166 FF90 pop r15 + 620 0168 EF90 pop r14 + 621 016a DF90 pop r13 + 622 016c CF90 pop r12 + 623 016e BF90 pop r11 + 624 0170 9F90 pop r9 + 625 0172 8F90 pop r8 + 626 0174 0895 ret + 631 .Lscope4: + 633 .stabd 78,0,0 + 636 znajdzWolnyKlaster: + 637 .stabd 46,0,0 + 50:../../../../Lib/ramdysk.c **** uint8_t i; + 639 .LM42: + 640 .LFBB5: + 641 /* prologue: function */ + 642 /* frame size = 0 */ + 643 /* stack size = 0 */ + 644 .L__stack_usage = 0 + 52:../../../../Lib/ramdysk.c **** { //Może być rozszerzony na inne klastry. + 646 .LM43: + 647 0176 81E0 ldi r24,lo8(1) + 648 0178 90E0 ldi r25,0 + 649 .L34: + 52:../../../../Lib/ramdysk.c **** { //Może być rozszerzony na inne klastry. + 651 .LM44: + 652 017a 8038 cpi r24,-128 + 653 017c 9105 cpc r25,__zero_reg__ + 654 017e 01F0 breq .L38 + 655 0180 9C01 movw r18,r24 + 656 0182 2F5F subi r18,-1 + 657 0184 3F4F sbci r19,-1 + 658 0186 FC01 movw r30,r24 + 659 0188 E050 subi r30,lo8(-(klastry)) + 660 018a F040 sbci r31,hi8(-(klastry)) + 54:../../../../Lib/ramdysk.c **** { + 662 .LM45: + 663 018c 4081 ld r20,Z + 664 018e 4111 cpse r20,__zero_reg__ + 665 0190 00C0 rjmp .L37 + 56:../../../../Lib/ramdysk.c **** czyscKlaster(i); //Czyszczenie zawartoÅ›ci klastra. + 667 .LM46: + 668 0192 8083 st Z,r24 + 669 .LBB9: + 670 .LBB10: + 21:../../../../Lib/ramdysk.c **** } + 672 .LM47: + 673 0194 E0E0 ldi r30,0 + 674 0196 F0E8 ldi r31,lo8(-128) + 675 0198 F80F add r31,r24 + 676 019a 20E0 ldi r18,0 + 677 019c 31E0 ldi r19,lo8(1) + 678 019e DF01 movw r26,r30 + 679 01a0 A901 movw r20,r18 + 680 0: + 681 01a2 1D92 st X+,__zero_reg__ + 682 01a4 4150 subi r20,1 + 683 01a6 5040 sbci r21,0 + 684 01a8 01F4 brne 0b + 685 .LBE10: + 686 .LBE9: + 58:../../../../Lib/ramdysk.c **** } + 688 .LM48: + 689 01aa 0895 ret + 690 .L37: + 691 01ac C901 movw r24,r18 + 692 01ae 00C0 rjmp .L34 + 693 .L38: + 61:../../../../Lib/ramdysk.c **** } + 695 .LM49: + 696 01b0 80E0 ldi r24,0 + 62:../../../../Lib/ramdysk.c **** + 698 .LM50: + 699 01b2 0895 ret + 701 .Lscope5: + 703 .stabd 78,0,0 + 705 .global ramDyskInit + 707 ramDyskInit: + 708 .stabd 46,0,0 + 157:../../../../Lib/ramdysk.c **** + 158:../../../../Lib/ramdysk.c **** static struct ramPlik* znajdzMiejsceNaWpis(void) + 159:../../../../Lib/ramdysk.c **** { + 160:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 161:../../../../Lib/ramdysk.c **** uint8_t temp; + 162:../../../../Lib/ramdysk.c **** uint8_t tempKlaster=0; //Przeszukiwanie głównego wpisu katalogo + 163:../../../../Lib/ramdysk.c **** uint8_t tempKlaster2; //Przeszukiwanie głównego wpisu katalogo + 164:../../../../Lib/ramdysk.c **** do + 165:../../../../Lib/ramdysk.c **** { + 166:../../../../Lib/ramdysk.c **** plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w kla + 167:../../../../Lib/ramdysk.c **** for (temp=0; temp <16; temp++) + 168:../../../../Lib/ramdysk.c **** { + 169:../../../../Lib/ramdysk.c **** if (plik->nazwa[0] == 0) + 170:../../../../Lib/ramdysk.c **** return plik; + 171:../../../../Lib/ramdysk.c **** plik++; //PrzejÅ›cie do kolejnego wpisu (w tym sam + 172:../../../../Lib/ramdysk.c **** } + 173:../../../../Lib/ramdysk.c **** tempKlaster2 = tempKlaster; + 174:../../../../Lib/ramdysk.c **** tempKlaster = klastry[tempKlaster]; + 175:../../../../Lib/ramdysk.c **** } + 176:../../../../Lib/ramdysk.c **** while (tempKlaster2 != tempKlaster); + 177:../../../../Lib/ramdysk.c **** + 178:../../../../Lib/ramdysk.c **** klastry[tempKlaster] = znajdzWolnyKlaster(); + 179:../../../../Lib/ramdysk.c **** plik = NULL; + 180:../../../../Lib/ramdysk.c **** if (klastry[tempKlaster] != 0) + 181:../../../../Lib/ramdysk.c **** plik = (struct ramPlik*) (dataPtr(klastry[tempKlaster], 0)); + 182:../../../../Lib/ramdysk.c **** + 183:../../../../Lib/ramdysk.c **** return plik; + 184:../../../../Lib/ramdysk.c **** } + 185:../../../../Lib/ramdysk.c **** + 186:../../../../Lib/ramdysk.c **** + 187:../../../../Lib/ramdysk.c **** void ramDyskInit(void) + 188:../../../../Lib/ramdysk.c **** { + 710 .LM51: + 711 .LFBB6: + 712 /* prologue: function */ + 713 /* frame size = 0 */ + 714 /* stack size = 0 */ + 715 .L__stack_usage = 0 + 189:../../../../Lib/ramdysk.c **** memset (klastry, 0, 128); //Czyszczenie tablicy klastrów (wszystkie sÄ… puste) + 717 .LM52: + 718 01b4 80E8 ldi r24,lo8(-128) + 719 01b6 E0E0 ldi r30,lo8(klastry) + 720 01b8 F0E0 ldi r31,hi8(klastry) + 721 01ba DF01 movw r26,r30 + 722 0: + 723 01bc 1D92 st X+,__zero_reg__ + 724 01be 8A95 dec r24 + 725 01c0 01F4 brne 0b + 190:../../../../Lib/ramdysk.c **** memset (dataPtr(0,0), 0, 256); //Czyszczenie zerowego klastra z tablicÄ… plików + 727 .LM53: + 728 01c2 80E0 ldi r24,0 + 729 01c4 91E0 ldi r25,lo8(1) + 730 01c6 E0E0 ldi r30,0 + 731 01c8 F0E8 ldi r31,lo8(-128) + 732 01ca DF01 movw r26,r30 + 733 01cc 9C01 movw r18,r24 + 734 0: + 735 01ce 1D92 st X+,__zero_reg__ + 736 01d0 2150 subi r18,1 + 737 01d2 3040 sbci r19,0 + 738 01d4 01F4 brne 0b + 739 01d6 0895 ret + 741 .Lscope6: + 743 .stabd 78,0,0 + 746 .global ramDyskUtworzPlik + 748 ramDyskUtworzPlik: + 749 .stabd 46,0,0 + 191:../../../../Lib/ramdysk.c **** } + 192:../../../../Lib/ramdysk.c **** uint8_t ramDyskUtworzPlik(const char *nazwa) + 193:../../../../Lib/ramdysk.c **** { //Nowo utworzony plik nie zajmuje żadnego klastra + 751 .LM54: + 752 .LFBB7: + 753 01d8 FF92 push r15 + 754 01da 0F93 push r16 + 755 01dc 1F93 push r17 + 756 01de CF93 push r28 + 757 01e0 DF93 push r29 + 758 /* prologue: function */ + 759 /* frame size = 0 */ + 760 /* stack size = 5 */ + 761 .L__stack_usage = 5 + 762 01e2 8C01 movw r16,r24 + 194:../../../../Lib/ramdysk.c **** uint8_t dlNazwy = strlen(nazwa); + 764 .LM55: + 765 01e4 FC01 movw r30,r24 + 766 0: + 767 01e6 0190 ld __tmp_reg__,Z+ + 768 01e8 0020 tst __tmp_reg__ + 769 01ea 01F4 brne 0b + 770 01ec 3197 sbiw r30,1 + 771 01ee FE2E mov r15,r30 + 772 01f0 F81A sub r15,r24 + 773 01f2 88E0 ldi r24,lo8(8) + 774 01f4 8F15 cp r24,r15 + 775 01f6 00F4 brsh .L41 + 776 01f8 58E0 ldi r21,lo8(8) + 777 01fa F52E mov r15,r21 + 778 .L41: + 779 01fc 902F mov r25,r16 + 195:../../../../Lib/ramdysk.c **** uint8_t i; + 196:../../../../Lib/ramdysk.c **** if (dlNazwy > 8) + 197:../../../../Lib/ramdysk.c **** dlNazwy = 8; + 198:../../../../Lib/ramdysk.c **** + 199:../../../../Lib/ramdysk.c **** for (i=0; inazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + 219:../../../../Lib/ramdysk.c **** plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + 220:../../../../Lib/ramdysk.c **** return 0; + 221:../../../../Lib/ramdysk.c **** } + 222:../../../../Lib/ramdysk.c **** return 1; + 864 .LM68: + 865 0264 81E0 ldi r24,lo8(1) + 866 0266 00C0 rjmp .L45 + 867 .L49: + 868 .LBB16: + 869 .LBB15: + 181:../../../../Lib/ramdysk.c **** + 871 .LM69: + 872 0268 90E0 ldi r25,0 + 873 026a C92F mov r28,r25 + 874 026c D0E8 ldi r29,lo8(-128) + 875 026e D80F add r29,r24 + 876 .L46: + 877 .LBE15: + 878 .LBE16: + 215:../../../../Lib/ramdysk.c **** { + 880 .LM70: + 881 0270 2097 sbiw r28,0 + 882 0272 01F0 breq .L50 + 217:../../../../Lib/ramdysk.c **** strncpy(plik->nazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + 884 .LM71: + 885 0274 8CE0 ldi r24,lo8(12) + 886 0276 FE01 movw r30,r28 + 887 0: + 888 0278 1192 st Z+,__zero_reg__ + 889 027a 8A95 dec r24 + 890 027c 01F4 brne 0b + 218:../../../../Lib/ramdysk.c **** plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + 892 .LM72: + 893 027e 4F2D mov r20,r15 + 894 0280 50E0 ldi r21,0 + 895 0282 B801 movw r22,r16 + 896 0284 CE01 movw r24,r28 + 897 0286 0496 adiw r24,4 + 898 0288 0E94 0000 call strncpy + 219:../../../../Lib/ramdysk.c **** return 0; + 900 .LM73: + 901 028c 1C86 std Y+12,__zero_reg__ + 902 028e 1D86 std Y+13,__zero_reg__ + 903 0290 1E86 std Y+14,__zero_reg__ + 904 0292 1F86 std Y+15,__zero_reg__ + 905 .L53: + 207:../../../../Lib/ramdysk.c **** + 907 .LM74: + 908 0294 80E0 ldi r24,0 + 909 .L45: + 910 /* epilogue start */ + 223:../../../../Lib/ramdysk.c **** } + 912 .LM75: + 913 0296 DF91 pop r29 + 914 0298 CF91 pop r28 + 915 029a 1F91 pop r17 + 916 029c 0F91 pop r16 + 917 029e FF90 pop r15 + 918 02a0 0895 ret + 920 .Lscope7: + 922 .stabd 78,0,0 + 926 .global ramDyskOtworzPlik + 928 ramDyskOtworzPlik: + 929 .stabd 46,0,0 + 224:../../../../Lib/ramdysk.c **** + 225:../../../../Lib/ramdysk.c **** uint8_t ramDyskOtworzPlik(const char *nazwa, struct ramPlikFd *fd) + 226:../../../../Lib/ramdysk.c **** { + 931 .LM76: + 932 .LFBB8: + 933 02a2 CF93 push r28 + 934 02a4 DF93 push r29 + 935 /* prologue: function */ + 936 /* frame size = 0 */ + 937 /* stack size = 2 */ + 938 .L__stack_usage = 2 + 939 02a6 EB01 movw r28,r22 + 227:../../../../Lib/ramdysk.c **** uint8_t wynik = 1; + 228:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 229:../../../../Lib/ramdysk.c **** if ((plik = znajdzPlik(nazwa)) != NULL) + 941 .LM77: + 942 02a8 0E94 0000 call znajdzPlik + 943 02ac 0097 sbiw r24,0 + 944 02ae 01F0 breq .L65 + 230:../../../../Lib/ramdysk.c **** { + 231:../../../../Lib/ramdysk.c **** memset(fd, 0, 3); //Zerowanie struktury deskryptora pliku + 946 .LM78: + 947 02b0 1882 st Y,__zero_reg__ + 948 02b2 1982 std Y+1,__zero_reg__ + 949 02b4 1A82 std Y+2,__zero_reg__ + 232:../../../../Lib/ramdysk.c **** fd->wpis = plik; //Ustawianie w deskryptorze wskaźnika n + 951 .LM79: + 952 02b6 9D83 std Y+5,r25 + 953 02b8 8C83 std Y+4,r24 + 233:../../../../Lib/ramdysk.c **** plik->lAktOtw++; //Uaktualnienie licznika otwarć plików + 955 .LM80: + 956 02ba FC01 movw r30,r24 + 957 02bc 2381 ldd r18,Z+3 + 958 02be 2F5F subi r18,lo8(-(1)) + 959 02c0 2383 std Z+3,r18 + 234:../../../../Lib/ramdysk.c **** wynik = 0; + 961 .LM81: + 962 02c2 80E0 ldi r24,0 + 963 02c4 00C0 rjmp .L64 + 964 .L65: + 227:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 966 .LM82: + 967 02c6 81E0 ldi r24,lo8(1) + 968 .L64: + 969 /* epilogue start */ + 235:../../../../Lib/ramdysk.c **** } + 236:../../../../Lib/ramdysk.c **** return wynik; + 237:../../../../Lib/ramdysk.c **** } + 971 .LM83: + 972 02c8 DF91 pop r29 + 973 02ca CF91 pop r28 + 974 02cc 0895 ret + 980 .Lscope8: + 982 .stabd 78,0,0 + 985 .global ramDyskUsunPlik + 987 ramDyskUsunPlik: + 988 .stabd 46,0,0 + 238:../../../../Lib/ramdysk.c **** + 239:../../../../Lib/ramdysk.c **** uint8_t ramDyskUsunPlik(const char *nazwa) + 240:../../../../Lib/ramdysk.c **** { + 990 .LM84: + 991 .LFBB9: + 992 /* prologue: function */ + 993 /* frame size = 0 */ + 994 /* stack size = 0 */ + 995 .L__stack_usage = 0 + 241:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 242:../../../../Lib/ramdysk.c **** if ((plik = znajdzPlik(nazwa)) == NULL) + 997 .LM85: + 998 02ce 0E94 0000 call znajdzPlik + 999 02d2 FC01 movw r30,r24 + 1000 02d4 892B or r24,r25 + 1001 02d6 01F0 breq .L72 + 243:../../../../Lib/ramdysk.c **** return 1; //Nie znaleziono pliku + 244:../../../../Lib/ramdysk.c **** if (plik->lAktOtw != 0) + 1003 .LM86: + 1004 02d8 8381 ldd r24,Z+3 + 1005 02da 8111 cpse r24,__zero_reg__ + 1006 02dc 00C0 rjmp .L73 + 1007 .L68: + 245:../../../../Lib/ramdysk.c **** return 2; //Plik jest otwarty + 246:../../../../Lib/ramdysk.c **** + 247:../../../../Lib/ramdysk.c **** uint8_t usuwanyKlaster; + 248:../../../../Lib/ramdysk.c **** while(plik->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ oka + 1009 .LM87: + 1010 02de 8081 ld r24,Z + 1011 02e0 8823 tst r24 + 1012 02e2 01F0 breq .L74 + 249:../../../../Lib/ramdysk.c **** { + 250:../../../../Lib/ramdysk.c **** usuwanyKlaster = plik->pierwszyKlaster; + 251:../../../../Lib/ramdysk.c **** if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostatnieg + 1014 .LM88: + 1015 02e4 A82F mov r26,r24 + 1016 02e6 B0E0 ldi r27,0 + 1017 02e8 A050 subi r26,lo8(-(klastry)) + 1018 02ea B040 sbci r27,hi8(-(klastry)) + 1019 02ec 9C91 ld r25,X + 1020 02ee 9813 cpse r25,r24 + 1021 02f0 00C0 rjmp .L69 + 252:../../../../Lib/ramdysk.c **** plik->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwanie pl + 1023 .LM89: + 1024 02f2 1082 st Z,__zero_reg__ + 1025 02f4 00C0 rjmp .L70 + 1026 .L69: + 253:../../../../Lib/ramdysk.c **** else + 254:../../../../Lib/ramdysk.c **** plik->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + 1028 .LM90: + 1029 02f6 9083 st Z,r25 + 1030 .L70: + 255:../../../../Lib/ramdysk.c **** klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + 1032 .LM91: + 1033 02f8 1C92 st X,__zero_reg__ + 1034 02fa 00C0 rjmp .L68 + 1035 .L74: + 256:../../../../Lib/ramdysk.c **** } + 257:../../../../Lib/ramdysk.c **** + 258:../../../../Lib/ramdysk.c **** memset (plik, 0, 16); //Wpis katalogowy zostaje. Jest pusty. I + 1037 .LM92: + 1038 02fc 90E1 ldi r25,lo8(16) + 1039 02fe DF01 movw r26,r30 + 1040 0: + 1041 0300 1D92 st X+,__zero_reg__ + 1042 0302 9A95 dec r25 + 1043 0304 01F4 brne 0b + 259:../../../../Lib/ramdysk.c **** //relokacjaTablicyWpisow() + 260:../../../../Lib/ramdysk.c **** return 0; + 1045 .LM93: + 1046 0306 0895 ret + 1047 .L72: + 243:../../../../Lib/ramdysk.c **** if (plik->lAktOtw != 0) + 1049 .LM94: + 1050 0308 81E0 ldi r24,lo8(1) + 1051 030a 0895 ret + 1052 .L73: + 245:../../../../Lib/ramdysk.c **** + 1054 .LM95: + 1055 030c 82E0 ldi r24,lo8(2) + 261:../../../../Lib/ramdysk.c **** } + 1057 .LM96: + 1058 030e 0895 ret + 1063 .Lscope9: + 1065 .stabd 78,0,0 + 1068 .global ramDyskZamknijPlik + 1070 ramDyskZamknijPlik: + 1071 .stabd 46,0,0 + 262:../../../../Lib/ramdysk.c **** + 263:../../../../Lib/ramdysk.c **** void ramDyskZamknijPlik(struct ramPlikFd *fd) + 264:../../../../Lib/ramdysk.c **** { + 1073 .LM97: + 1074 .LFBB10: + 1075 /* prologue: function */ + 1076 /* frame size = 0 */ + 1077 /* stack size = 0 */ + 1078 .L__stack_usage = 0 + 1079 0310 FC01 movw r30,r24 + 265:../../../../Lib/ramdysk.c **** if (fd -> wpis -> lAktOtw > 0) //Sprawdzanie, czy licznik otwarć jest + 1081 .LM98: + 1082 0312 A481 ldd r26,Z+4 + 1083 0314 B581 ldd r27,Z+5 + 1084 0316 1396 adiw r26,3 + 1085 0318 9C91 ld r25,X + 1086 031a 1397 sbiw r26,3 + 1087 031c 9923 tst r25 + 1088 031e 01F0 breq .L75 + 266:../../../../Lib/ramdysk.c **** { + 267:../../../../Lib/ramdysk.c **** fd->wpis->lAktOtw--; //Zmniejszanie licznika otwarć pliku + 1090 .LM99: + 1091 0320 9150 subi r25,lo8(-(-1)) + 1092 0322 1396 adiw r26,3 + 1093 0324 9C93 st X,r25 + 268:../../../../Lib/ramdysk.c **** memset(fd, 0, sizeof(struct ramPlikFd)); //CZyszczenie struktury deskryptora plik + 1095 .LM100: + 1096 0326 86E0 ldi r24,lo8(6) + 1097 0328 DF01 movw r26,r30 + 1098 0: + 1099 032a 1D92 st X+,__zero_reg__ + 1100 032c 8A95 dec r24 + 1101 032e 01F4 brne 0b + 1102 .L75: + 1103 0330 0895 ret + 1105 .Lscope10: + 1107 .stabd 78,0,0 + 1110 .global ramDyskCzyscPlik + 1112 ramDyskCzyscPlik: + 1113 .stabd 46,0,0 + 269:../../../../Lib/ramdysk.c **** } + 270:../../../../Lib/ramdysk.c **** } + 271:../../../../Lib/ramdysk.c **** + 272:../../../../Lib/ramdysk.c **** uint8_t ramDyskCzyscPlik(struct ramPlikFd *fd) + 273:../../../../Lib/ramdysk.c **** { + 1115 .LM101: + 1116 .LFBB11: + 1117 0332 CF93 push r28 + 1118 0334 DF93 push r29 + 1119 /* prologue: function */ + 1120 /* frame size = 0 */ + 1121 /* stack size = 2 */ + 1122 .L__stack_usage = 2 + 1123 0336 FC01 movw r30,r24 + 1124 .L81: + 274:../../../../Lib/ramdysk.c **** uint8_t usuwanyKlaster; + 275:../../../../Lib/ramdysk.c **** while(fd->wpis->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ + 1126 .LM102: + 1127 0338 A481 ldd r26,Z+4 + 1128 033a B581 ldd r27,Z+5 + 1129 033c 8C91 ld r24,X + 1130 033e 8823 tst r24 + 1131 0340 01F0 breq .L85 + 276:../../../../Lib/ramdysk.c **** { + 277:../../../../Lib/ramdysk.c **** usuwanyKlaster = fd->wpis->pierwszyKlaster; + 278:../../../../Lib/ramdysk.c **** if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostat + 1133 .LM103: + 1134 0342 C82F mov r28,r24 + 1135 0344 D0E0 ldi r29,0 + 1136 0346 C050 subi r28,lo8(-(klastry)) + 1137 0348 D040 sbci r29,hi8(-(klastry)) + 1138 034a 9881 ld r25,Y + 1139 034c 9813 cpse r25,r24 + 1140 034e 00C0 rjmp .L82 + 279:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwani + 1142 .LM104: + 1143 0350 1C92 st X,__zero_reg__ + 1144 0352 00C0 rjmp .L83 + 1145 .L82: + 280:../../../../Lib/ramdysk.c **** else + 281:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + 1147 .LM105: + 1148 0354 9C93 st X,r25 + 1149 .L83: + 282:../../../../Lib/ramdysk.c **** klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + 1151 .LM106: + 1152 0356 1882 st Y,__zero_reg__ + 1153 0358 00C0 rjmp .L81 + 1154 .L85: + 283:../../../../Lib/ramdysk.c **** } + 284:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 0; + 1156 .LM107: + 1157 035a 1196 adiw r26,1 + 1158 035c 1C92 st X,__zero_reg__ + 285:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarHi = 0; + 1160 .LM108: + 1161 035e A481 ldd r26,Z+4 + 1162 0360 B581 ldd r27,Z+5 + 1163 0362 1296 adiw r26,2 + 1164 0364 1C92 st X,__zero_reg__ + 286:../../../../Lib/ramdysk.c **** fd->wpis->dataMod = systemTime(); + 1166 .LM109: + 1167 0366 A481 ldd r26,Z+4 + 1168 0368 B581 ldd r27,Z+5 + 1169 036a 1C96 adiw r26,12 + 1170 036c 1D92 st X+,__zero_reg__ + 1171 036e 1D92 st X+,__zero_reg__ + 1172 0370 1D92 st X+,__zero_reg__ + 1173 0372 1C92 st X,__zero_reg__ + 1174 0374 1F97 sbiw r26,12+3 + 287:../../../../Lib/ramdysk.c **** memset (fd, 0, 4); + 1176 .LM110: + 1177 0376 1082 st Z,__zero_reg__ + 1178 0378 1182 std Z+1,__zero_reg__ + 1179 037a 1282 std Z+2,__zero_reg__ + 1180 037c 1382 std Z+3,__zero_reg__ + 1181 /* epilogue start */ + 288:../../../../Lib/ramdysk.c **** return 0; + 289:../../../../Lib/ramdysk.c **** } + 1183 .LM111: + 1184 037e DF91 pop r29 + 1185 0380 CF91 pop r28 + 1186 0382 0895 ret + 1188 .Lscope11: + 1190 .stabd 78,0,0 + 1194 .global ramDyskZapiszBajtDoPliku + 1196 ramDyskZapiszBajtDoPliku: + 1197 .stabd 46,0,0 + 290:../../../../Lib/ramdysk.c **** + 291:../../../../Lib/ramdysk.c **** uint8_t ramDyskZapiszBajtDoPliku(struct ramPlikFd *fd, uint8_t znak) + 292:../../../../Lib/ramdysk.c **** { + 1199 .LM112: + 1200 .LFBB12: + 1201 0384 1F93 push r17 + 1202 0386 CF93 push r28 + 1203 0388 DF93 push r29 + 1204 /* prologue: function */ + 1205 /* frame size = 0 */ + 1206 /* stack size = 3 */ + 1207 .L__stack_usage = 3 + 1208 038a EC01 movw r28,r24 + 1209 038c 162F mov r17,r22 + 293:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster; + 294:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 1211 .LM113: + 1212 038e EC81 ldd r30,Y+4 + 1213 0390 FD81 ldd r31,Y+5 + 1214 0392 8081 ld r24,Z + 1215 0394 8111 cpse r24,__zero_reg__ + 1216 0396 00C0 rjmp .L87 + 295:../../../../Lib/ramdysk.c **** { + 296:../../../../Lib/ramdysk.c **** if ((tmpKlaster = znajdzWolnyKlaster()) == 0) + 1218 .LM114: + 1219 0398 0E94 0000 call znajdzWolnyKlaster + 1220 039c 8823 tst r24 + 1221 039e 01F0 breq .L92 + 297:../../../../Lib/ramdysk.c **** return 1; //Nie można byÅ‚o przydzielić pierwszego + 298:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = tmpKlaster; + 1223 .LM115: + 1224 03a0 EC81 ldd r30,Y+4 + 1225 03a2 FD81 ldd r31,Y+5 + 1226 03a4 8083 st Z,r24 + 1227 .L87: + 299:../../../../Lib/ramdysk.c **** } + 300:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) + 1229 .LM116: + 1230 03a6 8A81 ldd r24,Y+2 + 1231 03a8 8111 cpse r24,__zero_reg__ + 1232 03aa 00C0 rjmp .L89 + 301:../../../../Lib/ramdysk.c **** { + 302:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Wyszukanie lub dodanie nas + 1234 .LM117: + 1235 03ac EC81 ldd r30,Y+4 + 1236 03ae FD81 ldd r31,Y+5 + 1237 03b0 6B81 ldd r22,Y+3 + 1238 03b2 8081 ld r24,Z + 1239 03b4 0E94 0000 call znajdzKlasterN + 303:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) + 1241 .LM118: + 1242 03b8 8823 tst r24 + 1243 03ba 01F0 breq .L93 + 304:../../../../Lib/ramdysk.c **** { + 305:../../../../Lib/ramdysk.c **** return 2; //Nie można byÅ‚o przydzielić kolejnego kla + 306:../../../../Lib/ramdysk.c **** } + 307:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek nowego k + 1245 .LM119: + 1246 03bc 90E0 ldi r25,0 + 1247 03be 8058 subi r24,-128 + 1248 03c0 9F4F sbci r25,-1 + 1249 03c2 1882 st Y,__zero_reg__ + 1250 03c4 8983 std Y+1,r24 + 1251 .L89: + 308:../../../../Lib/ramdysk.c **** } + 309:../../../../Lib/ramdysk.c **** + 310:../../../../Lib/ramdysk.c **** *(fd->Wsk) = znak; //Zapis bajtu do pliku + 1253 .LM120: + 1254 03c6 E881 ld r30,Y + 1255 03c8 F981 ldd r31,Y+1 + 1256 03ca 1083 st Z,r17 + 311:../../../../Lib/ramdysk.c **** + 312:../../../../Lib/ramdysk.c **** fd->IndLo++; //ZwiÄ™kszanie indeksu odczytu/zapisu + 1258 .LM121: + 1259 03cc 8A81 ldd r24,Y+2 + 1260 03ce 8F5F subi r24,lo8(-(1)) + 1261 03d0 8A83 std Y+2,r24 + 313:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //JeÅ›li ma on wartość 0, to oznacza to, ż + 1263 .LM122: + 1264 03d2 8111 cpse r24,__zero_reg__ + 1265 03d4 00C0 rjmp .L90 + 314:../../../../Lib/ramdysk.c **** fd->IndHi++; //Należy zwiÄ™kszyć bardziej znaczÄ…cy bajt + 1267 .LM123: + 1268 03d6 8B81 ldd r24,Y+3 + 1269 03d8 8F5F subi r24,lo8(-(1)) + 1270 03da 8B83 std Y+3,r24 + 1271 03dc 00C0 rjmp .L91 + 1272 .L90: + 315:../../../../Lib/ramdysk.c **** else //Wziąż dziaÅ‚amy na tym samym klastrze. + 316:../../../../Lib/ramdysk.c **** fd->Wsk++; //Można uaktualnić wskaźnik + 1274 .LM124: + 1275 03de 8881 ld r24,Y + 1276 03e0 9981 ldd r25,Y+1 + 1277 03e2 0196 adiw r24,1 + 1278 03e4 9983 std Y+1,r25 + 1279 03e6 8883 st Y,r24 + 1280 .L91: + 317:../../../../Lib/ramdysk.c **** + 318:../../../../Lib/ramdysk.c **** uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru + 1282 .LM125: + 1283 03e8 CE01 movw r24,r28 + 1284 03ea 0E94 0000 call uaktualnijRozmiarPliku + 319:../../../../Lib/ramdysk.c **** return 0; + 1286 .LM126: + 1287 03ee 80E0 ldi r24,0 + 1288 03f0 00C0 rjmp .L88 + 1289 .L92: + 297:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = tmpKlaster; + 1291 .LM127: + 1292 03f2 81E0 ldi r24,lo8(1) + 1293 03f4 00C0 rjmp .L88 + 1294 .L93: + 305:../../../../Lib/ramdysk.c **** } + 1296 .LM128: + 1297 03f6 82E0 ldi r24,lo8(2) + 1298 .L88: + 1299 /* epilogue start */ + 320:../../../../Lib/ramdysk.c **** } + 1301 .LM129: + 1302 03f8 DF91 pop r29 + 1303 03fa CF91 pop r28 + 1304 03fc 1F91 pop r17 + 1305 03fe 0895 ret + 1307 .Lscope12: + 1309 .stabd 78,0,0 + 1314 putSTD: + 1315 .stabd 46,0,0 + 321:../../../../Lib/ramdysk.c **** + 322:../../../../Lib/ramdysk.c **** uint8_t ramDyskCzytajBajtZPliku(struct ramPlikFd *fd, uint8_t *bajt) + 323:../../../../Lib/ramdysk.c **** { + 324:../../../../Lib/ramdysk.c **** if (wObrebiePliku(fd) != 0) //Sprawdzanie, czy jesteÅ›my w obrÄ™bie pliku + 325:../../../../Lib/ramdysk.c **** return 1; //1 - eof + 326:../../../../Lib/ramdysk.c **** + 327:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //Sprawdzanie, czy dziaÅ‚amy na poczÄ…tku now + 328:../../../../Lib/ramdysk.c **** { + 329:../../../../Lib/ramdysk.c **** uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + 330:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(nrKlastra, 0); //Ustawianie wskaźnika na poczÄ…tek nowego k + 331:../../../../Lib/ramdysk.c **** } + 332:../../../../Lib/ramdysk.c **** + 333:../../../../Lib/ramdysk.c **** *bajt = *(fd->Wsk); //Odczyt z pliku + 334:../../../../Lib/ramdysk.c **** fd->IndLo++; //ZwiÄ™kszenie indeksu o 1 + 335:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //Sprawdzamy, czy przeszliÅ›my do nowego klas + 336:../../../../Lib/ramdysk.c **** fd->IndHi++; //Tak: uaktualniamy liczbÄ™ przeskokół wzgl + 337:../../../../Lib/ramdysk.c **** else //DziaÅ‚amy na tym samym klastrze + 338:../../../../Lib/ramdysk.c **** fd->Wsk++; //Uaktualniamy wskaźnik do tego klastra + 339:../../../../Lib/ramdysk.c **** return 0; + 340:../../../../Lib/ramdysk.c **** } + 341:../../../../Lib/ramdysk.c **** + 342:../../../../Lib/ramdysk.c **** uint8_t ramDyskZapiszBlokDoPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) + 343:../../../../Lib/ramdysk.c **** { + 344:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 345:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 346:../../../../Lib/ramdysk.c **** + 347:../../../../Lib/ramdysk.c **** uint16_t dlBloku = 256 - fd->IndLo; //Obliczanie liczby bajtów, jakÄ… da siÄ™ zapisa + 348:../../../../Lib/ramdysk.c **** uint16_t doZapisu = *dlugosc; + 349:../../../../Lib/ramdysk.c **** *dlugosc = 0; //Jak do tÄ…d jeszcze nic nie zapisano + 350:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 351:../../../../Lib/ramdysk.c **** while (doZapisu > 0) + 352:../../../../Lib/ramdysk.c **** { + 353:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //JeÅ›li indeks pokazuje na poczÄ…tek klastra, to + 354:../../../../Lib/ramdysk.c **** { + 355:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) //Pierwsza operacja zapisu, nie odczytano jeszcze + 356:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Odczyt numeru klastra + 357:../../../../Lib/ramdysk.c **** else //Znamy poprzedni klaster + 358:../../../../Lib/ramdysk.c **** tmpKlaster = nastepnyKlaster(tmpKlaster); //Wystarczy przejść do nastÄ™pnego + 359:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) //Sprawdzanie, czy udaÅ‚o siÄ™ znaleźć klaster + 360:../../../../Lib/ramdysk.c **** return 1; //1 - Brak wolnego klastra + 361:../../../../Lib/ramdysk.c **** + 362:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek klastra. Ter + 363:../../../../Lib/ramdysk.c **** } + 364:../../../../Lib/ramdysk.c **** if (doZapisu > dlBloku) //Sprawdzanie, czy wszystko uda siÄ™ zapisać w b + 365:../../../../Lib/ramdysk.c **** { //Nie uda siÄ™, teraz zapiszemy caÅ‚y klastr do k + 366:../../../../Lib/ramdysk.c **** memcpy(fd->Wsk, znaki, dlBloku); //Zapis do koÅ„ca aktualnego klastra + 367:../../../../Lib/ramdysk.c **** znaki +=dlBloku; + 368:../../../../Lib/ramdysk.c **** fd->IndLo = 0; //Mniej znaczÄ…cy bajt odczytu wskazuje na poczÄ… + 369:../../../../Lib/ramdysk.c **** doZapisu -= dlBloku; //Uaktualnianie informacji o liczbie bajtów jaka + 370:../../../../Lib/ramdysk.c **** *dlugosc += dlBloku; //Uaktualnianie informacji o liczbie zapisanych d + 371:../../../../Lib/ramdysk.c **** fd->IndHi++; //Ustawienie bardziej znaczÄ…cego bajtu indeksu. + 372:../../../../Lib/ramdysk.c **** dlBloku = 256; //Do nastÄ™pnego klastra możemy zapisać do 256 + 373:../../../../Lib/ramdysk.c **** } + 374:../../../../Lib/ramdysk.c **** else //Jest to ostatni zapis. CaÅ‚e dane zostanÄ… skop + 375:../../../../Lib/ramdysk.c **** { + 376:../../../../Lib/ramdysk.c **** memcpy(fd->Wsk, znaki, doZapisu); //Ostatnia operacja zapisu do klasrta. + 377:../../../../Lib/ramdysk.c **** fd->IndLo += doZapisu; //Uaktualnianie indeksu (wystarczy uaktualnić mn + 378:../../../../Lib/ramdysk.c **** *dlugosc += doZapisu; //Uaktualnianie informacji o liczbie zapisanych d + 379:../../../../Lib/ramdysk.c **** doZapisu = 0; //Równie dobrze można tutaj wstawić break; + 380:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce kla + 381:../../../../Lib/ramdysk.c **** } + 382:../../../../Lib/ramdysk.c **** } + 383:../../../../Lib/ramdysk.c **** uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + 384:../../../../Lib/ramdysk.c **** return 0; + 385:../../../../Lib/ramdysk.c **** } + 386:../../../../Lib/ramdysk.c **** + 387:../../../../Lib/ramdysk.c **** uint8_t ramDyskCzytajBlokZPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) + 388:../../../../Lib/ramdysk.c **** { + 389:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 390:../../../../Lib/ramdysk.c **** { + 391:../../../../Lib/ramdysk.c **** *dlugosc = 0; + 392:../../../../Lib/ramdysk.c **** return 1; //1 - Plik jest pusty + 393:../../../../Lib/ramdysk.c **** } + 394:../../../../Lib/ramdysk.c **** if (wObrebiePliku(fd) != 0) + 395:../../../../Lib/ramdysk.c **** { + 396:../../../../Lib/ramdysk.c **** *dlugosc = 0; + 397:../../../../Lib/ramdysk.c **** return 2; //2 - Źle ustawiony indeks odczytu/zapisu (poza obszarem pli + 398:../../../../Lib/ramdysk.c **** } + 399:../../../../Lib/ramdysk.c **** + 400:../../../../Lib/ramdysk.c **** uint16_t lDanych = (fd->wpis->rozmiarHi - fd->IndHi); + 401:../../../../Lib/ramdysk.c **** lDanych +=fd->wpis->rozmiarLo; //Obliczanie liczby bajtów jaka zostaÅ‚Ä… zapisana jeszcze z + 402:../../../../Lib/ramdysk.c **** lDanych -=fd->IndLo; //Na podstawie wczeÅ›niej sprawdzonych warunków jest to zaws + 403:../../../../Lib/ramdysk.c **** + 404:../../../../Lib/ramdysk.c **** uint16_t doOdczytania = (lDanych < *dlugosc)? //Sprawdzenie liczby zapisanych bajtół w pliku i + 405:../../../../Lib/ramdysk.c **** lDanych : //W pliku jest mniej bajtów do odczytu niż chcemy odczytaÄ + 406:../../../../Lib/ramdysk.c **** *dlugosc; //W pliku jest wiÄ™cej bajtów niż chcemy odczytać + 407:../../../../Lib/ramdysk.c **** *dlugosc = 0; //Jak do tÄ…d odczytano 0 bajtów + 408:../../../../Lib/ramdysk.c **** uint16_t dlBloku = 256 - fd->IndLo; //OkreÅ›lanie liczby bajtół jaka zostaÅ‚Ä… do koÅ„ca aktua + 409:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 410:../../../../Lib/ramdysk.c **** while (doOdczytania > 0) + 411:../../../../Lib/ramdysk.c **** { + 412:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //Indeks odczytu wskazuje na poczÄ…tek klastra. Oznacza to, + 413:../../../../Lib/ramdysk.c **** { //Bardziej znaczÄ…cy bajt indeksu okreÅ›la o ile klastrów ( + 414:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) + 415:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + 416:../../../../Lib/ramdysk.c **** else + 417:../../../../Lib/ramdysk.c **** tmpKlaster = nastepnyKlaster(tmpKlaster); + 418:../../../../Lib/ramdysk.c **** if (tmpKlaster != 0) //JeÅ›li znaleziono odpowiedni klaster, to + 419:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, 0); //przestaw wskaźnik na poczÄ…tek tego klastra + 420:../../../../Lib/ramdysk.c **** else + 421:../../../../Lib/ramdysk.c **** return 3; //3 - Nie udaÅ‚o siÄ™ znaleźć odpowiedniego klastra + 422:../../../../Lib/ramdysk.c **** } + 423:../../../../Lib/ramdysk.c **** + 424:../../../../Lib/ramdysk.c **** if (doOdczytania > dlBloku) //Odczyt do koÅ„ca zawartoÅ›ci klastra + 425:../../../../Lib/ramdysk.c **** { //dlBloku okreÅ›la ile zostaÅ‚o jeszcze bajtów do koÅ„ca kl + 426:../../../../Lib/ramdysk.c **** memcpy(znaki, fd->Wsk, dlBloku); //Odczyt zawartoÅ›ci Klastra + 427:../../../../Lib/ramdysk.c **** znaki +=dlBloku; //Przestawienie wskaźnika do tablicy, w której zapisujemy + 428:../../../../Lib/ramdysk.c **** fd->IndLo = 0; //Indeks wskazuje na poczÄ…tek nowego klastra + 429:../../../../Lib/ramdysk.c **** fd->IndHi++; //Bardziej znaczÄ…cy bajt okreÅ›la zmianÄ™ klastra. Teraz ni + 430:../../../../Lib/ramdysk.c **** doOdczytania -= dlBloku; //Uaktualnienie liczby bajtół jakÄ… należy odczytać + 431:../../../../Lib/ramdysk.c **** *dlugosc += dlBloku; //Uaktualnienie + 432:../../../../Lib/ramdysk.c **** dlBloku = 256; //Kolejny dostÄ™pny blok do odczytania, to dÅ‚ugość caÅ‚eg + 433:../../../../Lib/ramdysk.c **** } + 434:../../../../Lib/ramdysk.c **** else //Ostatnia operacja odczytu + 435:../../../../Lib/ramdysk.c **** { + 436:../../../../Lib/ramdysk.c **** memcpy(znaki, fd->Wsk, doOdczytania); + 437:../../../../Lib/ramdysk.c **** fd->Wsk += doOdczytania; //Po zakoÅ„czeniu operacji odczytu nadal dziaÅ‚amy w tym sam + 438:../../../../Lib/ramdysk.c **** fd->IndLo += doOdczytania; //Uaktualnianie indeksu. JesteÅ›my w tym samym klastrze, zat + 439:../../../../Lib/ramdysk.c **** *dlugosc += doOdczytania; //Uaktualnianie liczby odczytanych bajtów + 440:../../../../Lib/ramdysk.c **** doOdczytania = 0; //Tutaj równie dobrze może być brake + 441:../../../../Lib/ramdysk.c **** } + 442:../../../../Lib/ramdysk.c **** } + 443:../../../../Lib/ramdysk.c **** return 0; + 444:../../../../Lib/ramdysk.c **** } + 445:../../../../Lib/ramdysk.c **** + 446:../../../../Lib/ramdysk.c **** uint8_t ramDyskUstawWskaznik(struct ramPlikFd *fd, uint16_t indeks) + 447:../../../../Lib/ramdysk.c **** { + 448:../../../../Lib/ramdysk.c **** if (indeks == 0) //Sprawdzanie, czy wskaźnik nie pokazuje + 449:../../../../Lib/ramdysk.c **** { //JeÅ›li tak, to nie ma potzeby tworzenia + 450:../../../../Lib/ramdysk.c **** fd->IndLo = 0; //Ustawianie na 0 indeksów (mniej i bard + 451:../../../../Lib/ramdysk.c **** fd->IndHi = 0; + 452:../../../../Lib/ramdysk.c **** return 0; + 453:../../../../Lib/ramdysk.c **** } + 454:../../../../Lib/ramdysk.c **** indeks--; //Zmniejszamy indeks o 1, by odpowiednio + 455:../../../../Lib/ramdysk.c **** //JeÅ›li indeks jest wiÄ™kszy niż rozmia + 456:../../../../Lib/ramdysk.c **** + 457:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) //Sprawdzanie, czy plik ma już przydziel + 458:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); //Przydzielanie pierwszego klastra dla pl + 459:../../../../Lib/ramdysk.c **** + 460:../../../../Lib/ramdysk.c **** uint8_t klasterN = indeks >> 8; //Obliczanie liczby klastrów, jakÄ… nale + 461:../../../../Lib/ramdysk.c **** + 462:../../../../Lib/ramdysk.c **** fd->IndLo = indeks & 0xFF; //Obliczanie na podstawie wartoÅ›ci 16 mn + 463:../../../../Lib/ramdysk.c **** fd->IndHi = klasterN; //oraz bardziej znaczÄ…cego bajtu indeksu + 464:../../../../Lib/ramdysk.c **** + 465:../../../../Lib/ramdysk.c **** uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, klasterN); + 466:../../../../Lib/ramdysk.c **** if (nrKlastra == 0) + 467:../../../../Lib/ramdysk.c **** return 1; //Brak klastrów + 468:../../../../Lib/ramdysk.c **** + 469:../../../../Lib/ramdysk.c **** uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + 470:../../../../Lib/ramdysk.c **** + 471:../../../../Lib/ramdysk.c **** fd->IndLo++; //Powrót do zadanej wartoÅ›ci indeksu + 472:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //JeÅ›li jesteÅ›my na poczÄ…tku klastra, + 473:../../../../Lib/ramdysk.c **** fd->IndHi++; //Uaktualniamy tylko bardziej znaczÄ…cy b + 474:../../../../Lib/ramdysk.c **** else //JesteÅ›my w obszarze utworzonego klastr + 475:../../../../Lib/ramdysk.c **** fd->Wsk=dataPtr(nrKlastra, fd->IndLo); //ustawić wskaźnik na odpowiednie miejs + 476:../../../../Lib/ramdysk.c **** + 477:../../../../Lib/ramdysk.c **** return 0; + 478:../../../../Lib/ramdysk.c **** } + 479:../../../../Lib/ramdysk.c **** + 480:../../../../Lib/ramdysk.c **** uint8_t ramDyskUstawWskaznikNaKoniec(struct ramPlikFd *fd) + 481:../../../../Lib/ramdysk.c **** { + 482:../../../../Lib/ramdysk.c **** if (fd == NULL) + 483:../../../../Lib/ramdysk.c **** return 1; + 484:../../../../Lib/ramdysk.c **** fd->IndLo = fd->wpis->rozmiarLo; + 485:../../../../Lib/ramdysk.c **** fd->IndHi = fd->wpis->rozmiarHi; + 486:../../../../Lib/ramdysk.c **** // fd->IndLo++; + 487:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 488:../../../../Lib/ramdysk.c **** if (fd->IndLo != 0) + 489:../../../../Lib/ramdysk.c **** { + 490:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->wpis->rozmiarHi); + 491:../../../../Lib/ramdysk.c **** fd->Wsk=dataPtr(tmpKlaster, fd->IndLo); + 492:../../../../Lib/ramdysk.c **** } + 493:../../../../Lib/ramdysk.c **** return 0; + 494:../../../../Lib/ramdysk.c **** } + 495:../../../../Lib/ramdysk.c **** + 496:../../../../Lib/ramdysk.c **** uint8_t* ramDyskDodajBlokXmodem(struct ramPlikFd *fd, uint16_t nrBloku) + 497:../../../../Lib/ramdysk.c **** { + 498:../../../../Lib/ramdysk.c **** if (nrBloku == 0) + 499:../../../../Lib/ramdysk.c **** return NULL; + 500:../../../../Lib/ramdysk.c **** nrBloku --; + 501:../../../../Lib/ramdysk.c **** + 502:../../../../Lib/ramdysk.c **** uint8_t indHi = (uint8_t)(nrBloku / 2); + 503:../../../../Lib/ramdysk.c **** //uint8_t indLo = 0; + 504:../../../../Lib/ramdysk.c **** uint8_t *wynik; + 505:../../../../Lib/ramdysk.c **** + 506:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 507:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 508:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 509:../../../../Lib/ramdysk.c **** return NULL; + 510:../../../../Lib/ramdysk.c **** + 511:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster , indHi); + 512:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) + 513:../../../../Lib/ramdysk.c **** return NULL; + 514:../../../../Lib/ramdysk.c **** if ((nrBloku & 0x0001) == 0x0001) // Druga część klastra + 515:../../../../Lib/ramdysk.c **** { + 516:../../../../Lib/ramdysk.c **** //indLo = 128; + 517:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarHi <= indHi) + 518:../../../../Lib/ramdysk.c **** { + 519:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarHi = indHi+1; + 520:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 0; + 521:../../../../Lib/ramdysk.c **** } + 522:../../../../Lib/ramdysk.c **** wynik=dataPtr(tmpKlaster, 128); + 523:../../../../Lib/ramdysk.c **** } + 524:../../../../Lib/ramdysk.c **** else + 525:../../../../Lib/ramdysk.c **** { + 526:../../../../Lib/ramdysk.c **** if (fd->wpis->rozmiarHi < indHi) + 527:../../../../Lib/ramdysk.c **** { + 528:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarHi = indHi; + 529:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 128; + 530:../../../../Lib/ramdysk.c **** } + 531:../../../../Lib/ramdysk.c **** else if ((fd->wpis->rozmiarHi == indHi) && (fd->wpis->rozmiarLo < 128)) + 532:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 128; + 533:../../../../Lib/ramdysk.c **** + 534:../../../../Lib/ramdysk.c **** wynik=dataPtr(tmpKlaster, 0); + 535:../../../../Lib/ramdysk.c **** } + 536:../../../../Lib/ramdysk.c **** return wynik; + 537:../../../../Lib/ramdysk.c **** } + 538:../../../../Lib/ramdysk.c **** + 539:../../../../Lib/ramdysk.c **** void ramDyskDir(FILE *ostream) + 540:../../../../Lib/ramdysk.c **** { + 541:../../../../Lib/ramdysk.c **** fprintf(ostream, "nazwa\t\trozmiar\totwarty\r\n"); + 542:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 543:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 544:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster2; + 545:../../../../Lib/ramdysk.c **** uint8_t tmp, tmp2, tmp3; + 546:../../../../Lib/ramdysk.c **** do + 547:../../../../Lib/ramdysk.c **** { + 548:../../../../Lib/ramdysk.c **** plik = (struct ramPlik *)(dataPtr(tmpKlaster, 0)); + 549:../../../../Lib/ramdysk.c **** for (tmp=0; tmp<16; tmp++) + 550:../../../../Lib/ramdysk.c **** { + 551:../../../../Lib/ramdysk.c **** tmp3=plik->nazwa[0]; + 552:../../../../Lib/ramdysk.c **** if (tmp3 == 0) + 553:../../../../Lib/ramdysk.c **** break; //Ten wpis jest pusty. + 554:../../../../Lib/ramdysk.c **** fputc(tmp3 , ostream); + 555:../../../../Lib/ramdysk.c **** for (tmp2=1; tmp2<8; tmp2++) + 556:../../../../Lib/ramdysk.c **** { + 557:../../../../Lib/ramdysk.c **** if (tmp3 != 0) + 558:../../../../Lib/ramdysk.c **** tmp3=plik->nazwa[tmp2]; + 559:../../../../Lib/ramdysk.c **** + 560:../../../../Lib/ramdysk.c **** if (tmp3 != 0) + 561:../../../../Lib/ramdysk.c **** fputc(tmp3 , ostream); + 562:../../../../Lib/ramdysk.c **** else + 563:../../../../Lib/ramdysk.c **** fputc(' ' , ostream); + 564:../../../../Lib/ramdysk.c **** } + 565:../../../../Lib/ramdysk.c **** fprintf(ostream, "\t%d\t%d\r\n", 256*plik->rozmiarHi+plik->rozmiarLo, plik->lAktOtw); + 566:../../../../Lib/ramdysk.c **** plik++; + 567:../../../../Lib/ramdysk.c **** } + 568:../../../../Lib/ramdysk.c **** tmpKlaster2 = tmpKlaster; + 569:../../../../Lib/ramdysk.c **** tmpKlaster = klastry[tmpKlaster]; + 570:../../../../Lib/ramdysk.c **** } + 571:../../../../Lib/ramdysk.c **** while (tmpKlaster != tmpKlaster2); + 572:../../../../Lib/ramdysk.c **** } + 573:../../../../Lib/ramdysk.c **** + 574:../../../../Lib/ramdysk.c **** uint8_t ramDyskLiczbaWolnychKlastrow(void) + 575:../../../../Lib/ramdysk.c **** { + 576:../../../../Lib/ramdysk.c **** uint8_t wynik=0; + 577:../../../../Lib/ramdysk.c **** uint8_t temp; + 578:../../../../Lib/ramdysk.c **** for (temp = L_KLASTROW-1; temp > 0; temp--) + 579:../../../../Lib/ramdysk.c **** if (klastry[temp] == 0) + 580:../../../../Lib/ramdysk.c **** wynik++; + 581:../../../../Lib/ramdysk.c **** return wynik; + 582:../../../../Lib/ramdysk.c **** } + 583:../../../../Lib/ramdysk.c **** + 584:../../../../Lib/ramdysk.c **** + 585:../../../../Lib/ramdysk.c **** static int getSTD(FILE *stream) + 586:../../../../Lib/ramdysk.c **** { + 587:../../../../Lib/ramdysk.c **** uint8_t wynik; + 588:../../../../Lib/ramdysk.c **** struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + 589:../../../../Lib/ramdysk.c **** + 590:../../../../Lib/ramdysk.c **** if (ramDyskCzytajBajtZPliku(fd, &wynik) == 0) + 591:../../../../Lib/ramdysk.c **** return wynik; + 592:../../../../Lib/ramdysk.c **** return EOF; + 593:../../../../Lib/ramdysk.c **** } + 594:../../../../Lib/ramdysk.c **** + 595:../../../../Lib/ramdysk.c **** static int putSTD(char c, FILE *stream) + 596:../../../../Lib/ramdysk.c **** { + 1317 .LM130: + 1318 .LFBB13: + 1319 /* prologue: function */ + 1320 /* frame size = 0 */ + 1321 /* stack size = 0 */ + 1322 .L__stack_usage = 0 + 1323 0400 FB01 movw r30,r22 + 597:../../../../Lib/ramdysk.c **** struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + 598:../../../../Lib/ramdysk.c **** return ramDyskZapiszBajtDoPliku(fd, c); + 1325 .LM131: + 1326 0402 682F mov r22,r24 + 1327 0404 8485 ldd r24,Z+12 + 1328 0406 9585 ldd r25,Z+13 + 1329 0408 0E94 0000 call ramDyskZapiszBajtDoPliku + 599:../../../../Lib/ramdysk.c **** } + 1331 .LM132: + 1332 040c 90E0 ldi r25,0 + 1333 040e 0895 ret + 1335 .Lscope13: + 1337 .stabd 78,0,0 + 1341 .global ramDyskCzytajBajtZPliku + 1343 ramDyskCzytajBajtZPliku: + 1344 .stabd 46,0,0 + 323:../../../../Lib/ramdysk.c **** if (wObrebiePliku(fd) != 0) //Sprawdzanie, czy jesteÅ›my w obrÄ™bie pliku + 1346 .LM133: + 1347 .LFBB14: + 1348 0410 0F93 push r16 + 1349 0412 1F93 push r17 + 1350 0414 CF93 push r28 + 1351 0416 DF93 push r29 + 1352 /* prologue: function */ + 1353 /* frame size = 0 */ + 1354 /* stack size = 4 */ + 1355 .L__stack_usage = 4 + 1356 0418 EC01 movw r28,r24 + 1357 .LBB22: + 1358 .LBB23: + 26:../../../../Lib/ramdysk.c **** return 0; + 1360 .LM134: + 1361 041a EC81 ldd r30,Y+4 + 1362 041c FD81 ldd r31,Y+5 + 1363 041e 9281 ldd r25,Z+2 + 1364 0420 8B81 ldd r24,Y+3 + 1365 0422 8917 cp r24,r25 + 1366 0424 00F0 brlo .L96 + 29:../../../../Lib/ramdysk.c **** return 0; + 1368 .LM135: + 1369 0426 9813 cpse r25,r24 + 1370 0428 00C0 rjmp .L101 + 1371 042a 2181 ldd r18,Z+1 + 1372 042c 9A81 ldd r25,Y+2 + 1373 042e 2917 cp r18,r25 + 1374 0430 00F4 brsh .L96 + 1375 .L101: + 1376 .LBE23: + 1377 .LBE22: + 325:../../../../Lib/ramdysk.c **** + 1379 .LM136: + 1380 0432 81E0 ldi r24,lo8(1) + 1381 0434 00C0 rjmp .L102 + 1382 .L96: + 1383 0436 8B01 movw r16,r22 + 1384 .LBB24: + 1385 .LBB25: + 327:../../../../Lib/ramdysk.c **** { + 1387 .LM137: + 1388 0438 9A81 ldd r25,Y+2 + 1389 043a 9111 cpse r25,__zero_reg__ + 1390 043c 00C0 rjmp .L100 + 1391 .LBB26: + 329:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(nrKlastra, 0); //Ustawianie wskaźnika na poczÄ…tek nowego k + 1393 .LM138: + 1394 043e 682F mov r22,r24 + 1395 0440 8081 ld r24,Z + 1396 0442 0E94 0000 call znajdzKlasterN + 330:../../../../Lib/ramdysk.c **** } + 1398 .LM139: + 1399 0446 90E0 ldi r25,0 + 1400 0448 8058 subi r24,-128 + 1401 044a 9F4F sbci r25,-1 + 1402 044c 1882 st Y,__zero_reg__ + 1403 044e 8983 std Y+1,r24 + 1404 .L100: + 1405 .LBE26: + 333:../../../../Lib/ramdysk.c **** fd->IndLo++; //ZwiÄ™kszenie indeksu o 1 + 1407 .LM140: + 1408 0450 E881 ld r30,Y + 1409 0452 F981 ldd r31,Y+1 + 1410 0454 8081 ld r24,Z + 1411 0456 F801 movw r30,r16 + 1412 0458 8083 st Z,r24 + 334:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //Sprawdzamy, czy przeszliÅ›my do nowego klas + 1414 .LM141: + 1415 045a 8A81 ldd r24,Y+2 + 1416 045c 8F5F subi r24,lo8(-(1)) + 1417 045e 8A83 std Y+2,r24 + 335:../../../../Lib/ramdysk.c **** fd->IndHi++; //Tak: uaktualniamy liczbÄ™ przeskokół wzgl + 1419 .LM142: + 1420 0460 8111 cpse r24,__zero_reg__ + 1421 0462 00C0 rjmp .L98 + 336:../../../../Lib/ramdysk.c **** else //DziaÅ‚amy na tym samym klastrze + 1423 .LM143: + 1424 0464 9B81 ldd r25,Y+3 + 1425 0466 9F5F subi r25,lo8(-(1)) + 1426 0468 9B83 std Y+3,r25 + 1427 046a 00C0 rjmp .L102 + 1428 .L98: + 338:../../../../Lib/ramdysk.c **** return 0; + 1430 .LM144: + 1431 046c 8881 ld r24,Y + 1432 046e 9981 ldd r25,Y+1 + 1433 0470 0196 adiw r24,1 + 1434 0472 9983 std Y+1,r25 + 1435 0474 8883 st Y,r24 + 1436 0476 80E0 ldi r24,0 + 1437 .L102: + 1438 /* epilogue start */ + 1439 .LBE25: + 1440 .LBE24: + 340:../../../../Lib/ramdysk.c **** + 1442 .LM145: + 1443 0478 DF91 pop r29 + 1444 047a CF91 pop r28 + 1445 047c 1F91 pop r17 + 1446 047e 0F91 pop r16 + 1447 0480 0895 ret + 1452 .Lscope14: + 1454 .stabd 78,0,0 + 1458 getSTD: + 1459 .stabd 46,0,0 + 586:../../../../Lib/ramdysk.c **** uint8_t wynik; + 1461 .LM146: + 1462 .LFBB15: + 1463 0482 CF93 push r28 + 1464 0484 DF93 push r29 + 1465 0486 1F92 push __zero_reg__ + 1466 0488 CDB7 in r28,__SP_L__ + 1467 048a DEB7 in r29,__SP_H__ + 1468 /* prologue: function */ + 1469 /* frame size = 1 */ + 1470 /* stack size = 3 */ + 1471 .L__stack_usage = 3 + 590:../../../../Lib/ramdysk.c **** return wynik; + 1473 .LM147: + 1474 048c BE01 movw r22,r28 + 1475 048e 6F5F subi r22,-1 + 1476 0490 7F4F sbci r23,-1 + 1477 0492 FC01 movw r30,r24 + 1478 0494 8485 ldd r24,Z+12 + 1479 0496 9585 ldd r25,Z+13 + 1480 0498 0E94 0000 call ramDyskCzytajBajtZPliku + 1481 049c 8111 cpse r24,__zero_reg__ + 1482 049e 00C0 rjmp .L105 + 591:../../../../Lib/ramdysk.c **** return EOF; + 1484 .LM148: + 1485 04a0 8981 ldd r24,Y+1 + 1486 04a2 90E0 ldi r25,0 + 1487 04a4 00C0 rjmp .L104 + 1488 .L105: + 592:../../../../Lib/ramdysk.c **** } + 1490 .LM149: + 1491 04a6 8FEF ldi r24,lo8(-1) + 1492 04a8 9FEF ldi r25,lo8(-1) + 1493 .L104: + 1494 /* epilogue start */ + 593:../../../../Lib/ramdysk.c **** + 1496 .LM150: + 1497 04aa 0F90 pop __tmp_reg__ + 1498 04ac DF91 pop r29 + 1499 04ae CF91 pop r28 + 1500 04b0 0895 ret + 1505 .Lscope15: + 1507 .stabd 78,0,0 + 1512 .global ramDyskZapiszBlokDoPliku + 1514 ramDyskZapiszBlokDoPliku: + 1515 .stabd 46,0,0 + 343:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 1517 .LM151: + 1518 .LFBB16: + 1519 04b2 8F92 push r8 + 1520 04b4 9F92 push r9 + 1521 04b6 AF92 push r10 + 1522 04b8 BF92 push r11 + 1523 04ba DF92 push r13 + 1524 04bc EF92 push r14 + 1525 04be FF92 push r15 + 1526 04c0 0F93 push r16 + 1527 04c2 1F93 push r17 + 1528 04c4 CF93 push r28 + 1529 04c6 DF93 push r29 + 1530 /* prologue: function */ + 1531 /* frame size = 0 */ + 1532 /* stack size = 11 */ + 1533 .L__stack_usage = 11 + 1534 04c8 EC01 movw r28,r24 + 1535 04ca 4B01 movw r8,r22 + 1536 04cc 5A01 movw r10,r20 + 344:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 1538 .LM152: + 1539 04ce 0C81 ldd r16,Y+4 + 1540 04d0 1D81 ldd r17,Y+5 + 1541 04d2 F801 movw r30,r16 + 1542 04d4 8081 ld r24,Z + 1543 04d6 8111 cpse r24,__zero_reg__ + 1544 04d8 00C0 rjmp .L107 + 345:../../../../Lib/ramdysk.c **** + 1546 .LM153: + 1547 04da 0E94 0000 call znajdzWolnyKlaster + 1548 04de F801 movw r30,r16 + 1549 04e0 8083 st Z,r24 + 1550 .L107: + 347:../../../../Lib/ramdysk.c **** uint16_t doZapisu = *dlugosc; + 1552 .LM154: + 1553 04e2 8A81 ldd r24,Y+2 + 1554 04e4 20E0 ldi r18,0 + 1555 04e6 31E0 ldi r19,lo8(1) + 1556 04e8 7901 movw r14,r18 + 1557 04ea E81A sub r14,r24 + 1558 04ec F108 sbc r15,__zero_reg__ + 348:../../../../Lib/ramdysk.c **** *dlugosc = 0; //Jak do tÄ…d jeszcze nic nie zapisano + 1560 .LM155: + 1561 04ee F501 movw r30,r10 + 1562 04f0 0081 ld r16,Z + 1563 04f2 1181 ldd r17,Z+1 + 349:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 1565 .LM156: + 1566 04f4 1182 std Z+1,__zero_reg__ + 1567 04f6 1082 st Z,__zero_reg__ + 350:../../../../Lib/ramdysk.c **** while (doZapisu > 0) + 1569 .LM157: + 1570 04f8 D12C mov r13,__zero_reg__ + 1571 .L108: + 351:../../../../Lib/ramdysk.c **** { + 1573 .LM158: + 1574 04fa 0115 cp r16,__zero_reg__ + 1575 04fc 1105 cpc r17,__zero_reg__ + 1576 04fe 01F4 brne .+2 + 1577 0500 00C0 rjmp .L118 + 353:../../../../Lib/ramdysk.c **** { + 1579 .LM159: + 1580 0502 8A81 ldd r24,Y+2 + 1581 0504 8111 cpse r24,__zero_reg__ + 1582 0506 00C0 rjmp .L109 + 355:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Odczyt numeru klastra + 1584 .LM160: + 1585 0508 D110 cpse r13,__zero_reg__ + 1586 050a 00C0 rjmp .L110 + 356:../../../../Lib/ramdysk.c **** else //Znamy poprzedni klaster + 1588 .LM161: + 1589 050c EC81 ldd r30,Y+4 + 1590 050e FD81 ldd r31,Y+5 + 1591 0510 6B81 ldd r22,Y+3 + 1592 0512 8081 ld r24,Z + 1593 0514 0E94 0000 call znajdzKlasterN + 1594 0518 00C0 rjmp .L117 + 1595 .L110: + 358:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) //Sprawdzanie, czy udaÅ‚o siÄ™ znaleźć klaster + 1597 .LM162: + 1598 051a 8D2D mov r24,r13 + 1599 051c 0E94 0000 call nastepnyKlaster + 1600 .L117: + 1601 0520 D82E mov r13,r24 + 359:../../../../Lib/ramdysk.c **** return 1; //1 - Brak wolnego klastra + 1603 .LM163: + 1604 0522 8823 tst r24 + 1605 0524 01F4 brne .+2 + 1606 0526 00C0 rjmp .L116 + 362:../../../../Lib/ramdysk.c **** } + 1608 .LM164: + 1609 0528 90E0 ldi r25,0 + 1610 052a 8058 subi r24,-128 + 1611 052c 9F4F sbci r25,-1 + 1612 052e 1882 st Y,__zero_reg__ + 1613 0530 8983 std Y+1,r24 + 1614 .L109: + 1615 0532 8881 ld r24,Y + 1616 0534 9981 ldd r25,Y+1 + 364:../../../../Lib/ramdysk.c **** { //Nie uda siÄ™, teraz zapiszemy caÅ‚y klastr do k + 1618 .LM165: + 1619 0536 E016 cp r14,r16 + 1620 0538 F106 cpc r15,r17 + 1621 053a 00F4 brsh .L113 + 366:../../../../Lib/ramdysk.c **** znaki +=dlBloku; + 1623 .LM166: + 1624 053c A701 movw r20,r14 + 1625 053e B401 movw r22,r8 + 1626 0540 0E94 0000 call memcpy + 367:../../../../Lib/ramdysk.c **** fd->IndLo = 0; //Mniej znaczÄ…cy bajt odczytu wskazuje na poczÄ… + 1628 .LM167: + 1629 0544 8E0C add r8,r14 + 1630 0546 9F1C adc r9,r15 + 368:../../../../Lib/ramdysk.c **** doZapisu -= dlBloku; //Uaktualnianie informacji o liczbie bajtów jaka + 1632 .LM168: + 1633 0548 1A82 std Y+2,__zero_reg__ + 369:../../../../Lib/ramdysk.c **** *dlugosc += dlBloku; //Uaktualnianie informacji o liczbie zapisanych d + 1635 .LM169: + 1636 054a 0E19 sub r16,r14 + 1637 054c 1F09 sbc r17,r15 + 370:../../../../Lib/ramdysk.c **** fd->IndHi++; //Ustawienie bardziej znaczÄ…cego bajtu indeksu. + 1639 .LM170: + 1640 054e F501 movw r30,r10 + 1641 0550 8081 ld r24,Z + 1642 0552 9181 ldd r25,Z+1 + 1643 0554 E80E add r14,r24 + 1644 0556 F91E adc r15,r25 + 1645 0558 F182 std Z+1,r15 + 1646 055a E082 st Z,r14 + 371:../../../../Lib/ramdysk.c **** dlBloku = 256; //Do nastÄ™pnego klastra możemy zapisać do 256 + 1648 .LM171: + 1649 055c 8B81 ldd r24,Y+3 + 1650 055e 8F5F subi r24,lo8(-(1)) + 1651 0560 8B83 std Y+3,r24 + 372:../../../../Lib/ramdysk.c **** } + 1653 .LM172: + 1654 0562 E12C mov r14,__zero_reg__ + 1655 0564 FF24 clr r15 + 1656 0566 F394 inc r15 + 1657 0568 00C0 rjmp .L108 + 1658 .L113: + 376:../../../../Lib/ramdysk.c **** fd->IndLo += doZapisu; //Uaktualnianie indeksu (wystarczy uaktualnić mn + 1660 .LM173: + 1661 056a A801 movw r20,r16 + 1662 056c B401 movw r22,r8 + 1663 056e 0E94 0000 call memcpy + 377:../../../../Lib/ramdysk.c **** *dlugosc += doZapisu; //Uaktualnianie informacji o liczbie zapisanych d + 1665 .LM174: + 1666 0572 8A81 ldd r24,Y+2 + 1667 0574 800F add r24,r16 + 1668 0576 8A83 std Y+2,r24 + 378:../../../../Lib/ramdysk.c **** doZapisu = 0; //Równie dobrze można tutaj wstawić break; + 1670 .LM175: + 1671 0578 F501 movw r30,r10 + 1672 057a 8081 ld r24,Z + 1673 057c 9181 ldd r25,Z+1 + 1674 057e 080F add r16,r24 + 1675 0580 191F adc r17,r25 + 1676 0582 1183 std Z+1,r17 + 1677 0584 0083 st Z,r16 + 380:../../../../Lib/ramdysk.c **** } + 1679 .LM176: + 1680 0586 8D2D mov r24,r13 + 1681 0588 90E0 ldi r25,0 + 1682 058a 8058 subi r24,-128 + 1683 058c 9F4F sbci r25,-1 + 1684 058e 982F mov r25,r24 + 1685 0590 8827 clr r24 + 1686 0592 2A81 ldd r18,Y+2 + 1687 0594 820F add r24,r18 + 1688 0596 911D adc r25,__zero_reg__ + 1689 0598 9983 std Y+1,r25 + 1690 059a 8883 st Y,r24 + 379:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce kla + 1692 .LM177: + 1693 059c 00E0 ldi r16,0 + 1694 059e 10E0 ldi r17,0 + 1695 05a0 00C0 rjmp .L108 + 1696 .L118: + 383:../../../../Lib/ramdysk.c **** return 0; + 1698 .LM178: + 1699 05a2 CE01 movw r24,r28 + 1700 05a4 0E94 0000 call uaktualnijRozmiarPliku + 384:../../../../Lib/ramdysk.c **** } + 1702 .LM179: + 1703 05a8 80E0 ldi r24,0 + 1704 05aa 00C0 rjmp .L112 + 1705 .L116: + 360:../../../../Lib/ramdysk.c **** + 1707 .LM180: + 1708 05ac 81E0 ldi r24,lo8(1) + 1709 .L112: + 1710 /* epilogue start */ + 385:../../../../Lib/ramdysk.c **** + 1712 .LM181: + 1713 05ae DF91 pop r29 + 1714 05b0 CF91 pop r28 + 1715 05b2 1F91 pop r17 + 1716 05b4 0F91 pop r16 + 1717 05b6 FF90 pop r15 + 1718 05b8 EF90 pop r14 + 1719 05ba DF90 pop r13 + 1720 05bc BF90 pop r11 + 1721 05be AF90 pop r10 + 1722 05c0 9F90 pop r9 + 1723 05c2 8F90 pop r8 + 1724 05c4 0895 ret + 1731 .Lscope16: + 1733 .stabd 78,0,0 + 1738 .global ramDyskCzytajBlokZPliku + 1740 ramDyskCzytajBlokZPliku: + 1741 .stabd 46,0,0 + 388:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 1743 .LM182: + 1744 .LFBB17: + 1745 05c6 9F92 push r9 + 1746 05c8 AF92 push r10 + 1747 05ca BF92 push r11 + 1748 05cc CF92 push r12 + 1749 05ce DF92 push r13 + 1750 05d0 EF92 push r14 + 1751 05d2 FF92 push r15 + 1752 05d4 0F93 push r16 + 1753 05d6 1F93 push r17 + 1754 05d8 CF93 push r28 + 1755 05da DF93 push r29 + 1756 /* prologue: function */ + 1757 /* frame size = 0 */ + 1758 /* stack size = 11 */ + 1759 .L__stack_usage = 11 + 1760 05dc EC01 movw r28,r24 + 1761 05de 6B01 movw r12,r22 + 1762 05e0 7A01 movw r14,r20 + 389:../../../../Lib/ramdysk.c **** { + 1764 .LM183: + 1765 05e2 AC81 ldd r26,Y+4 + 1766 05e4 BD81 ldd r27,Y+5 + 1767 05e6 8C91 ld r24,X + 1768 05e8 8111 cpse r24,__zero_reg__ + 1769 05ea 00C0 rjmp .L120 + 391:../../../../Lib/ramdysk.c **** return 1; //1 - Plik jest pusty + 1771 .LM184: + 1772 05ec FA01 movw r30,r20 + 1773 05ee 1182 std Z+1,__zero_reg__ + 1774 05f0 1082 st Z,__zero_reg__ + 392:../../../../Lib/ramdysk.c **** } + 1776 .LM185: + 1777 05f2 81E0 ldi r24,lo8(1) + 1778 05f4 00C0 rjmp .L133 + 1779 .L120: + 1780 .LBB29: + 1781 .LBB30: + 26:../../../../Lib/ramdysk.c **** return 0; + 1783 .LM186: + 1784 05f6 1296 adiw r26,2 + 1785 05f8 2C91 ld r18,X + 1786 05fa 1297 sbiw r26,2 + 1787 05fc 8B81 ldd r24,Y+3 + 1788 05fe 8217 cp r24,r18 + 1789 0600 00F0 brlo .L122 + 29:../../../../Lib/ramdysk.c **** return 0; + 1791 .LM187: + 1792 0602 2813 cpse r18,r24 + 1793 0604 00C0 rjmp .L123 + 1794 0606 1196 adiw r26,1 + 1795 0608 3C91 ld r19,X + 1796 060a 1197 sbiw r26,1 + 1797 060c 9A81 ldd r25,Y+2 + 1798 060e 3917 cp r19,r25 + 1799 0610 00F4 brsh .L122 + 1800 .L123: + 1801 .LBE30: + 1802 .LBE29: + 396:../../../../Lib/ramdysk.c **** return 2; //2 - Źle ustawiony indeks odczytu/zapisu (poza obszarem pli + 1804 .LM188: + 1805 0612 F701 movw r30,r14 + 1806 0614 1182 std Z+1,__zero_reg__ + 1807 0616 1082 st Z,__zero_reg__ + 397:../../../../Lib/ramdysk.c **** } + 1809 .LM189: + 1810 0618 82E0 ldi r24,lo8(2) + 1811 061a 00C0 rjmp .L133 + 1812 .L122: + 400:../../../../Lib/ramdysk.c **** lDanych +=fd->wpis->rozmiarLo; //Obliczanie liczby bajtów jaka zostaÅ‚Ä… zapisana jeszcze z + 1814 .LM190: + 1815 061c 30E0 ldi r19,0 + 1816 061e F901 movw r30,r18 + 1817 0620 E81B sub r30,r24 + 1818 0622 F109 sbc r31,__zero_reg__ + 401:../../../../Lib/ramdysk.c **** lDanych -=fd->IndLo; //Na podstawie wczeÅ›niej sprawdzonych warunków jest to zaws + 1820 .LM191: + 1821 0624 1196 adiw r26,1 + 1822 0626 2C91 ld r18,X + 1823 0628 30E0 ldi r19,0 + 402:../../../../Lib/ramdysk.c **** + 1825 .LM192: + 1826 062a 8A81 ldd r24,Y+2 + 1827 062c 281B sub r18,r24 + 1828 062e 3109 sbc r19,__zero_reg__ + 1829 0630 2E0F add r18,r30 + 1830 0632 3F1F adc r19,r31 + 404:../../../../Lib/ramdysk.c **** lDanych : //W pliku jest mniej bajtów do odczytu niż chcemy odczytaÄ + 1832 .LM193: + 1833 0634 F701 movw r30,r14 + 1834 0636 0081 ld r16,Z + 1835 0638 1181 ldd r17,Z+1 + 1836 063a 2017 cp r18,r16 + 1837 063c 3107 cpc r19,r17 + 1838 063e 00F4 brsh .L130 + 1839 0640 8901 movw r16,r18 + 1840 .L130: + 407:../../../../Lib/ramdysk.c **** uint16_t dlBloku = 256 - fd->IndLo; //OkreÅ›lanie liczby bajtół jaka zostaÅ‚Ä… do koÅ„ca aktua + 1842 .LM194: + 1843 0642 F701 movw r30,r14 + 1844 0644 1182 std Z+1,__zero_reg__ + 1845 0646 1082 st Z,__zero_reg__ + 408:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster = 0; + 1847 .LM195: + 1848 0648 8A81 ldd r24,Y+2 + 1849 064a 20E0 ldi r18,0 + 1850 064c 31E0 ldi r19,lo8(1) + 1851 064e 5901 movw r10,r18 + 1852 0650 A81A sub r10,r24 + 1853 0652 B108 sbc r11,__zero_reg__ + 409:../../../../Lib/ramdysk.c **** while (doOdczytania > 0) + 1855 .LM196: + 1856 0654 912C mov r9,__zero_reg__ + 1857 .L131: + 410:../../../../Lib/ramdysk.c **** { + 1859 .LM197: + 1860 0656 0115 cp r16,__zero_reg__ + 1861 0658 1105 cpc r17,__zero_reg__ + 1862 065a 01F4 brne .+2 + 1863 065c 00C0 rjmp .L135 + 412:../../../../Lib/ramdysk.c **** { //Bardziej znaczÄ…cy bajt indeksu okreÅ›la o ile klastrów ( + 1865 .LM198: + 1866 065e 8A81 ldd r24,Y+2 + 1867 0660 8111 cpse r24,__zero_reg__ + 1868 0662 00C0 rjmp .L124 + 414:../../../../Lib/ramdysk.c **** tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + 1870 .LM199: + 1871 0664 9110 cpse r9,__zero_reg__ + 1872 0666 00C0 rjmp .L125 + 415:../../../../Lib/ramdysk.c **** else + 1874 .LM200: + 1875 0668 EC81 ldd r30,Y+4 + 1876 066a FD81 ldd r31,Y+5 + 1877 066c 6B81 ldd r22,Y+3 + 1878 066e 8081 ld r24,Z + 1879 0670 0E94 0000 call znajdzKlasterN + 1880 0674 00C0 rjmp .L134 + 1881 .L125: + 417:../../../../Lib/ramdysk.c **** if (tmpKlaster != 0) //JeÅ›li znaleziono odpowiedni klaster, to + 1883 .LM201: + 1884 0676 892D mov r24,r9 + 1885 0678 0E94 0000 call nastepnyKlaster + 1886 .L134: + 1887 067c 982E mov r9,r24 + 418:../../../../Lib/ramdysk.c **** fd->Wsk = dataPtr(tmpKlaster, 0); //przestaw wskaźnik na poczÄ…tek tego klastra + 1889 .LM202: + 1890 067e 8823 tst r24 + 1891 0680 01F0 breq .L132 + 419:../../../../Lib/ramdysk.c **** else + 1893 .LM203: + 1894 0682 90E0 ldi r25,0 + 1895 0684 8058 subi r24,-128 + 1896 0686 9F4F sbci r25,-1 + 1897 0688 1882 st Y,__zero_reg__ + 1898 068a 8983 std Y+1,r24 + 1899 .L124: + 1900 068c 6881 ld r22,Y + 1901 068e 7981 ldd r23,Y+1 + 424:../../../../Lib/ramdysk.c **** { //dlBloku okreÅ›la ile zostaÅ‚o jeszcze bajtów do koÅ„ca kl + 1903 .LM204: + 1904 0690 A016 cp r10,r16 + 1905 0692 B106 cpc r11,r17 + 1906 0694 00F4 brsh .L127 + 426:../../../../Lib/ramdysk.c **** znaki +=dlBloku; //Przestawienie wskaźnika do tablicy, w której zapisujemy + 1908 .LM205: + 1909 0696 A501 movw r20,r10 + 1910 0698 C601 movw r24,r12 + 1911 069a 0E94 0000 call memcpy + 427:../../../../Lib/ramdysk.c **** fd->IndLo = 0; //Indeks wskazuje na poczÄ…tek nowego klastra + 1913 .LM206: + 1914 069e CA0C add r12,r10 + 1915 06a0 DB1C adc r13,r11 + 428:../../../../Lib/ramdysk.c **** fd->IndHi++; //Bardziej znaczÄ…cy bajt okreÅ›la zmianÄ™ klastra. Teraz ni + 1917 .LM207: + 1918 06a2 1A82 std Y+2,__zero_reg__ + 429:../../../../Lib/ramdysk.c **** doOdczytania -= dlBloku; //Uaktualnienie liczby bajtół jakÄ… należy odczytać + 1920 .LM208: + 1921 06a4 8B81 ldd r24,Y+3 + 1922 06a6 8F5F subi r24,lo8(-(1)) + 1923 06a8 8B83 std Y+3,r24 + 430:../../../../Lib/ramdysk.c **** *dlugosc += dlBloku; //Uaktualnienie + 1925 .LM209: + 1926 06aa 0A19 sub r16,r10 + 1927 06ac 1B09 sbc r17,r11 + 431:../../../../Lib/ramdysk.c **** dlBloku = 256; //Kolejny dostÄ™pny blok do odczytania, to dÅ‚ugość caÅ‚eg + 1929 .LM210: + 1930 06ae F701 movw r30,r14 + 1931 06b0 8081 ld r24,Z + 1932 06b2 9181 ldd r25,Z+1 + 1933 06b4 A80E add r10,r24 + 1934 06b6 B91E adc r11,r25 + 1935 06b8 B182 std Z+1,r11 + 1936 06ba A082 st Z,r10 + 432:../../../../Lib/ramdysk.c **** } + 1938 .LM211: + 1939 06bc A12C mov r10,__zero_reg__ + 1940 06be BB24 clr r11 + 1941 06c0 B394 inc r11 + 1942 06c2 00C0 rjmp .L131 + 1943 .L127: + 436:../../../../Lib/ramdysk.c **** fd->Wsk += doOdczytania; //Po zakoÅ„czeniu operacji odczytu nadal dziaÅ‚amy w tym sam + 1945 .LM212: + 1946 06c4 A801 movw r20,r16 + 1947 06c6 C601 movw r24,r12 + 1948 06c8 0E94 0000 call memcpy + 437:../../../../Lib/ramdysk.c **** fd->IndLo += doOdczytania; //Uaktualnianie indeksu. JesteÅ›my w tym samym klastrze, zat + 1950 .LM213: + 1951 06cc 8881 ld r24,Y + 1952 06ce 9981 ldd r25,Y+1 + 1953 06d0 800F add r24,r16 + 1954 06d2 911F adc r25,r17 + 1955 06d4 9983 std Y+1,r25 + 1956 06d6 8883 st Y,r24 + 438:../../../../Lib/ramdysk.c **** *dlugosc += doOdczytania; //Uaktualnianie liczby odczytanych bajtów + 1958 .LM214: + 1959 06d8 8A81 ldd r24,Y+2 + 1960 06da 800F add r24,r16 + 1961 06dc 8A83 std Y+2,r24 + 439:../../../../Lib/ramdysk.c **** doOdczytania = 0; //Tutaj równie dobrze może być brake + 1963 .LM215: + 1964 06de F701 movw r30,r14 + 1965 06e0 8081 ld r24,Z + 1966 06e2 9181 ldd r25,Z+1 + 1967 06e4 080F add r16,r24 + 1968 06e6 191F adc r17,r25 + 1969 06e8 1183 std Z+1,r17 + 1970 06ea 0083 st Z,r16 + 440:../../../../Lib/ramdysk.c **** } + 1972 .LM216: + 1973 06ec 00E0 ldi r16,0 + 1974 06ee 10E0 ldi r17,0 + 1975 06f0 00C0 rjmp .L131 + 1976 .L135: + 443:../../../../Lib/ramdysk.c **** } + 1978 .LM217: + 1979 06f2 80E0 ldi r24,0 + 1980 06f4 00C0 rjmp .L133 + 1981 .L132: + 421:../../../../Lib/ramdysk.c **** } + 1983 .LM218: + 1984 06f6 83E0 ldi r24,lo8(3) + 1985 .L133: + 1986 /* epilogue start */ + 444:../../../../Lib/ramdysk.c **** + 1988 .LM219: + 1989 06f8 DF91 pop r29 + 1990 06fa CF91 pop r28 + 1991 06fc 1F91 pop r17 + 1992 06fe 0F91 pop r16 + 1993 0700 FF90 pop r15 + 1994 0702 EF90 pop r14 + 1995 0704 DF90 pop r13 + 1996 0706 CF90 pop r12 + 1997 0708 BF90 pop r11 + 1998 070a AF90 pop r10 + 1999 070c 9F90 pop r9 + 2000 070e 0895 ret + 2007 .Lscope17: + 2009 .stabd 78,0,0 + 2013 .global ramDyskUstawWskaznik + 2015 ramDyskUstawWskaznik: + 2016 .stabd 46,0,0 + 447:../../../../Lib/ramdysk.c **** if (indeks == 0) //Sprawdzanie, czy wskaźnik nie pokazuje + 2018 .LM220: + 2019 .LFBB18: + 2020 0710 EF92 push r14 + 2021 0712 FF92 push r15 + 2022 0714 0F93 push r16 + 2023 0716 1F93 push r17 + 2024 0718 CF93 push r28 + 2025 071a DF93 push r29 + 2026 /* prologue: function */ + 2027 /* frame size = 0 */ + 2028 /* stack size = 6 */ + 2029 .L__stack_usage = 6 + 2030 071c EC01 movw r28,r24 + 448:../../../../Lib/ramdysk.c **** { //JeÅ›li tak, to nie ma potzeby tworzenia + 2032 .LM221: + 2033 071e 6115 cp r22,__zero_reg__ + 2034 0720 7105 cpc r23,__zero_reg__ + 2035 0722 01F4 brne .L137 + 450:../../../../Lib/ramdysk.c **** fd->IndHi = 0; + 2037 .LM222: + 2038 0724 1A82 std Y+2,__zero_reg__ + 451:../../../../Lib/ramdysk.c **** return 0; + 2040 .LM223: + 2041 0726 1B82 std Y+3,__zero_reg__ + 2042 0728 00C0 rjmp .L142 + 2043 .L137: + 454:../../../../Lib/ramdysk.c **** //JeÅ›li indeks jest wiÄ™kszy niż rozmia + 2045 .LM224: + 2046 072a 8B01 movw r16,r22 + 2047 072c 0150 subi r16,1 + 2048 072e 1109 sbc r17,__zero_reg__ + 457:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); //Przydzielanie pierwszego klastra dla pl + 2050 .LM225: + 2051 0730 EC80 ldd r14,Y+4 + 2052 0732 FD80 ldd r15,Y+5 + 2053 0734 F701 movw r30,r14 + 2054 0736 8081 ld r24,Z + 2055 0738 8111 cpse r24,__zero_reg__ + 2056 073a 00C0 rjmp .L139 + 458:../../../../Lib/ramdysk.c **** + 2058 .LM226: + 2059 073c 0E94 0000 call znajdzWolnyKlaster + 2060 0740 F701 movw r30,r14 + 2061 0742 8083 st Z,r24 + 2062 .L139: + 462:../../../../Lib/ramdysk.c **** fd->IndHi = klasterN; //oraz bardziej znaczÄ…cego bajtu indeksu + 2064 .LM227: + 2065 0744 0A83 std Y+2,r16 + 463:../../../../Lib/ramdysk.c **** + 2067 .LM228: + 2068 0746 1B83 std Y+3,r17 + 465:../../../../Lib/ramdysk.c **** if (nrKlastra == 0) + 2070 .LM229: + 2071 0748 EC81 ldd r30,Y+4 + 2072 074a FD81 ldd r31,Y+5 + 2073 074c 612F mov r22,r17 + 2074 074e 8081 ld r24,Z + 2075 0750 0E94 0000 call znajdzKlasterN + 2076 0754 182F mov r17,r24 + 466:../../../../Lib/ramdysk.c **** return 1; //Brak klastrów + 2078 .LM230: + 2079 0756 8823 tst r24 + 2080 0758 01F0 breq .L141 + 469:../../../../Lib/ramdysk.c **** + 2082 .LM231: + 2083 075a CE01 movw r24,r28 + 2084 075c 0E94 0000 call uaktualnijRozmiarPliku + 471:../../../../Lib/ramdysk.c **** if (fd->IndLo == 0) //JeÅ›li jesteÅ›my na poczÄ…tku klastra, + 2086 .LM232: + 2087 0760 8A81 ldd r24,Y+2 + 2088 0762 8F5F subi r24,lo8(-(1)) + 2089 0764 8A83 std Y+2,r24 + 472:../../../../Lib/ramdysk.c **** fd->IndHi++; //Uaktualniamy tylko bardziej znaczÄ…cy b + 2091 .LM233: + 2092 0766 8111 cpse r24,__zero_reg__ + 2093 0768 00C0 rjmp .L140 + 473:../../../../Lib/ramdysk.c **** else //JesteÅ›my w obszarze utworzonego klastr + 2095 .LM234: + 2096 076a 9B81 ldd r25,Y+3 + 2097 076c 9F5F subi r25,lo8(-(1)) + 2098 076e 9B83 std Y+3,r25 + 2099 0770 00C0 rjmp .L138 + 2100 .L140: + 475:../../../../Lib/ramdysk.c **** + 2102 .LM235: + 2103 0772 212F mov r18,r17 + 2104 0774 30E0 ldi r19,0 + 2105 0776 2058 subi r18,-128 + 2106 0778 3F4F sbci r19,-1 + 2107 077a 322F mov r19,r18 + 2108 077c 2227 clr r18 + 2109 077e A901 movw r20,r18 + 2110 0780 480F add r20,r24 + 2111 0782 511D adc r21,__zero_reg__ + 2112 0784 5983 std Y+1,r21 + 2113 0786 4883 st Y,r20 + 2114 .L142: + 477:../../../../Lib/ramdysk.c **** } + 2116 .LM236: + 2117 0788 80E0 ldi r24,0 + 2118 078a 00C0 rjmp .L138 + 2119 .L141: + 467:../../../../Lib/ramdysk.c **** + 2121 .LM237: + 2122 078c 81E0 ldi r24,lo8(1) + 2123 .L138: + 2124 /* epilogue start */ + 478:../../../../Lib/ramdysk.c **** + 2126 .LM238: + 2127 078e DF91 pop r29 + 2128 0790 CF91 pop r28 + 2129 0792 1F91 pop r17 + 2130 0794 0F91 pop r16 + 2131 0796 FF90 pop r15 + 2132 0798 EF90 pop r14 + 2133 079a 0895 ret + 2138 .Lscope18: + 2140 .stabd 78,0,0 + 2143 .global ramDyskUstawWskaznikNaKoniec + 2145 ramDyskUstawWskaznikNaKoniec: + 2146 .stabd 46,0,0 + 481:../../../../Lib/ramdysk.c **** if (fd == NULL) + 2148 .LM239: + 2149 .LFBB19: + 2150 079c CF93 push r28 + 2151 079e DF93 push r29 + 2152 /* prologue: function */ + 2153 /* frame size = 0 */ + 2154 /* stack size = 2 */ + 2155 .L__stack_usage = 2 + 2156 07a0 FC01 movw r30,r24 + 482:../../../../Lib/ramdysk.c **** return 1; + 2158 .LM240: + 2159 07a2 892B or r24,r25 + 2160 07a4 01F0 breq .L145 + 484:../../../../Lib/ramdysk.c **** fd->IndHi = fd->wpis->rozmiarHi; + 2162 .LM241: + 2163 07a6 A481 ldd r26,Z+4 + 2164 07a8 B581 ldd r27,Z+5 + 2165 07aa 1196 adiw r26,1 + 2166 07ac 8C91 ld r24,X + 2167 07ae 1197 sbiw r26,1 + 2168 07b0 8283 std Z+2,r24 + 485:../../../../Lib/ramdysk.c **** // fd->IndLo++; + 2170 .LM242: + 2171 07b2 1296 adiw r26,2 + 2172 07b4 9C91 ld r25,X + 2173 07b6 1297 sbiw r26,2 + 2174 07b8 9383 std Z+3,r25 + 488:../../../../Lib/ramdysk.c **** { + 2176 .LM243: + 2177 07ba 8823 tst r24 + 2178 07bc 01F0 breq .L144 + 2179 07be EF01 movw r28,r30 + 490:../../../../Lib/ramdysk.c **** fd->Wsk=dataPtr(tmpKlaster, fd->IndLo); + 2181 .LM244: + 2182 07c0 1296 adiw r26,2 + 2183 07c2 6C91 ld r22,X + 2184 07c4 1297 sbiw r26,2 + 2185 07c6 8C91 ld r24,X + 2186 07c8 0E94 0000 call znajdzKlasterN + 491:../../../../Lib/ramdysk.c **** } + 2188 .LM245: + 2189 07cc 282F mov r18,r24 + 2190 07ce 30E0 ldi r19,0 + 2191 07d0 2058 subi r18,-128 + 2192 07d2 3F4F sbci r19,-1 + 2193 07d4 322F mov r19,r18 + 2194 07d6 2227 clr r18 + 2195 07d8 8A81 ldd r24,Y+2 + 2196 07da 280F add r18,r24 + 2197 07dc 311D adc r19,__zero_reg__ + 2198 07de 3983 std Y+1,r19 + 2199 07e0 2883 st Y,r18 + 493:../../../../Lib/ramdysk.c **** } + 2201 .LM246: + 2202 07e2 80E0 ldi r24,0 + 2203 07e4 00C0 rjmp .L144 + 2204 .L145: + 483:../../../../Lib/ramdysk.c **** fd->IndLo = fd->wpis->rozmiarLo; + 2206 .LM247: + 2207 07e6 81E0 ldi r24,lo8(1) + 2208 .L144: + 2209 /* epilogue start */ + 494:../../../../Lib/ramdysk.c **** + 2211 .LM248: + 2212 07e8 DF91 pop r29 + 2213 07ea CF91 pop r28 + 2214 07ec 0895 ret + 2219 .Lscope19: + 2221 .stabd 78,0,0 + 2225 .global ramDyskDodajBlokXmodem + 2227 ramDyskDodajBlokXmodem: + 2228 .stabd 46,0,0 + 497:../../../../Lib/ramdysk.c **** if (nrBloku == 0) + 2230 .LM249: + 2231 .LFBB20: + 2232 07ee AF92 push r10 + 2233 07f0 BF92 push r11 + 2234 07f2 CF92 push r12 + 2235 07f4 DF92 push r13 + 2236 07f6 EF92 push r14 + 2237 07f8 FF92 push r15 + 2238 07fa 1F93 push r17 + 2239 07fc CF93 push r28 + 2240 07fe DF93 push r29 + 2241 /* prologue: function */ + 2242 /* frame size = 0 */ + 2243 /* stack size = 9 */ + 2244 .L__stack_usage = 9 + 498:../../../../Lib/ramdysk.c **** return NULL; + 2246 .LM250: + 2247 0800 6115 cp r22,__zero_reg__ + 2248 0802 7105 cpc r23,__zero_reg__ + 2249 0804 01F4 brne .L150 + 2250 .L153: + 499:../../../../Lib/ramdysk.c **** nrBloku --; + 2252 .LM251: + 2253 0806 80E0 ldi r24,0 + 2254 0808 90E0 ldi r25,0 + 2255 080a 00C0 rjmp .L151 + 2256 .L150: + 2257 080c EC01 movw r28,r24 + 500:../../../../Lib/ramdysk.c **** + 2259 .LM252: + 2260 080e 6B01 movw r12,r22 + 2261 0810 81E0 ldi r24,1 + 2262 0812 C81A sub r12,r24 + 2263 0814 D108 sbc r13,__zero_reg__ + 502:../../../../Lib/ramdysk.c **** //uint8_t indLo = 0; + 2265 .LM253: + 2266 0816 7601 movw r14,r12 + 2267 0818 F694 lsr r15 + 2268 081a E794 ror r14 + 2269 081c 1E2D mov r17,r14 + 506:../../../../Lib/ramdysk.c **** fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 2271 .LM254: + 2272 081e AC80 ldd r10,Y+4 + 2273 0820 BD80 ldd r11,Y+5 + 2274 0822 F501 movw r30,r10 + 2275 0824 8081 ld r24,Z + 2276 0826 8111 cpse r24,__zero_reg__ + 2277 0828 00C0 rjmp .L152 + 507:../../../../Lib/ramdysk.c **** if (fd->wpis->pierwszyKlaster == 0) + 2279 .LM255: + 2280 082a 0E94 0000 call znajdzWolnyKlaster + 2281 082e F501 movw r30,r10 + 2282 0830 8083 st Z,r24 + 2283 .L152: + 508:../../../../Lib/ramdysk.c **** return NULL; + 2285 .LM256: + 2286 0832 EC81 ldd r30,Y+4 + 2287 0834 FD81 ldd r31,Y+5 + 2288 0836 8081 ld r24,Z + 2289 0838 8823 tst r24 + 2290 083a 01F0 breq .L153 + 511:../../../../Lib/ramdysk.c **** if (tmpKlaster == 0) + 2292 .LM257: + 2293 083c 6E2D mov r22,r14 + 2294 083e 0E94 0000 call znajdzKlasterN + 512:../../../../Lib/ramdysk.c **** return NULL; + 2296 .LM258: + 2297 0842 8823 tst r24 + 2298 0844 01F0 breq .L153 + 2299 0846 EC81 ldd r30,Y+4 + 2300 0848 FD81 ldd r31,Y+5 + 2301 084a 282F mov r18,r24 + 2302 084c 30E0 ldi r19,0 + 514:../../../../Lib/ramdysk.c **** { + 2304 .LM259: + 2305 084e C0FE sbrs r12,0 + 2306 0850 00C0 rjmp .L154 + 517:../../../../Lib/ramdysk.c **** { + 2308 .LM260: + 2309 0852 8281 ldd r24,Z+2 + 2310 0854 1817 cp r17,r24 + 2311 0856 00F0 brlo .L155 + 519:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 0; + 2313 .LM261: + 2314 0858 E394 inc r14 + 2315 085a E282 std Z+2,r14 + 520:../../../../Lib/ramdysk.c **** } + 2317 .LM262: + 2318 085c EC81 ldd r30,Y+4 + 2319 085e FD81 ldd r31,Y+5 + 2320 0860 1182 std Z+1,__zero_reg__ + 2321 .L155: + 522:../../../../Lib/ramdysk.c **** } + 2323 .LM263: + 2324 0862 322F mov r19,r18 + 2325 0864 2227 clr r18 + 2326 0866 2058 subi r18,-128 + 2327 0868 3F47 sbci r19,127 + 2328 086a C901 movw r24,r18 + 2329 086c 00C0 rjmp .L151 + 2330 .L154: + 526:../../../../Lib/ramdysk.c **** { + 2332 .LM264: + 2333 086e 9281 ldd r25,Z+2 + 2334 0870 9117 cp r25,r17 + 2335 0872 00F4 brsh .L156 + 528:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 128; + 2337 .LM265: + 2338 0874 E282 std Z+2,r14 + 529:../../../../Lib/ramdysk.c **** } + 2340 .LM266: + 2341 0876 EC81 ldd r30,Y+4 + 2342 0878 FD81 ldd r31,Y+5 + 2343 087a 00C0 rjmp .L164 + 2344 .L156: + 531:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 128; + 2346 .LM267: + 2347 087c 9113 cpse r25,r17 + 2348 087e 00C0 rjmp .L157 + 531:../../../../Lib/ramdysk.c **** fd->wpis->rozmiarLo = 128; + 2350 .LM268: + 2351 0880 8181 ldd r24,Z+1 + 2352 0882 87FD sbrc r24,7 + 2353 0884 00C0 rjmp .L157 + 2354 .L164: + 532:../../../../Lib/ramdysk.c **** + 2356 .LM269: + 2357 0886 80E8 ldi r24,lo8(-128) + 2358 0888 8183 std Z+1,r24 + 2359 .L157: + 534:../../../../Lib/ramdysk.c **** } + 2361 .LM270: + 2362 088a 80E0 ldi r24,0 + 2363 088c 90E8 ldi r25,lo8(-128) + 2364 088e 920F add r25,r18 + 2365 .L151: + 2366 /* epilogue start */ + 537:../../../../Lib/ramdysk.c **** + 2368 .LM271: + 2369 0890 DF91 pop r29 + 2370 0892 CF91 pop r28 + 2371 0894 1F91 pop r17 + 2372 0896 FF90 pop r15 + 2373 0898 EF90 pop r14 + 2374 089a DF90 pop r13 + 2375 089c CF90 pop r12 + 2376 089e BF90 pop r11 + 2377 08a0 AF90 pop r10 + 2378 08a2 0895 ret + 2384 .Lscope20: + 2386 .stabd 78,0,0 + 2387 .section .rodata.str1.1,"aMS",@progbits,1 + 2388 .LC0: + 2389 0000 6E61 7A77 .string "nazwa\t\trozmiar\totwarty\r\n" + 2389 6109 0972 + 2389 6F7A 6D69 + 2389 6172 096F + 2389 7477 6172 + 2390 .LC1: + 2391 0019 0925 6409 .string "\t%d\t%d\r\n" + 2391 2564 0D0A + 2391 00 + 2392 .text + 2394 .global ramDyskDir + 2396 ramDyskDir: + 2397 .stabd 46,0,0 + 540:../../../../Lib/ramdysk.c **** fprintf(ostream, "nazwa\t\trozmiar\totwarty\r\n"); + 2399 .LM272: + 2400 .LFBB21: + 2401 08a4 5F92 push r5 + 2402 08a6 6F92 push r6 + 2403 08a8 7F92 push r7 + 2404 08aa 8F92 push r8 + 2405 08ac 9F92 push r9 + 2406 08ae AF92 push r10 + 2407 08b0 BF92 push r11 + 2408 08b2 CF92 push r12 + 2409 08b4 DF92 push r13 + 2410 08b6 EF92 push r14 + 2411 08b8 FF92 push r15 + 2412 08ba 0F93 push r16 + 2413 08bc 1F93 push r17 + 2414 08be CF93 push r28 + 2415 08c0 DF93 push r29 + 2416 /* prologue: function */ + 2417 /* frame size = 0 */ + 2418 /* stack size = 15 */ + 2419 .L__stack_usage = 15 + 2420 08c2 B82E mov r11,r24 + 2421 08c4 A92E mov r10,r25 + 541:../../../../Lib/ramdysk.c **** struct ramPlik *plik; + 2423 .LM273: + 2424 08c6 682F mov r22,r24 + 2425 08c8 792F mov r23,r25 + 2426 08ca 80E0 ldi r24,lo8(.LC0) + 2427 08cc 90E0 ldi r25,hi8(.LC0) + 2428 08ce 0E94 0000 call fputs + 543:../../../../Lib/ramdysk.c **** uint8_t tmpKlaster2; + 2430 .LM274: + 2431 08d2 712C mov r7,__zero_reg__ + 565:../../../../Lib/ramdysk.c **** plik++; + 2433 .LM275: + 2434 08d4 30E0 ldi r19,lo8(.LC1) + 2435 08d6 C32E mov r12,r19 + 2436 08d8 30E0 ldi r19,hi8(.LC1) + 2437 08da D32E mov r13,r19 + 2438 .L167: + 548:../../../../Lib/ramdysk.c **** for (tmp=0; tmp<16; tmp++) + 2440 .LM276: + 2441 08dc E72C mov r14,r7 + 2442 08de F12C mov r15,__zero_reg__ + 2443 08e0 8701 movw r16,r14 + 2444 08e2 0058 subi r16,-128 + 2445 08e4 1F4F sbci r17,-1 + 2446 08e6 102F mov r17,r16 + 2447 08e8 0027 clr r16 + 2448 08ea E801 movw r28,r16 + 2449 08ec 2596 adiw r28,5 + 2450 08ee 0B5F subi r16,-5 + 2451 08f0 1E4F sbci r17,-2 + 2452 .L172: + 2453 08f2 FE01 movw r30,r28 + 2454 08f4 3197 sbiw r30,1 + 551:../../../../Lib/ramdysk.c **** if (tmp3 == 0) + 2456 .LM277: + 2457 08f6 6080 ld r6,Z + 552:../../../../Lib/ramdysk.c **** break; //Ten wpis jest pusty. + 2459 .LM278: + 2460 08f8 6110 cpse r6,__zero_reg__ + 2461 08fa 00C0 rjmp .L166 + 2462 .L173: + 569:../../../../Lib/ramdysk.c **** } + 2464 .LM279: + 2465 08fc F701 movw r30,r14 + 2466 08fe E050 subi r30,lo8(-(klastry)) + 2467 0900 F040 sbci r31,hi8(-(klastry)) + 2468 0902 8081 ld r24,Z + 571:../../../../Lib/ramdysk.c **** } + 2470 .LM280: + 2471 0904 8715 cp r24,r7 + 2472 0906 01F4 brne .+2 + 2473 0908 00C0 rjmp .L184 + 2474 090a 782E mov r7,r24 + 2475 090c 00C0 rjmp .L167 + 2476 .L166: + 554:../../../../Lib/ramdysk.c **** for (tmp2=1; tmp2<8; tmp2++) + 2478 .LM281: + 2479 090e 6B2D mov r22,r11 + 2480 0910 7A2D mov r23,r10 + 2481 0912 862D mov r24,r6 + 2482 0914 90E0 ldi r25,0 + 2483 0916 0E94 0000 call fputc + 2484 091a 4E01 movw r8,r28 + 2485 091c 97E0 ldi r25,lo8(7) + 2486 091e 592E mov r5,r25 + 2487 .L171: + 561:../../../../Lib/ramdysk.c **** else + 2489 .LM282: + 2490 0920 6B2D mov r22,r11 + 2491 0922 7A2D mov r23,r10 + 557:../../../../Lib/ramdysk.c **** tmp3=plik->nazwa[tmp2]; + 2493 .LM283: + 2494 0924 6620 tst r6 + 2495 0926 01F0 breq .L169 + 558:../../../../Lib/ramdysk.c **** + 2497 .LM284: + 2498 0928 F401 movw r30,r8 + 2499 092a 6080 ld r6,Z + 560:../../../../Lib/ramdysk.c **** fputc(tmp3 , ostream); + 2501 .LM285: + 2502 092c 6620 tst r6 + 2503 092e 01F0 breq .L169 + 561:../../../../Lib/ramdysk.c **** else + 2505 .LM286: + 2506 0930 862D mov r24,r6 + 2507 0932 90E0 ldi r25,0 + 2508 0934 0E94 0000 call fputc + 2509 0938 00C0 rjmp .L170 + 2510 .L169: + 563:../../../../Lib/ramdysk.c **** } + 2512 .LM287: + 2513 093a 80E2 ldi r24,lo8(32) + 2514 093c 90E0 ldi r25,0 + 2515 093e 0E94 0000 call fputc + 2516 0942 612C mov r6,__zero_reg__ + 2517 .L170: + 2518 0944 5A94 dec r5 + 2519 0946 FFEF ldi r31,-1 + 2520 0948 8F1A sub r8,r31 + 2521 094a 9F0A sbc r9,r31 + 555:../../../../Lib/ramdysk.c **** { + 2523 .LM288: + 2524 094c 5110 cpse r5,__zero_reg__ + 2525 094e 00C0 rjmp .L171 + 2526 0950 FE01 movw r30,r28 + 2527 0952 3297 sbiw r30,2 + 565:../../../../Lib/ramdysk.c **** plik++; + 2529 .LM289: + 2530 0954 8081 ld r24,Z + 2531 0956 1F92 push __zero_reg__ + 2532 0958 8F93 push r24 + 2533 095a 3197 sbiw r30,1 + 2534 095c 2081 ld r18,Z + 2535 095e 30E0 ldi r19,0 + 2536 0960 322F mov r19,r18 + 2537 0962 2227 clr r18 + 2538 0964 3197 sbiw r30,1 + 2539 0966 8081 ld r24,Z + 2540 0968 280F add r18,r24 + 2541 096a 311D adc r19,__zero_reg__ + 2542 096c 3F93 push r19 + 2543 096e 2F93 push r18 + 2544 0970 DF92 push r13 + 2545 0972 CF92 push r12 + 2546 0974 AF92 push r10 + 2547 0976 BF92 push r11 + 2548 0978 0E94 0000 call fprintf + 2549 097c 6096 adiw r28,16 + 549:../../../../Lib/ramdysk.c **** { + 2551 .LM290: + 2552 097e 8DB7 in r24,__SP_L__ + 2553 0980 9EB7 in r25,__SP_H__ + 2554 0982 0896 adiw r24,8 + 2555 0984 0FB6 in __tmp_reg__,__SREG__ + 2556 0986 F894 cli + 2557 0988 9EBF out __SP_H__,r25 + 2558 098a 0FBE out __SREG__,__tmp_reg__ + 2559 098c 8DBF out __SP_L__,r24 + 2560 098e C017 cp r28,r16 + 2561 0990 D107 cpc r29,r17 + 2562 0992 01F0 breq .+2 + 2563 0994 00C0 rjmp .L172 + 2564 0996 00C0 rjmp .L173 + 2565 .L184: + 2566 /* epilogue start */ + 572:../../../../Lib/ramdysk.c **** + 2568 .LM291: + 2569 0998 DF91 pop r29 + 2570 099a CF91 pop r28 + 2571 099c 1F91 pop r17 + 2572 099e 0F91 pop r16 + 2573 09a0 FF90 pop r15 + 2574 09a2 EF90 pop r14 + 2575 09a4 DF90 pop r13 + 2576 09a6 CF90 pop r12 + 2577 09a8 BF90 pop r11 + 2578 09aa AF90 pop r10 + 2579 09ac 9F90 pop r9 + 2580 09ae 8F90 pop r8 + 2581 09b0 7F90 pop r7 + 2582 09b2 6F90 pop r6 + 2583 09b4 5F90 pop r5 + 2584 09b6 0895 ret + 2589 .Lscope21: + 2591 .stabd 78,0,0 + 2593 .global ramDyskLiczbaWolnychKlastrow + 2595 ramDyskLiczbaWolnychKlastrow: + 2596 .stabd 46,0,0 + 575:../../../../Lib/ramdysk.c **** uint8_t wynik=0; + 2598 .LM292: + 2599 .LFBB22: + 2600 /* prologue: function */ + 2601 /* frame size = 0 */ + 2602 /* stack size = 0 */ + 2603 .L__stack_usage = 0 + 2604 09b8 20E0 ldi r18,lo8(klastry+128) + 2605 09ba 30E0 ldi r19,hi8(klastry+128) + 575:../../../../Lib/ramdysk.c **** uint8_t wynik=0; + 2607 .LM293: + 2608 09bc F901 movw r30,r18 + 576:../../../../Lib/ramdysk.c **** uint8_t temp; + 2610 .LM294: + 2611 09be 80E0 ldi r24,0 + 2612 .L187: + 579:../../../../Lib/ramdysk.c **** wynik++; + 2614 .LM295: + 2615 09c0 9291 ld r25,-Z + 2616 09c2 9111 cpse r25,__zero_reg__ + 2617 09c4 00C0 rjmp .L186 + 580:../../../../Lib/ramdysk.c **** return wynik; + 2619 .LM296: + 2620 09c6 8F5F subi r24,lo8(-(1)) + 2621 .L186: + 2622 09c8 9FE7 ldi r25,lo8(127) + 2623 09ca 9E0F add r25,r30 + 578:../../../../Lib/ramdysk.c **** if (klastry[temp] == 0) + 2625 .LM297: + 2626 09cc 9213 cpse r25,r18 + 2627 09ce 00C0 rjmp .L187 + 2628 /* epilogue start */ + 582:../../../../Lib/ramdysk.c **** + 2630 .LM298: + 2631 09d0 0895 ret + 2636 .Lscope22: + 2638 .stabd 78,0,0 + 2644 .global ramDyskOtworzPlikStdIo + 2646 ramDyskOtworzPlikStdIo: + 2647 .stabd 46,0,0 + 600:../../../../Lib/ramdysk.c **** + 601:../../../../Lib/ramdysk.c **** uint8_t ramDyskOtworzPlikStdIo(const char *nazwa, struct ramPlikFd *fd, FILE *stream, uint8_t flags + 602:../../../../Lib/ramdysk.c **** { + 2649 .LM299: + 2650 .LFBB23: + 2651 09d2 EF92 push r14 + 2652 09d4 FF92 push r15 + 2653 09d6 0F93 push r16 + 2654 09d8 1F93 push r17 + 2655 09da CF93 push r28 + 2656 09dc DF93 push r29 + 2657 09de 1F92 push __zero_reg__ + 2658 09e0 CDB7 in r28,__SP_L__ + 2659 09e2 DEB7 in r29,__SP_H__ + 2660 /* prologue: function */ + 2661 /* frame size = 1 */ + 2662 /* stack size = 7 */ + 2663 .L__stack_usage = 7 + 2664 09e4 8B01 movw r16,r22 + 2665 09e6 7A01 movw r14,r20 + 603:../../../../Lib/ramdysk.c **** uint8_t wynik = ramDyskOtworzPlik(nazwa, fd); + 2667 .LM300: + 2668 09e8 2983 std Y+1,r18 + 2669 09ea 0E94 0000 call ramDyskOtworzPlik + 604:../../../../Lib/ramdysk.c **** if (wynik != 0) + 2671 .LM301: + 2672 09ee 2981 ldd r18,Y+1 + 2673 09f0 8111 cpse r24,__zero_reg__ + 2674 09f2 00C0 rjmp .L190 + 605:../../../../Lib/ramdysk.c **** return wynik; + 606:../../../../Lib/ramdysk.c **** + 607:../../../../Lib/ramdysk.c **** fdev_setup_stream(stream, putSTD, getSTD, flags); + 2676 .LM302: + 2677 09f4 40E0 ldi r20,lo8(gs(putSTD)) + 2678 09f6 50E0 ldi r21,hi8(gs(putSTD)) + 2679 09f8 F701 movw r30,r14 + 2680 09fa 5187 std Z+9,r21 + 2681 09fc 4087 std Z+8,r20 + 2682 09fe 40E0 ldi r20,lo8(gs(getSTD)) + 2683 0a00 50E0 ldi r21,hi8(gs(getSTD)) + 2684 0a02 5387 std Z+11,r21 + 2685 0a04 4287 std Z+10,r20 + 2686 0a06 2383 std Z+3,r18 + 608:../../../../Lib/ramdysk.c **** fdev_set_udata(stream, fd); + 2688 .LM303: + 2689 0a08 1587 std Z+13,r17 + 2690 0a0a 0487 std Z+12,r16 + 2691 .L190: + 2692 /* epilogue start */ + 609:../../../../Lib/ramdysk.c **** return 0; + 610:../../../../Lib/ramdysk.c **** } + 2694 .LM304: + 2695 0a0c 0F90 pop __tmp_reg__ + 2696 0a0e DF91 pop r29 + 2697 0a10 CF91 pop r28 + 2698 0a12 1F91 pop r17 + 2699 0a14 0F91 pop r16 + 2700 0a16 FF90 pop r15 + 2701 0a18 EF90 pop r14 + 2702 0a1a 0895 ret + 2707 .Lscope23: + 2709 .stabd 78,0,0 + 2712 .global ramDyskZamknijPlikStdIo + 2714 ramDyskZamknijPlikStdIo: + 2715 .stabd 46,0,0 + 611:../../../../Lib/ramdysk.c **** + 612:../../../../Lib/ramdysk.c **** uint8_t ramDyskZamknijPlikStdIo(FILE *stream) + 613:../../../../Lib/ramdysk.c **** { + 2717 .LM305: + 2718 .LFBB24: + 2719 0a1c 0F93 push r16 + 2720 0a1e 1F93 push r17 + 2721 0a20 CF93 push r28 + 2722 0a22 DF93 push r29 + 2723 /* prologue: function */ + 2724 /* frame size = 0 */ + 2725 /* stack size = 4 */ + 2726 .L__stack_usage = 4 + 2727 0a24 8C01 movw r16,r24 + 614:../../../../Lib/ramdysk.c **** struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + 2729 .LM306: + 2730 0a26 FC01 movw r30,r24 + 2731 0a28 C485 ldd r28,Z+12 + 2732 0a2a D585 ldd r29,Z+13 + 615:../../../../Lib/ramdysk.c **** ramDyskZamknijPlik(fd); + 2734 .LM307: + 2735 0a2c CE01 movw r24,r28 + 2736 0a2e 0E94 0000 call ramDyskZamknijPlik + 616:../../../../Lib/ramdysk.c **** fclose(stream); + 2738 .LM308: + 2739 0a32 C801 movw r24,r16 + 2740 0a34 0E94 0000 call fclose + 617:../../../../Lib/ramdysk.c **** return fd->wpis->lAktOtw; + 2742 .LM309: + 2743 0a38 EC81 ldd r30,Y+4 + 2744 0a3a FD81 ldd r31,Y+5 + 618:../../../../Lib/ramdysk.c **** } + 2746 .LM310: + 2747 0a3c 8381 ldd r24,Z+3 + 2748 /* epilogue start */ + 2749 0a3e DF91 pop r29 + 2750 0a40 CF91 pop r28 + 2751 0a42 1F91 pop r17 + 2752 0a44 0F91 pop r16 + 2753 0a46 0895 ret + 2758 .Lscope24: + 2760 .stabd 78,0,0 + 2761 .comm klastry,128,1 + 2762 .comm czasRtc,7,1 + 2763 .comm sockets,2,1 + 2764 .comm tcpDebugLevel,1,1 + 2765 .comm tcpDebugStream,2,1 + 2766 .comm IpMyConfig,15,1 + 2767 .comm udpDbgLevel,1,1 + 2768 .comm udpDbgStream,2,1 + 2769 .comm udpSocket,2,1 + 2770 .comm icmpDebugLevel,1,1 + 2771 .comm icmpDebug,2,1 + 2772 .comm arpDebugLevel,1,1 + 2773 .comm arpDebug,2,1 + 2774 .comm nicState,14,1 + 2775 .comm xSemaphoreRs485,2,1 + 2776 .comm lockSensors,2,1 + 2777 .comm portB,1,1 + 2778 .comm portA,1,1 + 2779 .comm xSemaphoreSpiSS,2,1 + 2780 .comm rollers,2,1 + 2781 .comm wwwport,1,1 + 2804 .Letext0: + 2805 .ident "GCC: (GNU) 4.9.2" + 2806 .global __do_copy_data + 2807 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 ramdysk.c + /tmp/ccQRYyUA.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccQRYyUA.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccQRYyUA.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccQRYyUA.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccQRYyUA.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccQRYyUA.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccQRYyUA.s:275 .text:0000000000000000 uaktualnijRozmiarPliku + /tmp/ccQRYyUA.s:339 .text:0000000000000044 nastepnyKlaster + *COM*:0000000000000080 klastry + /tmp/ccQRYyUA.s:422 .text:0000000000000090 znajdzKlasterN + /tmp/ccQRYyUA.s:477 .text:00000000000000bc znajdzPlik + /tmp/ccQRYyUA.s:636 .text:0000000000000176 znajdzWolnyKlaster + /tmp/ccQRYyUA.s:707 .text:00000000000001b4 ramDyskInit + /tmp/ccQRYyUA.s:748 .text:00000000000001d8 ramDyskUtworzPlik + /tmp/ccQRYyUA.s:928 .text:00000000000002a2 ramDyskOtworzPlik + /tmp/ccQRYyUA.s:987 .text:00000000000002ce ramDyskUsunPlik + /tmp/ccQRYyUA.s:1070 .text:0000000000000310 ramDyskZamknijPlik + /tmp/ccQRYyUA.s:1112 .text:0000000000000332 ramDyskCzyscPlik + /tmp/ccQRYyUA.s:1196 .text:0000000000000384 ramDyskZapiszBajtDoPliku + /tmp/ccQRYyUA.s:1314 .text:0000000000000400 putSTD + /tmp/ccQRYyUA.s:1343 .text:0000000000000410 ramDyskCzytajBajtZPliku + /tmp/ccQRYyUA.s:1458 .text:0000000000000482 getSTD + /tmp/ccQRYyUA.s:1514 .text:00000000000004b2 ramDyskZapiszBlokDoPliku + /tmp/ccQRYyUA.s:1740 .text:00000000000005c6 ramDyskCzytajBlokZPliku + /tmp/ccQRYyUA.s:2015 .text:0000000000000710 ramDyskUstawWskaznik + /tmp/ccQRYyUA.s:2145 .text:000000000000079c ramDyskUstawWskaznikNaKoniec + /tmp/ccQRYyUA.s:2227 .text:00000000000007ee ramDyskDodajBlokXmodem + /tmp/ccQRYyUA.s:2396 .text:00000000000008a4 ramDyskDir + /tmp/ccQRYyUA.s:2595 .text:00000000000009b8 ramDyskLiczbaWolnychKlastrow + /tmp/ccQRYyUA.s:2646 .text:00000000000009d2 ramDyskOtworzPlikStdIo + /tmp/ccQRYyUA.s:2714 .text:0000000000000a1c ramDyskZamknijPlikStdIo + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +strncmp +strncpy +memcpy +fputs +fputc +fprintf +fclose +__do_copy_data +__do_clear_bss diff --git a/Lib/spi.c b/Lib/spi.c new file mode 100644 index 0000000..415cb86 --- /dev/null +++ b/Lib/spi.c @@ -0,0 +1,57 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "hardware.h" +#include "spi.h" +#include "semphr.h" + + +void spiInit(void (*disableAllSpiDevicesFun)(void)) +{ + disableAllSpiDevicesFun(); + portENTER_CRITICAL(); + vSemaphoreCreateBinary(xSemaphoreSpiSS); + + SPCR = (1< + 2:../../../../Lib/spi.c **** #include + 3:../../../../Lib/spi.c **** #include "FreeRTOS.h" + 4:../../../../Lib/spi.c **** #include "queue.h" + 5:../../../../Lib/spi.c **** #include "task.h" + 6:../../../../Lib/spi.c **** #include "hardware.h" + 7:../../../../Lib/spi.c **** #include "spi.h" + 8:../../../../Lib/spi.c **** #include "semphr.h" + 9:../../../../Lib/spi.c **** + 10:../../../../Lib/spi.c **** + 11:../../../../Lib/spi.c **** void spiInit(void (*disableAllSpiDevicesFun)(void)) + 12:../../../../Lib/spi.c **** { + 277 .LM0: + 278 .LFBB1: + 279 /* prologue: function */ + 280 /* frame size = 0 */ + 281 /* stack size = 0 */ + 282 .L__stack_usage = 0 + 13:../../../../Lib/spi.c **** disableAllSpiDevicesFun(); + 284 .LM1: + 285 0000 FC01 movw r30,r24 + 286 0002 0995 icall + 14:../../../../Lib/spi.c **** portENTER_CRITICAL(); + 288 .LM2: + 289 /* #APP */ + 290 ; 14 "../../../../Lib/spi.c" 1 + 291 0004 0FB6 in __tmp_reg__, __SREG__ + 292 ; 0 "" 2 + 293 ; 14 "../../../../Lib/spi.c" 1 + 294 0006 F894 cli + 295 ; 0 "" 2 + 296 ; 14 "../../../../Lib/spi.c" 1 + 297 0008 0F92 push __tmp_reg__ + 298 ; 0 "" 2 + 15:../../../../Lib/spi.c **** vSemaphoreCreateBinary(xSemaphoreSpiSS); + 300 .LM3: + 301 /* #NOAPP */ + 302 000a 60E0 ldi r22,0 + 303 000c 81E0 ldi r24,lo8(1) + 304 000e 0E94 0000 call xQueueCreate + 305 0012 9093 0000 sts xSemaphoreSpiSS+1,r25 + 306 0016 8093 0000 sts xSemaphoreSpiSS,r24 + 307 001a 0097 sbiw r24,0 + 308 001c 01F0 breq .L2 + 310 .LM4: + 311 001e 20E0 ldi r18,0 + 312 0020 40E0 ldi r20,0 + 313 0022 50E0 ldi r21,0 + 314 0024 60E0 ldi r22,0 + 315 0026 70E0 ldi r23,0 + 316 0028 0E94 0000 call xQueueGenericSend + 317 .L2: + 16:../../../../Lib/spi.c **** + 17:../../../../Lib/spi.c **** SPCR = (1< +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "hardware.h" +#include "spi.h" +#include "semphr.h" + + +void spiInit(void (*disableAllSpiDevicesFun)(void)) +{ + disableAllSpiDevicesFun(); + portENTER_CRITICAL(); + vSemaphoreCreateBinary(xSemaphoreSpiSS); + + //SPCR = (1< +#include +#include "net.h" +#include "enc28j60.h" +#include "softwareConfig.h" + +//@{ + +extern uint8_t wwwport; +extern uint8_t macaddr[6]; +extern uint8_t ipaddr[4]; +extern int16_t info_hdr_len; +extern int16_t info_data_len; +extern uint8_t seqnum; // my initial tcp sequence number + + + +uint16_t checksum(uint8_t *buf1, uint16_t len,uint8_t type) +{ + // type 0=ip + // 1=udp + // 2=tcp + uint32_t sum = 0; + + //if(type==0){ + // // do not add anything + //} + if(type==1) + { + sum+=IP_PROTO_UDP; // protocol udp + // the length here is the length of udp (data+header len) + // =length given to this function - (IP.scr+IP.dst length) + sum+=len-8; // = real tcp len + } + if(type==2) + { + sum+=IP_PROTO_TCP; + // the length here is the length of tcp (data+header len) + // =length given to this function - (IP.scr+IP.dst length) + sum+=len-8; // = real tcp len + } + // build the sum of 16bit words + while(len >1) + { + sum += 0xFFFF & (((uint32_t)*buf1<<8)|*(buf1+1)); + buf1+=2; + len-=2; + } + // if there is a byte left then add it (padded with zero) + if (len) + { + sum += ((uint32_t)(0xFF & *buf1))<<8; + } + // now calculate the sum over the bytes in the sum + // until the result is only 16bit long + while (sum>>16) + { + sum = (sum & 0xFFFF)+(sum >> 16); + } + // build 1's complement: + return( (uint16_t) sum ^ 0xFFFF); +} + +// you must call this function once before you use any of the other functions: +void init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp) +{ + uint8_t i=0; + wwwport=wwwp; + while(i<4) + { + ipaddr[i]=myip[i]; + i++; + } + i=0; + while(i<6) + { + macaddr[i]=mymac[i]; + i++; + } +} + +uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf1,uint16_t len) +{ + uint8_t i=0; + + if (len<41) + return(0); + + if(buf1[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || buf1[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V) + return(0); + + while(i<4) + { + if(buf1[ETH_ARP_DST_IP_P+i] != ipaddr[i]) + return(0); + i++; + } + return(1); +} + +uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf1,uint16_t len) +{ + uint8_t i=0; + //eth+ip+udp header is 42 + if (len<42) + { + return(0); + } + if(buf1[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V || buf1[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V) + return(0); + + if (buf1[IP_HEADER_LEN_VER_P]!=0x45) + { + // must be IP V4 and 20 byte header + return(0); + } + while(i<4) + { + if(buf1[IP_DST_P+i]!=ipaddr[i]) + { + return(0); + } + i++; + } + return(1); +} + +// make a return eth header from a received eth packet +void make_eth(uint8_t *buf) +{ + uint8_t i=0; + // + //copy the destination mac from the source and fill my mac into src + while(i<6) + { + buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i]; + buf[ETH_SRC_MAC +i]=macaddr[i]; + i++; + } +} + +void fill_ip_hdr_checksum(uint8_t *buf1) +{ + uint16_t ck; + // clear the 2 byte checksum + buf1[IP_CHECKSUM_P]=0; + buf1[IP_CHECKSUM_P+1]=0; + buf1[IP_FLAGS_P]=0x40; // don't fragment + buf1[IP_FLAGS_P+1]=0; // fragement offset + buf1[IP_TTL_P]=64; // ttl + // calculate the checksum: + ck=checksum(&buf1[IP_P], IP_HEADER_LEN,0); + buf1[IP_CHECKSUM_P]=ck>>8; + buf1[IP_CHECKSUM_P+1]=ck& 0xff; +} + +void make_ip(uint8_t *buf1) +{ + uint8_t i=0; + while(i<4) + { + buf1[IP_DST_P+i]=buf1[IP_SRC_P+i]; + buf1[IP_SRC_P+i]=ipaddr[i]; + i++; + } + fill_ip_hdr_checksum(buf1); +} + +void make_tcphead(uint8_t *buf1,uint16_t rel_ack_num,uint8_t mss,uint8_t cp_seq) +{ + uint8_t i=0; + uint8_t tseq; + while(i<2){ + buf1[TCP_DST_PORT_H_P+i]=buf1[TCP_SRC_PORT_H_P+i]; + buf1[TCP_SRC_PORT_H_P+i]=0; // clear source port + i++; + } + // set source port (http): + buf1[TCP_SRC_PORT_L_P]=wwwport; + i=4; + // sequence numbers: + // add the rel ack num to SEQACK + while(i>0){ + rel_ack_num=buf1[TCP_SEQ_H_P+i-1]+rel_ack_num; + tseq=buf1[TCP_SEQACK_H_P+i-1]; + buf1[TCP_SEQACK_H_P+i-1]=0xff&rel_ack_num; + if (cp_seq){ + // copy the acknum sent to us into the sequence number + buf1[TCP_SEQ_H_P+i-1]=tseq; + }else{ + buf1[TCP_SEQ_H_P+i-1]= 0; // some preset vallue + } + rel_ack_num=rel_ack_num>>8; + i--; + } + if (cp_seq==0){ + // put inital seq number + buf1[TCP_SEQ_H_P+0]= 0; + buf1[TCP_SEQ_H_P+1]= 0; + // we step only the second byte, this allows us to send packts + // with 255 bytes or 512 (if we step the initial seqnum by 2) + buf1[TCP_SEQ_H_P+2]= seqnum; + buf1[TCP_SEQ_H_P+3]= 0; + // step the inititial seq num by something we will not use + // during this tcp session: + seqnum+=2; + } + // zero the checksum + buf1[TCP_CHECKSUM_H_P]=0; + buf1[TCP_CHECKSUM_L_P]=0; + + // The tcp header length is only a 4 bit field (the upper 4 bits). + // It is calculated in units of 4 bytes. + // E.g 24 bytes: 24/4=6 => 0x60=header len field + //buf1[TCP_HEADER_LEN_P]=(((TCP_HEADER_LEN_PLAIN+4)/4)) <<4; // 0x60 + if (mss){ + // the only option we set is MSS to 1408: + // 1408 in hex is 0x580 + buf1[TCP_OPTIONS_P]=2; + buf1[TCP_OPTIONS_P+1]=4; + buf1[TCP_OPTIONS_P+2]=0x05; + buf1[TCP_OPTIONS_P+3]=0x80; + // 24 bytes: + buf1[TCP_HEADER_LEN_P]=0x60; + }else{ + // no options: + // 20 bytes: + buf1[TCP_HEADER_LEN_P]=0x50; + } +} + +void make_arp_answer_from_request(uint8_t *buf1) +{ + uint8_t i=0; + // + make_eth(buf1); + buf1[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V; + buf1[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V; + // fill the mac addresses: + while(i<6){ + buf1[ETH_ARP_DST_MAC_P+i]=buf1[ETH_ARP_SRC_MAC_P+i]; + buf1[ETH_ARP_SRC_MAC_P+i]=macaddr[i]; + i++; + } + i=0; + while(i<4){ + buf1[ETH_ARP_DST_IP_P+i]=buf1[ETH_ARP_SRC_IP_P+i]; + buf1[ETH_ARP_SRC_IP_P+i]=ipaddr[i]; + i++; + } + // eth+arp is 42 bytes: + enc28j60PacketSend(42, buf1); +} + +void make_echo_reply_from_request(uint8_t *buf1,uint16_t len) +{ + make_eth(buf1); + make_ip(buf1); + buf1[ICMP_TYPE_P]=ICMP_TYPE_ECHOREPLY_V; + // we changed only the icmp.type field from request(=8) to reply(=0). + // we can therefore easily correct the checksum: + if (buf1[ICMP_CHECKSUM_P] > (0xff-0x08)){ + buf1[ICMP_CHECKSUM_P+1]++; + } + buf1[ICMP_CHECKSUM_P]+=0x08; + // + enc28j60PacketSend(len,buf1); +} + +// you can send a max of 220 bytes of data +void make_udp_reply_from_request(uint8_t *buf1, char *data, uint8_t datalen, uint16_t port) +{ + uint8_t i=0; + uint16_t ck; + make_eth(buf1); + if (datalen>220){ + datalen=220; + } + // total length field in the IP header must be set: + buf1[IP_TOTLEN_H_P]=0; + buf1[IP_TOTLEN_L_P]=IP_HEADER_LEN+UDP_HEADER_LEN+datalen; + make_ip(buf1); + // send to port: + //buf1[UDP_DST_PORT_H_P]=port>>8; + //buf1[UDP_DST_PORT_L_P]=port & 0xff; + // sent to port of sender and use "port" as own source: + buf1[UDP_DST_PORT_H_P]=buf1[UDP_SRC_PORT_H_P]; + buf1[UDP_DST_PORT_L_P]= buf1[UDP_SRC_PORT_L_P]; + buf1[UDP_SRC_PORT_H_P]=port>>8; + buf1[UDP_SRC_PORT_L_P]=port & 0xff; + // calculte the udp length: + buf1[UDP_LEN_H_P]=0; + buf1[UDP_LEN_L_P]=UDP_HEADER_LEN+datalen; + // zero the checksum + buf1[UDP_CHECKSUM_H_P]=0; + buf1[UDP_CHECKSUM_L_P]=0; + // copy the data: + while(i>8; + buf1[UDP_CHECKSUM_L_P]=ck& 0xff; + enc28j60PacketSend(UDP_HEADER_LEN+IP_HEADER_LEN+ETH_HEADER_LEN+datalen, buf1); +} + +void make_tcp_synack_from_syn(uint8_t *buf1) +{ + uint16_t ck; + make_eth(buf1); + // total length field in the IP header must be set: + // 20 bytes IP + 24 bytes (20tcp+4tcp options) + buf1[IP_TOTLEN_H_P]=0; + buf1[IP_TOTLEN_L_P]=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4; + make_ip(buf1); + buf1[TCP_FLAGS_P]=TCP_FLAGS_SYNACK_V; + make_tcphead(buf1, 1, 1, 0); + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + 4 (one option: mss) + ck=checksum(&buf1[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+4,2); + buf1[TCP_CHECKSUM_H_P]=ck>>8; + buf1[TCP_CHECKSUM_L_P]=ck& 0xff; + // add 4 for option mss: + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4+ETH_HEADER_LEN, buf1); +} + +uint16_t get_tcp_data_pointer(void) +{ + if (info_data_len) + { + return((uint16_t)TCP_SRC_PORT_H_P+info_hdr_len); + } + else + { + return(0); + } +} + +void init_len_info(uint8_t *buf1) +{ + info_data_len=(((int16_t)buf1[IP_TOTLEN_H_P])<<8)|(buf1[IP_TOTLEN_L_P]&0xff); + info_data_len-=IP_HEADER_LEN; + info_hdr_len=(buf1[TCP_HEADER_LEN_P]>>4)*4; // generate len in bytes; + info_data_len-=info_hdr_len; + if (info_data_len<=0) + { + info_data_len=0; + } +} + +char *getBufPosToWrite(uint8_t *buf, uint16_t pos) +{ + return &buf[TCP_CHECKSUM_L_P+3+pos]; +} + +uint16_t fill_tcp_data_p(uint8_t *buf1, uint16_t pos, const prog_char *progmem_s) +{ + char c; + // fill in tcp data at position pos + // + // with no options the data starts after the checksum + 2 more bytes (urgent ptr) + while ((c = pgm_read_byte(progmem_s++))) + { + buf1[TCP_CHECKSUM_L_P+3+pos]=c; + pos++; + } + return(pos); +} + +uint16_t fill_tcp_data(uint8_t *buf1,uint16_t pos, const char *s) +{ + // fill in tcp data at position pos + // + // with no options the data starts after the checksum + 2 more bytes (urgent ptr) + while (*s) + { + buf1[TCP_CHECKSUM_L_P+3+pos]=*s; + pos++; + s++; + } + return(pos); +} + +uint16_t add_tcp_byte(uint8_t *buf1,uint16_t pos, const char data) +{ + buf1[TCP_CHECKSUM_L_P+3+pos]=data; + pos++; + + return(pos); +} + + +void make_tcp_ack_from_any(uint8_t *buf1) +{ + uint16_t j; + make_eth(buf1); + // fill the header: + buf1[TCP_FLAGS_P]=TCP_FLAGS_ACK_V; + if (info_data_len==0) + { + // if there is no data then we must still acknoledge one packet + make_tcphead(buf1, 1, 0, 1); // no options + } + else + { + make_tcphead(buf1,info_data_len,0,1); // no options + } + + // total length field in the IP header must be set: + // 20 bytes IP + 20 bytes tcp (when no options) + j = IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN; + buf1[IP_TOTLEN_H_P] = j>>8; + buf1[IP_TOTLEN_L_P]=j& 0xff; + make_ip(buf1); + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len + j=checksum(&buf1[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN,2); + buf1[TCP_CHECKSUM_H_P]=j>>8; + buf1[TCP_CHECKSUM_L_P]=j& 0xff; + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+ETH_HEADER_LEN,buf1); +} + +void make_tcp_ack_with_data(uint8_t *buf1,uint16_t dlen) +{ + uint16_t j; + // fill the header: + // This code requires that we send only one data packet + // because we keep no state information. We must therefore set + // the fin here: + buf1[TCP_FLAGS_P]=TCP_FLAGS_ACK_V|TCP_FLAGS_PUSH_V|TCP_FLAGS_FIN_V; + + // total length field in the IP header must be set: + // 20 bytes IP + 20 bytes tcp (when no options) + len of data + j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen; + buf1[IP_TOTLEN_H_P]=j>>8; + buf1[IP_TOTLEN_L_P]=j& 0xff; + fill_ip_hdr_checksum(buf1); + // zero the checksum + buf1[TCP_CHECKSUM_H_P]=0; + buf1[TCP_CHECKSUM_L_P]=0; + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len + j=checksum(&buf1[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlen, 2); + buf1[TCP_CHECKSUM_H_P]=j>>8; + buf1[TCP_CHECKSUM_L_P]=j& 0xff; + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen+ETH_HEADER_LEN, buf1); +} +//@} +/* end of ip_arp_udp.c */ diff --git a/Lib/tlvProt.c b/Lib/tlvProt.c new file mode 100644 index 0000000..13000a3 --- /dev/null +++ b/Lib/tlvProt.c @@ -0,0 +1,178 @@ +#include "tlvProt.h" + +void tlvIinitializeInterpreter(tlvInterpreter_t *tlvInt, FILE *ioStr, FILE *errStr, const tlvCommand_t *commands) +{ + tlvCommand_t tmpCmd; + memset(tlvInt, 0, sizeof(struct tlvInterpreter)); + + tlvInt->ioStr = ioStr; + tlvInt->errStr = errStr; + tlvInt->commands = commands; + + tlvInt->noOfCmds = -1; + do + { + memcpy_P(&tmpCmd, commands, sizeof(tlvCommand_t)); + tlvInt->noOfCmds++; + commands++; + } + while(tmpCmd.type != 0); +} + +void tlvCalculateCrc(tlvMsg_t *message) +{ + uint16_t crc; + crc = _crc16_update(0, message->address); + crc = _crc16_update(0, message->type); + crc = _crc16_update(0, message->dtaLen); + + uint8_t i; + for (i=0; idtaLen; i++) + crc = _crc16_update(0, message->data[i]); + + message->crcLo = (uint8_t) crc; + message->crcHi = (uint8_t) crc>>8; +} + +void tlvCalculateCrcSepDta(tlvMsg_t *message, const uint8_t dta[]) +{ + uint16_t crc; + crc = _crc16_update(0, message->address); + crc = _crc16_update(0, message->type); + crc = _crc16_update(0, message->dtaLen); + + uint8_t i; + for (i=0; idtaLen; i++) + crc = _crc16_update(0, dta[i]); + + message->crcLo = (uint8_t) crc; + message->crcHi = (uint8_t) crc>>8; +} + +uint8_t tlvCheckCrc(tlvMsg_t *message) +{ + uint16_t crc; + crc = _crc16_update(0, message->address); + crc = _crc16_update(0, message->type); + crc = _crc16_update(0, message->dtaLen); + + uint8_t i; + for (i=0; idtaLen; i++) + crc = _crc16_update(0, message->data[i]); + + uint8_t crcLo = (uint8_t) crc; + uint8_t crcHi = (uint8_t) crc>>8; + + if (message->crcLo != crcLo) + return 0; + + if (message->crcHi != crcHi) + return 0; + + return 1; +} + +void tlvProcessDta(tlvInterpreter_t *tlvInt, uint8_t dta) +{ + uint8_t i, j; + struct tlvMsg *myRecMsg = (struct tlvMsg *)tlvInt->buffer; + + if (tlvInt->bufIdx >= TLV_BUF_LEN) + { + fprintf_P(tlvInt->errStr, PSTR("# TLV buffer overflow")); + tlvInt->bufIdx = 0; + } + + if (tlvInt->bufIdx == 0 && dta != TLV_SYNC) + return; + + tlvInt->buffer[tlvInt->bufIdx] = dta; + tlvInt->bufIdx++; + + if (tlvInt->bufIdx < sizeof(struct tlvMsg)) + return; + + if (tlvInt->bufIdx < myRecMsg->dtaLen + sizeof(struct tlvMsg)) + return; + + if (tlvCheckCrc(myRecMsg) == 0) + { + fprintf_P(tlvInt->errStr, PSTR("# CRC mismatch: buffer idx %d\r\n"), tlvInt->bufIdx); + fprintf_P(tlvInt->errStr, PSTR("\taddress : %x\r\n"), myRecMsg->address); + fprintf_P(tlvInt->errStr, PSTR("\tmsg type : %x\r\n"), myRecMsg->type); + fprintf_P(tlvInt->errStr, PSTR("\tcrc lo : %x\r\n"), myRecMsg->crcLo); + fprintf_P(tlvInt->errStr, PSTR("\tcrc hi : %x\r\n"), myRecMsg->crcHi); + fprintf_P(tlvInt->errStr, PSTR("\tdta len : %x\r\n"), myRecMsg->dtaLen); + + fprintf_P(tlvInt->errStr, PSTR("\tdata:")); + for(i=sizeof(struct tlvMsg); ibufIdx; i++) + fprintf_P(tlvInt->errStr, PSTR(" %2x"), tlvInt->buffer[i]); + fprintf_P(tlvInt->errStr, PSTR("\r\n")); + + for (i=1; ibufIdx; i++) + { + if (tlvInt->buffer[i] == TLV_SYNC) + { + for (j=0; i+j < tlvInt->bufIdx; j++) + tlvInt->buffer[j] = tlvInt->buffer[i+j]; + + tlvInt->bufIdx -= i; + return; + } + } + tlvInt->bufIdx = 0; + return; + } + + tlvCommand_t tmp; // We need to create this object. We can't directly + for (i=0; inoOfCmds; i++) + { + memcpy_P(&tmp, &tlvInt->commands[i], sizeof(tlvCommand_t)); + if (myRecMsg->type == tmp.type) + { + tmp.fun(tlvInt, myRecMsg); + break; + } + } + if (i == tlvInt->noOfCmds) + fprintf_P(tlvInt->errStr, PSTR("! Unknown command: %d\r\n"), myRecMsg->type); + else + fprintf_P(tlvInt->errStr, PSTR("TLV command %x was executed\r\n"), myRecMsg->type); + + tlvInt->bufIdx = 0; +} + +void sendTlvMsg(tlvMsg_t *message, FILE *ostream) +{ + int i, len; + len = sizeof(struct tlvMsg) + message->dtaLen; + uint8_t *ptr = (uint8_t *) message; + + for (i=0; idtaLen; + for (i=0; i + 40:/usr/lib/avr/include/util/crc16.h **** + 41:/usr/lib/avr/include/util/crc16.h **** /** \file */ + 42:/usr/lib/avr/include/util/crc16.h **** /** \defgroup util_crc : CRC Computations + 43:/usr/lib/avr/include/util/crc16.h **** \code#include \endcode + 44:/usr/lib/avr/include/util/crc16.h **** + 45:/usr/lib/avr/include/util/crc16.h **** This header file provides a optimized inline functions for calculating + 46:/usr/lib/avr/include/util/crc16.h **** cyclic redundancy checks (CRC) using common polynomials. + 47:/usr/lib/avr/include/util/crc16.h **** + 48:/usr/lib/avr/include/util/crc16.h **** \par References: + 49:/usr/lib/avr/include/util/crc16.h **** + 50:/usr/lib/avr/include/util/crc16.h **** \par + 51:/usr/lib/avr/include/util/crc16.h **** + 52:/usr/lib/avr/include/util/crc16.h **** See the Dallas Semiconductor app note 27 for 8051 assembler example and + 53:/usr/lib/avr/include/util/crc16.h **** general CRC optimization suggestions. The table on the last page of the + 54:/usr/lib/avr/include/util/crc16.h **** app note is the key to understanding these implementations. + 55:/usr/lib/avr/include/util/crc16.h **** + 56:/usr/lib/avr/include/util/crc16.h **** \par + 57:/usr/lib/avr/include/util/crc16.h **** + 58:/usr/lib/avr/include/util/crc16.h **** Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e + 59:/usr/lib/avr/include/util/crc16.h **** Embedded \e Systems \e Programming. This may be difficult to find, but it + 60:/usr/lib/avr/include/util/crc16.h **** explains CRC's in very clear and concise terms. Well worth the effort to + 61:/usr/lib/avr/include/util/crc16.h **** obtain a copy. + 62:/usr/lib/avr/include/util/crc16.h **** + 63:/usr/lib/avr/include/util/crc16.h **** A typical application would look like: + 64:/usr/lib/avr/include/util/crc16.h **** + 65:/usr/lib/avr/include/util/crc16.h **** \code + 66:/usr/lib/avr/include/util/crc16.h **** // Dallas iButton test vector. + 67:/usr/lib/avr/include/util/crc16.h **** uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + 68:/usr/lib/avr/include/util/crc16.h **** + 69:/usr/lib/avr/include/util/crc16.h **** int + 70:/usr/lib/avr/include/util/crc16.h **** checkcrc(void) + 71:/usr/lib/avr/include/util/crc16.h **** { + 72:/usr/lib/avr/include/util/crc16.h **** uint8_t crc = 0, i; + 73:/usr/lib/avr/include/util/crc16.h **** + 74:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + 75:/usr/lib/avr/include/util/crc16.h **** crc = _crc_ibutton_update(crc, serno[i]); + 76:/usr/lib/avr/include/util/crc16.h **** + 77:/usr/lib/avr/include/util/crc16.h **** return crc; // must be 0 + 78:/usr/lib/avr/include/util/crc16.h **** } + 79:/usr/lib/avr/include/util/crc16.h **** \endcode + 80:/usr/lib/avr/include/util/crc16.h **** */ + 81:/usr/lib/avr/include/util/crc16.h **** + 82:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 83:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-16 calculation. + 84:/usr/lib/avr/include/util/crc16.h **** + 85:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ 86:/usr/lib/avr/include/util/crc16.h **** Initial value: 0xffff + 87:/usr/lib/avr/include/util/crc16.h **** + 88:/usr/lib/avr/include/util/crc16.h **** This CRC is normally used in disk-drive controllers. + 89:/usr/lib/avr/include/util/crc16.h **** + 90:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 91:/usr/lib/avr/include/util/crc16.h **** + 92:/usr/lib/avr/include/util/crc16.h **** \code + 93:/usr/lib/avr/include/util/crc16.h **** uint16_t + 94:/usr/lib/avr/include/util/crc16.h **** crc16_update(uint16_t crc, uint8_t a) + 95:/usr/lib/avr/include/util/crc16.h **** { + 96:/usr/lib/avr/include/util/crc16.h **** int i; + 97:/usr/lib/avr/include/util/crc16.h **** + 98:/usr/lib/avr/include/util/crc16.h **** crc ^= a; + 99:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < 8; ++i) + 100:/usr/lib/avr/include/util/crc16.h **** { + 101:/usr/lib/avr/include/util/crc16.h **** if (crc & 1) + 102:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1) ^ 0xA001; + 103:/usr/lib/avr/include/util/crc16.h **** else + 104:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1); + 105:/usr/lib/avr/include/util/crc16.h **** } + 106:/usr/lib/avr/include/util/crc16.h **** + 107:/usr/lib/avr/include/util/crc16.h **** return crc; + 108:/usr/lib/avr/include/util/crc16.h **** } + 109:/usr/lib/avr/include/util/crc16.h **** + 110:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 111:/usr/lib/avr/include/util/crc16.h **** + 112:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 113:/usr/lib/avr/include/util/crc16.h **** _crc16_update(uint16_t __crc, uint8_t __data) + 507 .LM0: + 508 .LFBB1: + 509 /* prologue: function */ + 510 /* frame size = 0 */ + 511 /* stack size = 0 */ + 512 .L__stack_usage = 0 + 114:/usr/lib/avr/include/util/crc16.h **** { + 115:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp; + 116:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; + 117:/usr/lib/avr/include/util/crc16.h **** + 118:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 119:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%2" "\n\t" + 120:/usr/lib/avr/include/util/crc16.h **** "mov %1,%A0" "\n\t" + 121:/usr/lib/avr/include/util/crc16.h **** "swap %1" "\n\t" + 122:/usr/lib/avr/include/util/crc16.h **** "eor %1,%A0" "\n\t" + 123:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 124:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 125:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 126:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 127:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 128:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 129:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 130:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x07" "\n\t" + 131:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%A0" "\n\t" + 132:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%B0" "\n\t" + 133:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 134:/usr/lib/avr/include/util/crc16.h **** "ror __tmp_reg__" "\n\t" + 135:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 136:/usr/lib/avr/include/util/crc16.h **** "mov %B0,__tmp_reg__" "\n\t" + 137:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" "\n\t" + 138:/usr/lib/avr/include/util/crc16.h **** "lsr __tmp_reg__" "\n\t" + 139:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 140:/usr/lib/avr/include/util/crc16.h **** "eor %B0,__tmp_reg__" "\n\t" + 141:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" + 142:/usr/lib/avr/include/util/crc16.h **** : "=r" (__ret), "=d" (__tmp) + 143:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 144:/usr/lib/avr/include/util/crc16.h **** : "r0" + 145:/usr/lib/avr/include/util/crc16.h **** ); + 146:/usr/lib/avr/include/util/crc16.h **** return __ret; + 147:/usr/lib/avr/include/util/crc16.h **** } + 514 .LM1: + 515 0000 20E0 ldi r18,0 + 516 0002 30E0 ldi r19,0 + 517 0004 A901 movw r20,r18 + 518 /* #APP */ + 519 ; 118 "/usr/lib/avr/include/util/crc16.h" 1 + 520 0006 4827 eor r20,r24 + 521 0008 242F mov r18,r20 + 522 000a 2295 swap r18 + 523 000c 2427 eor r18,r20 + 524 000e 022E mov __tmp_reg__,r18 + 525 0010 2695 lsr r18 + 526 0012 2695 lsr r18 + 527 0014 2025 eor r18,__tmp_reg__ + 528 0016 022E mov __tmp_reg__,r18 + 529 0018 2695 lsr r18 + 530 001a 2025 eor r18,__tmp_reg__ + 531 001c 2770 andi r18,0x07 + 532 001e 042E mov __tmp_reg__,r20 + 533 0020 452F mov r20,r21 + 534 0022 2695 lsr r18 + 535 0024 0794 ror __tmp_reg__ + 536 0026 2795 ror r18 + 537 0028 502D mov r21,__tmp_reg__ + 538 002a 4227 eor r20,r18 + 539 002c 0694 lsr __tmp_reg__ + 540 002e 2795 ror r18 + 541 0030 5025 eor r21,__tmp_reg__ + 542 0032 4227 eor r20,r18 + 543 ; 0 "" 2 + 544 /* #NOAPP */ + 545 0034 CA01 movw r24,r20 + 546 0036 0895 ret + 548 .Lscope1: + 550 .stabd 78,0,0 + 556 .global tlvIinitializeInterpreter + 558 tlvIinitializeInterpreter: + 559 .stabd 46,0,0 + 561 .Ltext2: + 1:../../../Lib/tlvProt.c **** #include "tlvProt.h" + 2:../../../Lib/tlvProt.c **** + 3:../../../Lib/tlvProt.c **** void tlvIinitializeInterpreter(tlvInterpreter_t *tlvInt, FILE *ioStr, FILE *errStr, const tlvComman + 4:../../../Lib/tlvProt.c **** { + 563 .LM2: + 564 .LFBB2: + 565 0038 EF92 push r14 + 566 003a FF92 push r15 + 567 003c 0F93 push r16 + 568 003e 1F93 push r17 + 569 0040 CF93 push r28 + 570 0042 DF93 push r29 + 571 0044 00D0 rcall . + 572 0046 CDB7 in r28,__SP_L__ + 573 0048 DEB7 in r29,__SP_H__ + 574 /* prologue: function */ + 575 /* frame size = 3 */ + 576 /* stack size = 9 */ + 577 .L__stack_usage = 9 + 578 004a 8C01 movw r16,r24 + 579 004c 7901 movw r14,r18 + 5:../../../Lib/tlvProt.c **** tlvCommand_t tmpCmd; + 6:../../../Lib/tlvProt.c **** memset(tlvInt, 0, sizeof(struct tlvInterpreter)); + 581 .LM3: + 582 004e 88E2 ldi r24,lo8(40) + 583 0050 F801 movw r30,r16 + 584 0: + 585 0052 1192 st Z+,__zero_reg__ + 586 0054 8A95 dec r24 + 587 0056 01F4 brne 0b + 7:../../../Lib/tlvProt.c **** + 8:../../../Lib/tlvProt.c **** tlvInt->ioStr = ioStr; + 589 .LM4: + 590 0058 F801 movw r30,r16 + 591 005a 64A3 std Z+36,r22 + 592 005c 75A3 std Z+37,r23 + 9:../../../Lib/tlvProt.c **** tlvInt->errStr = errStr; + 594 .LM5: + 595 005e 46A3 std Z+38,r20 + 596 0060 57A3 std Z+39,r21 + 10:../../../Lib/tlvProt.c **** tlvInt->commands = commands; + 598 .LM6: + 599 0062 21A3 std Z+33,r18 + 600 0064 32A3 std Z+34,r19 + 11:../../../Lib/tlvProt.c **** + 12:../../../Lib/tlvProt.c **** tlvInt->noOfCmds = -1; + 602 .LM7: + 603 0066 8FEF ldi r24,lo8(-1) + 604 0068 83A3 std Z+35,r24 + 605 .L3: + 13:../../../Lib/tlvProt.c **** do + 14:../../../Lib/tlvProt.c **** { + 15:../../../Lib/tlvProt.c **** memcpy_P(&tmpCmd, commands, sizeof(tlvCommand_t)); + 607 .LM8: + 608 006a 43E0 ldi r20,lo8(3) + 609 006c 50E0 ldi r21,0 + 610 006e B701 movw r22,r14 + 611 0070 CE01 movw r24,r28 + 612 0072 0196 adiw r24,1 + 613 0074 0E94 0000 call memcpy_P + 16:../../../Lib/tlvProt.c **** tlvInt->noOfCmds++; + 615 .LM9: + 616 0078 F801 movw r30,r16 + 617 007a 83A1 ldd r24,Z+35 + 618 007c 8F5F subi r24,lo8(-(1)) + 619 007e 83A3 std Z+35,r24 + 17:../../../Lib/tlvProt.c **** commands++; + 621 .LM10: + 622 0080 F3E0 ldi r31,3 + 623 0082 EF0E add r14,r31 + 624 0084 F11C adc r15,__zero_reg__ + 18:../../../Lib/tlvProt.c **** } + 19:../../../Lib/tlvProt.c **** while(tmpCmd.type != 0); + 626 .LM11: + 627 0086 8981 ldd r24,Y+1 + 628 0088 8111 cpse r24,__zero_reg__ + 629 008a 00C0 rjmp .L3 + 630 /* epilogue start */ + 20:../../../Lib/tlvProt.c **** } + 632 .LM12: + 633 008c 2396 adiw r28,3 + 634 008e CDBF out __SP_L__,r28 + 635 0090 DEBF out __SP_H__,r29 + 636 0092 DF91 pop r29 + 637 0094 CF91 pop r28 + 638 0096 1F91 pop r17 + 639 0098 0F91 pop r16 + 640 009a FF90 pop r15 + 641 009c EF90 pop r14 + 642 009e 0895 ret + 647 .Lscope2: + 649 .stabd 78,0,0 + 652 .global tlvCalculateCrc + 654 tlvCalculateCrc: + 655 .stabd 46,0,0 + 21:../../../Lib/tlvProt.c **** + 22:../../../Lib/tlvProt.c **** void tlvCalculateCrc(tlvMsg_t *message) + 23:../../../Lib/tlvProt.c **** { + 657 .LM13: + 658 .LFBB3: + 659 00a0 1F93 push r17 + 660 00a2 CF93 push r28 + 661 00a4 DF93 push r29 + 662 /* prologue: function */ + 663 /* frame size = 0 */ + 664 /* stack size = 3 */ + 665 .L__stack_usage = 3 + 666 00a6 EC01 movw r28,r24 + 24:../../../Lib/tlvProt.c **** uint16_t crc; + 25:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->address); + 668 .LM14: + 669 00a8 8981 ldd r24,Y+1 + 670 00aa 0E94 0000 call _crc16_update.constprop.0 + 26:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->type); + 672 .LM15: + 673 00ae 8A81 ldd r24,Y+2 + 674 00b0 0E94 0000 call _crc16_update.constprop.0 + 27:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->dtaLen); + 676 .LM16: + 677 00b4 8B81 ldd r24,Y+3 + 678 00b6 0E94 0000 call _crc16_update.constprop.0 + 28:../../../Lib/tlvProt.c **** + 29:../../../Lib/tlvProt.c **** uint8_t i; + 30:../../../Lib/tlvProt.c **** for (i=0; idtaLen; i++) + 680 .LM17: + 681 00ba 10E0 ldi r17,0 + 682 .L7: + 684 .LM18: + 685 00bc 9B81 ldd r25,Y+3 + 686 00be 1917 cp r17,r25 + 687 00c0 00F4 brsh .L9 + 31:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->data[i]); + 689 .LM19: + 690 00c2 FE01 movw r30,r28 + 691 00c4 E10F add r30,r17 + 692 00c6 F11D adc r31,__zero_reg__ + 693 00c8 8681 ldd r24,Z+6 + 694 00ca 0E94 0000 call _crc16_update.constprop.0 + 30:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->data[i]); + 696 .LM20: + 697 00ce 1F5F subi r17,lo8(-(1)) + 698 00d0 00C0 rjmp .L7 + 699 .L9: + 32:../../../Lib/tlvProt.c **** + 33:../../../Lib/tlvProt.c **** message->crcLo = (uint8_t) crc; + 701 .LM21: + 702 00d2 8C83 std Y+4,r24 + 34:../../../Lib/tlvProt.c **** message->crcHi = (uint8_t) crc>>8; + 704 .LM22: + 705 00d4 1D82 std Y+5,__zero_reg__ + 706 /* epilogue start */ + 35:../../../Lib/tlvProt.c **** } + 708 .LM23: + 709 00d6 DF91 pop r29 + 710 00d8 CF91 pop r28 + 711 00da 1F91 pop r17 + 712 00dc 0895 ret + 717 .Lscope3: + 719 .stabd 78,0,0 + 723 .global tlvCalculateCrcSepDta + 725 tlvCalculateCrcSepDta: + 726 .stabd 46,0,0 + 36:../../../Lib/tlvProt.c **** + 37:../../../Lib/tlvProt.c **** void tlvCalculateCrcSepDta(tlvMsg_t *message, const uint8_t dta[]) + 38:../../../Lib/tlvProt.c **** { + 728 .LM24: + 729 .LFBB4: + 730 00de EF92 push r14 + 731 00e0 FF92 push r15 + 732 00e2 1F93 push r17 + 733 00e4 CF93 push r28 + 734 00e6 DF93 push r29 + 735 /* prologue: function */ + 736 /* frame size = 0 */ + 737 /* stack size = 5 */ + 738 .L__stack_usage = 5 + 739 00e8 EC01 movw r28,r24 + 740 00ea 7B01 movw r14,r22 + 39:../../../Lib/tlvProt.c **** uint16_t crc; + 40:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->address); + 742 .LM25: + 743 00ec 8981 ldd r24,Y+1 + 744 00ee 0E94 0000 call _crc16_update.constprop.0 + 41:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->type); + 746 .LM26: + 747 00f2 8A81 ldd r24,Y+2 + 748 00f4 0E94 0000 call _crc16_update.constprop.0 + 42:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->dtaLen); + 750 .LM27: + 751 00f8 8B81 ldd r24,Y+3 + 752 00fa 0E94 0000 call _crc16_update.constprop.0 + 43:../../../Lib/tlvProt.c **** + 44:../../../Lib/tlvProt.c **** uint8_t i; + 45:../../../Lib/tlvProt.c **** for (i=0; idtaLen; i++) + 754 .LM28: + 755 00fe 10E0 ldi r17,0 + 756 .L11: + 758 .LM29: + 759 0100 9B81 ldd r25,Y+3 + 760 0102 1917 cp r17,r25 + 761 0104 00F4 brsh .L13 + 46:../../../Lib/tlvProt.c **** crc = _crc16_update(0, dta[i]); + 763 .LM30: + 764 0106 F701 movw r30,r14 + 765 0108 E10F add r30,r17 + 766 010a F11D adc r31,__zero_reg__ + 767 010c 8081 ld r24,Z + 768 010e 0E94 0000 call _crc16_update.constprop.0 + 45:../../../Lib/tlvProt.c **** crc = _crc16_update(0, dta[i]); + 770 .LM31: + 771 0112 1F5F subi r17,lo8(-(1)) + 772 0114 00C0 rjmp .L11 + 773 .L13: + 47:../../../Lib/tlvProt.c **** + 48:../../../Lib/tlvProt.c **** message->crcLo = (uint8_t) crc; + 775 .LM32: + 776 0116 8C83 std Y+4,r24 + 49:../../../Lib/tlvProt.c **** message->crcHi = (uint8_t) crc>>8; + 778 .LM33: + 779 0118 1D82 std Y+5,__zero_reg__ + 780 /* epilogue start */ + 50:../../../Lib/tlvProt.c **** } + 782 .LM34: + 783 011a DF91 pop r29 + 784 011c CF91 pop r28 + 785 011e 1F91 pop r17 + 786 0120 FF90 pop r15 + 787 0122 EF90 pop r14 + 788 0124 0895 ret + 793 .Lscope4: + 795 .stabd 78,0,0 + 798 .global tlvCheckCrc + 800 tlvCheckCrc: + 801 .stabd 46,0,0 + 51:../../../Lib/tlvProt.c **** + 52:../../../Lib/tlvProt.c **** uint8_t tlvCheckCrc(tlvMsg_t *message) + 53:../../../Lib/tlvProt.c **** { + 803 .LM35: + 804 .LFBB5: + 805 0126 1F93 push r17 + 806 0128 CF93 push r28 + 807 012a DF93 push r29 + 808 /* prologue: function */ + 809 /* frame size = 0 */ + 810 /* stack size = 3 */ + 811 .L__stack_usage = 3 + 812 012c EC01 movw r28,r24 + 54:../../../Lib/tlvProt.c **** uint16_t crc; + 55:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->address); + 814 .LM36: + 815 012e 8981 ldd r24,Y+1 + 816 0130 0E94 0000 call _crc16_update.constprop.0 + 56:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->type); + 818 .LM37: + 819 0134 8A81 ldd r24,Y+2 + 820 0136 0E94 0000 call _crc16_update.constprop.0 + 57:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->dtaLen); + 822 .LM38: + 823 013a 8B81 ldd r24,Y+3 + 824 013c 0E94 0000 call _crc16_update.constprop.0 + 58:../../../Lib/tlvProt.c **** + 59:../../../Lib/tlvProt.c **** uint8_t i; + 60:../../../Lib/tlvProt.c **** for (i=0; idtaLen; i++) + 826 .LM39: + 827 0140 10E0 ldi r17,0 + 828 .L15: + 830 .LM40: + 831 0142 9B81 ldd r25,Y+3 + 832 0144 1917 cp r17,r25 + 833 0146 00F4 brsh .L23 + 61:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->data[i]); + 835 .LM41: + 836 0148 FE01 movw r30,r28 + 837 014a E10F add r30,r17 + 838 014c F11D adc r31,__zero_reg__ + 839 014e 8681 ldd r24,Z+6 + 840 0150 0E94 0000 call _crc16_update.constprop.0 + 60:../../../Lib/tlvProt.c **** crc = _crc16_update(0, message->data[i]); + 842 .LM42: + 843 0154 1F5F subi r17,lo8(-(1)) + 844 0156 00C0 rjmp .L15 + 845 .L23: + 62:../../../Lib/tlvProt.c **** + 63:../../../Lib/tlvProt.c **** uint8_t crcLo = (uint8_t) crc; + 64:../../../Lib/tlvProt.c **** uint8_t crcHi = (uint8_t) crc>>8; + 65:../../../Lib/tlvProt.c **** + 66:../../../Lib/tlvProt.c **** if (message->crcLo != crcLo) + 847 .LM43: + 848 0158 9C81 ldd r25,Y+4 + 849 015a 9813 cpse r25,r24 + 850 015c 00C0 rjmp .L19 + 67:../../../Lib/tlvProt.c **** return 0; + 68:../../../Lib/tlvProt.c **** + 69:../../../Lib/tlvProt.c **** if (message->crcHi != crcHi) + 852 .LM44: + 853 015e 81E0 ldi r24,lo8(1) + 854 0160 9D81 ldd r25,Y+5 + 855 0162 9111 cpse r25,__zero_reg__ + 856 .L19: + 67:../../../Lib/tlvProt.c **** return 0; + 858 .LM45: + 859 0164 80E0 ldi r24,0 + 860 .L17: + 861 /* epilogue start */ + 70:../../../Lib/tlvProt.c **** return 0; + 71:../../../Lib/tlvProt.c **** + 72:../../../Lib/tlvProt.c **** return 1; + 73:../../../Lib/tlvProt.c **** } + 863 .LM46: + 864 0166 DF91 pop r29 + 865 0168 CF91 pop r28 + 866 016a 1F91 pop r17 + 867 016c 0895 ret + 872 .Lscope5: + 874 .stabd 78,0,0 + 878 .global tlvProcessDta + 880 tlvProcessDta: + 881 .stabd 46,0,0 + 74:../../../Lib/tlvProt.c **** + 75:../../../Lib/tlvProt.c **** void tlvProcessDta(tlvInterpreter_t *tlvInt, uint8_t dta) + 76:../../../Lib/tlvProt.c **** { + 883 .LM47: + 884 .LFBB6: + 885 016e CF92 push r12 + 886 0170 DF92 push r13 + 887 0172 FF92 push r15 + 888 0174 0F93 push r16 + 889 0176 1F93 push r17 + 890 0178 CF93 push r28 + 891 017a DF93 push r29 + 892 017c 00D0 rcall . + 893 017e 1F92 push __zero_reg__ + 894 0180 CDB7 in r28,__SP_L__ + 895 0182 DEB7 in r29,__SP_H__ + 896 /* prologue: function */ + 897 /* frame size = 4 */ + 898 /* stack size = 11 */ + 899 .L__stack_usage = 11 + 900 0184 8C01 movw r16,r24 + 77:../../../Lib/tlvProt.c **** uint8_t i, j; + 78:../../../Lib/tlvProt.c **** struct tlvMsg *myRecMsg = (struct tlvMsg *)tlvInt->buffer; + 79:../../../Lib/tlvProt.c **** + 80:../../../Lib/tlvProt.c **** if (tlvInt->bufIdx >= TLV_BUF_LEN) + 902 .LM48: + 903 0186 FC01 movw r30,r24 + 904 0188 80A1 ldd r24,Z+32 + 905 018a 8032 cpi r24,lo8(32) + 906 018c 00F0 brlo .L25 + 81:../../../Lib/tlvProt.c **** { + 82:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("# TLV buffer overflow")); + 908 .LM49: + 909 018e 80E0 ldi r24,lo8(__c.4233) + 910 0190 90E0 ldi r25,hi8(__c.4233) + 911 0192 9F93 push r25 + 912 0194 8F93 push r24 + 913 0196 87A1 ldd r24,Z+39 + 914 0198 8F93 push r24 + 915 019a 86A1 ldd r24,Z+38 + 916 019c 8F93 push r24 + 917 019e 6C83 std Y+4,r22 + 918 01a0 0E94 0000 call fprintf_P + 83:../../../Lib/tlvProt.c **** tlvInt->bufIdx = 0; + 920 .LM50: + 921 01a4 F801 movw r30,r16 + 922 01a6 10A2 std Z+32,__zero_reg__ + 923 01a8 0F90 pop __tmp_reg__ + 924 01aa 0F90 pop __tmp_reg__ + 925 01ac 0F90 pop __tmp_reg__ + 926 01ae 0F90 pop __tmp_reg__ + 927 01b0 6C81 ldd r22,Y+4 + 928 .L25: + 84:../../../Lib/tlvProt.c **** } + 85:../../../Lib/tlvProt.c **** + 86:../../../Lib/tlvProt.c **** if (tlvInt->bufIdx == 0 && dta != TLV_SYNC) + 930 .LM51: + 931 01b2 F801 movw r30,r16 + 932 01b4 80A1 ldd r24,Z+32 + 933 01b6 8111 cpse r24,__zero_reg__ + 934 01b8 00C0 rjmp .L26 + 936 .LM52: + 937 01ba 6535 cpi r22,lo8(85) + 938 01bc 01F0 breq .+2 + 939 01be 00C0 rjmp .L24 + 940 .L26: + 87:../../../Lib/tlvProt.c **** return; + 88:../../../Lib/tlvProt.c **** + 89:../../../Lib/tlvProt.c **** tlvInt->buffer[tlvInt->bufIdx] = dta; + 942 .LM53: + 943 01c0 F801 movw r30,r16 + 944 01c2 E80F add r30,r24 + 945 01c4 F11D adc r31,__zero_reg__ + 946 01c6 6083 st Z,r22 + 90:../../../Lib/tlvProt.c **** tlvInt->bufIdx++; + 948 .LM54: + 949 01c8 8F5F subi r24,lo8(-(1)) + 950 01ca F801 movw r30,r16 + 951 01cc 80A3 std Z+32,r24 + 91:../../../Lib/tlvProt.c **** + 92:../../../Lib/tlvProt.c **** if (tlvInt->bufIdx < sizeof(struct tlvMsg)) + 953 .LM55: + 954 01ce 8630 cpi r24,lo8(6) + 955 01d0 00F4 brsh .+2 + 956 01d2 00C0 rjmp .L24 + 93:../../../Lib/tlvProt.c **** return; + 94:../../../Lib/tlvProt.c **** + 95:../../../Lib/tlvProt.c **** if (tlvInt->bufIdx < myRecMsg->dtaLen + sizeof(struct tlvMsg)) + 958 .LM56: + 959 01d4 90E0 ldi r25,0 + 960 01d6 2381 ldd r18,Z+3 + 961 01d8 30E0 ldi r19,0 + 962 01da 2A5F subi r18,-6 + 963 01dc 3F4F sbci r19,-1 + 964 01de 8217 cp r24,r18 + 965 01e0 9307 cpc r25,r19 + 966 01e2 00F4 brsh .+2 + 967 01e4 00C0 rjmp .L24 + 96:../../../Lib/tlvProt.c **** return; + 97:../../../Lib/tlvProt.c **** + 98:../../../Lib/tlvProt.c **** if (tlvCheckCrc(myRecMsg) == 0) + 969 .LM57: + 970 01e6 C801 movw r24,r16 + 971 01e8 0E94 0000 call tlvCheckCrc + 972 01ec 8111 cpse r24,__zero_reg__ + 973 01ee 00C0 rjmp .L42 + 99:../../../Lib/tlvProt.c **** { + 100:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("# CRC mismatch: buffer idx %d\r\n"), tlvInt->bufIdx); + 975 .LM58: + 976 01f0 F801 movw r30,r16 + 977 01f2 80A1 ldd r24,Z+32 + 978 01f4 1F92 push __zero_reg__ + 979 01f6 8F93 push r24 + 980 01f8 80E0 ldi r24,lo8(__c.4235) + 981 01fa 90E0 ldi r25,hi8(__c.4235) + 982 01fc 9F93 push r25 + 983 01fe 8F93 push r24 + 984 0200 87A1 ldd r24,Z+39 + 985 0202 8F93 push r24 + 986 0204 86A1 ldd r24,Z+38 + 987 0206 8F93 push r24 + 988 0208 0E94 0000 call fprintf_P + 101:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\taddress : %x\r\n"), myRecMsg->address); + 990 .LM59: + 991 020c F801 movw r30,r16 + 992 020e 8181 ldd r24,Z+1 + 993 0210 1F92 push __zero_reg__ + 994 0212 8F93 push r24 + 995 0214 80E0 ldi r24,lo8(__c.4237) + 996 0216 90E0 ldi r25,hi8(__c.4237) + 997 0218 9F93 push r25 + 998 021a 8F93 push r24 + 999 021c 87A1 ldd r24,Z+39 + 1000 021e 8F93 push r24 + 1001 0220 86A1 ldd r24,Z+38 + 1002 0222 8F93 push r24 + 1003 0224 0E94 0000 call fprintf_P + 102:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\tmsg type : %x\r\n"), myRecMsg->type); + 1005 .LM60: + 1006 0228 F801 movw r30,r16 + 1007 022a 8281 ldd r24,Z+2 + 1008 022c 1F92 push __zero_reg__ + 1009 022e 8F93 push r24 + 1010 0230 80E0 ldi r24,lo8(__c.4239) + 1011 0232 90E0 ldi r25,hi8(__c.4239) + 1012 0234 9F93 push r25 + 1013 0236 8F93 push r24 + 1014 0238 87A1 ldd r24,Z+39 + 1015 023a 8F93 push r24 + 1016 023c 86A1 ldd r24,Z+38 + 1017 023e 8F93 push r24 + 1018 0240 0E94 0000 call fprintf_P + 103:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\tcrc lo : %x\r\n"), myRecMsg->crcLo); + 1020 .LM61: + 1021 0244 F801 movw r30,r16 + 1022 0246 8481 ldd r24,Z+4 + 1023 0248 1F92 push __zero_reg__ + 1024 024a 8F93 push r24 + 1025 024c 80E0 ldi r24,lo8(__c.4241) + 1026 024e 90E0 ldi r25,hi8(__c.4241) + 1027 0250 9F93 push r25 + 1028 0252 8F93 push r24 + 1029 0254 87A1 ldd r24,Z+39 + 1030 0256 8F93 push r24 + 1031 0258 86A1 ldd r24,Z+38 + 1032 025a 8F93 push r24 + 1033 025c 0E94 0000 call fprintf_P + 104:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\tcrc hi : %x\r\n"), myRecMsg->crcHi); + 1035 .LM62: + 1036 0260 F801 movw r30,r16 + 1037 0262 8581 ldd r24,Z+5 + 1038 0264 1F92 push __zero_reg__ + 1039 0266 8F93 push r24 + 1040 0268 80E0 ldi r24,lo8(__c.4243) + 1041 026a 90E0 ldi r25,hi8(__c.4243) + 1042 026c 9F93 push r25 + 1043 026e 8F93 push r24 + 1044 0270 87A1 ldd r24,Z+39 + 1045 0272 8F93 push r24 + 1046 0274 86A1 ldd r24,Z+38 + 1047 0276 8F93 push r24 + 1048 0278 0E94 0000 call fprintf_P + 105:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\tdta len : %x\r\n"), myRecMsg->dtaLen); + 1050 .LM63: + 1051 027c F801 movw r30,r16 + 1052 027e 8381 ldd r24,Z+3 + 1053 0280 1F92 push __zero_reg__ + 1054 0282 8F93 push r24 + 1055 0284 80E0 ldi r24,lo8(__c.4245) + 1056 0286 90E0 ldi r25,hi8(__c.4245) + 1057 0288 9F93 push r25 + 1058 028a 8F93 push r24 + 1059 028c 87A1 ldd r24,Z+39 + 1060 028e 8F93 push r24 + 1061 0290 86A1 ldd r24,Z+38 + 1062 0292 8F93 push r24 + 1063 0294 0E94 0000 call fprintf_P + 106:../../../Lib/tlvProt.c **** + 107:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\tdata:")); + 1065 .LM64: + 1066 0298 CDBF out __SP_L__,r28 + 1067 029a DEBF out __SP_H__,r29 + 1068 029c 80E0 ldi r24,lo8(__c.4247) + 1069 029e 90E0 ldi r25,hi8(__c.4247) + 1070 02a0 9F93 push r25 + 1071 02a2 8F93 push r24 + 1072 02a4 F801 movw r30,r16 + 1073 02a6 87A1 ldd r24,Z+39 + 1074 02a8 8F93 push r24 + 1075 02aa 86A1 ldd r24,Z+38 + 1076 02ac 8F93 push r24 + 1077 02ae 0E94 0000 call fprintf_P + 108:../../../Lib/tlvProt.c **** for(i=sizeof(struct tlvMsg); ibufIdx; i++) + 1079 .LM65: + 1080 02b2 0F90 pop __tmp_reg__ + 1081 02b4 0F90 pop __tmp_reg__ + 1082 02b6 0F90 pop __tmp_reg__ + 1083 02b8 0F90 pop __tmp_reg__ + 1084 02ba 86E0 ldi r24,lo8(6) + 1085 02bc F82E mov r15,r24 + 109:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR(" %2x"), tlvInt->buffer[i]); + 1087 .LM66: + 1088 02be 90E0 ldi r25,lo8(__c.4249) + 1089 02c0 C92E mov r12,r25 + 1090 02c2 90E0 ldi r25,hi8(__c.4249) + 1091 02c4 D92E mov r13,r25 + 1092 .L29: + 108:../../../Lib/tlvProt.c **** for(i=sizeof(struct tlvMsg); ibufIdx; i++) + 1094 .LM67: + 1095 02c6 F801 movw r30,r16 + 1096 02c8 20A1 ldd r18,Z+32 + 1097 02ca 97A1 ldd r25,Z+39 + 1098 02cc 86A1 ldd r24,Z+38 + 1099 02ce F216 cp r15,r18 + 1100 02d0 00F4 brsh .L46 + 1102 .LM68: + 1103 02d2 F801 movw r30,r16 + 1104 02d4 EF0D add r30,r15 + 1105 02d6 F11D adc r31,__zero_reg__ + 1106 02d8 2081 ld r18,Z + 1107 02da 1F92 push __zero_reg__ + 1108 02dc 2F93 push r18 + 1109 02de DF92 push r13 + 1110 02e0 CF92 push r12 + 1111 02e2 9F93 push r25 + 1112 02e4 8F93 push r24 + 1113 02e6 0E94 0000 call fprintf_P + 108:../../../Lib/tlvProt.c **** for(i=sizeof(struct tlvMsg); ibufIdx; i++) + 1115 .LM69: + 1116 02ea F394 inc r15 + 1117 02ec 0F90 pop __tmp_reg__ + 1118 02ee 0F90 pop __tmp_reg__ + 1119 02f0 0F90 pop __tmp_reg__ + 1120 02f2 0F90 pop __tmp_reg__ + 1121 02f4 0F90 pop __tmp_reg__ + 1122 02f6 0F90 pop __tmp_reg__ + 1123 02f8 00C0 rjmp .L29 + 1124 .L46: + 110:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("\r\n")); + 1126 .LM70: + 1127 02fa 20E0 ldi r18,lo8(__c.4254) + 1128 02fc 30E0 ldi r19,hi8(__c.4254) + 1129 02fe 3F93 push r19 + 1130 0300 2F93 push r18 + 1131 0302 9F93 push r25 + 1132 0304 8F93 push r24 + 1133 0306 0E94 0000 call fprintf_P + 111:../../../Lib/tlvProt.c **** + 112:../../../Lib/tlvProt.c **** for (i=1; ibufIdx; i++) + 1135 .LM71: + 1136 030a F801 movw r30,r16 + 1137 030c 80A1 ldd r24,Z+32 + 1138 030e 0F90 pop __tmp_reg__ + 1139 0310 0F90 pop __tmp_reg__ + 1140 0312 0F90 pop __tmp_reg__ + 1141 0314 0F90 pop __tmp_reg__ + 1142 0316 21E0 ldi r18,lo8(1) + 1143 0318 30E0 ldi r19,0 + 1144 .L31: + 1145 031a F22E mov r15,r18 + 1147 .LM72: + 1148 031c 2817 cp r18,r24 + 1149 031e 00F0 brlo .+2 + 1150 0320 00C0 rjmp .L45 + 1151 0322 A901 movw r20,r18 + 1152 0324 4F5F subi r20,-1 + 1153 0326 5F4F sbci r21,-1 + 1154 0328 D801 movw r26,r16 + 1155 032a A20F add r26,r18 + 1156 032c B31F adc r27,r19 + 113:../../../Lib/tlvProt.c **** { + 114:../../../Lib/tlvProt.c **** if (tlvInt->buffer[i] == TLV_SYNC) + 1158 .LM73: + 1159 032e 9C91 ld r25,X + 1160 0330 9535 cpi r25,lo8(85) + 1161 0332 01F4 brne .L43 + 1162 0334 90E0 ldi r25,0 + 115:../../../Lib/tlvProt.c **** { + 116:../../../Lib/tlvProt.c **** for (j=0; i+j < tlvInt->bufIdx; j++) + 1164 .LM74: + 1165 0336 A82F mov r26,r24 + 1166 0338 B0E0 ldi r27,0 + 1167 .L32: + 1169 .LM75: + 1170 033a 692F mov r22,r25 + 1171 033c 70E0 ldi r23,0 + 1172 033e A901 movw r20,r18 + 1173 0340 460F add r20,r22 + 1174 0342 571F adc r21,r23 + 1175 0344 4A17 cp r20,r26 + 1176 0346 5B07 cpc r21,r27 + 1177 0348 04F4 brge .L47 + 117:../../../Lib/tlvProt.c **** tlvInt->buffer[j] = tlvInt->buffer[i+j]; + 1179 .LM76: + 1180 034a 400F add r20,r16 + 1181 034c 511F adc r21,r17 + 1182 034e FA01 movw r30,r20 + 1183 0350 4081 ld r20,Z + 1184 0352 600F add r22,r16 + 1185 0354 711F adc r23,r17 + 1186 0356 FB01 movw r30,r22 + 1187 0358 4083 st Z,r20 + 116:../../../Lib/tlvProt.c **** tlvInt->buffer[j] = tlvInt->buffer[i+j]; + 1189 .LM77: + 1190 035a 9F5F subi r25,lo8(-(1)) + 1191 035c 00C0 rjmp .L32 + 1192 .L47: + 118:../../../Lib/tlvProt.c **** + 119:../../../Lib/tlvProt.c **** tlvInt->bufIdx -= i; + 1194 .LM78: + 1195 035e 8F19 sub r24,r15 + 1196 0360 F801 movw r30,r16 + 1197 0362 80A3 std Z+32,r24 + 120:../../../Lib/tlvProt.c **** return; + 1199 .LM79: + 1200 0364 00C0 rjmp .L24 + 1201 .L43: + 1202 0366 9A01 movw r18,r20 + 1203 0368 00C0 rjmp .L31 + 1204 .L42: + 1205 036a F12C mov r15,__zero_reg__ + 1206 .L28: + 121:../../../Lib/tlvProt.c **** } + 122:../../../Lib/tlvProt.c **** } + 123:../../../Lib/tlvProt.c **** tlvInt->bufIdx = 0; + 124:../../../Lib/tlvProt.c **** return; + 125:../../../Lib/tlvProt.c **** } + 126:../../../Lib/tlvProt.c **** + 127:../../../Lib/tlvProt.c **** tlvCommand_t tmp; // We need to create this o + 128:../../../Lib/tlvProt.c **** for (i=0; inoOfCmds; i++) + 1208 .LM80: + 1209 036c F801 movw r30,r16 + 1210 036e 83A1 ldd r24,Z+35 + 1211 0370 F816 cp r15,r24 + 1212 0372 00F4 brsh .L37 + 129:../../../Lib/tlvProt.c **** { + 130:../../../Lib/tlvProt.c **** memcpy_P(&tmp, &tlvInt->commands[i], sizeof(tlvCommand_t)); + 1214 .LM81: + 1215 0374 F801 movw r30,r16 + 1216 0376 61A1 ldd r22,Z+33 + 1217 0378 72A1 ldd r23,Z+34 + 1218 037a F3E0 ldi r31,lo8(3) + 1219 037c FF9E mul r15,r31 + 1220 037e 600D add r22,r0 + 1221 0380 711D adc r23,r1 + 1222 0382 1124 clr __zero_reg__ + 1223 0384 43E0 ldi r20,lo8(3) + 1224 0386 50E0 ldi r21,0 + 1225 0388 CE01 movw r24,r28 + 1226 038a 0196 adiw r24,1 + 1227 038c 0E94 0000 call memcpy_P + 131:../../../Lib/tlvProt.c **** if (myRecMsg->type == tmp.type) + 1229 .LM82: + 1230 0390 F801 movw r30,r16 + 1231 0392 9281 ldd r25,Z+2 + 1232 0394 8981 ldd r24,Y+1 + 1233 0396 9813 cpse r25,r24 + 1234 0398 00C0 rjmp .L36 + 132:../../../Lib/tlvProt.c **** { + 133:../../../Lib/tlvProt.c **** tmp.fun(tlvInt, myRecMsg); + 1236 .LM83: + 1237 039a EA81 ldd r30,Y+2 + 1238 039c FB81 ldd r31,Y+3 + 1239 039e B801 movw r22,r16 + 1240 03a0 C801 movw r24,r16 + 1241 03a2 1995 eicall + 134:../../../Lib/tlvProt.c **** break; + 1243 .LM84: + 1244 03a4 00C0 rjmp .L37 + 1245 .L36: + 128:../../../Lib/tlvProt.c **** { + 1247 .LM85: + 1248 03a6 F394 inc r15 + 1249 03a8 00C0 rjmp .L28 + 1250 .L37: + 135:../../../Lib/tlvProt.c **** } + 136:../../../Lib/tlvProt.c **** } + 137:../../../Lib/tlvProt.c **** if (i == tlvInt->noOfCmds) + 1252 .LM86: + 1253 03aa F801 movw r30,r16 + 1254 03ac 33A1 ldd r19,Z+35 + 1255 03ae 97A1 ldd r25,Z+39 + 1256 03b0 86A1 ldd r24,Z+38 + 1257 03b2 2281 ldd r18,Z+2 + 1258 03b4 F312 cpse r15,r19 + 1259 03b6 00C0 rjmp .L39 + 138:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("! Unknown command: %d\r\n"), myRecMsg->type); + 1261 .LM87: + 1262 03b8 1F92 push __zero_reg__ + 1263 03ba 2F93 push r18 + 1264 03bc 20E0 ldi r18,lo8(__c.4266) + 1265 03be 30E0 ldi r19,hi8(__c.4266) + 1266 03c0 00C0 rjmp .L44 + 1267 .L39: + 139:../../../Lib/tlvProt.c **** else + 140:../../../Lib/tlvProt.c **** fprintf_P(tlvInt->errStr, PSTR("TLV command %x was executed\r\n"), myRecMsg->type); + 1269 .LM88: + 1270 03c2 1F92 push __zero_reg__ + 1271 03c4 2F93 push r18 + 1272 03c6 20E0 ldi r18,lo8(__c.4268) + 1273 03c8 30E0 ldi r19,hi8(__c.4268) + 1274 .L44: + 1275 03ca 3F93 push r19 + 1276 03cc 2F93 push r18 + 1277 03ce 9F93 push r25 + 1278 03d0 8F93 push r24 + 1279 03d2 0E94 0000 call fprintf_P + 1280 03d6 0F90 pop __tmp_reg__ + 1281 03d8 0F90 pop __tmp_reg__ + 1282 03da 0F90 pop __tmp_reg__ + 1283 03dc 0F90 pop __tmp_reg__ + 1284 03de 0F90 pop __tmp_reg__ + 1285 03e0 0F90 pop __tmp_reg__ + 1286 .L45: + 141:../../../Lib/tlvProt.c **** + 142:../../../Lib/tlvProt.c **** tlvInt->bufIdx = 0; + 1288 .LM89: + 1289 03e2 F801 movw r30,r16 + 1290 03e4 10A2 std Z+32,__zero_reg__ + 1291 .L24: + 1292 /* epilogue start */ + 143:../../../Lib/tlvProt.c **** } + 1294 .LM90: + 1295 03e6 2496 adiw r28,4 + 1296 03e8 CDBF out __SP_L__,r28 + 1297 03ea DEBF out __SP_H__,r29 + 1298 03ec DF91 pop r29 + 1299 03ee CF91 pop r28 + 1300 03f0 1F91 pop r17 + 1301 03f2 0F91 pop r16 + 1302 03f4 FF90 pop r15 + 1303 03f6 DF90 pop r13 + 1304 03f8 CF90 pop r12 + 1305 03fa 0895 ret + 1311 .Lscope6: + 1313 .stabd 78,0,0 + 1317 .global sendTlvMsg + 1319 sendTlvMsg: + 1320 .stabd 46,0,0 + 144:../../../Lib/tlvProt.c **** + 145:../../../Lib/tlvProt.c **** void sendTlvMsg(tlvMsg_t *message, FILE *ostream) + 146:../../../Lib/tlvProt.c **** { + 1322 .LM91: + 1323 .LFBB7: + 1324 03fc CF92 push r12 + 1325 03fe DF92 push r13 + 1326 0400 EF92 push r14 + 1327 0402 FF92 push r15 + 1328 0404 0F93 push r16 + 1329 0406 1F93 push r17 + 1330 0408 CF93 push r28 + 1331 040a DF93 push r29 + 1332 /* prologue: function */ + 1333 /* frame size = 0 */ + 1334 /* stack size = 8 */ + 1335 .L__stack_usage = 8 + 1336 040c 8C01 movw r16,r24 + 1337 040e 6B01 movw r12,r22 + 147:../../../Lib/tlvProt.c **** int i, len; + 148:../../../Lib/tlvProt.c **** len = sizeof(struct tlvMsg) + message->dtaLen; + 1339 .LM92: + 1340 0410 FC01 movw r30,r24 + 1341 0412 C381 ldd r28,Z+3 + 1342 0414 D0E0 ldi r29,0 + 1343 0416 2696 adiw r28,6 + 149:../../../Lib/tlvProt.c **** uint8_t *ptr = (uint8_t *) message; + 1345 .LM93: + 1346 0418 7C01 movw r14,r24 + 1347 .L49: + 150:../../../Lib/tlvProt.c **** + 151:../../../Lib/tlvProt.c **** for (i=0; idtaLen; + 1433 .LM101: + 1434 047e CB81 ldd r28,Y+3 + 1435 0480 D0E0 ldi r29,0 + 170:../../../Lib/tlvProt.c **** len = message->dtaLen; + 1437 .LM102: + 1438 0482 8701 movw r16,r14 + 1439 .L53: + 1440 0484 C801 movw r24,r16 + 1441 0486 8E19 sub r24,r14 + 1442 0488 9F09 sbc r25,r15 + 172:../../../Lib/tlvProt.c **** for (i=0; i + #include + #include +#endif + +#include "main.h" +#include "vt100.h" +#include + +// Program ROM constants + +// Global variables + +// Functions +void vt100Init(cmdState_t *state) +{ + // initializes terminal to "power-on" settings + // ESC c + + fprintf_P(state->myStdInOut, "\x1B\x63"); +} + +void vt100ClearScreen(cmdState_t *state) +{ + // ESC [ 2 J + fprintf_P(state->myStdInOut, "\x1B[2J"); +} + +void vt100SetAttr(uint8_t attr, cmdState_t *state) +{ + // ESC [ Ps m + fprintf_P(state->myStdInOut, "\x1B[%dm",attr); +} + +void vt100SetCursorMode(uint8_t visible, cmdState_t *state) +{ + if(visible) + // ESC [ ? 25 h + fprintf_P(state->myStdInOut, "\x1B[?25h"); + else + // ESC [ ? 25 l + fprintf_P(state->myStdInOut, "\x1B[?25l"); +} + +void vt100SetCursorPos(uint8_t line, uint8_t col, cmdState_t *state) +{ + // ESC [ Pl ; Pc H + fprintf_P(state->myStdInOut, "\x1B[%d;%dH",line,col); +} diff --git a/Lib/vt100.lst b/Lib/vt100.lst new file mode 100644 index 0000000..abab718 --- /dev/null +++ b/Lib/vt100.lst @@ -0,0 +1,287 @@ + 1 .file "vt100.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 190 .section .rodata.str1.1,"aMS",@progbits,1 + 191 .LC0: + 192 0000 1B63 00 .string "\033c" + 193 .text + 196 .global vt100Init + 198 vt100Init: + 199 .stabd 46,0,0 + 1:../../../../Lib/vt100.c **** /*! \file vt100.c \brief VT100 terminal function library. */ + 2:../../../../Lib/vt100.c **** //***************************************************************************** + 3:../../../../Lib/vt100.c **** // + 4:../../../../Lib/vt100.c **** // File Name : 'vt100.c' + 5:../../../../Lib/vt100.c **** // Title : VT100 terminal function library + 6:../../../../Lib/vt100.c **** // Author : Pascal Stang - Copyright (C) 2002 + 7:../../../../Lib/vt100.c **** // Created : 2002.08.27 + 8:../../../../Lib/vt100.c **** // Revised : 2002.08.27 + 9:../../../../Lib/vt100.c **** // Version : 0.1 + 10:../../../../Lib/vt100.c **** // Target MCU : Atmel AVR Series + 11:../../../../Lib/vt100.c **** // Editor Tabs : 4 + 12:../../../../Lib/vt100.c **** // + 13:../../../../Lib/vt100.c **** // NOTE: This code is currently below version 1.0, and therefore is considered + 14:../../../../Lib/vt100.c **** // to be lacking in some functionality or documentation, or may not be fully + 15:../../../../Lib/vt100.c **** // tested. Nonetheless, you can expect most functions to work. + 16:../../../../Lib/vt100.c **** // + 17:../../../../Lib/vt100.c **** // This code is distributed under the GNU Public License + 18:../../../../Lib/vt100.c **** // which can be found at http://www.gnu.org/licenses/gpl.txt + 19:../../../../Lib/vt100.c **** // + 20:../../../../Lib/vt100.c **** //***************************************************************************** + 21:../../../../Lib/vt100.c **** + 22:../../../../Lib/vt100.c **** #ifndef WIN32 + 23:../../../../Lib/vt100.c **** #include + 24:../../../../Lib/vt100.c **** #include + 25:../../../../Lib/vt100.c **** #include + 26:../../../../Lib/vt100.c **** #endif + 27:../../../../Lib/vt100.c **** + 28:../../../../Lib/vt100.c **** #include "main.h" + 29:../../../../Lib/vt100.c **** #include "vt100.h" + 30:../../../../Lib/vt100.c **** #include + 31:../../../../Lib/vt100.c **** + 32:../../../../Lib/vt100.c **** // Program ROM constants + 33:../../../../Lib/vt100.c **** + 34:../../../../Lib/vt100.c **** // Global variables + 35:../../../../Lib/vt100.c **** + 36:../../../../Lib/vt100.c **** // Functions + 37:../../../../Lib/vt100.c **** void vt100Init(cmdState_t *state) + 38:../../../../Lib/vt100.c **** { + 201 .LM0: + 202 .LFBB1: + 203 /* prologue: function */ + 204 /* frame size = 0 */ + 205 /* stack size = 0 */ + 206 .L__stack_usage = 0 + 39:../../../../Lib/vt100.c **** // initializes terminal to "power-on" settings + 40:../../../../Lib/vt100.c **** // ESC c + 41:../../../../Lib/vt100.c **** + 42:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B\x63"); + 208 .LM1: + 209 0000 20E0 ldi r18,lo8(.LC0) + 210 0002 30E0 ldi r19,hi8(.LC0) + 211 0004 3F93 push r19 + 212 0006 2F93 push r18 + 213 0008 FC01 movw r30,r24 + 214 000a 238D ldd r18,Z+27 + 215 000c 2F93 push r18 + 216 000e 828D ldd r24,Z+26 + 217 0010 8F93 push r24 + 218 0012 0E94 0000 call fprintf_P + 219 0016 0F90 pop __tmp_reg__ + 220 0018 0F90 pop __tmp_reg__ + 221 001a 0F90 pop __tmp_reg__ + 222 001c 0F90 pop __tmp_reg__ + 223 001e 0895 ret + 225 .Lscope1: + 227 .stabd 78,0,0 + 228 .section .rodata.str1.1 + 229 .LC1: + 230 0003 1B5B 324A .string "\033[2J" + 230 00 + 231 .text + 234 .global vt100ClearScreen + 236 vt100ClearScreen: + 237 .stabd 46,0,0 + 43:../../../../Lib/vt100.c **** } + 44:../../../../Lib/vt100.c **** + 45:../../../../Lib/vt100.c **** void vt100ClearScreen(cmdState_t *state) + 46:../../../../Lib/vt100.c **** { + 239 .LM2: + 240 .LFBB2: + 241 /* prologue: function */ + 242 /* frame size = 0 */ + 243 /* stack size = 0 */ + 244 .L__stack_usage = 0 + 47:../../../../Lib/vt100.c **** // ESC [ 2 J + 48:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B[2J"); + 246 .LM3: + 247 0020 20E0 ldi r18,lo8(.LC1) + 248 0022 30E0 ldi r19,hi8(.LC1) + 249 0024 3F93 push r19 + 250 0026 2F93 push r18 + 251 0028 FC01 movw r30,r24 + 252 002a 238D ldd r18,Z+27 + 253 002c 2F93 push r18 + 254 002e 828D ldd r24,Z+26 + 255 0030 8F93 push r24 + 256 0032 0E94 0000 call fprintf_P + 257 0036 0F90 pop __tmp_reg__ + 258 0038 0F90 pop __tmp_reg__ + 259 003a 0F90 pop __tmp_reg__ + 260 003c 0F90 pop __tmp_reg__ + 261 003e 0895 ret + 263 .Lscope2: + 265 .stabd 78,0,0 + 266 .section .rodata.str1.1 + 267 .LC2: + 268 0008 1B5B 2564 .string "\033[%dm" + 268 6D00 + 269 .text + 273 .global vt100SetAttr + 275 vt100SetAttr: + 276 .stabd 46,0,0 + 49:../../../../Lib/vt100.c **** } + 50:../../../../Lib/vt100.c **** + 51:../../../../Lib/vt100.c **** void vt100SetAttr(uint8_t attr, cmdState_t *state) + 52:../../../../Lib/vt100.c **** { + 278 .LM4: + 279 .LFBB3: + 280 /* prologue: function */ + 281 /* frame size = 0 */ + 282 /* stack size = 0 */ + 283 .L__stack_usage = 0 + 53:../../../../Lib/vt100.c **** // ESC [ Ps m + 54:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B[%dm",attr); + 285 .LM5: + 286 0040 1F92 push __zero_reg__ + 287 0042 8F93 push r24 + 288 0044 80E0 ldi r24,lo8(.LC2) + 289 0046 90E0 ldi r25,hi8(.LC2) + 290 0048 9F93 push r25 + 291 004a 8F93 push r24 + 292 004c FB01 movw r30,r22 + 293 004e 838D ldd r24,Z+27 + 294 0050 8F93 push r24 + 295 0052 828D ldd r24,Z+26 + 296 0054 8F93 push r24 + 297 0056 0E94 0000 call fprintf_P + 298 005a 0F90 pop __tmp_reg__ + 299 005c 0F90 pop __tmp_reg__ + 300 005e 0F90 pop __tmp_reg__ + 301 0060 0F90 pop __tmp_reg__ + 302 0062 0F90 pop __tmp_reg__ + 303 0064 0F90 pop __tmp_reg__ + 304 0066 0895 ret + 306 .Lscope3: + 308 .stabd 78,0,0 + 309 .section .rodata.str1.1 + 310 .LC3: + 311 000e 1B5B 3F32 .string "\033[?25h" + 311 3568 00 + 312 .LC4: + 313 0015 1B5B 3F32 .string "\033[?25l" + 313 356C 00 + 314 .text + 318 .global vt100SetCursorMode + 320 vt100SetCursorMode: + 321 .stabd 46,0,0 + 55:../../../../Lib/vt100.c **** } + 56:../../../../Lib/vt100.c **** + 57:../../../../Lib/vt100.c **** void vt100SetCursorMode(uint8_t visible, cmdState_t *state) + 58:../../../../Lib/vt100.c **** { + 323 .LM6: + 324 .LFBB4: + 325 /* prologue: function */ + 326 /* frame size = 0 */ + 327 /* stack size = 0 */ + 328 .L__stack_usage = 0 + 329 0068 FB01 movw r30,r22 + 330 006a 238D ldd r18,Z+27 + 331 006c 928D ldd r25,Z+26 + 59:../../../../Lib/vt100.c **** if(visible) + 333 .LM7: + 334 006e 8823 tst r24 + 335 0070 01F0 breq .L5 + 60:../../../../Lib/vt100.c **** // ESC [ ? 25 h + 61:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B[?25h"); + 337 .LM8: + 338 0072 40E0 ldi r20,lo8(.LC3) + 339 0074 50E0 ldi r21,hi8(.LC3) + 340 0076 00C0 rjmp .L7 + 341 .L5: + 62:../../../../Lib/vt100.c **** else + 63:../../../../Lib/vt100.c **** // ESC [ ? 25 l + 64:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B[?25l"); + 343 .LM9: + 344 0078 40E0 ldi r20,lo8(.LC4) + 345 007a 50E0 ldi r21,hi8(.LC4) + 346 .L7: + 347 007c 5F93 push r21 + 348 007e 4F93 push r20 + 349 0080 2F93 push r18 + 350 0082 9F93 push r25 + 351 0084 0E94 0000 call fprintf_P + 352 0088 0F90 pop __tmp_reg__ + 353 008a 0F90 pop __tmp_reg__ + 354 008c 0F90 pop __tmp_reg__ + 355 008e 0F90 pop __tmp_reg__ + 356 0090 0895 ret + 358 .Lscope4: + 360 .stabd 78,0,0 + 361 .section .rodata.str1.1 + 362 .LC5: + 363 001c 1B5B 2564 .string "\033[%d;%dH" + 363 3B25 6448 + 363 00 + 364 .text + 369 .global vt100SetCursorPos + 371 vt100SetCursorPos: + 372 .stabd 46,0,0 + 65:../../../../Lib/vt100.c **** } + 66:../../../../Lib/vt100.c **** + 67:../../../../Lib/vt100.c **** void vt100SetCursorPos(uint8_t line, uint8_t col, cmdState_t *state) + 68:../../../../Lib/vt100.c **** { + 374 .LM10: + 375 .LFBB5: + 376 /* prologue: function */ + 377 /* frame size = 0 */ + 378 /* stack size = 0 */ + 379 .L__stack_usage = 0 + 69:../../../../Lib/vt100.c **** // ESC [ Pl ; Pc H + 70:../../../../Lib/vt100.c **** fprintf_P(state->myStdInOut, "\x1B[%d;%dH",line,col); + 381 .LM11: + 382 0092 1F92 push __zero_reg__ + 383 0094 6F93 push r22 + 384 0096 1F92 push __zero_reg__ + 385 0098 8F93 push r24 + 386 009a 80E0 ldi r24,lo8(.LC5) + 387 009c 90E0 ldi r25,hi8(.LC5) + 388 009e 9F93 push r25 + 389 00a0 8F93 push r24 + 390 00a2 FA01 movw r30,r20 + 391 00a4 838D ldd r24,Z+27 + 392 00a6 8F93 push r24 + 393 00a8 828D ldd r24,Z+26 + 394 00aa 8F93 push r24 + 395 00ac 0E94 0000 call fprintf_P + 396 00b0 8DB7 in r24,__SP_L__ + 397 00b2 9EB7 in r25,__SP_H__ + 398 00b4 0896 adiw r24,8 + 399 00b6 0FB6 in __tmp_reg__,__SREG__ + 400 00b8 F894 cli + 401 00ba 9EBF out __SP_H__,r25 + 402 00bc 0FBE out __SREG__,__tmp_reg__ + 403 00be 8DBF out __SP_L__,r24 + 404 00c0 0895 ret + 406 .Lscope5: + 408 .stabd 78,0,0 + 409 .comm xSemaphoreRs485,2,1 + 410 .comm cliBuffer,128,1 + 414 .Letext0: + 415 .ident "GCC: (GNU) 4.9.2" + 416 .global __do_copy_data + 417 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 vt100.c + /tmp/ccOea6ff.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccOea6ff.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccOea6ff.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccOea6ff.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccOea6ff.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccOea6ff.s:198 .text:0000000000000000 vt100Init + /tmp/ccOea6ff.s:236 .text:0000000000000020 vt100ClearScreen + /tmp/ccOea6ff.s:275 .text:0000000000000040 vt100SetAttr + /tmp/ccOea6ff.s:320 .text:0000000000000068 vt100SetCursorMode + /tmp/ccOea6ff.s:371 .text:0000000000000092 vt100SetCursorPos + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000080 cliBuffer + +UNDEFINED SYMBOLS +fprintf_P +__do_copy_data +__do_clear_bss diff --git a/Lib/xmodem.c b/Lib/xmodem.c new file mode 100644 index 0000000..afdf63b --- /dev/null +++ b/Lib/xmodem.c @@ -0,0 +1,3 @@ +#include "xmodem.h" + + diff --git a/Lib/xmodem.lst b/Lib/xmodem.lst new file mode 100644 index 0000000..7edce56 --- /dev/null +++ b/Lib/xmodem.lst @@ -0,0 +1,65 @@ + 1 .file "xmodem.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 .comm czasRtc,7,1 + 276 .comm sockets,2,1 + 277 .comm tcpDebugLevel,1,1 + 278 .comm tcpDebugStream,2,1 + 279 .comm IpMyConfig,15,1 + 280 .comm udpDbgLevel,1,1 + 281 .comm udpDbgStream,2,1 + 282 .comm udpSocket,2,1 + 283 .comm icmpDebugLevel,1,1 + 284 .comm icmpDebug,2,1 + 285 .comm arpDebugLevel,1,1 + 286 .comm arpDebug,2,1 + 287 .comm nicState,14,1 + 288 .comm xSemaphoreRs485,2,1 + 289 .comm lockSensors,2,1 + 290 .comm portB,1,1 + 291 .comm portA,1,1 + 292 .comm xSemaphoreSpiSS,2,1 + 293 .comm rollers,2,1 + 294 .comm wwwport,1,1 + 295 .comm klastry,128,1 + 318 .Letext0: + 319 .ident "GCC: (GNU) 4.9.2" + 320 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 xmodem.c + /tmp/ccS6UZmS.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccS6UZmS.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccS6UZmS.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccS6UZmS.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccS6UZmS.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccS6UZmS.s:7 *ABS*:0000000000000001 __zero_reg__ + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +__do_clear_bss diff --git a/Projects/ArduinoUno/Adam/cliTask/FreeRTOSConfig.h b/Projects/ArduinoUno/Adam/cliTask/FreeRTOSConfig.h new file mode 100644 index 0000000..933b5a2 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/FreeRTOSConfig.h @@ -0,0 +1,101 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 16000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 0x80 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 0x05A0 ) ) +#define configMAX_TASK_NAME_LEN 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 0x03DE + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/ArduinoUno/Adam/cliTask/Makefile b/Projects/ArduinoUno/Adam/cliTask/Makefile new file mode 100644 index 0000000..ce59041 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/Makefile @@ -0,0 +1,453 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega328p + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTS_SRC_DIR = ../../../../FreeRtosCore/Source +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega168 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang +LIB_DIR = ../../../../Lib + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +vty.c \ +cli_task.c \ +loop_task.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/queueStream.c \ +$(RTS_SRC_DIR)/tasks.c \ +$(RTS_SRC_DIR)/queue.c \ +$(RTS_SRC_DIR)/list.c \ +$(RTS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTS_SRC_DIR)/include -I$(LIB_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=16000000UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. + +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = arduino +AVRDUDE_MCU = m328p +AVRDUDE_PORT = /dev/ttyACM0 +AVRDUDE_BITRATE = 115200 + +AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b $(AVRDUDE_BITRATE) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +#AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +#AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +#AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + if killall minicom; then sleep 10; fi + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +program2: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + + +programfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/ArduinoUno/Adam/cliTask/cliTask.cbp b/Projects/ArduinoUno/Adam/cliTask/cliTask.cbp new file mode 100644 index 0000000..a24eff3 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/cliTask.cbp @@ -0,0 +1,124 @@ + + + + + + diff --git a/Projects/ArduinoUno/Adam/cliTask/cli_task.c b/Projects/ArduinoUno/Adam/cliTask/cli_task.c new file mode 100644 index 0000000..203fc50 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/cli_task.c @@ -0,0 +1,19 @@ +#include "cli_task.h" + +void vTaskVTY(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + diff --git a/Projects/ArduinoUno/Adam/cliTask/cli_task.h b/Projects/ArduinoUno/Adam/cliTask/cli_task.h new file mode 100644 index 0000000..7cd5c04 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/cli_task.h @@ -0,0 +1,23 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTY(void *cliStatePtr); + + + +#endif /* CLI_TASK_H */ diff --git a/Projects/ArduinoUno/Adam/cliTask/configuration.c b/Projects/ArduinoUno/Adam/cliTask/configuration.c new file mode 100644 index 0000000..2b16faa --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/configuration.c @@ -0,0 +1,18 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +void loadConfiguration(void) +{ +// eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); +} + +void saveConfiguration(void) +{ + //saveNic(); + //ipSaveConfig(); + //udpSaveConfig(); +} diff --git a/Projects/ArduinoUno/Adam/cliTask/configuration.h b/Projects/ArduinoUno/Adam/cliTask/configuration.h new file mode 100644 index 0000000..7ec125d --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/configuration.h @@ -0,0 +1,13 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "hardware.h" + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + + +#endif diff --git a/Projects/ArduinoUno/Adam/cliTask/hardware.c b/Projects/ArduinoUno/Adam/cliTask/hardware.c new file mode 100644 index 0000000..0c05511 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/hardware.c @@ -0,0 +1,10 @@ +#include "hardware.h" + +void hardwareInit(void) +{ + DDRB = 0x20; + PORTB = 0x20; + + DDRD = 0x02; +} + diff --git a/Projects/ArduinoUno/Adam/cliTask/hardware.h b/Projects/ArduinoUno/Adam/cliTask/hardware.h new file mode 100644 index 0000000..33f3c3b --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/hardware.h @@ -0,0 +1,23 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + + +/** + * Hardware initialize + */ +void hardwareInit(void); + +#endif + + diff --git a/Projects/ArduinoUno/Adam/cliTask/hardwareConfig.h b/Projects/ArduinoUno/Adam/cliTask/hardwareConfig.h new file mode 100644 index 0000000..5b39d0f --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/hardwareConfig.h @@ -0,0 +1,9 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + + +#endif diff --git a/Projects/ArduinoUno/Adam/cliTask/loop_task.c b/Projects/ArduinoUno/Adam/cliTask/loop_task.c new file mode 100644 index 0000000..da80429 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/loop_task.c @@ -0,0 +1,15 @@ +#include "loop_task.h" + +void vTaskLoop(void *arg) +{ + (void) arg; + + for( ;; ) + { + vTaskDelay(100); + PORTB = 0; + + vTaskDelay(100); + PORTB |= 0x20; + } +} diff --git a/Projects/ArduinoUno/Adam/cliTask/loop_task.h b/Projects/ArduinoUno/Adam/cliTask/loop_task.h new file mode 100644 index 0000000..f1cbbf8 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/loop_task.h @@ -0,0 +1,10 @@ +#ifndef LOOP_TASK_H_INCLUDED +#define LOOP_TASK_H_INCLUDED + +#include +#include "FreeRTOS.h" +#include "task.h" + +void vTaskLoop(void *arg); + +#endif // LOOP_TASK_H_INCLUDED diff --git a/Projects/ArduinoUno/Adam/cliTask/main.c b/Projects/ArduinoUno/Adam/cliTask/main.c new file mode 100644 index 0000000..cf0c529 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/main.c @@ -0,0 +1,97 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include + +#include "main.h" + + +xTaskHandle xHandleVTY; +xTaskHandle xHandleLoop; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; +cmdState_t cliStateUSB; +FILE usbStream; +uint8_t timer100Hz = 0; + + +void vApplicationIdleHook( void ); +void vApplicationTickHook( void ); + +portSHORT main( void ) +{ + hardwareInit(); + + xSerialPortInitMinimal(); + loadConfiguration(); + + initQueueStreamUSB(&usbStream); + VtyInit(&cliStateUSB, &usbStream); + + xTaskCreate(vTaskVTY, NULL /*"" */, STACK_SIZE_VTY, (void *)(&cliStateUSB), 1, &xHandleVTY); + xTaskCreate(vTaskLoop, NULL /*"" */, 0x80, NULL, 1, &xHandleLoop); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + } +} diff --git a/Projects/ArduinoUno/Adam/cliTask/main.h b/Projects/ArduinoUno/Adam/cliTask/main.h new file mode 100644 index 0000000..620b9eb --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/main.h @@ -0,0 +1,37 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + + +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "queueStream.h" +#include "cli_task.h" +#include "loop_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" + +#include "cmdline.h" +#include "memory_x.h" +#include "vty.h" + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.31" + + +#endif diff --git a/Projects/ArduinoUno/Adam/cliTask/serial.c b/Projects/ArduinoUno/Adam/cliTask/serial.c new file mode 100644 index 0000000..5fee2b6 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/serial.c @@ -0,0 +1,101 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + return 0; +} + +void xSerialPortInitMinimal(void) +{ ///500 000 @ 16MHz + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + } + portEXIT_CRITICAL(); + + UBRR0L = 1; + UBRR0H = 0; + + UCSR0B = ((1< + + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +/* CLI */ +#define CLI_BUF_TOT_LEN 0x0080 +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + + +//#define HEAP_BEGIN 0x0100 +//#define HEAP_END CLI_1_BUF_ADDR - 1 +//#define HEAP_SIZE HEAP_END - HEAP_BEGIN + 1 + + +char cliBuffer[CLI_BUF_TOT_LEN]; + +//#define configUSE_MALLOC_FAILED_HOOK 1 + + + +/* Memory Map + 0x0000 +-----------------------------+ + 256 | Controll registers | + 0x0100 +-----------------------------+ + 2k | Internal memory | + + + + + + 0x08FF +-----------------------------+ +*/ + +#endif diff --git a/Projects/ArduinoUno/Adam/cliTask/vty.c b/Projects/ArduinoUno/Adam/cliTask/vty.c new file mode 100644 index 0000000..6ad9782 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/vty.c @@ -0,0 +1,152 @@ +#include "main.h" +#include "vty.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "softwareConfig.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t saveConfigFunction (cmdState_t *state); + +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; +const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + +const char * const errorStrings[] PROGMEM = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, cliBuffer, CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} + +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); +// printErrorInfo(state); //TODO fix and uncomment +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t statusFunction(cmdState_t *state) +{ + printStatus(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} diff --git a/Projects/ArduinoUno/Adam/cliTask/vty.h b/Projects/ArduinoUno/Adam/cliTask/vty.h new file mode 100644 index 0000000..bbf1e7b --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/vty.h @@ -0,0 +1,38 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include + +#include "memory_x.h" +#include "configuration.h" + +#include "cmdline.h" + + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/ArduinoUno/Adam/cliTask/vty_en.h b/Projects/ArduinoUno/Adam/cliTask/vty_en.h new file mode 100644 index 0000000..848f53a --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/vty_en.h @@ -0,0 +1,40 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; +const char errorNoFile[] PROGMEM = "No File\r\n"; +const char errorxModemFrameStartTimeout[] PROGMEM = "\r\n"; +const char errorxModemByteSendTimeout[] PROGMEM = "\r\n"; +const char errorxModemWrongFrameNo[] PROGMEM = "\r\n"; +const char errorxModemFrameFrameNoCorrectionNotMatch[] PROGMEM = "\r\n"; +const char errorxModemFrameCrc[] PROGMEM = "xModem CRC error\r\n"; +const char errorxModemRemoteSideCan[] PROGMEM = "Remote side cancelled at frame no %d\r\n"; +const char errorxModemUnknownResponse[] PROGMEM = "xModem unknown response 0x%x\r\n"; +const char errorNoRemoteDevice[] PROGMEM = "Device %d is not responding (%d)\r\n"; +const char errorBootloaderNotResponding[] PROGMEM = "Bootloader is not responding\r\n"; +const char errorOpenFile[] PROGMEM = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; + +const char debugEnabledInfoStr[] PROGMEM = "Enabled %s debug\r\n"; +const char debugDisabledInfoStr[] PROGMEM = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Enable mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "View mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configure mode"; +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; +#endif + diff --git a/Projects/ArduinoUno/Adam/cliTask/vty_pl.h b/Projects/ArduinoUno/Adam/cliTask/vty_pl.h new file mode 100644 index 0000000..0a805c7 --- /dev/null +++ b/Projects/ArduinoUno/Adam/cliTask/vty_pl.h @@ -0,0 +1,34 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/FreeRTOSConfig.h b/Projects/ArduinoUno/Zubr/c2h5ohino/FreeRTOSConfig.h new file mode 100644 index 0000000..933b5a2 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/FreeRTOSConfig.h @@ -0,0 +1,101 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 16000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 0x80 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 0x05A0 ) ) +#define configMAX_TASK_NAME_LEN 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 0x03DE + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/Makefile b/Projects/ArduinoUno/Zubr/c2h5ohino/Makefile new file mode 100644 index 0000000..ce59041 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/Makefile @@ -0,0 +1,453 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega328p + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTS_SRC_DIR = ../../../../FreeRtosCore/Source +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega168 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang +LIB_DIR = ../../../../Lib + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +vty.c \ +cli_task.c \ +loop_task.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/queueStream.c \ +$(RTS_SRC_DIR)/tasks.c \ +$(RTS_SRC_DIR)/queue.c \ +$(RTS_SRC_DIR)/list.c \ +$(RTS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTS_SRC_DIR)/include -I$(LIB_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=16000000UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. + +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = arduino +AVRDUDE_MCU = m328p +AVRDUDE_PORT = /dev/ttyACM0 +AVRDUDE_BITRATE = 115200 + +AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b $(AVRDUDE_BITRATE) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +#AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +#AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +#AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + if killall minicom; then sleep 10; fi + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +program2: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + + +programfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/c2h5ohino.cbp b/Projects/ArduinoUno/Zubr/c2h5ohino/c2h5ohino.cbp new file mode 100644 index 0000000..e84b143 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/c2h5ohino.cbp @@ -0,0 +1,124 @@ + + + + + + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.c b/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.c new file mode 100644 index 0000000..203fc50 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.c @@ -0,0 +1,19 @@ +#include "cli_task.h" + +void vTaskVTY(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.h b/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.h new file mode 100644 index 0000000..7cd5c04 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/cli_task.h @@ -0,0 +1,23 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTY(void *cliStatePtr); + + + +#endif /* CLI_TASK_H */ diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.c b/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.c new file mode 100644 index 0000000..2b16faa --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.c @@ -0,0 +1,18 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +void loadConfiguration(void) +{ +// eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); +} + +void saveConfiguration(void) +{ + //saveNic(); + //ipSaveConfig(); + //udpSaveConfig(); +} diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.h b/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.h new file mode 100644 index 0000000..7ec125d --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/configuration.h @@ -0,0 +1,13 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "hardware.h" + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/firmware.lock b/Projects/ArduinoUno/Zubr/c2h5ohino/firmware.lock new file mode 100644 index 0000000..1996e8f --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/firmware.lock @@ -0,0 +1 @@ +:00000001FF diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.c b/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.c new file mode 100644 index 0000000..0c05511 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.c @@ -0,0 +1,10 @@ +#include "hardware.h" + +void hardwareInit(void) +{ + DDRB = 0x20; + PORTB = 0x20; + + DDRD = 0x02; +} + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.h b/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.h new file mode 100644 index 0000000..33f3c3b --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/hardware.h @@ -0,0 +1,23 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + + +/** + * Hardware initialize + */ +void hardwareInit(void); + +#endif + + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/hardwareConfig.h b/Projects/ArduinoUno/Zubr/c2h5ohino/hardwareConfig.h new file mode 100644 index 0000000..5b39d0f --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/hardwareConfig.h @@ -0,0 +1,9 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.c b/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.c new file mode 100644 index 0000000..da80429 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.c @@ -0,0 +1,15 @@ +#include "loop_task.h" + +void vTaskLoop(void *arg) +{ + (void) arg; + + for( ;; ) + { + vTaskDelay(100); + PORTB = 0; + + vTaskDelay(100); + PORTB |= 0x20; + } +} diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.h b/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.h new file mode 100644 index 0000000..f1cbbf8 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/loop_task.h @@ -0,0 +1,10 @@ +#ifndef LOOP_TASK_H_INCLUDED +#define LOOP_TASK_H_INCLUDED + +#include +#include "FreeRTOS.h" +#include "task.h" + +void vTaskLoop(void *arg); + +#endif // LOOP_TASK_H_INCLUDED diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/main.c b/Projects/ArduinoUno/Zubr/c2h5ohino/main.c new file mode 100644 index 0000000..cf0c529 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/main.c @@ -0,0 +1,97 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include + +#include "main.h" + + +xTaskHandle xHandleVTY; +xTaskHandle xHandleLoop; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; +cmdState_t cliStateUSB; +FILE usbStream; +uint8_t timer100Hz = 0; + + +void vApplicationIdleHook( void ); +void vApplicationTickHook( void ); + +portSHORT main( void ) +{ + hardwareInit(); + + xSerialPortInitMinimal(); + loadConfiguration(); + + initQueueStreamUSB(&usbStream); + VtyInit(&cliStateUSB, &usbStream); + + xTaskCreate(vTaskVTY, NULL /*"" */, STACK_SIZE_VTY, (void *)(&cliStateUSB), 1, &xHandleVTY); + xTaskCreate(vTaskLoop, NULL /*"" */, 0x80, NULL, 1, &xHandleLoop); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + } +} diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/main.h b/Projects/ArduinoUno/Zubr/c2h5ohino/main.h new file mode 100644 index 0000000..620b9eb --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/main.h @@ -0,0 +1,37 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + + +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "queueStream.h" +#include "cli_task.h" +#include "loop_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" + +#include "cmdline.h" +#include "memory_x.h" +#include "vty.h" + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.31" + + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/serial.c b/Projects/ArduinoUno/Zubr/c2h5ohino/serial.c new file mode 100644 index 0000000..5fee2b6 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/serial.c @@ -0,0 +1,101 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + return 0; +} + +void xSerialPortInitMinimal(void) +{ ///500 000 @ 16MHz + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + } + portEXIT_CRITICAL(); + + UBRR0L = 1; + UBRR0H = 0; + + UCSR0B = ((1< + + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +/* CLI */ +#define CLI_BUF_TOT_LEN 0x0080 +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + + +//#define HEAP_BEGIN 0x0100 +//#define HEAP_END CLI_1_BUF_ADDR - 1 +//#define HEAP_SIZE HEAP_END - HEAP_BEGIN + 1 + + +char cliBuffer[CLI_BUF_TOT_LEN]; + +//#define configUSE_MALLOC_FAILED_HOOK 1 + + + +/* Memory Map + 0x0000 +-----------------------------+ + 256 | Controll registers | + 0x0100 +-----------------------------+ + 2k | Internal memory | + + + + + + 0x08FF +-----------------------------+ +*/ + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/vty.c b/Projects/ArduinoUno/Zubr/c2h5ohino/vty.c new file mode 100644 index 0000000..6ad9782 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/vty.c @@ -0,0 +1,152 @@ +#include "main.h" +#include "vty.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "softwareConfig.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t saveConfigFunction (cmdState_t *state); + +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; +const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + +const char * const errorStrings[] PROGMEM = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, cliBuffer, CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} + +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); +// printErrorInfo(state); //TODO fix and uncomment +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t statusFunction(cmdState_t *state) +{ + printStatus(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/vty.h b/Projects/ArduinoUno/Zubr/c2h5ohino/vty.h new file mode 100644 index 0000000..bbf1e7b --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/vty.h @@ -0,0 +1,38 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include + +#include "memory_x.h" +#include "configuration.h" + +#include "cmdline.h" + + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/vty_en.h b/Projects/ArduinoUno/Zubr/c2h5ohino/vty_en.h new file mode 100644 index 0000000..848f53a --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/vty_en.h @@ -0,0 +1,40 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; +const char errorNoFile[] PROGMEM = "No File\r\n"; +const char errorxModemFrameStartTimeout[] PROGMEM = "\r\n"; +const char errorxModemByteSendTimeout[] PROGMEM = "\r\n"; +const char errorxModemWrongFrameNo[] PROGMEM = "\r\n"; +const char errorxModemFrameFrameNoCorrectionNotMatch[] PROGMEM = "\r\n"; +const char errorxModemFrameCrc[] PROGMEM = "xModem CRC error\r\n"; +const char errorxModemRemoteSideCan[] PROGMEM = "Remote side cancelled at frame no %d\r\n"; +const char errorxModemUnknownResponse[] PROGMEM = "xModem unknown response 0x%x\r\n"; +const char errorNoRemoteDevice[] PROGMEM = "Device %d is not responding (%d)\r\n"; +const char errorBootloaderNotResponding[] PROGMEM = "Bootloader is not responding\r\n"; +const char errorOpenFile[] PROGMEM = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; + +const char debugEnabledInfoStr[] PROGMEM = "Enabled %s debug\r\n"; +const char debugDisabledInfoStr[] PROGMEM = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Enable mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "View mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configure mode"; +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; +#endif + diff --git a/Projects/ArduinoUno/Zubr/c2h5ohino/vty_pl.h b/Projects/ArduinoUno/Zubr/c2h5ohino/vty_pl.h new file mode 100644 index 0000000..0a805c7 --- /dev/null +++ b/Projects/ArduinoUno/Zubr/c2h5ohino/vty_pl.h @@ -0,0 +1,34 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/FreeRTOSConfig.h b/Projects/AtXmegaRobo/Drobo/FreeRTOSConfig.h new file mode 100644 index 0000000..1bccee3 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/FreeRTOSConfig.h @@ -0,0 +1,143 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include +//#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 //1 jakiego planisty wybieramy 1- preemptive 0 - cooperative (wspó³dzielony ) + +#define configUSE_IDLE_HOOK 0 //1 + +#define configUSE_TICK_HOOK 0 //0 + +#define configCPU_CLOCK_HZ ( ( unsigned long ) 32000000 )//2MHz is default value for xmega.//16MHz + +//If you you want another frequency don't forget to modify period of timer counter used for tick interrupt + +#define configTICK_RATE_HZ ( ( portTickType ) 100 )// czestotliwoœæ RTOS przerwania tick, sluzy do odmierzania czasu + +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 )//4 maksymalna liczba priorytetów obs³ugiwana przez zadanie + +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 150 )//85 // min rozmiar stosu, który wykorzystywany jest przez zadanie IDle + +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 7000 ) )//1500// całkowita ilość pamięci RAM dostępna dla jądra RTOS + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +#define configUSE_MUTEXES 1 + +#define configMAX_TASK_NAME_LEN ( 10 ) + +#define configUSE_TRACE_FACILITY 1 //Set to 1 if you wish to include additional structure members and functions to assist with execution visualisation and tracing + +#define configUSE_16_BIT_TICKS 1//Time is measured in 'ticks' Defining configUSE_16_BIT_TICKS as 1 causes portTickType to be defined (typedef'ed) as an unsigned 16bit type. Defining configUSE_16_BIT_TICKS as 0 causes portTickType to be defined (typedef'ed) as an unsigned 32bit type. + +#define configIDLE_SHOULD_YIELD 1//This parameter controls the behaviour of tasks at the idle priority. + +#define configQUEUE_REGISTRY_SIZE 0 + + + +/* Debug */ + +//#define configCHECK_FOR_STACK_OVERFLOW 1//0 + + + +/* Co-routine definitions. */ + +#define configUSE_CO_ROUTINES 0 //1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 )//2 + + + +/* Set the following definitions to 1 to include the API function, or zero + +to exclude the API function. */ + + + +#define INCLUDE_vTaskPrioritySet 1 + +#define INCLUDE_uxTaskPriorityGet 1 + +#define INCLUDE_vTaskDelete 0 + +#define INCLUDE_vTaskCleanUpResources 0 + +#define INCLUDE_vTaskSuspend 1 + +#define INCLUDE_vTaskDelayUntil 1 + +#define INCLUDE_vTaskDelay 1 + + + +#define STACK_SIZE_VTY 1000 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/AtXmegaRobo/Drobo/Makefile b/Projects/AtXmegaRobo/Drobo/Makefile new file mode 100644 index 0000000..237f7a5 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/Makefile @@ -0,0 +1,464 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atxmega128a4u + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTOS_SRC_DIR = ../../../FreeRtosCore/Source +LIB_DIR = ../../../Lib +LIB_NET_DIR = ../../../Lib/net +PORT_DIR = ../../../FreeRtosCore/portable/GCC/ATXmega +PORT_MEM = ../../../FreeRtosCore/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +vty.c \ +cli_task.c \ +tlv_task.c\ +main_task.c\ +hc12.c\ +sim900.c\ +tlv.c\ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_DIR)/tlvProt.c \ +$(RTOS_SRC_DIR)/tasks.c \ +$(RTOS_SRC_DIR)/queue.c \ +$(RTOS_SRC_DIR)/list.c \ +$(RTOS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#$(LIB_DIR)/ebi.c\ To zostało usunięte. Gdzie jest ten plik ??? +#netstack_task.c \ +#$(LIB_DIR)/enc28j60.c \ +#sensors_task.c \ +#$(LIB_DIR)/ds1305.c \ +#$$(LIB_DIR)/mpc23s17.c \ +#$(LIB_DIR)/mcp3008.c \ +#$(LIB_DIR)/mcp4150.c \ + + +#$(LIB_NET_DIR)/udp.c \ +#$(LIB_NET_DIR)/ip.c \ +#$(LIB_NET_DIR)/icmp.c \ +#$(LIB_NET_DIR)/arp.c \ +#$(LIB_NET_DIR)/tcp.c \ +#$(LIB_NET_DIR)/nic.c \ +#$(LIB_NET_DIR)/net.c \ + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused -Wattributes + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTOS_SRC_DIR)/include -I$(LIB_DIR)/include -I$(LIB_NET_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=32000000UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +# heap_start=0x804000 heap_end=0x8056FF +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x804000,--defsym=__heap_end=0x8027ff +EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = avrispmkII +# jtag1 +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = usb +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling!!!!!!: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/AtXmegaRobo/Drobo/TODO.txt b/Projects/AtXmegaRobo/Drobo/TODO.txt new file mode 100644 index 0000000..74a6ea8 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/TODO.txt @@ -0,0 +1,4 @@ +1) Modyfikacja bibliotek. Zrezygnować ze wskaźników do funkcji. Zastosować __attribute__(weak) +2) Dodać możliwość tworzenia buforów cyklicznych, których tablica pamięci umieszczona jest w zewnętrznej pamięci +3) Dodać obsługę specjalnych koment VTY (odpowiednia interpretacja nowych linii, itd) +4) Uruchomić sokety \ No newline at end of file diff --git a/Projects/AtXmegaRobo/Drobo/avr_compiler.h b/Projects/AtXmegaRobo/Drobo/avr_compiler.h new file mode 100644 index 0000000..662e6ac --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/avr_compiler.h @@ -0,0 +1,153 @@ +/* This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief This file implements some macros that makes the IAR C-compiler and + * avr-gcc work with the same code base for the AVR architecture. + * + * \par Documentation + * For comprehensive code documentation, supported compilers, compiler + * settings and supported devices see readme.html + * + * \author + * Atmel Corporation: http://www.atmel.com \n + * Support email: avr@atmel.com + * + * $Revision: 613 $ + * $Date: 2006-04-07 14:40:07 +0200 (fr, 07 apr 2006) $ \n + * + * Copyright (c) 2008, Atmel Corporation All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of ATMEL may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND + * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +#ifndef COMPILER_AVR_H +#define COMPILER_AVR_H + +#ifndef F_CPU +/*! \brief Define default CPU frequency, if this is not already defined. */ +#define F_CPU 16000000UL//tu na 16MHz +#endif + +#include +#include +#include + +/*! \brief This macro will protect the following code from interrupts. */ +#define AVR_ENTER_CRITICAL_REGION( ) uint8_t volatile saved_sreg = SREG; \ + cli(); + +/*! \brief This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION + * so the interrupts are enabled again. + */ +#define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg; + +#if defined( __ICCAVR__ ) + +#include +#include +#include +#include + +#ifndef __HAS_ELPM__ +#define _MEMATTR __flash +#else /* __HAS_ELPM__ */ +#define _MEMATTR __farflash +#endif /* __HAS_ELPM__ */ + +/*! \brief Perform a delay of \c us microseconds. + * + * The macro F_CPU is supposed to be defined to a constant defining the CPU + * clock frequency (in Hertz). + * + * The maximal possible delay is 262.14 ms / F_CPU in MHz. + * + * \note For the IAR compiler, currently F_CPU must be a + * multiple of 1000000UL (1 MHz). + */ +#define delay_us( us ) ( __delay_cycles( ( F_CPU / 1000000UL ) * ( us ) ) ) + +/*! \brief Preprocessor magic. + * + * Some preprocessor magic to allow for a header file abstraction of + * interrupt service routine declarations for the IAR compiler. This + * requires the use of the C99 _Pragma() directive (rather than the + * old #pragma one that could not be used as a macro replacement), as + * well as two different levels of preprocessor concetanations in + * order to do both, assign the correct interrupt vector name, as well + * as construct a unique function name for the ISR. + * + * \note Do *NOT* try to reorder the macros below, as this will only + * work in the given order. + */ +#define PRAGMA(x) _Pragma( #x ) +#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) +#define sei( ) (__enable_interrupt( )) +#define cli( ) (__disable_interrupt( )) + +/*! \brief Define the no operation macro. */ +#define nop( ) (__no_operation()) + +/*! \brief Define the watchdog reset macro. */ +#define watchdog_reset( ) (__watchdog_reset( )) + + +#define INLINE PRAGMA( inline=forced ) static + +#define FLASH_DECLARE(x) _MEMATTR x +#define FLASH_STRING(x) ((_MEMATTR const char *)(x)) +#define FLASH_STRING_T char const _MEMATTR * +#define FLASH_BYTE_ARRAY_T uint8_t const _MEMATTR * +#define PGM_READ_BYTE(x) *(x) +#define PGM_READ_WORD(x) *(x) + +#define SHORTENUM /**/ + +#elif defined( __GNUC__ ) + +#include +#include +#include +#include + +/*! \brief Define the delay_us macro for GCC. */ +#define delay_us( us ) (_delay_us( us )) + +#define INLINE static inline + +/*! \brief Define the no operation macro. */ +#define nop() do { __asm__ __volatile__ ("nop"); } while (0) + +#define MAIN_TASK_PROLOGUE int + +#define MAIN_TASK_EPILOGUE() return -1; + +#define SHORTENUM __attribute__ ((packed)) + +#else +#error Compiler not supported. +#endif + +#endif + diff --git a/Projects/AtXmegaRobo/Drobo/cli_task.c b/Projects/AtXmegaRobo/Drobo/cli_task.c new file mode 100644 index 0000000..98962f5 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/cli_task.c @@ -0,0 +1,19 @@ +#include "cli_task.h" + +void vTaskVTYusb(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char recSymbol; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &recSymbol, portMAX_DELAY)) + { + cmdlineInputFunc((char)recSymbol, state); + cmdlineMainLoop(state); + } + } +} + diff --git a/Projects/AtXmegaRobo/Drobo/cli_task.h b/Projects/AtXmegaRobo/Drobo/cli_task.h new file mode 100644 index 0000000..8da473b --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/cli_task.h @@ -0,0 +1,33 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +#include "task.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYusb(void *cliStatePtr); + + + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod uniwersalny dla dowolnego strumienia FILE + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +//void vTaskVTYsocket(void *cliStatePtr); + + +#endif /* CLI_TASK_H */ diff --git a/Projects/AtXmegaRobo/Drobo/configuration.c b/Projects/AtXmegaRobo/Drobo/configuration.c new file mode 100644 index 0000000..8b799b2 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/configuration.c @@ -0,0 +1,47 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + + +uint8_t confEepHC12mode __attribute__((section (".eeprom"))) = 1; //1 - 3 +uint16_t confEepHC12baud __attribute__((section (".eeprom"))) = 9600; // +uint8_t confEepHC12channel __attribute__((section (".eeprom"))) = 10; //1-100 +uint8_t confEepHC12power __attribute__((section (".eeprom"))) = 1; //1-8 + +uint8_t confEepPwmFreq __attribute__((section (".eeprom"))) = 6; //4 - 7 4: 40 kHZ, 5: 5kHz, 6: 7: 320 Hz + + +uint8_t confHC12mode; //1 - 3 +uint16_t confHC12baud; // +uint8_t confHC12channel; +uint8_t confHC12power; //1-8 + + +void loadConfiguration(void) +{ + confHC12mode = eeprom_read_byte(&confEepHC12mode); + confHC12baud = eeprom_read_word(&confEepHC12baud); + confHC12channel = eeprom_read_byte(&confEepHC12channel); + confHC12power = eeprom_read_byte(&confEepHC12power); + + uint8_t tmp = eeprom_read_byte(&confEepPwmFreq); + if (tmp >= 4 && tmp <=7) + { + TCC0.CTRLA &= 0xF0; + TCC0.CTRLA |= tmp; + } + //Preskaler 256 PWM @ 1.28 kHz +} + +void saveConfiguration(void) +{ + eeprom_write_byte(&confEepHC12mode, confHC12mode); + eeprom_write_word(&confEepHC12baud, confHC12baud); + eeprom_write_byte(&confEepHC12channel, confHC12channel); + eeprom_write_byte(&confEepHC12power, confHC12power); + + eeprom_write_byte(&confEepPwmFreq, (TCC0.CTRLA & 0x0F)); +} diff --git a/Projects/AtXmegaRobo/Drobo/configuration.h b/Projects/AtXmegaRobo/Drobo/configuration.h new file mode 100644 index 0000000..7b48c8d --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/configuration.h @@ -0,0 +1,18 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "hardware.h" + +#ifdef USE_NET +#include "enc28j60.h" +#include "ip.h" +#include "nic.h" +#include "udp.h" +#endif + +void loadConfiguration(void); +void saveConfiguration(void); + + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/drobo.cbp b/Projects/AtXmegaRobo/Drobo/drobo.cbp new file mode 100644 index 0000000..e89eb28 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/drobo.cbp @@ -0,0 +1,140 @@ + + + + + + diff --git a/Projects/AtXmegaRobo/Drobo/flash.sh b/Projects/AtXmegaRobo/Drobo/flash.sh new file mode 100755 index 0000000..4282698 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/flash.sh @@ -0,0 +1,20 @@ +#!/usr/bin/expect -f + +system "hex2bin firmware.hex" +system "echo To_jest_wypelnienie_poniewaz_bootloader_ma_jeszcze_buga_i_nie_wgrywa_ostatniego_bloku_256_bajtow._Zatem_tutaj_jest_jakis_zbedny_tekst_ktory_bedzie_widzany_w_obrazie_firmware_procka._Chyba_juz_starcz_tego_tekstu >> firmware.bin" + + +set dev "/dev/atmega128eval" +set file "./firmware.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" + +send "flash" +expect "C" +send_user "\nStarting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" diff --git a/Projects/AtXmegaRobo/Drobo/hardware.c b/Projects/AtXmegaRobo/Drobo/hardware.c new file mode 100644 index 0000000..2553684 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hardware.c @@ -0,0 +1,242 @@ +#include "hardware.h" +#include +#include + +//xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję do czasu zakończenia wysyłania poprzedniego bajtu +//xQueueHandle xSpiRxEnc; + +uint8_t ReadCalibrationByte( uint8_t index ) +{ + uint8_t result; + + /* Load the NVM Command register to read the calibration row. */ + NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; + result = pgm_read_byte(index); + + /* Clean up NVM Command register. */ + NVM_CMD = NVM_CMD_NO_OPERATION_gc; + + return( result ); +} + +void hardwareInit(void) +{ + /// PORT A MOSTKI H + //0 - (18) 4 - B1 in + //1 - (17) 5 - A1 in + //2 - (20) 6 - B2 in + //3 - (19) 7 - A2 in + PORTA.DIR=0xFF; + PORTA.OUT=0x00; + + ///PORT B - Złącze 20 pin + //0 - 13 2 - 14 + //1 - 14 3 - 15 + PORTB.DIR=0x00; + PORTB.OUT=0x00; + + ///PORT C + // 0 I2C // 4 PWMA + // 1 I2C // 5 PWMB + // 2 UART VTY RxD // 6 UART radio RxD + // 3 UART VTY TxD // 7 UART radio TxD + + PORTC.REMAP=((1< +//#include + +//#include "hardwareConfig.h" +//#include "softwareConfig.h" + + + + +/** + * Hardware initialize + */ + +uint8_t ReadCalibrationByte(uint8_t index); +void hardwareInit(void); + +void offHbridge(void); + +void forwardA(uint8_t left, uint8_t right); +void backwordA(uint8_t left, uint8_t right); +void rotateLeftA(uint8_t left, uint8_t right); +void rotateRightA(uint8_t left, uint8_t right); + +void forwardB(uint8_t left, uint8_t right); +void backwordB(uint8_t left, uint8_t right); +void rotateLeftB(uint8_t left, uint8_t right); +void rotateRightB(uint8_t left, uint8_t right); + +void pwrOn4v3(void); +void pwrOff4v3(void); +void pwrOn3v3rpi(void); +void pwrOff3v3rpi(void); +void pwrOn4v3rpi(void); +void pwrOff4v3rpi(void); + +uint8_t isPwr4v3(void); +uint8_t isPwr3v3rpi(void); +uint8_t isPwr4v3rpi(void); + +#endif + diff --git a/Projects/AtXmegaRobo/Drobo/hardwareConfig.h b/Projects/AtXmegaRobo/Drobo/hardwareConfig.h new file mode 100644 index 0000000..f3d50f1 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hardwareConfig.h @@ -0,0 +1,14 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +// --------------------- Configuration I/O module -------------------------------- + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + +#define CLI_BUF_TOT_LEN 0x000100 + +#define TLV_BUF_LEN 32 + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/hardware_en.h b/Projects/AtXmegaRobo/Drobo/hardware_en.h new file mode 100644 index 0000000..87701b4 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hardware_en.h @@ -0,0 +1,10 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE EN +#include + +const char statusLockerSensDescStr[] PROGMEM = " locker %d"; +const char statusLockerOpenStr[] PROGMEM = " open "; +const char statusLockerCloseStr[] PROGMEM = " locked "; +const char statusLockerSensAdditionalDescStr[] PROGMEM = " (threshold %d, AC value %d)\r\n"; + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/hardware_pl.h b/Projects/AtXmegaRobo/Drobo/hardware_pl.h new file mode 100644 index 0000000..9bf0733 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hardware_pl.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE PL + +prog_char statusLockerSensDescStr[] = " rygiel %d"; +prog_char statusLockerOpenStr[] = " otwarty "; +prog_char statusLockerCloseStr[] = " zamkniety"; +prog_char statusLockerSensAdditionalDescStr[] = " (granica %d, wartosc AC %d)\r\n"; + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/hc12.c b/Projects/AtXmegaRobo/Drobo/hc12.c new file mode 100644 index 0000000..caa2c76 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hc12.c @@ -0,0 +1,12 @@ +#include "hc12.h" + +void HC12setAtMode() +{ + PORTD.OUTCLR = PIN0_bm; +} + +void HC12setTransparentMode() +{ + PORTD.OUTSET = PIN0_bm; +} + diff --git a/Projects/AtXmegaRobo/Drobo/hc12.h b/Projects/AtXmegaRobo/Drobo/hc12.h new file mode 100644 index 0000000..45e0fba --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/hc12.h @@ -0,0 +1,11 @@ +#ifndef HC_12 +#define HC_12 + +#include + +void HC12setAtMode(void); +void HC12setTransparentMode(void); + + + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/main.c b/Projects/AtXmegaRobo/Drobo/main.c new file mode 100644 index 0000000..21ba5ed --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/main.c @@ -0,0 +1,172 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + + +uint8_t timer100Hz = 0; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; + +xQueueHandle xHC12Tx; +xQueueHandle xHC12Rec; +xQueueHandle xMainRec; + +xQueueHandle xSIM900Rec; +xQueueHandle xSIM900Tx; + +cmdState_t *CLIStateSerialUsb; +tlvInterpreter_t *TLVstate; + +FILE usbStream; +FILE hc12Stream; +FILE hc12FakeStream; + + +xSemaphoreHandle Hc12semaphore; + +xTaskHandle xHandleVTY_USB; +xTaskHandle xHandleTLV; +xTaskHandle xHandleMain; + + +void vApplicationIdleHook( void ); + +/** + * RTC clock support + */ +void vApplicationTickHook( void ); + + + +//xTaskHandle xHandleTranslator; + +/** + * konfiguracja zegara. Zegar wewnętrzny 32 MHz + */ +void my_init_clock(void) +{// Configure clock to 32MHz + OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm; /* Enable the internal 32MHz & 32KHz oscillators */ + while(!(OSC.STATUS & OSC_RC32KRDY_bm)); /* Wait for 32Khz oscillator to stabilize */ + while(!(OSC.STATUS & OSC_RC32MRDY_bm)); /* Wait for 32MHz oscillator to stabilize */ + DFLLRC32M.CTRL = DFLL_ENABLE_bm ; /* Enable DFLL - defaults to calibrate against internal 32Khz clock */ + CCP = CCP_IOREG_gc; /* Disable register security for clock update */ + CLK.CTRL = CLK_SCLKSEL_RC32M_gc; /* Switch to 32MHz clock */ + OSC.CTRL &= ~OSC_RC2MEN_bm; /* Disable 2Mhz oscillator */ +} + + +#ifdef USENET +cmdState_t *CLIStateSerialUdp; +FILE udpStream; +#endif + +streamBuffers_t udpBuffers; + +//#include + +// Define CPU clock frequency (if not already defined) +#ifndef F_CPU + // Enable/Disable internal oscillators + //#define F_CPU 2000000 + #define F_CPU 32000000 + // Enable/Disable external 14.7456 MHz oscillator + //#define F_CPU 14745600 +#endif + + +portSHORT main( void ) +{ + hardwareInit(); + loadConfiguration(); + xSerialPortInitMinimal(); + + xMainRec = xQueueCreate(16, 1); + + + CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + TLVstate = xmalloc(sizeof(tlvInterpreter_t)); + + Hc12semaphore = xSemaphoreCreateMutex(); + + initQueueStreamUSB(&usbStream); + initQueueStreamHC12(&hc12Stream); + initQueueStreamHC12fake(&hc12FakeStream); + + VtyInit(CLIStateSerialUsb, &usbStream); + tlvIinitializeInterpreter(TLVstate, &hc12Stream, &usbStream, tlvCmdList); + + sei(); + + xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb), 1, &xHandleVTY_USB); + xTaskCreate(vTaskTLV, NULL /*"TLV" */, STACK_SIZE_VTY, (void *)(TLVstate), 1, &xHandleTLV); + xTaskCreate(vTaskMain, NULL /*"TLV" */, STACK_SIZE_VTY, NULL, 1, &xHandleMain); + + vTaskStartScheduler(); + + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint16_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; +#ifdef USENET + arpTimer(); +#endif + } +} diff --git a/Projects/AtXmegaRobo/Drobo/main.h b/Projects/AtXmegaRobo/Drobo/main.h new file mode 100644 index 0000000..03509c0 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/main.h @@ -0,0 +1,49 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include +#include + +#include "memory_x.h" +//#include "Rs485_prot.h" + +#include "../../../FreeRtosCore/Source/include/FreeRTOS.h" +#include "../../../FreeRtosCore/Source/include/croutine.h" +#include "../../../FreeRtosCore/Source/include/queue.h" +#include "../../../FreeRtosCore/Source/include/task.h" +#include "../../../FreeRtosCore/Source/include/semphr.h" + +#include "queueStream.h" +#include "cli_task.h" +#include "tlv_task.h" +#include "main_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" + + +#include "cmdline.h" +#include "vty.h" +#include "tlv.h" + + + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.11" + +extern const tlvCommand_t tlvCmdList[]; + +void my_init_clock (void) __attribute__ ((naked)) __attribute__ ((section (".init0"))); + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/main_task.c b/Projects/AtXmegaRobo/Drobo/main_task.c new file mode 100644 index 0000000..e1c360b --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/main_task.c @@ -0,0 +1,12 @@ +#include "main_task.h" + +void vTaskMain(void *Ptr) +{ + (void) Ptr; + + for( ;; ) + { + vTaskDelay(10); + } +} + diff --git a/Projects/AtXmegaRobo/Drobo/main_task.h b/Projects/AtXmegaRobo/Drobo/main_task.h new file mode 100644 index 0000000..5328f59 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/main_task.h @@ -0,0 +1,39 @@ +#ifndef MAIN_TASK_H +#define MAIN_TASK_H + +#include +#include + + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +#include "task.h" + +#include "../../Lib/include/tlvProt.h" +#include "main.h" + + +extern xQueueHandle xMainRec; + + + +typedef struct mainMsg +{ + uint16_t duration; + uint8_t command; + uint8_t data[4]; +} mainMsg_t; + + +/** + * Proces odpowiedzialny za obsługę głównej pętli programu + * @param *Ptr + */ +void vTaskMain(void *Ptr); + + + + +#endif /* MAIN_TASK_H */ diff --git a/Projects/AtXmegaRobo/Drobo/serial.c b/Projects/AtXmegaRobo/Drobo/serial.c new file mode 100644 index 0000000..6662601 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/serial.c @@ -0,0 +1,273 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +void initQueueStreamHC12(FILE *stream) +{ + fdev_setup_stream(stream, HC12PutChar, HC12GetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +void initQueueStreamHC12fake(FILE *stream) +{ + fdev_setup_stream(stream, HC12PutCharFake, HC12GetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + return 0; +} + +int HC12GetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xHC12Rec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int HC12PutChar(char c, FILE *stream) +{ + (void) stream; + uartHC12SendByte(c); + return 0; +} + +int SIM900GetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xSIM900Rec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int SIM900PutChar(char c, FILE *stream) +{ + (void) stream; + uartSIM900SendByte(c); + return 0; +} + + +int HC12PutCharFake(char c, FILE *stream) +{ + (void) stream; + uartHC12SendByteFake(c); + return 0; +} + +//#include +void xSerialPortInitMinimal(void) +{ + ///VTY - USART C0 + USARTC0.CTRLA = USART_RXCINTLVL_LO_gc;// | USART_DREINTLVL_LO_gc; // Włączenie przerwań Odebrano. By włączyć przerwanie pusty bufor nadawczy dodać: USART_DREINTLVL_LO_gc + USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm; // Włączenie nadajnika i odbiornika + USARTC0.CTRLC = USART_CHSIZE_8BIT_gc; // Tryb 8 bitów + // 115200 @ 32MHz + USARTC0.BAUDCTRLA= 2094 & 0xFF; //BSEL = 2094 BSCALE = -7 + USARTC0.BAUDCTRLB= (-7 << USART_BSCALE0_bp)|(2094 >> 8); + + + /// HC-12 / ZigBee - USART C1 + USARTC1.CTRLA = USART_RXCINTLVL_LO_gc;// | USART_DREINTLVL_LO_gc; // Włączenie przerwań Odebrano. By włączyć przerwanie pusty bufor nadawczy dodać: USART_DREINTLVL_LO_gc + USARTC1.CTRLB = USART_RXEN_bm | USART_TXEN_bm; // Włączenie nadajnika i odbiornika + USARTC1.CTRLC = USART_CHSIZE_8BIT_gc; // Tryb 8 bitów + // 9600 @ 32MHz + USARTC1.BAUDCTRLA= 3317 & 0xFF; //BSEL = 3317 BSCALE = -4 + USARTC1.BAUDCTRLB= (-4 << USART_BSCALE0_bp)|(3317 >> 8); + + ///SIM900 - USART D0 + USARTD0.CTRLA = USART_RXCINTLVL_LO_gc;// | USART_DREINTLVL_LO_gc; // Włączenie przerwań Odebrano. By włączyć przerwanie pusty bufor nadawczy dodać: USART_DREINTLVL_LO_gc + USARTD0.CTRLB = USART_RXEN_bm | USART_TXEN_bm; // Włączenie nadajnika i odbiornika + USARTD0.CTRLC = USART_CHSIZE_8BIT_gc; // Tryb 8 bitów + // 115200 @ 32MHz + USARTD0.BAUDCTRLA= 2094 & 0xFF; //BSEL = 2094 BSCALE = -7 + USARTD0.BAUDCTRLB= (-7 << USART_BSCALE0_bp)|(2094 >> 8); + + + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + + xHC12Rec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xHC12Tx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + + xSIM900Rec = xQueueCreate(128,( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xSIM900Tx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + } + portEXIT_CRITICAL(); + return; +} + + +/** VTY ---------------------------------------------------*/ +ISR(USARTC0_RXC_vect) +{ + + static signed portBASE_TYPE xHigherPriorityTaskWoken; + signed portCHAR cChar; + + cChar = USARTC0.DATA; + //return; + //USARTC0.DATA = cChar+1; + + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(xVtyRec, &cChar, &xHigherPriorityTaskWoken); + if( xHigherPriorityTaskWoken ) + { + taskYIELD(); + } +} + +void uartVtySendByte(uint8_t data) +{ + xQueueSend(xVtyTx, &data, portMAX_DELAY); + vInterruptVtyOn(); +} + +ISR(USARTC0_DRE_vect) // USART1_UDRE_vect +{ + static signed portBASE_TYPE xHigherPriorityTaskWoken; + static char data; + if(xQueueReceiveFromISR(xVtyTx, &data, &xHigherPriorityTaskWoken) == pdTRUE) + { + USARTC0.DATA = data; + } + else + { + xHigherPriorityTaskWoken = pdFALSE; + vInterruptVtyOff(); + } + //if( xHigherPriorityTaskWoken ) + //{ + // taskYIELD(); + //} +} + + +/** HC12 ************************************/ + +ISR(USARTC1_RXC_vect) +{ + + static signed portBASE_TYPE xHigherPriorityTaskWoken; + signed portCHAR cChar; + + cChar = USARTC1.DATA; + //return; + //USARTC0.DATA = cChar+1; + + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(xHC12Rec, &cChar, &xHigherPriorityTaskWoken); + if( xHigherPriorityTaskWoken ) + { + taskYIELD(); + } +} + +void uartHC12SendByte(uint8_t data) +{ + xQueueSend(xHC12Tx, &data, 10); + vInterruptHC12On(); +} + +void uartHC12SendByteFake(uint8_t data) +{ + xQueueSend(xHC12Rec, &data, 0); +} + +ISR(USARTC1_DRE_vect) +{ + static signed portBASE_TYPE xHigherPriorityTaskWoken; + static char data; + if(xQueueReceiveFromISR(xHC12Tx, &data, &xHigherPriorityTaskWoken) == pdTRUE) + { + USARTC1.DATA = data; + } + else + { + xHigherPriorityTaskWoken = pdFALSE; + vInterruptHC12Off(); + } + if( xHigherPriorityTaskWoken ) + { + taskYIELD(); + } +} + +/** SIM900 ************************************/ + +ISR(USARTD0_RXC_vect) +{ + + static signed portBASE_TYPE xHigherPriorityTaskWoken; + signed portCHAR cChar; + + cChar = USARTD0.DATA; + //return; + //USARTC0.DATA = cChar+1; + + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(xSIM900Rec, &cChar, &xHigherPriorityTaskWoken); + if( xHigherPriorityTaskWoken ) + { + taskYIELD(); + } +} + +void uartSIM900SendByte(uint8_t data) +{ + xQueueSend(xSIM900Tx, &data, 10); + vInterruptSIM900On(); +} + +ISR(USARTD0_DRE_vect) +{ + static signed portBASE_TYPE xHigherPriorityTaskWoken; + static char data; + if(xQueueReceiveFromISR(xSIM900Tx, &data, &xHigherPriorityTaskWoken) == pdTRUE) + { + USARTD0.DATA = data; + } + else + { + xHigherPriorityTaskWoken = pdFALSE; + vInterruptSIM900Off(); + } + if( xHigherPriorityTaskWoken ) + { + taskYIELD(); + } +} diff --git a/Projects/AtXmegaRobo/Drobo/serial.h b/Projects/AtXmegaRobo/Drobo/serial.h new file mode 100644 index 0000000..4b7c9b0 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/serial.h @@ -0,0 +1,134 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#include "main.h" +#include "semphr.h" +#include "queue.h" +#include "task.h" +#include "hardware.h" + +/* Constants for writing to UCSRB. */ +#define serRX_INT_ENABLE ( ( unsigned portCHAR ) 0x80 ) +#define serTX_INT_ENABLE ( ( unsigned portCHAR ) 0x40 ) +#define serDATA_INT_ENABLE ( ( unsigned portCHAR ) 0x20 ) + + +#define serRX_ENABLE ( ( unsigned portCHAR ) 0x10 ) +#define serTX_ENABLE ( ( unsigned portCHAR ) 0x08 ) + +/* Constants for writing to UCSRC. */ +#define serUCSRC_SELECT ( ( unsigned portCHAR ) 0x80 ) +#define serEIGHT_DATA_BITS ( ( unsigned portCHAR ) 0x06 ) + + +// ******************************* Serial USB *********************** + +/* + * Włączenie przerwania pusty bufor nadawczy dla VTY + */ + +#define vIsInterruptVtyOn() (USARTC0.CTRLA & USART_DREINTLVL_LO_gc) + +/* + * Wyłączenie przerwania pusty bufor nadawczy dla VTY + */ + +#define vInterruptVtyOff() \ +{ \ + unsigned portCHAR ucInByte; \ + \ + ucInByte = USARTC0.CTRLA; \ + ucInByte &= ~USART_DREINTLVL_LO_gc; \ + USARTC0.CTRLA = ucInByte; \ +} + +#define vInterruptVtyOn() \ +{ \ + unsigned portCHAR ucByte; \ + \ + ucByte = USARTC0.CTRLA; \ + ucByte |= USART_DREINTLVL_LO_gc; \ + USARTC0.CTRLA = ucByte; \ +} + +// ******************************* Serial HC12 + +/* + * Włączenie przerwania pusty bufor nadawczy dla HC12 + */ + +#define vIsInterruptHC12On() (USARTC1.CTRLA & USART_DREINTLVL_LO_gc) + +/* + * Wyłączenie przerwania pusty bufor nadawczy dla HC12 + */ + +#define vInterruptHC12Off() \ +{ \ + unsigned portCHAR ucInByte; \ + \ + ucInByte = USARTC1.CTRLA; \ + ucInByte &= ~USART_DREINTLVL_LO_gc; \ + USARTC1.CTRLA = ucInByte; \ +} + +#define vInterruptHC12On() \ +{ \ + unsigned portCHAR ucByte; \ + \ + ucByte = USARTC1.CTRLA; \ + ucByte |= USART_DREINTLVL_LO_gc; \ + USARTC1.CTRLA = ucByte; \ +} + +#define vInterruptSIM900Off() \ +{ \ + unsigned portCHAR ucInByte; \ + \ + ucInByte = USARTD0.CTRLA; \ + ucInByte &= ~USART_DREINTLVL_LO_gc; \ + USARTD0.CTRLA = ucInByte; \ +} + +#define vInterruptSIM900On() \ +{ \ + unsigned portCHAR ucByte; \ + \ + ucByte = USARTD0.CTRLA; \ + ucByte |= USART_DREINTLVL_LO_gc; \ + USARTD0.CTRLA = ucByte; \ +} + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; +extern xQueueHandle xHC12Rec; +extern xQueueHandle xHC12Tx; +extern xQueueHandle xSIM900Rec; +extern xQueueHandle xSIM900Tx; + +// ******************************* RS485 ********************* + +/*********************************************/ + +void initQueueStreamUSB(FILE *stream); +void initQueueStreamHC12(FILE *stream); +void initQueueStreamHC12fake(FILE *stream); + +int VtyPutChar(char c, FILE *stream); +int VtyGetChar(FILE *stream); + +int HC12PutChar(char c, FILE *stream); +int HC12PutCharFake(char c, FILE *stream); +int HC12GetChar(FILE *stream); + +int SIM900PutChar(char c, FILE *stream); +int SIM900GetChar(FILE *stream); + +void uartVtySendByte(uint8_t data); +void uartHC12SendByte(uint8_t data); +void uartHC12SendByteFake(uint8_t data); +void uartSIM900SendByte(uint8_t data); + +void xSerialPortInitMinimal(void); + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/sim900.c b/Projects/AtXmegaRobo/Drobo/sim900.c new file mode 100644 index 0000000..812210d --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/sim900.c @@ -0,0 +1,63 @@ +#include "sim900.h" + +#include "FreeRTOS.h" +#include "task.h" + + +tcpConDesc_t definedTcpConnectrions[] __attribute__((section (".eeprom"))) = +{ + { "makgywer.vipserv.org", 2002}, + { "makgywer.vipserv.org", 2002}, + { "makgywer.vipserv.org", 2002}, + { "makgywer.vipserv.org", 2002} +}; + +void sim900pwrOn(void) +{ + PORTR.OUTSET = 0x00; + vTaskDelay(100); + PORTD.DIRSET = 0x10; + PORTD.OUTCLR = 0x10; + vTaskDelay(150); + PORTD.DIRCLR = 0x10; +} + +void sim900pwrOffHw(void) +{ + PORTD.DIRSET = 0x10; + PORTD.OUTCLR = 0x10; + vTaskDelay(150); + PORTD.DIRCLR = 0x10; +vTaskDelay(200); +} + + +void sim900pwrOffSoft(void) +{ + //fprintf_P(&sim900Str, PSRT("AT+CPOWD=1")); +} + +void sim900reset(void) +{ + PORTD.DIRSET = 0x02; + PORTD.OUTCLR = 0x10; + vTaskDelay(15); + PORTD.DIRCLR = 0x10; +} + +void openTcpCon(uint8_t bufNo, uint8_t defConNo) +{ +#warning "Implement it" + (void) bufNo; + (void) defConNo; + //uint16_t portNo = eeprom_read_word(&definedTcpConnectrions[defConNo].dstPortNo); + //uint8_t *eepromPtr = (uint8_t *) definedTcpConnectrions[defConNo].srcAddress; +// eeprom_read_block() +} + +void closeTcpCon(uint8_t conNo) +{ +#warning "Implement it" + (void) conNo; + +} diff --git a/Projects/AtXmegaRobo/Drobo/sim900.h b/Projects/AtXmegaRobo/Drobo/sim900.h new file mode 100644 index 0000000..11db7f1 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/sim900.h @@ -0,0 +1,49 @@ +#ifndef SIM900_H +#define SIM900_H + +#include +#include + +struct tcpConDesc +{ + char srcAddress[30]; + uint16_t dstPortNo; +}; + +typedef struct tcpConDesc tcpConDesc_t; + +/** + * Włączenie modułu sim900 + */ +void sim900pwrOn(void); + +/** + * Odłączenie zasilania od modułu sim900 + */ +void sim900pwrOffHw(void); + +/** + * Programowe wyłączenie modułu sim900 + */ +void sim900pwrOffSoft(void); + +/** + * Rsetart modułu + */ +void sim900reset(void); + + +/** + * Otwiera połączenie TCP + * @param bufNo - numer bufora (1-4) + * @param defConNo - numer połączenia, które zostało zdefiniowane wcześniej + */ +void openTcpCon(uint8_t bufNo, uint8_t defConNo); + +/** + * + */ +void closeTcpCon(uint8_t conNo); + + +#endif // SIM900_H diff --git a/Projects/AtXmegaRobo/Drobo/softwareConfig.h b/Projects/AtXmegaRobo/Drobo/softwareConfig.h new file mode 100644 index 0000000..0c4b1a3 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/softwareConfig.h @@ -0,0 +1,17 @@ +#ifndef SOFTWARE_CONFIG_H +#define SOFTWARE_CONFIG_H 1 + +#include + + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +/* CLI */ +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/tlv.c b/Projects/AtXmegaRobo/Drobo/tlv.c new file mode 100644 index 0000000..837fcad --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/tlv.c @@ -0,0 +1,63 @@ +#include "tlv.h" + +static void tlvForwardFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +static void tlvBackwordFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +static void tlvRotateLeftFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +static void tlvRotateRightFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +static void tlvStopFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); +static void tlvPingFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg); + +const tlvCommand_t tlvCmdList[] PROGMEM = +{ + {FORWARD, tlvForwardFunction}, + {BACKWORD, tlvBackwordFunction}, + {ROTATE_LEFT, tlvRotateLeftFunction}, + {ROTATE_RIGHT, tlvRotateRightFunction}, + {STOP, tlvStopFunction}, + {PING, tlvPingFunction}, + {0, NULL} +}; + +static void tlvForwardFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; + forwardB(msg->data.pwmLeft, msg->data.pwmRight); +} + +static void tlvBackwordFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; + backwordB(msg->data.pwmLeft, msg->data.pwmRight); +} + +static void tlvRotateLeftFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; + rotateLeftB(msg->data.pwmLeft, msg->data.pwmRight); +} + +static void tlvRotateRightFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; + rotateRightB(msg->data.pwmLeft, msg->data.pwmRight); +} + +static void tlvStopFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + (void) myTlvMsg; + //tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; + offHbridge(); +} + +static void tlvPingFunction(tlvInterpreter_t *tlvInt, tlvMsg_t *myTlvMsg) +{ + (void) tlvInt; + (void) myTlvMsg; + sendTlvMsgDta(myTlvMsg, myTlvMsg->data, tlvInt->errStr); + //tlvMsgMove_t *msg = (tlvMsgMove_t *) myTlvMsg; +} diff --git a/Projects/AtXmegaRobo/Drobo/tlv.h b/Projects/AtXmegaRobo/Drobo/tlv.h new file mode 100644 index 0000000..e61c11a --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/tlv.h @@ -0,0 +1,37 @@ +#ifndef TLV +#define TLV + + +#include "../../../Lib/include/tlvProt.h" +#include "hardware.h" + +typedef enum +{ + FORWARD = 1, + BACKWORD = 2, + ROTATE_LEFT = 3, + ROTATE_RIGHT = 4, + STOP = 6, + PING = 7, +} commandType_t; + + + +//MSG type = 1 + +typedef struct +{ + uint8_t duration; + uint8_t pwmLeft; + uint8_t pwmRight; +} tlvMsgMoveDta_t; + +typedef struct +{ + tlvMsg_t header; + tlvMsgMoveDta_t data; +} tlvMsgMove_t; + + + +#endif // TLV diff --git a/Projects/AtXmegaRobo/Drobo/tlv_task.c b/Projects/AtXmegaRobo/Drobo/tlv_task.c new file mode 100644 index 0000000..47ea74c --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/tlv_task.c @@ -0,0 +1,66 @@ +#include "tlv_task.h" + +static void sendHc12CmdVal(const char str[], uint16_t val, FILE *errStr) +{ + vTaskDelay(25); + fprintf_P(errStr, str, val); + fprintf_P(&hc12Stream, str, val); + while (xQueueReceive(xHC12Rec, &val, 10) == pdTRUE) + { + fputc(val, errStr); + } +} + + +void vTaskTLV(void *tlvIntPtr) +{ + tlvInterpreter_t *state = (tlvInterpreter_t *)(tlvIntPtr); + + + if (xSemaphoreTake(Hc12semaphore, 10) == pdTRUE) + { + vTaskDelay(2); + HC12setAtMode(); + + + sendHc12CmdVal(PSTR("AT+FU%d\r\n"), confHC12mode, state->errStr); + + if (confHC12channel < 10) + sendHc12CmdVal(PSTR("AT+C00%d\r\n"), confHC12channel, state->errStr); + else if (confHC12channel < 100) + sendHc12CmdVal(PSTR("AT+C0%d\r\n"), confHC12channel, state->errStr); + else + sendHc12CmdVal(PSTR("AT+C00%d\r\n"), confHC12channel, state->errStr); + + sendHc12CmdVal(PSTR("AT+B%d\r\n"), confHC12baud, state->errStr); + sendHc12CmdVal(PSTR("AT+P%d\r\n"), confHC12power, state->errStr); + + HC12setTransparentMode(); + xSemaphoreGive(Hc12semaphore ); + } + + uint8_t znak; + for( ;; ) + { + vTaskDelay(0); + if (xSemaphoreTake(Hc12semaphore, 5) == pdFALSE) + continue; + + if( xQueueReceive(xHC12Rec, &znak, 0) == pdFALSE) + { + xSemaphoreGive(Hc12semaphore); + continue; + } + + HC12setTransparentMode(); + do + { + fprintf_P(state->errStr, PSTR("0x%02x "), znak); + tlvProcessDta(state, znak); + } + while( xQueueReceive(xHC12Rec, &znak, 1) == pdTRUE); + + xSemaphoreGive(Hc12semaphore); + } +} + diff --git a/Projects/AtXmegaRobo/Drobo/tlv_task.h b/Projects/AtXmegaRobo/Drobo/tlv_task.h new file mode 100644 index 0000000..8f8040c --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/tlv_task.h @@ -0,0 +1,45 @@ +#ifndef TLV_TASK_H +#define TLV_TASK_H + +#include +#include + + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +#include "task.h" + +#include "../../Lib/include/tlvProt.h" +#include "main.h" + + + + +extern xSemaphoreHandle HC21semaphore; + +extern FILE hc12Stream; + +extern xQueueHandle xTlvRec; +extern xQueueHandle xTlvTx; + + +extern uint8_t confHC12mode; //1 - 3 +extern uint16_t confHC12baud; // +extern uint8_t confHC12channel; +extern uint8_t confHC12power; //1-8 + + +/** + * Proces odpowiedzialny za obsługę protokołu TLV + * Kod zoptymalizowany do szczególnego przypadku + * @param *TlvPtr wskaźnik do struktury przechowującej stan sesji protokołu TLV + */ +void vTaskTLV(void *tlvIntPtr); + + + + + +#endif /* TLV_TASK_H */ diff --git a/Projects/AtXmegaRobo/Drobo/vty.c b/Projects/AtXmegaRobo/Drobo/vty.c new file mode 100644 index 0000000..ce88253 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/vty.c @@ -0,0 +1,614 @@ +#include "main.h" +#include "vty.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "softwareConfig.h" +#include "hardware.h" +#include "sim900.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); +static cliExRes_t saveConfigFunction (cmdState_t *state); + +static cliExRes_t forwardFunction (cmdState_t *state); +static cliExRes_t backwordFunction (cmdState_t *state); +static cliExRes_t rotateLeftFunction (cmdState_t *state); +static cliExRes_t rotateRightFunction (cmdState_t *state); +static cliExRes_t stopFunction (cmdState_t *state); + +static cliExRes_t pwrFunction (cmdState_t *state); + +static cliExRes_t hc12modeFunction (cmdState_t *state); +static cliExRes_t hc12channelFunction (cmdState_t *state); +static cliExRes_t hc12baudrateFunction (cmdState_t *state); +static cliExRes_t hc12powerFunction (cmdState_t *state); +static cliExRes_t hc12statusFunction (cmdState_t *state); + +static cliExRes_t pwmSetFreq (cmdState_t *state); + +static cliExRes_t hc12sendForwardFunction (cmdState_t *state); +static cliExRes_t hc12sendBackwordFunction (cmdState_t *state); +static cliExRes_t hc12sendRotateLeftFunction (cmdState_t *state); +static cliExRes_t hc12sendRotateRightFunction(cmdState_t *state); +static cliExRes_t hc12sendStopFunction (cmdState_t *state); + +static cliExRes_t sim900OnFunction (cmdState_t *state); +static cliExRes_t sim900OffFunction (cmdState_t *state); +static cliExRes_t sim900atMode (cmdState_t *state); + +static cliExRes_t sendHC12(cmdState_t *state, uint8_t addr, uint8_t type, uint8_t len, const uint8_t const cmdDta[]); +static cliExRes_t sendHC12AtCmd(cmdState_t *state, const char cmd[]); + +static cliExRes_t sendHC12loopback(cmdState_t *state, uint8_t addr, uint8_t type, uint8_t len, const uint8_t const cmdDta[]); + + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; + +const const char* const errorStrings[] PROGMEM = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_forward, cmd_help_forward, forwardFunction}, + {cmd_backward, cmd_help_backward, backwordFunction}, + {cmd_rotateLeft, cmd_help_rotateLeft, rotateLeftFunction}, + {cmd_rotateRight, cmd_help_rotateRight, rotateRightFunction}, + {cmd_stop, cmd_help_stop, stopFunction}, + {cmd_hc12forward, cmd_help_hc12forward, hc12sendForwardFunction}, + {cmd_hc12backward, cmd_help_hc12backward, hc12sendBackwordFunction}, + {cmd_hc12rotateLeft, cmd_help_hc12rotateLeft, hc12sendRotateLeftFunction}, + {cmd_hc12rotateRight, cmd_help_hc12rotateRight, hc12sendRotateRightFunction}, + {cmd_hc12stop, cmd_help_hc12stop, hc12sendStopFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {cmd_forward, cmd_help_forward, forwardFunction}, + {cmd_backward, cmd_help_backward, backwordFunction}, + {cmd_rotateLeft, cmd_help_rotateLeft, rotateLeftFunction}, + {cmd_rotateRight, cmd_help_rotateRight, rotateRightFunction}, + {cmd_stop, cmd_help_stop, stopFunction}, + + {cmd_pwr, cmd_help_pwr, pwrFunction}, + + {cmd_HC12status, cmd_help_HC12status, hc12statusFunction}, + + {cmd_hc12forward, cmd_help_hc12forward, hc12sendForwardFunction}, + {cmd_hc12backward, cmd_help_hc12backward, hc12sendBackwordFunction}, + {cmd_hc12rotateLeft, cmd_help_hc12rotateLeft, hc12sendRotateLeftFunction}, + {cmd_hc12rotateRight, cmd_help_hc12rotateRight, hc12sendRotateRightFunction}, + {cmd_hc12stop, cmd_help_hc12stop, hc12sendStopFunction}, + + {cmd_sim900on, cmd_help_sim900on, sim900OnFunction}, + {cmd_sim900off, cmd_help_sim900off, sim900OffFunction}, + {cmd_sim900at, cmd_help_sim900at, sim900atMode}, + + {NULL, NULL, NULL} +}; + + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_HC12mode, cmd_help_HC12mode, hc12modeFunction}, + {cmd_HC12channel, cmd_help_HC12channel, hc12channelFunction}, + {cmd_HC12baudrate, cmd_help_HC12baudrate, hc12baudrateFunction}, + {cmd_HC12power, cmd_help_HC12power, hc12powerFunction}, + {cmd_HC12status, cmd_help_HC12status, hc12statusFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_pwm_freq, cmd_help_pwm_freq, pwmSetFreq}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, (char *)(xmalloc(CLI_BUF_TOT_LEN)), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + fprintf_P(stream, PSTR("PWR status: 4v3 %s, RPI 3v3 %s, RPI 4v3 %s\r\n"), isPwr4v3() ? "On": "Off", isPwr3v3rpi() ? "On": "Off", isPwr4v3rpi() ? "On": "Off"); + + fprintf_P(stream, PSTR("Hc12 config:\r\n")); + fprintf_P(stream, PSTR("\tmode %d\r\n"), confHC12mode); + fprintf_P(stream, PSTR("\tbaud %d\r\n"), confHC12baud); + fprintf_P(stream, PSTR("\tchannel %d\r\n"), confHC12channel); + fprintf_P(stream, PSTR("\tpower %d\r\n"), confHC12power); + + +// uint16_t res = ADCA.CH0RES; + ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; //Pojedyncze wejście + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN8_gc; //PB0 + + ADCA.CH1.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; //Pojedyncze wejście + ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN9_gc; //PB0 + + + ADCA.CTRLA = ADC_ENABLE_bm | ADC_CH0START_bm | ADC_CH1START_bm; //Włączenie przetwornika AC oraz uruchomienie pomiaru na kanale 0 + + while (ADCA.CH0.INTFLAGS==0); + uint16_t res = ADCA.CH0RES; + ADCA.CH0.INTFLAGS=1; + + while (ADCA.CH1.INTFLAGS==0); + uint16_t res2 = ADCA.CH1RES; + ADCA.CH1.INTFLAGS=1; + + + ADCA.CTRLA = ADC_ENABLE_bm; + + fprintf_P(stream, PSTR("Pwr: %d + %d/128 V\r\n"), res>>7, res&0x7F); + fprintf_P(stream, PSTR(" %d + %d/32 A\r\n"), res2>>5, res2&0x1F); + + //Print system state +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + printStatus(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} + +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + + +static cliExRes_t forwardFunction (cmdState_t *state) +{/* + uint8_t left = 50; + uint8_t right = 50; + + if (state->argc == 1) + left = right = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + left = cmdlineGetArgInt(1, state); + right = cmdlineGetArgInt(2, state); + } + + forwardB(left, right); +*/ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12loopback(state, 0, FORWARD, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} + +static cliExRes_t backwordFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12loopback(state, 0, BACKWORD, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} +static cliExRes_t rotateLeftFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12loopback(state, 0, ROTATE_LEFT, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} + +static cliExRes_t rotateRightFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12loopback(state, 0, ROTATE_RIGHT, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} + +static cliExRes_t stopFunction (cmdState_t *state) +{/* + (void) state; + offHbridge(); +*/ + uint8_t dta[1]; + dta[0] = 0; + sendHC12loopback(state, 0, STOP, 1, dta); + + return OK_SILENT; +} + + +static cliExRes_t pwrFunction (cmdState_t *state) +{ + if (state->argc <2) + return ERROR_INFORM; + + uint8_t devNo = cmdlineGetArgInt(1, state); + uint8_t devState = cmdlineGetArgInt(2, state); + + if (devState == 0) + { + switch (devNo) + { + case 1: pwrOff4v3(); break; + case 2: pwrOff3v3rpi(); break; + case 3: pwrOff4v3rpi(); break; + default: break; + } + } + else + { + switch (devNo) + { + case 1: pwrOn4v3(); break; + case 2: pwrOn3v3rpi(); break; + case 3: pwrOn4v3rpi(); break; + default: break; + } + } + return OK_SILENT; +} + +static cliExRes_t hc12sendForwardFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12(state, 0, FORWARD, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + return OK_SILENT; +} + +static cliExRes_t hc12sendBackwordFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12(state, 0, BACKWORD, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + return OK_SILENT; +} + + +static cliExRes_t hc12sendRotateLeftFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12(state, 0, ROTATE_LEFT, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} + +static cliExRes_t hc12sendRotateRightFunction (cmdState_t *state) +{ + tlvMsgMoveDta_t dta; + dta.duration = 0; + dta.pwmLeft = 50; + dta.pwmRight = 50; + + if (state->argc == 1) + dta.pwmLeft = dta.pwmRight = cmdlineGetArgInt(1, state); + if (state->argc >=2) + { + dta.pwmLeft = cmdlineGetArgInt(1, state); + dta.pwmRight = cmdlineGetArgInt(2, state); + } + sendHC12(state, 0, ROTATE_RIGHT, sizeof(tlvMsgMoveDta_t), (uint8_t *) &dta); + + return OK_SILENT; +} + +static cliExRes_t hc12sendStopFunction (cmdState_t *state) +{ + sendHC12(state, 0, STOP, 0, NULL); + return OK_SILENT; +} + +static cliExRes_t sendHC12AtCmd(cmdState_t *state, const char cmd[]) +{ + if (xSemaphoreTake(Hc12semaphore, 10) == pdTRUE) + { + vTaskDelay(2); + HC12setAtMode(); + vTaskDelay(25); + fprintf_P(state->myStdInOut, cmd, cmdlineGetArgStr(1, state)); + fprintf_P(&hc12Stream, cmd, cmdlineGetArgStr(1, state)); + + uint8_t val; + while (xQueueReceive(xHC12Rec, &val, 100) == pdTRUE) + { + fputc(val, state->myStdInOut); + } + + HC12setTransparentMode(); + xSemaphoreGive(Hc12semaphore ); + return OK_SILENT; + } + else + { + return ERROR_INFORM; + } +} + +static cliExRes_t sendHC12(cmdState_t *state, uint8_t addr, uint8_t type, uint8_t len, const uint8_t const cmdDta[]) +{ + (void) state; + tlvMsg_t msg; + msg.sync = TLV_SYNC; + msg.address = addr; + msg.type = type; + msg.dtaLen = len; + + tlvCalculateCrcSepDta(&msg, cmdDta); + + sendTlvMsgDta(&msg, cmdDta, &hc12Stream); + + return OK_INFORM; +} + +static cliExRes_t sendHC12loopback(cmdState_t *state, uint8_t addr, uint8_t type, uint8_t len, const uint8_t const cmdDta[]) +{ + (void) state; + tlvMsg_t msg; + msg.sync = TLV_SYNC; + msg.address = addr; + msg.type = type; + msg.dtaLen = len; + + tlvCalculateCrcSepDta(&msg, cmdDta); + + sendTlvMsgDta(&msg, cmdDta, &hc12FakeStream); + + return OK_INFORM; +} + +static cliExRes_t pwmSetFreq (cmdState_t *state) +{ + uint8_t preskaler = cmdlineGetArgInt(1, state); + if (preskaler > 7 || preskaler < 4) + return ERROR_INFORM; + + TCC0.CTRLA &= 0xF0; + TCC0.CTRLA |= preskaler; + + return OK_INFORM; +} + +static cliExRes_t hc12modeFunction (cmdState_t *state) +{ + confHC12mode = cmdlineGetArgInt(1, state); + return sendHC12AtCmd(state, PSTR("AT+FU%s\r\n")); +} + +static cliExRes_t hc12channelFunction (cmdState_t *state) +{ + confHC12channel = cmdlineGetArgInt(1, state); + return sendHC12AtCmd(state, PSTR("AT+C%s\r\n")); +} + +static cliExRes_t hc12baudrateFunction (cmdState_t *state) +{ + confHC12baud = cmdlineGetArgInt(1, state); + return sendHC12AtCmd(state, PSTR("AT+B%s\r\n")); +} + +static cliExRes_t hc12powerFunction (cmdState_t *state) +{ + confHC12power = cmdlineGetArgInt(1, state); + return sendHC12AtCmd(state, PSTR("AT+P%s\r\n")); +} + +static cliExRes_t hc12statusFunction (cmdState_t *state) +{ + return sendHC12AtCmd(state, PSTR("AT+RX\r\n")); +} + +static cliExRes_t sim900OnFunction (cmdState_t *state) +{ + (void) state; + sim900pwrOn(); + return OK_INFORM; +} + +static cliExRes_t sim900OffFunction (cmdState_t *state) +{ + (void) state; + sim900pwrOffHw(); + return OK_INFORM; +} + +static cliExRes_t sim900atMode (cmdState_t *state) +{ + uint8_t znak; + fprintf_P(state->myStdInOut, PSTR("Press ^z to exit at mode\r\n")); + for ( ; ;) + { + if (xQueueReceive(xVtyRec, &znak, 0) == pdTRUE) + { + if (znak == 0x1A) + break; + xQueueSend(xSIM900Tx, &znak, 0); + } + if (xQueueReceive(xSIM900Rec, &znak, 0) == pdTRUE) + fputc(znak, state->myStdInOut); + } + return OK_INFORM; +} + +/* +static void printTable(FILE *stream) +{ + fprintf_P(stream, PSTR("\r\nAddress Table:\r\n\r\n")); //Print system state + + uint16_t i; + for(i=0; i<256; i++) + { + fprintf_P(stream, PSTR("%3d -> %3d\t"), i, translateTable[i]); + i++ ; + fprintf_P(stream, PSTR("%3d -> %3d\t"), i, translateTable[i]); + i++ ; + fprintf_P(stream, PSTR("%3d -> %3d\t"), i, translateTable[i]); + i++ ; + fprintf_P(stream, PSTR("%3d -> %3d\r\n"), i, translateTable[i]); + } + fprintf_P(stream, PSTR("\r\n")); +} +*/ diff --git a/Projects/AtXmegaRobo/Drobo/vty.h b/Projects/AtXmegaRobo/Drobo/vty.h new file mode 100644 index 0000000..9d7f4dc --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/vty.h @@ -0,0 +1,54 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include +#include + +#include "memory_x.h" +#include "configuration.h" +#include "cmdline.h" +#include "FreeRTOS.h" +#include "hc12.h" + +#include "../../../FreeRtosCore/Source/include/FreeRTOS.h" +#include "../../../FreeRtosCore/Source/include/croutine.h" +#include "../../../FreeRtosCore/Source/include/queue.h" +#include "../../../FreeRtosCore/Source/include/task.h" + + +extern xSemaphoreHandle Hc12semaphore; + +void VtyInit(cmdState_t *state, FILE *stream); +void printErrorInfo(cmdState_t *state); +void printStatus(FILE *stream); + +extern FILE hc12Stream; +extern FILE hc12FakeStream; + + +extern uint8_t confHC12mode; //1 - 3 +extern uint16_t confHC12baud; // +extern uint8_t confHC12channel; +extern uint8_t confHC12power; //1-8 + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/vty_en.h b/Projects/AtXmegaRobo/Drobo/vty_en.h new file mode 100644 index 0000000..5da8ca9 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/vty_en.h @@ -0,0 +1,72 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include + +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; +const char errorNoFile[] PROGMEM = "No File\r\n"; +const char errorxModemFrameStartTimeout[] PROGMEM = "\r\n"; +const char errorxModemByteSendTimeout[] PROGMEM = "\r\n"; +const char errorxModemWrongFrameNo[] PROGMEM = "\r\n"; +const char errorxModemFrameFrameNoCorrectionNotMatch[] PROGMEM = "\r\n"; +const char errorxModemFrameCrc[] PROGMEM = "xModem CRC error\r\n"; +const char errorxModemRemoteSideCan[] PROGMEM = "Remote side cancelled at frame no %d\r\n"; +const char errorxModemUnknownResponse[] PROGMEM = "xModem unknown response 0x%x\r\n"; +const char errorNoRemoteDevice[] PROGMEM = "Device %d is not responding (%d)\r\n"; +const char errorBootloaderNotResponding[] PROGMEM = "Bootloader is not responding\r\n"; +const char errorOpenFile[] PROGMEM = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char statusRamDiskStateStr[] PROGMEM = " Ram disc space : %d free of %d clusters\r\n"; +const char statusTemperatureStr[] PROGMEM = " Temperature : %d C\r\n"; +const char statusVoltageStr[] PROGMEM = " Voltage : %d V\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; + + + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; + +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Admin mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "Normal mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configuration mode"; + +const char cmd_HC12mode[] PROGMEM = "hc12mode"; const char cmd_help_HC12mode[] PROGMEM = "[1-3] Set HC12 operation mode"; +const char cmd_HC12channel[] PROGMEM = "hc12chan"; const char cmd_help_HC12channel[] PROGMEM = "[1-100] Set transmission channel for HC12"; +const char cmd_HC12baudrate[] PROGMEM = "hc12baud"; const char cmd_help_HC12baudrate[] PROGMEM = "[] Set HC12 bandwidth"; +const char cmd_HC12power[] PROGMEM = "hc12pwr"; const char cmd_help_HC12power[] PROGMEM = "[1-8] Set HC12 power"; +const char cmd_HC12status[] PROGMEM = "hc12stat"; const char cmd_help_HC12status[] PROGMEM = "Get HC-12 status"; + +const char cmd_pwm_freq[] PROGMEM = "pwm"; const char cmd_help_pwm_freq[] PROGMEM = "[4-7] Set PWM prescaler 4: 40 kHz, 7: 320 Hz"; + +const char cmd_forward[] PROGMEM = "fw"; const char cmd_help_forward[] PROGMEM = "{left PW} {right PW} move forward"; +const char cmd_backward[] PROGMEM = "bw"; const char cmd_help_backward[] PROGMEM = "{left PW} {right PW} move backward"; +const char cmd_rotateLeft[] PROGMEM = "rl"; const char cmd_help_rotateLeft[] PROGMEM = "{left PW} {right PW} rotate left"; +const char cmd_rotateRight[] PROGMEM = "rr"; const char cmd_help_rotateRight[] PROGMEM = "{left PW} {right PW} rotate right"; +const char cmd_stop[] PROGMEM = "stop"; const char cmd_help_stop[] PROGMEM = "Disable H-bridges"; + +const char cmd_pwr[] PROGMEM = "pwr"; const char cmd_help_pwr[] PROGMEM = "Power [src no] [0, 1]"; + + +const char cmd_hc12forward[] PROGMEM = "hfw"; const char cmd_help_hc12forward[] PROGMEM = "{left PW} {right PW} move forward"; +const char cmd_hc12backward[] PROGMEM = "hbw"; const char cmd_help_hc12backward[] PROGMEM = "{left PW} {right PW} move backward"; +const char cmd_hc12rotateLeft[] PROGMEM = "hrl"; const char cmd_help_hc12rotateLeft[] PROGMEM = "{left PW} {right PW} rotate left"; +const char cmd_hc12rotateRight[] PROGMEM = "hrr"; const char cmd_help_hc12rotateRight[] PROGMEM = "{left PW} {right PW} rotate right"; +const char cmd_hc12stop[] PROGMEM = "hstop"; const char cmd_help_hc12stop[] PROGMEM = "Disable H-bridges"; + +const char cmd_sim900on[] PROGMEM = "son"; const char cmd_help_sim900on[] PROGMEM = "Sim 900 power on"; +const char cmd_sim900off[] PROGMEM = "soff"; const char cmd_help_sim900off[] PROGMEM = "Sim 900 power off"; +const char cmd_sim900at[] PROGMEM = "sat"; const char cmd_help_sim900at[] PROGMEM = "Foreword Sim 900 port"; + +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; + +#endif diff --git a/Projects/AtXmegaRobo/Drobo/vty_pl.h b/Projects/AtXmegaRobo/Drobo/vty_pl.h new file mode 100644 index 0000000..12e9651 --- /dev/null +++ b/Projects/AtXmegaRobo/Drobo/vty_pl.h @@ -0,0 +1,99 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char statusRamDiskStateStr[] = " Ram dysk : %d wolnych z %d klastrow\r\n"; +prog_char statusTemperatureStr[] = " Temperatura : %d C\r\n"; +prog_char statusVoltageStr[] = " Napiecie : %d V\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; +prog_char statusMacStr[] = " Adres MAC : "; +prog_char statusIpStr[] = " IP adres : "; +prog_char statusIpMaskStr[] = " maska : "; +prog_char statusIpGwStr[] = " brama : "; + +prog_char statusRs485listStr[] = "Wykryte urzadzenia na magistrali RS 485:\r\n"; +prog_char statusNoRs485Dev[] = " Nie moge znale ani jednego urzadzenia\r\n"; + +prog_char statusLockerSensorsStr[] = "Stan czujników rygli:\r\n"; +prog_char statusLockerSensorsDisStr[] = " Czujniki rygli wyłączone\r\n"; + +prog_char editRamFileIntroStr[] = "Zapis do pliku. CTRL+C koniec\r\n"; +prog_char readRamFIleLenStr[] = "Dlugosc pliku: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: rozpoczynanie wysylania\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Wlaczono debugowanie %s\r\n"; +prog_char debugDisabledInfoStr[] = "Wylaczono debugowanie %s\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Wypisz rejestry Enc 28j60"; +prog_char cmd_time[] = "czas"; prog_char cmd_help_time[] = "Wypisuje czas"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[arp|icmp|ip|tcp|udp] [poziom] wypisywanie komunikatow. Poziom 0 wylacza komunikaty"; + +prog_char cmd_HC12mode[] = "hc12mode"; prog_char cmd_help_HC12mode[] = "[1-3] Ustawianie trybu pracy HC12"; +prog_char cmd_HC12channel[] = "hc12chan"; prog_char cmd_help_HC12channel[] = "[1-100] Ustawianie kanału dla HC12"; +prog_char cmd_HC12baudrate[]= "hc12baud"; prog_char cmd_help_HC12baudrate[]= "[] Ustawienie szybkości transmisji HC12"; +prog_char cmd_HC12power[] = "hc12pwr"; prog_char cmd_help_HC12power[] = "[] Ustawienie mocy nadajnika HC12"; + +prog_char cmd_pwm_freq[] = "pwm"; prog_char cmd_help_pwm_freq[] = "[4-7] Ustawienie preskalera pwm 4: 40 kHz, 7: 320 Hz"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[numer sterownika] Wysyla ping do sterownika podpietego do magistrali Rs485"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Wysyla ping przez ethernet"; +prog_char cmd_xRec[] = "xodb"; prog_char cmd_help_xRec[] = "[nazwa pliku] odbiera plik za pomoca protokolu xModem"; +prog_char cmd_xSend[] = "xwyslij"; prog_char cmd_help_xSend[] = "[nazwa pliku] wysyla plik za pomoca protokolu xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[numer urzadzenia] [nazwa pliku] wgrywa firmware do urzadzenia podpietego do Rs485"; +#ifdef testZewPamiec +prog_char cmd_rtest[] = "rtest"; prog_char cmd_help_rtest[] = "Test pamieci zewnetrznej"; +#endif +prog_char cmd_dir_rf[] = "dirrp" ; prog_char cmd_help_dir_rf[] = "Wypisuje nazwy plikow zapisanych w pamieci RAM"; +prog_char cmd_create_rf[] = "utwrp"; prog_char cmd_help_create_rf[] = "[nazwa pliku] Tworzy plik w pamieci RAM"; +prog_char cmd_erase_rf[] = "kasrp"; prog_char cmd_help_erase_rf[] = "[nazwa pliku] Usuwa plik z pamieci RAM"; +prog_char cmd_edit_rf[] = "dopiszrp"; prog_char cmd_help_edit_rf[] = "[nazwa pliku] Dopisuje do pliku zapisanego w pamieci ram"; +prog_char cmd_read_rf[] = "czytrp"; prog_char cmd_help_read_rf[] = "[nazwa pliku] Wypisuje zawartosc pliku"; + +prog_char cmd_up[] = "podnies"; prog_char cmd_help_up[] = "[numer sterownika] [nr rolety] {wartosc} podnoszenie rolety"; +prog_char cmd_down[] = "opusc"; prog_char cmd_help_down[] = "[numer sterownika] [nr rolety] {wartosc} opuszczanie rolety"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[wartosc] ustaw zewnetrzny port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[wartosc] ustaw zewnetrzny port B"; + +prog_char cmd_settime[] = "ustawcz"; prog_char cmd_help_settime[] = "[h] [m] [s] ustawia czas w formacie 24h format"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[wejscie 0-7] czyta analogowa wartosc na wejsciu przetwornika"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A2] [A3] ustaw adres IP"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} ustaw adres klienta udp oraz porty"; +prog_char cmd_conf_ip_mask[]= "maska"; prog_char cmd_conf_ip_mask_help[]= "[maska] ustaw maske adresu IP"; +prog_char cmd_conf_ip_gw[] = "brama"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] ustaw domyslna brame"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] set MAC address"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] ustaw adres MAC"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/.kdev4/SterownikGlowny.kdev4 b/Projects/DidacticSystem/Adam/MainController/.kdev4/SterownikGlowny.kdev4 new file mode 100644 index 0000000..000f9a3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/.kdev4/SterownikGlowny.kdev4 @@ -0,0 +1,22 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x1e\x00S\x00t\x00e\x00r\x00o\x00w\x00n\x00i\x00k\x00G\x00l\x00o\x00w\x00n\x00y) + +[CMake] +Build Directory Count=1 +CMakeDir=/usr/share/cmake-2.8/Modules +Current Build Directory Index=0 +ProjectRootRelative=./ + +[CMake][CMake Build Directory 0] +Build Directory Path=file:///home/adam/Dokumenty/akme/FreeRtos/projektyAdam/SterownikGlowny/build +Build Type=Debug +CMake Binary=file:///usr/bin/cmake +Environment Profile= +Extra Arguments= +Install Directory=file:///usr/local + +[MakeBuilder] +Number Of Jobs=1 + +[Project] +VersionControlSupport=kdevsubversion diff --git a/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths b/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths new file mode 100644 index 0000000..cef4f56 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths @@ -0,0 +1,6 @@ +RESOLVE: SOURCE=/usr/lib/avr/lib BUILD= +/usr/lib/avr/include +/usr/lib/avr/include/avr +/home/adam/akme/FreeRtos/freeRtos/Lib/include +/home/adam/akme/FreeRtos/freeRtos/Lib/net/include +/home/adam/akme/FreeRtos/freeRtos/Source/include diff --git a/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths_student b/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths_student new file mode 100644 index 0000000..9c6f948 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/.kdev_include_paths_student @@ -0,0 +1,5 @@ +/usr/lib/avr/include +/usr/lib/avr/include/avr +/student/adam/akme/FreeRtos/freeRtos/Lib/include +/student/adam/akme/FreeRtos/freeRtos/Lib/net/include +/student/adam/akme/FreeRtos/freeRtos/Source/include diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader/Bootldr.aps b/Projects/DidacticSystem/Adam/MainController/Bootloader/Bootldr.aps new file mode 100644 index 0000000..a2aff75 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader/Bootldr.aps @@ -0,0 +1 @@ +bootloader01-May-2010 21:38:1601-May-2010 21:42:47241001-May-2010 21:38:1644, 18, 0, 670AVR GCCD:\Dokumenty\Adam\FreeRtos\projekty\SterownikGlowny\Bootloader\JTAG ICEATmega64.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000bootldr.cbootldr.hdefaultNOatmega64111bootloader.elfdefault\1-Wall -gdwarf-2 -std=gnu99 -DF_CPU=14576200UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums.textFLASH
0x7e00
default1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exe
D:\Dokumenty\Adam\FreeRtos\projekty\SterownikGlowny\Bootloader\bootldr.hD:\Dokumenty\Adam\FreeRtos\projekty\SterownikGlowny\Bootloader\bootldr.c
diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader/Makefile b/Projects/DidacticSystem/Adam/MainController/Bootloader/Makefile new file mode 100644 index 0000000..a64be7d --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader/Makefile @@ -0,0 +1,86 @@ +############################################################################### +# Makefile for the project Bootldr +############################################################################### + +## General Flags +PROJECT = Bootloader +MCU = atmega128 +TARGET = bootloader +CC = avr-gcc +CPP = avr-g++ + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -DF_CPU=14745600UL -Os -fsigned-char +#CFLAGS += -gdwarf-2 +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-section-start=.text=0xFE00 + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + +## Objects that must be built in order to link +OBJECTS = bootldr.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET).elf Bootldr.hex Bootldr.eep size + +## Compile +bootldr.o: bootldr.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET).elf: $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf + +%.hex: $(TARGET).elf + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET).elf + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET).elf + avr-objdump -h -S $< > $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +AVRDUDE_PORT = /dev/jtag +#AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) Bootldr.elf dep/* Bootldr.hex Bootldr.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.aws b/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.aws new file mode 100644 index 0000000..ab7171e --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.aws @@ -0,0 +1 @@ + diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.c b/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.c new file mode 100644 index 0000000..1f3cb52 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader/bootldr.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include + +#include "bootldr.h" + +uint8_t KEY[] = {'f', 'l', 'a', 's', 'h'}; +uint8_t buf[BUFFERSIZE]; // xModem receive buffer + +void main(void) +{ + uint8_t ch; + uint8_t cl; + uint8_t crch; + uint8_t crcl; + uint8_t packNO; + uint8_t li; + uint8_t tmp; + uint16_t crc; + uint32_t FlashAddr; + uint8_t pagptr; + uint8_t cnt; + + cli(); // disable interrupt + + //Configure timer T1 + OCR1A = (uint16_t)(timeclk * (F_CPU / (1024 * 1000.0f))); + TCCR1A = 0; + TCCR1B = (1 << WGM12)|(1 << CS12)|(1 << CS10); + + //Configure ports + + //initialize serial port UART1 + UCSR1A = 0; + UCSR1B = (1 << RXEN1)|(1 << TXEN1); + UCSR1C = (1 << UCSZ11)|(1 << UCSZ10); + UBRR1H = 0; + UBRR1L = 7; + + cnt = TimeOutCnt; // Timeout 1 = 1s + cl = 0; // Number of matching password's letters + + WriteCom('B'); + //Waiting for sequence "flash" to start flashing + while(1) + { + if(TIFRREG & (1< + break; + } + + //begin xModem transmission - receive data + packNO = 1; + cnt = 0; + FlashAddr = 0; + pagptr = 0; + + while(1) + { + ch = ReadCom_withWaiting(); // get package number + cl = ~ReadCom_withWaiting(); + if ((packNO == ch) && (packNO == cl)) + { + uint16_t crc = 0; // start calculate CRC + for(li = 0; li < BUFFERSIZE; li++) // receive a full data frame + { + tmp = ReadCom_withWaiting(); // read from uart + buf[li] = tmp; // write to temporary buffer + crc = _crc_xmodem_update(crc, tmp); // calculate CRC + } + + crch = ReadCom_withWaiting(); // get checksum Hi + crcl = ReadCom_withWaiting(); // get checksum Lo + ch = crc / 256; + cl = crc % 256; + if ((crch == ch) && (crcl == cl)) + { + packNO++; + cnt = 0; + uint16_t *tmpPtr = (uint16_t *)(buf); // Compiller have to be little bit endian + for (tmp=0; tmp < BUFFERSIZE/2; tmp++) + { +//#define TEST 1 +#ifndef TEST + if (pagptr == 0) + { + eeprom_busy_wait(); + boot_page_erase(FlashAddr); // Kasowanie strony + boot_spm_busy_wait(); // Czekanie na wykonanie operacji + } + boot_page_fill(FlashAddr+pagptr, *tmpPtr); //brzydkie rzutowanie 2X uint8_t na uint16_t +#endif + tmpPtr++; //wskaźnik zwiększa się o 2 + pagptr+=2; + +#if SPM_PAGESIZE != 256 + if (pagptr == SPM_PAGESIZE) +#else + if (pagptr == 0) +#endif + { +#ifndef TEST + boot_page_write(FlashAddr); //Zapis strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji +#endif + FlashAddr += SPM_PAGESIZE; // modify Flash page address +#if SPM_PAGESIZE != 256 + pagptr = 0; +#endif + } + + if (FlashAddr > 2*BootStart) // BootStart is word number (not byte number) + { + WriteCom(XMODEM_CAN); // Stop transmission + quit(); + } + } + WriteCom(XMODEM_ACK); // All OK send ACK + } + else // CRC error + { + WriteCom(XMODEM_NAK); // Ask resend + cnt++; + } + } + else // Wrong PackNo + { + WriteCom(XMODEM_NAK); // Ask resend + cnt++; + } + if(cnt > 3) // Too much error, update abort + { + WriteCom(XMODEM_CAN); // Cancel + quit(); + } + + tmp = ReadCom_withWaiting(); + + if (tmp == XMODEM_EOT) + { +#ifndef TEST + if (pagptr != 0) + { + boot_page_write(FlashAddr); //Zapis ostatniej strony. Nie jest ona w całości zapełniona + boot_spm_busy_wait(); //Czekanie na wykonanie operacji + } +#endif + WriteCom(XMODEM_ACK); // Firmware downloaded. Send NAK to stop transmission + break; + } + if (tmp == XMODEM_CAN) + break; + } + //while(1); + quit(); +} + +//! quit boot mode and jump to user's application +void quit(void) +{ + boot_rww_enable(); // Enable application section + (*((void(*)(void))PROG_START))(); // Jump to aplication code +} + +//! wait for uart data and read it next +uint8_t ReadCom_withWaiting(void) +{ +// uint8_t tmp=3; + while (1) + { + if (UCSR1A & (1 << RXC1)) + { + return UDR1; + } +// if(TIFRREG & (1< Rs232 baudrate + +#define timeclk 500 /// basic timer interval(ms) +#define TimeOutCnt 10 /// max wait for password time = TimeOutCnt * timeclk +#define TimeOutCntC 40 /// numbers of sending C char for start xModem + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE + #if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE + #error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" + #error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" + #endif +#else + #if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE + #error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" + #error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" + #endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#define DataInCom() (UCSR1A & (1 << RXC1)) +#define ReadCom() UDR1 + +void quit (void) __attribute__((noreturn)); +uint8_t ReadCom_withWaiting(void); +void WriteCom (uint8_t dat); + +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/Bootldr.aps b/Projects/DidacticSystem/Adam/MainController/Bootloader2/Bootldr.aps new file mode 100755 index 0000000..8ba7f37 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/Bootldr.aps @@ -0,0 +1 @@ +Bootldr15-Mar-2007 10:14:1213-Sep-2007 22:00:10241015-Mar-2007 10:14:1244, 13, 0, 528AVR GCCdefault\Bootldr.elfG:\szy\AVR Common BootLoader\3.0\avrub\en\Butterfly\AVR SimulatorATmega169falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000bootldr.creadme.txtdefaultNOatmega169100Bootldr.elfdefault\1-Wall -gdwarf-2 -Os -fsigned-char.textFLASH
0x1c00
default1D:\WinAVR\bin\avr-gcc.exeD:\WinAVR\utils\bin\make.exe
0216232123800000001100000bootldr.c25900001readme.txt100002bootldr.h1266 127 1048 47191 23262 97 1166 62470 28Maximized332 214 1118 562138 15
diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/Makefile b/Projects/DidacticSystem/Adam/MainController/Bootloader2/Makefile new file mode 100644 index 0000000..46998b5 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/Makefile @@ -0,0 +1,86 @@ +############################################################################### +# Makefile for the project Bootldr +############################################################################### + +## General Flags +PROJECT = Bootloader +MCU = atmega128 +TARGET = bootloader +CC = avr-gcc +CPP = avr-g++ + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -DF_CPU=14745600UL -Os -fsigned-char +#CFLAGS += -gdwarf-2 +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-section-start=.text=0xFC00 + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + +## Objects that must be built in order to link +OBJECTS = bootldr.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET).elf Bootldr.hex Bootldr.eep size + +## Compile +bootldr.o: bootldr.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET).elf: $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf + +%.hex: $(TARGET).elf + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET).elf + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET).elf + avr-objdump -h -S $< > $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +AVRDUDE_PORT = /dev/jtag +#AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) Bootldr.elf dep/* Bootldr.hex Bootldr.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootcfg.h b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootcfg.h new file mode 100755 index 0000000..1e42892 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootcfg.h @@ -0,0 +1,117 @@ +/* + + e Y8b Y8b YV3.18P888 88e + d8b Y8b Y8b Y888P 888 888D + d888b Y8b Y8b Y8P 888 88" + d888WuHan8b Y8b Y 888 b, + d8888888b Y8b Y8P 888 88b, + 8888 8888 ,e, 888 + 8888 888820078e " Y8b Y888P ,e e, 888,8, dP"Y ,"Y88b888 + 8888 8888888 88b888 Y8b Y8P d88 88b888 " C88b "8" 888888 + 8888 8888888 888888 Y8b " 888 ,888 Y88D,ee 888888 + 'Y88 88P'888 888888 Y8P "YeeP"888 d,dP "88 888888 + 888 88b, d8 888 888 + 888 88P' e88 88e e88 88e d88 888 e88 88e ,"Y88b e88 888 ,e e, 888,8, + 888 8K d888 888bd888 8Shaoziyang88d888 888b"8" 888d888 888d88 88b888 " + 888 88b,Y888 888PY888 888P 888 888Y888 888P,ee 888Y888 888888 ,888 + 888 88P' "88 88" "88 88" 888 888 "88 88" "88 888 "88 888 "YeeP"888 + + + Project: AVR Universal BootLoader + File: bootcfg.h + user's configuration. + Version: 3.1 + + Compiler: GCC 4.1.2 + AVR Studio 4.13.528 + + Author: Shaoziyang + Shaoziyang@gmail.com + http://shaoziyang.googlepages.com or + http://shaoziyang.bloger.com.cn (Chinese) + Date: 2007.9 + + Modify: Add your modify log here + + See readme.txt to get more information. + +*/ + +#ifndef _BOOTCFG_H_ +#define _BOOTCFG_H_ 1 + +//define uart buffer's length +#define BUFFERSIZE 128 + +//system clock(MHz) +#ifndef F_CPU +#define F_CPU 15754600UL +#endif + +//baudrate +#define BAUDRATE 115200 + +//Boot section start address(byte) +//define BootStart to 0 will disable this function +#define BootStart 0xFC00 + +//verify flash's data while write +//ChipCheck will only take effect while BootStart enable +#define ChipCheck 1 + +//Bootloader launch 0:comport password 1:port level +#define LEVELMODE 0 + +#define LEVELPORT C +#define LEVELPIN PC3 +//port level 1:High 0:Low +#define PINLEVEL 0 + +//max wait password time = TimeOutCnt * timeclk +//timeout count +#define TimeOutCnt 5 + +//basic timer interval(ms) +#define timeclk 500 + +//max wait data time = TimeOutCntC * timeclk +//send 'C' command count +#define TimeOutCntC 40 + +//password length +#define CONNECTCNT 5 + +//password +#if LEVELMODE == 0 +unsigned char KEY[] = {'f', 'l', 'a', 's', 'h'}; +#endif + +//comport number: 0/1/2.. +#define COMPORTNo 1 + +//enable watchdog +#define WDGEn 0 + +//enable RS485/RS422 mode +#define RS485 0 +//RS485/RS422 send control port +#define RS485PORT C +#define RS485TXEn PC1 + +//enable LED indication +#define LEDEn 0 +//LED control port +#define LEDPORT A +#define LEDPORTNo PA5 + +//some kind of AVR need this special delay after comport initialization +#define InitDelay 0 + +//communication checksum mode 0:CRC16 1:add up +#define CRCMODE 0 + +//Verbose mode: display more prompt message +#define VERBOSE 1 + +#endif + +//End of file: bootcfg.h diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.aws b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.aws new file mode 100755 index 0000000..f749b3d --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.aws @@ -0,0 +1 @@ + diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.c b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.c new file mode 100755 index 0000000..e4b6883 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.c @@ -0,0 +1,483 @@ +/* + + e Y8b Y8b YV3.18P888 88e + d8b Y8b Y8b Y888P 888 888D + d888b Y8b Y8b Y8P 888 88" + d888WuHan8b Y8b Y 888 b, + d8888888b Y8b Y8P 888 88b, + 8888 8888 ,e, 888 + 8888 888820078e " Y8b Y888P ,e e, 888,8, dP"Y ,"Y88b888 + 8888 8888888 88b888 Y8b Y8P d88 88b888 " C88b "8" 888888 + 8888 8888888 888888 Y8b " 888 ,888 Y88D,ee 888888 + 'Y88 88P'888 888888 Y8P "YeeP"888 d,dP "88 888888 + 888 88b, d8 888 888 + 888 88P' e88 88e e88 88e d88 888 e88 88e ,"Y88b e88 888 ,e e, 888,8, + 888 8K d888 888bd888 8Shaoziyang88d888 888b"8" 888d888 888d88 88b888 " + 888 88b,Y888 888PY888 888P 888 888Y888 888P,ee 888Y888 888888 ,888 + 888 88P' "88 88" "88 88" 888 888 "88 88" "88 888 "88 888 "YeeP"888 + + + Project: AVR Universal BootLoader + File: bootldr.c + main program code + Version: 3.1 + + Compiler: GCC 4.1.2 + AVR Studio 4.13.528 + + Author: Shaoziyang + Shaoziyang@gmail.com + http://shaoziyang.googlepages.com or + http://shaoziyang.bloger.com.cn (Chinese) + Date: 2007.9 + + Modify: Add your modify log here + + See readme.txt to get more information. + +*/ + +#include "bootcfg.h" +#include "bootldr.h" + +//user's application start address +#define PROG_START 0x0000 + +//receive buffer' size will not smaller than SPM_PAGESIZE +#if BUFFERSIZE < SPM_PAGESIZE +#define BUFSIZE SPM_PAGESIZE +#else +#define BUFSIZE BUFFERSIZE +#endif + +//define receive buffer +unsigned char buf[BUFSIZE]; + +#if BUFSIZE > 255 +unsigned int bufptr, pagptr; +#else +unsigned char bufptr, pagptr; +#endif + +unsigned char ch, cl; + +//Flash address +#if FLASHEND > 0xFFFFUL +unsigned long int FlashAddr; +#else +unsigned int FlashAddr; +#endif + + +//update one Flash page +void write_one_page(unsigned char *buf) +{ + boot_page_erase(FlashAddr); //erase one Flash page + boot_spm_busy_wait(); + for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2) //fill data to Flash buffer + { + boot_page_fill(pagptr, buf[pagptr] + (buf[pagptr + 1] << 8)); + } + boot_page_write(FlashAddr); //write buffer to one Flash page + boot_spm_busy_wait(); //wait Flash page write finish +} + +//jump to user's application +void quit() +{ + boot_rww_enable(); //enable application section + (*((void(*)(void))PROG_START))(); //jump +} + +//send data to comport +void WriteCom(unsigned char dat) +{ +#if RS485 + RS485Enable(); +#endif + + UDRREG(COMPORTNo) = dat; + //wait send finish + while(!(UCSRAREG(COMPORTNo) & (1< 255 +void crc16(unsigned char *buf) +{ + unsigned int j; +#else +void crc16(unsigned char *buf) +{ + unsigned char j; +#endif + +#if CRCMODE == 0 + unsigned char i; + unsigned int t; +#endif + unsigned int crc; + + crc = 0; + for(j = BUFFERSIZE; j > 0; j--) + { +#if CRCMODE == 0 + //CRC1021 checksum + crc = (crc ^ (((unsigned int) *buf) << 8)); + for(i = 8; i > 0; i--) + { + t = crc << 1; + if(crc & 0x8000) + t = t ^ 0x1021; + crc = t; + } +#elif CRCMODE == 1 + //word add up checksum + crc += (unsigned int)(*buf); +#elif + +#endif + buf++; + } + ch = crc / 256; + cl = crc % 256; +} + +int main(void) +{ + unsigned char cnt; + unsigned char packNO; + unsigned char crch, crcl; + +#if InitDelay > 255 + unsigned int di; +#elif InitDelay + unsigned char di; +#endif + +#if BUFFERSIZE > 255 + unsigned int li; +#else + unsigned char li; +#endif + + //disable interrupt + __asm__ __volatile__("cli": : ); + +#if WDGEn + //if enable watchdog, setup timeout + wdt_enable(WDTO_1S); +#endif + + //initialize timer1, CTC mode + TimerInit(); + +#if RS485 + DDRREG(RS485PORT) |= (1 << RS485TXEn); + RS485Disable(); +#endif + +#if LEDEn + //set LED control port to output + DDRREG(LEDPORT) = (1 << LEDPORTNo); +#endif + + //initialize comport with special config value + ComInit(); + +#if InitDelay + //some kind of avr mcu need special delay after comport initialization + for(di = InitDelay; di > 0; di--) + __asm__ __volatile__ ("nop": : ); +#endif + +#if LEVELMODE + //port level launch boot + //set port to input + DDRREG(LEVELPORT) &= ~(1 << LEVELPIN); +#if PINLEVEL + if(PINREG(LEVELPORT) & (1 << LEVELPIN)) +#else + if(!(PINREG(LEVELPORT) & (1 << LEVELPIN))) +#endif + { +#if VERBOSE + //prompt enter boot mode + putstr(msg6); +#endif + } + else + { +#if VERBOSE + //prompt execute user application + putstr(msg7); +#endif + + quit(); + } + +#else + //comport launch boot + +#if VERBOSE + //prompt waiting for password + putstr(msg1); +#endif + + cnt = TimeOutCnt; + cl = 0; + while(1) + { +#if WDGEn + //clear watchdog + wdt_reset(); +#endif + + if(TIFRREG & (1< + cnt = TimeOutCntC; + while(1) + { + if(TIFRREG & (1 << OCF1A)) //T1 overflow + { + TIFRREG |= (1 << OCF1A); + WriteCom(XMODEM_RWC) ; //send "C" + +#if LEDEn + //toggle LED + LEDAlt(); +#endif + + cnt--; + if(cnt == 0) + { +#if VERBOSE + //prompt timeout + putstr(msg2); +#endif + quit(); + } + } + +#if WDGEn + //clear watchdog + wdt_reset(); +#endif + + if(DataInCom()) + { + if(ReadCom() == XMODEM_SOH) //XMODEM command + break; + } + } + //close timer1 + TCCR1B = 0; + + //begin to receive data + packNO = 0; + bufptr = 0; + cnt = 0; + FlashAddr = 0; + do + { + packNO++; + ch = WaitCom(); //get package number + cl = ~WaitCom(); + if ((packNO == ch) && (packNO == cl)) + { + for(li = 0; li < BUFFERSIZE; li++) //receive a full data frame + { + buf[bufptr++] = WaitCom(); + } + crch = WaitCom(); //get checksum + crcl = WaitCom(); + crc16(&buf[bufptr - BUFFERSIZE]); //calculate checksum + if((crch == ch) && (crcl == cl)) + { +#if BootStart + if(FlashAddr < BootStart) //avoid write to boot section + { +#endif + +#if BUFFERSIZE < SPM_PAGESIZE + if(bufptr >= SPM_PAGESIZE) //Flash page full, write flash page;otherwise receive next frame + { //receive multi frames, write one page + write_one_page(buf); //write data to Flash + FlashAddr += SPM_PAGESIZE; //modify Flash page address + bufptr = 0; + } +#else + while(bufptr > 0) //receive one frame, write multi pages + { + write_one_page(&buf[BUFSIZE - bufptr]); + FlashAddr += SPM_PAGESIZE; //modify Flash page address + bufptr -= SPM_PAGESIZE; + } +#endif + +#if BootStart + } + else //ignore flash write when Flash address exceed BootStart + { + bufptr = 0; //reset receive pointer + } +#endif + +//read flash, compare with buffer's content +#if (ChipCheck > 0) && (BootStart > 0) +#if BUFFERSIZE < SPM_PAGESIZE + if((bufptr == 0) && (FlashAddr <= BootStart)) +#else + if(FlashAddr <= BootStart) +#endif + { + boot_rww_enable(); //enable application section + cl = 1; //clear error flag + for(pagptr = 0; pagptr < BUFSIZE; pagptr++) + { + if(pgm_read_byte(FlashAddr - BUFSIZE + pagptr) != buf[pagptr]) + { + cl = 0; //set error flag + break; + } + } + if(cl) //checksum equal, send ACK + { + WriteCom(XMODEM_ACK); + cnt = 0; + } + else + { + WriteCom(XMODEM_NAK); //checksum error, ask resend + cnt++; //increase error counter + FlashAddr -= BUFSIZE; //modify Flash page address + } + } + else //no verify, send ACK directly + { + WriteCom(XMODEM_ACK); + cnt = 0; + } +#else + //no verify, send ACK directly + WriteCom(XMODEM_ACK); + cnt = 0; +#endif + +#if WDGEn + //clear watchdog + wdt_reset(); +#endif + +#if LEDEn + //LED indicate update status + LEDAlt(); +#endif + } + else //CRC + { + //ask resend + WriteCom(XMODEM_NAK); + cnt++; + } + } + else //PackNo + { + //ask resend + WriteCom(XMODEM_NAK); + cnt++; + } + //too much error, update abort + if(cnt > 3) + break; + } + while(WaitCom() != XMODEM_EOT); + WriteCom(XMODEM_ACK); + + +#if VERBOSE + if(cnt == 0) + { + //prompt update success + putstr(msg4); + } + else + { + //prompt update fail + putstr(msg5); + +#if WDGEn + //dead loop, wait watchdog reset + while(1); +#endif + + } +#endif + + //quit boot mode + quit(); + return 0; +} + +//End of file: bootldr.c diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.h b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.h new file mode 100755 index 0000000..71ac705 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/bootldr.h @@ -0,0 +1,206 @@ +/* + + e Y8b Y8b YV3.18P888 88e + d8b Y8b Y8b Y888P 888 888D + d888b Y8b Y8b Y8P 888 88" + d888WuHan8b Y8b Y 888 b, + d8888888b Y8b Y8P 888 88b, + 8888 8888 ,e, 888 + 8888 888820078e " Y8b Y888P ,e e, 888,8, dP"Y ,"Y88b888 + 8888 8888888 88b888 Y8b Y8P d88 88b888 " C88b "8" 888888 + 8888 8888888 888888 Y8b " 888 ,888 Y88D,ee 888888 + 'Y88 88P'888 888888 Y8P "YeeP"888 d,dP "88 888888 + 888 88b, d8 888 888 + 888 88P' e88 88e e88 88e d88 888 e88 88e ,"Y88b e88 888 ,e e, 888,8, + 888 8K d888 888bd888 8Shaoziyang88d888 888b"8" 888d888 888d88 88b888 " + 888 88b,Y888 888PY888 888P 888 888Y888 888P,ee 888Y888 888888 ,888 + 888 88P' "88 88" "88 88" 888 888 "88 88" "88 888 "88 888 "YeeP"888 + + + Project: AVR Universal BootLoader + File: bootldr.h + necessary macro declare + Version: 3.1 + + Compiler: GCC 4.1.2 + AVR Studio 4.13.528 + + Author: Shaoziyang + Shaoziyang@gmail.com + http://shaoziyang.googlepages.com or + http://shaoziyang.bloger.com.cn (Chinese) + Date: 2007.9 + + Modify: Add your modify log here + + See readme.txt to get more information. + +*/ + +#ifndef _BOOTLDR_H_ +#define _BOOTLDR_H_ 1 + +#include +#include +#include +#include +#include + +//Don't modify code below, unless your really konw what to do + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE +#if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#else +#if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + +//check baudrate register error +//mocro below maybe not same in different C compiler +#define FreqTemp (16UL * BAUDRATE * (((F_CPU * 10) / (16 * BAUDRATE) + 5)/ 10)) +#if ((FreqTemp * 50) > (51 * F_CPU) || (FreqTemp * 50) < (49 * F_CPU)) +#error "BaudRate error > 2% ! Please check BaudRate and F_CPU value." +#endif + +#define True 1 +#define False 0 +#define TRUE 1 +#define FALSE 0 + +//internal use macro +#define CONCAT(a, b) a ## b +#define CONCAT3(a, b, c) a ## b ## c + +//register of PORT and bit define +#define PORTREG(No) CONCAT(PORT, No) +#define PINREG(No) CONCAT(PIN, No) +#define UDRREG(No) CONCAT(UDR, No) +#define DDRREG(No) CONCAT(DDR, No) +#define TXCBIT(No) CONCAT(TXC, No) +#define RXCBIT(No) CONCAT(RXC, No) +#define RXENBIT(No) CONCAT(RXEN, No) +#define TXENBIT(No) CONCAT(TXEN, No) +#define URSELBIT(No) CONCAT(URSEL, No) + +//comport register +#define UBRRHREG(No) CONCAT3(UBRR, No, H) +#define UBRRLREG(No) CONCAT3(UBRR, No, L) +#define UCSRAREG(No) CONCAT3(UCSR, No, A) +#define UCSRBREG(No) CONCAT3(UCSR, No, B) +#define UCSRCREG(No) CONCAT3(UCSR, No, C) +#define UCSZBIT(No1, No2) CONCAT3(UCSZ, No1, No2) + +//some kind of AVR need URSEL define when comport initialize +#if defined(URSEL) || defined(URSEL0) +#define USEURSEL URSELBIT(COMPORTNo) +#else +#define USEURSEL 0 +#endif + +//define UART0 register +#if !defined(UDR0) +#define UBRR0H UBRRH +#define UBRR0L UBRRL +#define UCSR0A UCSRA +#define UCSR0B UCSRB +#define UCSR0C UCSRC +#define UDR0 UDR +#define TXC0 TXC +#define RXC0 RXC +#define RXEN0 RXEN +#define TXEN0 TXEN +#define UCSZ01 UCSZ1 +#define UCSZ00 UCSZ0 +#define URSEL0 URSEL +#endif + +//initialize comport +#define ComInit() \ + { \ + UCSRAREG(COMPORTNo) = 0; \ + UCSRBREG(COMPORTNo) = (1 << RXENBIT(COMPORTNo))|(1 << TXENBIT(COMPORTNo)); \ + UCSRCREG(COMPORTNo) = USEURSEL|(1 << UCSZBIT(COMPORTNo, 1))|(1 << UCSZBIT(COMPORTNo, 0));\ + UBRRHREG(COMPORTNo) = BAUDREG/256; \ + UBRRLREG(COMPORTNo) = BAUDREG%256; \ + } + +//prompt messages +#if VERBOSE +#if LEVELMODE +const char msg6[] = "bootloader mode."; +const char msg7[] = "application mode."; +#else +//waiting for password +const char msg1[] = "waiting for password."; +#endif +//timeout +const char msg2[] = "timeout."; +//waiting for data +const char msg3[] = "waiting for data."; +//update success +const char msg4[] = "update success."; +//update fail +const char msg5[] = "update fail."; +#endif + +//toggle LED output +#define LEDAlt() PORTREG(LEDPORT) ^= (1 << LEDPORTNo) + +//timer1: prescale 1024, CTC mode 4, interval unit is millisecond +#define TimerInit() \ + { \ + OCR1A = (unsigned int)(timeclk * (F_CPU / (1024 * 1000.0f)));\ + TCCR1A = 0; \ + TCCR1B = (1 << WGM12)|(1 << CS12)|(1 << CS10); \ + } + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#if RS485 +#define RS485Enable() PORTREG(RS485PORT) |= (1 << RS485TXEn) +#define RS485Disable() PORTREG(RS485PORT) &= ~(1 << RS485TXEn) +#endif + +#define DataInCom() (UCSRAREG(COMPORTNo) & (1 << RXCBIT(COMPORTNo))) +#define ReadCom() UDRREG(COMPORTNo) + +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.htm b/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.htm new file mode 100755 index 0000000..8d00e08 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.htm @@ -0,0 +1,643 @@ + + + + +readme + + + + + + +

**********************************
+*                                *
+*  AVR Universal Bootloader      *
+*  AVR Universal Bootloader      *
+*                                *
+**********************************

+

 

+

Introduction
+Main feature
+Version
+Develop environment
+Project files
+Usage
+Main parameters
+Tested device
+Frequently asked questions
+Special thanks
+License

+

¡ø

+

Introduction

+

This project is a general AVR bootloader, for different type of AVR device, all you need to do is modify macro definition, and you don not need to modify the main program. There are many bootloader program on internet, but most of them are only available for special types. When we need to use other types device, we must do a lot of modification. And many of them are only realize the basic functions, and have bugs, hidden problem or may be used inconveniently, so we have developed this program. This project based on ATmega128 bootloader program which developed by Mr ChaoMa, and combined experience in bootloader of PIC18 microcontroller I have wrote before, and used the macro definition skill from AVRUSB, and optimize and test the code time after time, finally get this project.

+

This AVR universal bootloader can support most types of AVR microcontrollers(Mega series), which have self-programable capability, boot section and UART. If the device have many serial ports, you can use any one of them. This bootloader supports RS232, RS485 and RS422. It can also supports USI, SPI, I2C interface if you made some modify. 

+

This bootloader will occupy less than 1k words flash maximum, and it may occupy less than 300 words minimum. The space occupied by the bootloader is relative with device type, configuration parameters, funcations you select, and the optimize grade that the compiler use.

+

 

+

¡ø

+

Main feature

+
    +
  • Support many types of AVR microcontrollers.
  • +
  • Support AVR device with multi-uart.
  • +
  • Support RS232/RS485/RS422 mode.
  • +
  • Support customize communication baudrate and system clock frequcene.
  • +
  • Automatically calculate the baudrate error.
  • +
  • Write with AVR GCC, 100% C code.
  • +
  • High optimized code, occupy small space.
  • +
  • Cut out the function conveniently, and can meet different requirements.
  • +
  • Support Watchdog.
  • +
  • User may use the LED to show the upgrade status.
  • +
  • Support to use super terminal as download software on PC.
  • +
  • Support verification while write to FLASH.
  • +
  • Can define the size of user program section.
  • +
  • ...
  • +
+

¡ø

+

Version

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
v3.12007.Sep +

According to Douglas Hammond's suggest, modify ComInit macro.

+
+

v3.0

+
+ +

2007.Jun

+
+ +

Fix bug on ATmega162.
Modify uart port number configuration.
Pass test with WinAVR 20070522.
 

+
+

v2.0

+
+

2007.Apr.10

+
+

Add verification function while write Flash, improve the security of Bootloader.
 

+
+

v1.2

+
+

2007.Apr.02

+
+ +

Correct a hidden error in baudrate register calculate. (This error is very common. We can find it in many books and codes in network).
 

+
+ +

v1.0

+
+ +

2007.Mar.22

+
+ +

This is the first version. It realized all necessary functions, and extended XModem protocol to fit different application.

+
   
+

¡ø

+

Develop environment

+

The Develop environment of this project: WinAVR + AVR Studio
WinAVR version:        20070525
AVR Studio version£º   4.13.528

+

You may use other IDE or software to edit, debug AVR universal bootloader, such as KamAVR¡¢AtmanAVR¡¢PN.

+

 

+

¡ø

+

Project files

+

Whole project include flowing files:

+

bootldr.c           Main program
bootldr.h           The header file of main program
bootcfg.h           User configuration of main aprogram
bootldr.aps         AVR Studio's project file of bootloader
test.c              Demo program to test uart communication
testcfg.h           Configuration file of test.c
test.aps            Project file of test
readme.txt          this file
readme.htm          HTML edition of readme.txt

+

Because many people have AVR Butterfly demo board, so all project file here use AVR Butterfly hardware as example. If you use other hardware environment, all you need is to modify the congiguation parameter in file bootcfg.h.

+

 

+

¡ø

+

Usage

+
    +
  1. Creat a new project, and copy all above files to the folder where the new project is.
  2. +
  3. Add bootldr.c¡¢bootldr.h¡¢bootcfg.h to the project.
  4. +
  5. Modify the configuration parameter in bootcfg.h. The meaning of these parameters are introduced in next section.
  6. +
  7. Set the flash section address of the project as the beginning address of bootloader. Here the address is counted as word. Besides that, we need to set some parameters, such as the type of device( if you use AVR Studio or KamAVR, can set the parameters in IDE, otherwise you need to manual modify makefile file yourself).
  8. +
  9. Compile the project, then generate the target HEX file.
  10. +
  11. Program the target HEX file of Bootloader to the mcu.
  12. +
  13. Set lock bits and fuse bits to configurate Boot section size and enable Boot Reset Vector, and select clock source.
  14. +
  15. Connect target board to PC via comport, test bootloader.
  16. +
+

¡ø

+

Main parameters

+

The flowing parameters are very important. Please set these parameters carefully according to user system's hardware.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
parametersnote
+

BUFFERSIZE

+
+ +

The size of communication buffer. When use the hyper terminal, it must be equal to 128. This parmeter must be multiple or submultiple of SPM_PAGESIZE which is the size of mcu's flash section page.

+
+

F_CPU

+
+ +

Frequency of system clock (in Hz).

+
+

BAUDRATE

+
+ +

Baudrate of uart communication(bps).

+
+

LEVELMODE

+
+ +

Bootloader triger mode(0=uart  1= pin level)

+
+

timeclk

+
+ +

Basic time interval(ms)

+
+

TimeOutCnt

+
+ +

Bootloader maximal timeout count(<=255)

+
+

TimeOutCntC

+
+ +

The maximal timeout count when wait for receiving file(<=255)

+
+

CONNECTCNT

+
+ +

The length of password that will be used to connect to PC

+
+

KEY

+
+ +

The password to connect to PC. It can be hex numeral or string

+
+

COMPORTNo

+
+ +

´®Uart port number. One uart mcu is set to 0 or blank, to multi uart mcurt0 is 0, uart1 is 1, and so on.

+
+

WDGEn

+
+ +

Enable watchdog

+
+

RS485

+
+ +

Enable RS485/RS422 mode

+
+

RS485PORT

+
+ +

Control port of RS485/RS422 transmission(A/B/C/D...)

+
+

RS485TXEn

+
+ +

Control pin of RS485/RS422 transmission(PC0/PC1/PC2...)

+
+

LEDEn

+
+ +

Enable use LED to indication status.

+
+

LEDPORT

+
+ +

Port which LED used

+
+

LEDPORTNo

+
+ +

Pin which LED used

+
+

InitDelay

+
+ +

Additional delay after uart initializtion(some early device need this, such as ATmega8)

+
+

VERBOSE

+
+ +

Hint mode. Show more prompt information, interactive input will be convenient while using hyper terminal.

+
+

CRCMODE

+
+ +

Communication check sum method(0=XMODEM CRC 1=simple accumulated summation)

+
+

BootStart

+
+ +

The start adrress of Boot section(counted by byte)

+
+

ChipCheck

+
+ +

Enable verify data after write data to flash. This parameter will only valid when Bootstart used

+
+

¡ø

+

Tested device

+

The AVR universal bootloader has benn test in several AVR device, below devcie are tested by myself:

+

  ATmega8
  ATmeag64
  ATmega128
  ATmega168
  ATmega169(Bufferfly)

+

below are tested by other people: 

+

  ATmega16
  ATmega32
  ATmega162

+

If you have success use this bootloader in device not list above, please send EMAIL to me.

+

¡ø

+

Frequently asked questions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

1.

+
+

Q:

+
+ +

How to protect boot section?

+
  +

A:

+
+ +

In order to prevent boot section avoid overwrite, user must set lock bits of mcu. Commonly we set Bootloader protection mode to 2 or 3 by set BLB11 and BLB12, disable boot section write operation.
 

+
2. +

Q:

+
+ +

Why use watchdog in bootloader?

+
  +

A:

+
+ +

In order to increase system stability, I suggest use watchdog, to avoid bootloader enter dead loop.
 

+
3. +

Q:

+
+ +

Is hyper terminal may use to download target HEX file?

+
  +

A:

+
+ +

Yes, you can use hyper terminal as PC download software. In order to use hyper terminal as download software, macro BUFFERSIZE must equal 128, and KEY will not set to long(1-2 characters), macro TimeOutCnt/TimeOutCntC/timeclk must define large enough to let you have enough time to input. And macro CRCMODE must equal 0, and you need convert target HEX file to BIN format before download.

+

In fact, AVRUBD(AVR universal bootloader download) is a better software than terminal, AVRUBD support HEX/BIN format, after you load target file, all you need is click download button.
 

+
4. +

Q:

+
+ +

How to confirm uart work fine(comport line link correct)?

+
  +

A:

+
+ +

Demo program test.c may use to test uart. If link correct, compute will receive a '>' periodically from AVR mcu. If you send a character to mcu via Hyper terminal, send data will become to what you send.
 

+
5. +

Q:

+
+ +

Why bootloader can't jump to user's application after upgrade?

+
  +

A:

+
+ +

If this happen, there are most likely to two reasons: one is compiler's bug, made jump incorrect. You may see disassemble code to analyse jump codes, or try to update you compiler to new version. The other reason is not set fuse bits and lock bits correctly.
 

+
6.

Q:

+
+ +

How to cutdown unused function?

+
 

A:

+
+ +

In file bootcfg.h, there are many macro definition, set macro to 0 will disable corresponding fuction. For example, not use LED in bootloader, set macro LEDEn to 0.
 

+
7. +

Q:

+
+ +

How to reduce bootloader target size, leave more flash space to user?

+
  +

A:

+
+ +

Cutdown unnecessary functions, such as verbose hint, LED indication, use add up instead of CRC as check sum... And you can also set optimization of compiler, these will reduce target file size. Due to indeterminacy of optimization, code size optimize will not get the smallest size in some condition.
 

+
8. +

Q:

+
+ +

If AVRUB support other AVR C compiler?

+
  +

A:

+
+ +

AVR universal bootloader use AVR GCC as compiler, other C compiler have not been test. IAR C compiler is very close to AVR GCC, I think there are only few place need to be modify(AVRUSB is compatible with AVR GCC and IAR C compiler). Other C compiler may be use too, because I write code according to ANSI standard. The code may need to modify is head file, some register name may be different.
 

+
9. +

Q:

+
+ +

Where can user get last version of AVRUB?

+
  +

A:

+
+ +

In http://shaoziyang.googlepages.com or http://shaoziyang.bloger.com.cn you will get last version or AVRUB. If you have any suggestion, or link above can't be access, please send email to me shaoziyang@gmail.com.

+
+

¡ø

+

Special thanks

+

There are many people given me help in develop this project.

+ + + + + + + + + + + + + + + + + + + + + +
+

Áõº£ÌÎ

+
+ +

give many help in coding and debuging

+
+

tda1552

+
+ +

Tested ATmega32

+
+

ÐìÑÓ¿µ

+
+ +

Found bug in HEX format convert

+
+

Ä߶÷ΰ

+
+

give some useful suggestion

+
+

³ÌÏè

+
+

help to translate this document to English

+
+

And many people who have not left names.

+

¡ø

+

License

+

Base on GPL license.

+

¡ø

+

 

+

2007.6 Shao ziyang in WuHan

+

 

+ + + + +
+

                        e Y8b    Y8b YV3.08P888 88e                      
+                       d8b Y8b    Y8b Y888P 888 888D                     
+                      d888b Y8b    Y8b Y8P  888 88"                      
+                     d888WuHan8b    Y8b Y   888 b,                       
+                    d8888888b Y8b    Y8P    888 88b,                     
+        8888 8888       ,e,                                  888         
+        8888 888820078e  " Y8b Y888P ,e e, 888,8, dP"Y ,"Y88b888         
+        8888 8888888 88b888 Y8b Y8P d88 88b888 " C88b "8" 888888         
+        8888 8888888 888888  Y8b "  888   ,888    Y88D,ee 888888         
+        'Y88 88P'888 888888   Y8P    "YeeP"888   d,dP "88 888888         
+888 88b,                    d8  888                     888              
+888 88P' e88 88e  e88 88e  d88  888 e88 88e  ,"Y88b e88 888 ,e e, 888,8,
+888 8K  d888 888bd888 8Shaoziyang88d888 888b"8" 888d888 888d88 88b888 "  
+888 88b,Y888 888PY888 888P 888  888Y888 888P,ee 888Y888 888888   ,888    
+888 88P' "88 88"  "88 88"  888  888 "88 88" "88 888 "88 888 "YeeP"888    
+                                                                         
+                                                                         
+                                                                         
+       __                                                                
+      / _)                                                               
+     /(_)(/                                    __                        
+         /                                    (_ |_  _. _  _ o   _.._  _
+                                              __)| |(_|(_) /_|\/(_|| |(_|
+                                                              /        _|

+
+

 

+ + + \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.txt b/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.txt new file mode 100755 index 0000000..38746d8 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Bootloader2/readme.txt @@ -0,0 +1,290 @@ +************************************* +* * +* AVR Universal Bootloader(AVRUB) * +* * +************************************* + + + +Introduction +============ +This project is a general AVR bootloader, for different type of AVR device, +all you need to do is modify macro definition, and you don not need to +modify the main program. There are many bootloader program on internet, but +most of them are only available for special types. When we need to use other +types device, we must do a lot of modification. And many of them are only +realize the basic functions, and have bugs, hidden problem or may be used +inconveniently, so we have developed this program. This project based on +ATmega128 bootloader program which developed by Mr ChaoMa, and combined +experience in bootloader of PIC18 microcontroller I have wrote before, and +used the macro definition skill from AVRUSB, and optimize and test the code +time after time, finally get this project. + +This AVR universal bootloader can support most types of AVR microcontrollers +(Mega series), which have self-programable capability, boot section and UART. +If the device have many serial ports, you can use any one of them. This +bootloader supports RS232, RS485 and RS422. It can also supports USI, SPI, +I2C interface if you made some modify. + +This bootloader will occupy less than 1k words flash maximum, and it may +occupy less than 300 words minimum. The space occupied by the bootloader is +relative with device type, configuration parameters, funcations you select, +and the optimize grade that the compiler use. + + + +Main feature +============ +* Support many types of AVR microcontrollers. +* Support AVR device with multi-uart. +* Support RS232/RS485/RS422 mode. +* Support customize communication baudrate and system clock frequcene. +* Automatically calculate the baudrate error. +* Write with AVR GCC, 100% C code. +* High optimized code, occupy small space. +* Cut out the function conveniently, and can meet different requirements. +* Support Watchdog. +* User may use the LED to show the upgrade status. +* Support to use super terminal as download software on PC. +* Support verification while write to FLASH. +* Can define the size of user program section. +* ... + + + +Version +======= +v3.1 2007.Sep According to Douglas Hammond's suggest, modify ComInit + macro. + +v3.0 2007.Jun Fix bug on ATmega162. + Modify uart port number configuration. + Pass test with WinAVR 20070522. + +v2.0 2007.Apr.10 Add verification function while write Flash, improve the + security of Bootloader. + +v1.2 2007.Apr.02 Correct a hidden error in baudrate register calculate. + (This error is very common. We can find it in many books + and codes in network) + +v1.0 2007.Mar.22 This is the first version. It realized all necessary + functions, and extended XModem protocol to fit different + application. + + + +Develop environment +=================== +The Develop environment of this project: WinAVR + AVR Studio +WinAVR version: 20070525 +AVR Studio version£º 4.13.528 + +You may use other IDE or software to edit, debug AVR universal bootloader, +such as KamAVR¡¢AtmanAVR¡¢PN. + + + +Project files +============= +Whole project include flowing files. + +bootldr.c Main program +bootldr.h The header file of main program +bootcfg.h User configuration of main aprogram +bootldr.aps AVR Studio's project file of bootloader +test.c Demo program to test uart communication +testcfg.h Configuration file of test.c +test.aps Project file of test +readme.txt this file +readme.htm HTML edition of readme.txt + +Because many people have AVR Butterfly demo board, so all project file here +use AVR Butterfly hardware as example. If you use other hardware environment, +all you need is to modify the congiguation parameter in file bootcfg.h. + + + +Usage +===== +1. Creat a new project, and copy all above files to the folder where the new + project is. +2. Add bootldr.c¡¢bootldr.h¡¢bootcfg.h to the project. +3. Modify the configuration parameter in bootcfg.h. The meaning of these + parameters are introduced in next section. +4. Set the flash section address of the project as the beginning address of + bootloader. Here the address is counted as word. Besides that, we need to + set some parameters, such as the type of device( if you use AVR Studio or + KamAVR, can set the parameters in IDE, otherwise you need to manual modify + makefile file yourself). +5. Compile the project, then generate the target HEX file. +6. Program the target HEX file of Bootloader to the mcu. +7. Set lock bits and fuse bits to configurate Boot section size and enable + Boot Reset Vector, and select clock source. +8. Connect target board to PC via comport, test bootloader. + + + +Main parameters +=============== +The flowing parameters are very important. Please set these parameters +carefully according to user system's hardware. + +BUFFERSIZE The size of communication buffer. When use the hyper terminal, + it must be equal to 128. This parmeter must be multiple or + submultiple of SPM_PAGESIZE which is the size of mcu's flash + section page. +F_CPU Frequency of system clock (in Hz). +BAUDRATE Baudrate of uart communication(bps). +LEVELMODE Bootloader triger mode(0=uart 1= pin level) +timeclk Basic time interval(ms) +TimeOutCnt Bootloader maximal timeout count(<=255) +TimeOutCntC The maximal timeout count when wait for receiving file(<=255) +CONNECTCNT The length of password that will be used to connect to PC +KEY The password to connect to PC. It can be hex numeral or string +COMPORTNo Uart port number. One uart mcu is set to 0 or blank, to multi + uart mcu, uart0 is 0, uart1 is 1, and so on. +WDGEn Enable watchdog +RS485 Enable RS485/RS422 mode +RS485PORT Control port of RS485/RS422 transmission(A/B/C/D...) +RS485TXEn Control pin of RS485/RS422 transmission(PC0/PC1/PC2...) +LEDEn Enable use LED to indication status. +LEDPORT Port which LED used +LEDPORTNo Pin which LED used +InitDelay Additional delay after uart initializtion(some early device + need this, such as ATmega8) +VERBOSE Hint mode. Show more prompt information, interactive input will + be convenient while using hyper terminal. +CRCMODE Communication check sum method(0=XMODEM CRC 1=simple accumulated + summation) +BootStart The start adrress of Boot section(counted by byte) +ChipCheck Enable verify data after write data to flash. This parameter + will only valid when Bootstart used + + + +Tested device +============= +The AVR universal bootloader has benn test in several AVR device, below devcie +are tested by myself: + + ATmega8 + ATmeag64 + ATmega128 + ATmega168 + ATmega169(Bufferfly) + +below are tested by other people: + + ATmega16 + ATmega32 + ATmega162 + +If you have success use this bootloader in device not list above, please send +EMAIL to me. + + + +Frequently asked questions +========================== +1.Q: How to protect boot section? + A: In order to prevent boot section avoid overwrite, user must set lock bits + of mcu. Commonly we set Bootloader protection mode to 2 or 3 by set BLB11 + and BLB12, disable boot section write operation. +2.Q: Why use watchdog in bootloader? + A: In order to increase system stability, I suggest use watchdog, to avoid + bootloader enter dead loop. +3.Q: Is hyper terminal may use to download target HEX file? + A: Yes, you can use hyper terminal as PC download software. In order to use + hyper terminal as download software, macro BUFFERSIZE must equal 128, and + KEY will not set to long(1-2 characters), macro TimeOutCnt/TimeOutCntC/ + timeclk must define large enough to let you have enough time to input. + And macro CRCMODE must equal 0, and you need convert target HEX file to + BIN format before download. + In fact, AVRUBD(AVR universal bootloader download) is a better software + than terminal, AVRUBD support HEX/BIN format, after you load target file, + all you need is click download button. +4.Q: How to confirm uart work fine(comport line link correct)? + A: Demo program test.c may use to test uart. If link correct, compute will + receive a '>' periodically from AVR mcu. If you send a character to mcu + via Hyper terminal, send data will become to what you send. +5.Q: Why bootloader can't jump to user's application after upgrade? + A: If this happen, there are most likely to two reasons: one is compiler's + bug, made jump incorrect. You may see disassemble code to analyse jump + codes, or try to update you compiler to new version. The other reason is + not set fuse bits and lock bits correctly. +6.Q: How to cutdown unused function? + A: In file bootcfg.h, there are many macro definition, set macro to 0 will + disable corresponding fuction. For example, not use LED in bootloader, + set macro LEDEn to 0. +7.Q: How to reduce bootloader target size, leave more flash space to user? + A: Cutdown unnecessary functions, such as verbose hint, LED indication, use + add up instead of CRC as check sum... And you can also set optimization + of compiler, these will reduce target file size. Due to indeterminacy of + optimization, code size optimize will not get the smallest size in some + condition. +8.Q: If AVRUB support other AVR C compiler? + A: AVR universal bootloader use AVR GCC as compiler, other C compiler have + not been test. IAR C compiler is very close to AVR GCC, I think there + are only few place need to be modify(AVRUSB is compatible with AVR GCC + and IAR C compiler). Other C compiler may be use too, because I write + code according to ANSI standard. The code may need to modify is head + file, some register name may be different. +9.Q: Where can user get last version of AVRUB? + A: In http://shaoziyang.googlepages.com or http://shaoziyang.bloger.com.cn + you will get last version or AVRUB. If you have any suggestion, or link + above can't be access, please send email to me shaoziyang@gmail.com. + + + +Special thanks +============== +There are many people given me help in develop this project. + + Áõº£ÌÎ give many help in coding and debuging + tda1552 Tested ATmega32 + ÐìÑÓ¿µ Found bug in HEX format convert + Ä߶÷ΰ give some useful suggestion + ³ÌÏè help to translate this document to English + +And many people who have not left names. + + + +License +======= + +Base on GPL license. + + + +2007.6 Shao ziyang in WuHan + + + + e Y8b Y8b YV3.08P888 88e + d8b Y8b Y8b Y888P 888 888D + d888b Y8b Y8b Y8P 888 88" + d888WuHan8b Y8b Y 888 b, + d8888888b Y8b Y8P 888 88b, + 8888 8888 ,e, 888 + 8888 888820078e " Y8b Y888P ,e e, 888,8, dP"Y ,"Y88b888 + 8888 8888888 88b888 Y8b Y8P d88 88b888 " C88b "8" 888888 + 8888 8888888 888888 Y8b " 888 ,888 Y88D,ee 888888 + 'Y88 88P'888 888888 Y8P "YeeP"888 d,dP "88 888888 +888 88b, d8 888 888 +888 88P' e88 88e e88 88e d88 888 e88 88e ,"Y88b e88 888 ,e e, 888,8, +888 8K d888 888bd888 8Shaoziyang88d888 888b"8" 888d888 888d88 88b888 " +888 88b,Y888 888PY888 888P 888 888Y888 888P,ee 888Y888 888888 ,888 +888 88P' "88 88" "88 88" 888 888 "88 88" "88 888 "88 888 "YeeP"888 + + + + __ + / _) + /(_)(/ __ + / (_ |_ _. _ _ o _.._ _ + __)| |(_|(_) /_|\/(_|| |(_| + / _| + + diff --git a/Projects/DidacticSystem/Adam/MainController/CMakeLists.txt b/Projects/DidacticSystem/Adam/MainController/CMakeLists.txt new file mode 100644 index 0000000..4e12c92 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/CMakeLists.txt @@ -0,0 +1,145 @@ +cmake_minimum_required(VERSION 2.8) +PROJECT("Główny Sterownik") +PROJECT("Main Controller Template") +SET(CMAKE_SYSTEM_NAME "Główny Sterownik") + +SET(MCU atmega128) +SET(PROGRAMMER_DEV /dev/avrMultiTool) + +SET(IMAGENAME firmware) + +SET(CMAKE_C_COMPILER avr-gcc) +SET(CMAKE_CXX_COMPILER avr-g++) + +# Output format. (can be srec, ihex, binary) +SET(FORMAT "ihex") + +# Target file name (without extension). +SET(TARGET_NAME ${IMAGENAME}) + + +SET(SOURCE_DIR "../../freeRtos/Source") +SET(LIB_DIR "../../freeRtos/Lib") +SET(LIB_NET_DIR "../../freeRtos/Lib/net") +SET(PORT_DIR "../../freeRtos/portable/GCC/ATMega64") +SET(PORT_MEM "../../freeRtos/portable/MemMang") + +include_directories("./" "${SOURCE_DIR}/include" "${LIB_DIR}/include" "${LIB_NET_DIR}/include" "${PORT_DIR}") + +SET(CSTANDARD "-std=gnu99") +SET(CDEBUG "-gstabs") +SET(CWARN "-Wall -Wstrict-prototypes") +SET(CTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums") +SET(COPT "-Os") +SET(CINCS "-I. -I${SOURCE_DIR}/include -I${LIB_DIR}/include -I${LIB_NET_DIR}/include") +SET(CMCU "-mmcu=${MCU}") +SET(CDEFS "-DF_CPU=14745600") + +SET(CFLAGS "${CMCU} ${CDEBUG} ${CDEFS} ${CINCS} ${COPT} ${CWARN} ${CSTANDARD} ${CEXTRA}") +SET(CXXFLAGS "${CMCU} ${CDEFS} ${CINCS} ${COPT}") + +SET(CMAKE_C_FLAGS ${CFLAGS}) +SET(CMAKE_CXX_FLAGS ${CXXFLAGS}) + + +add_executable(${IMAGENAME} + main.c configuration.c serial.c hardware.c sensors_task.c vty.c netstack_task.c cli_task.c + ${LIB_DIR}/spi.c ${LIB_DIR}/memory_x.c ${LIB_DIR}/ramdysk.c ${LIB_DIR}/cmdline.c ${LIB_DIR}/xmodem.c + ${LIB_DIR}/vt100.c ${LIB_DIR}/ds1305.c ${LIB_DIR}/mpc23s17.c ${LIB_DIR}/mcp3008.c ${LIB_DIR}/mcp4150.c + ${LIB_DIR}/enc28j60.c ${LIB_DIR}/queueStream.c + ${LIB_NET_DIR}/nic.c ${LIB_NET_DIR}/net.c ${LIB_NET_DIR}/ip.c ${LIB_NET_DIR}/icmp.c ${LIB_NET_DIR}/arp.c + ${LIB_NET_DIR}/tcp.c ${LIB_NET_DIR}/udp.c ${LIB_DIR}/Rs485_prot.c + ${SOURCE_DIR}/tasks.c ${SOURCE_DIR}/queue.c ${SOURCE_DIR}/list.c ${SOURCE_DIR}/croutine.c + ${PORT_MEM}/heap_avr.c + ${PORT_DIR}/port.c ) + + + +add_custom_target(mainController DEPENDS + main.c main.h + configuration.c configuration.h # Load / save configuration + hardware.c hardware.h + serial.c serial.h + vty.c vty.h + sensors_task.c sensors_task.h + netstack_task.c netstack_task.h + cli_task.c cli_task.h + ) + +add_custom_target(languageFiles DEPENDS + vty_pl.h vty_en.h + Rs485_prot_pl.h Rs485_prot_en.h + hardware_pl.h hardware_en.h + ) + +add_custom_target(Config DEPENDS + hardwareConfig.h # Hardware config + FreeRTOSConfig.h # FreeRTOSConfig.h + softwareConfig.h # Software configuration ie. language + ffconf.h # Petits File system config + ) + +add_custom_target(Protocols DEPENDS + ${LIB_DIR}/vt100.c ${LIB_DIR}/include/vt100.h # ObsÅ‚uga sekwencji stosowanytch w VT100 + ${LIB_DIR}/cmdline.c ${LIB_DIR}/include/cmdline.h # ObsÅ‚uga interpretera poleceÅ„ + ${LIB_DIR}/xmodem.c ${LIB_DIR}/include/xmodem.h # ObsÅ‚uga systemu transmisji Xmodem + ${LIB_DIR}/Rs485_prot.c ${LIB_DIR}/include/Rs485_prot.h # ObsÅ‚uga protokoÅ‚u komunikujÄ…cego siÄ™ przez magistralÄ™ Rs485 z moduÅ‚ami wykonawczymi + ${LIB_DIR}/include/protocol1.h # Rs485 Protocol constans + ) + +add_custom_target(FreeRtos DEPENDS + ${SOURCE_DIR}/include/FreeRTOS.h + ${SOURCE_DIR}/include/semphr.h + ${SOURCE_DIR}/include/portable.h + ${SOURCE_DIR}/list.c ${SOURCE_DIR}/include/list.h + ${SOURCE_DIR}/queue.c ${SOURCE_DIR}/include/queue.h + ${SOURCE_DIR}/tasks.c ${SOURCE_DIR}/include/task.h + ${LIB_DIR}/queueStream.c ${LIB_DIR}/include/queueStream.h # obsÅ‚uga strumienia FILE na potrzeby biblioteki libc + ) + +add_custom_target(Hardware DEPENDS + ${LIB_DIR}/spi.c ${LIB_DIR}/include/spi.h # ObsÅ‚uga magistrali SPI + ${LIB_DIR}/memory_x.c ${LIB_DIR}/include/memory_x.h # ObsÅ‚uga malloc. Zlicza wolnÄ… i zajÄ™tÄ… pamięć na stercie. + ${LIB_DIR}/mpc23s17.c ${LIB_DIR}/include/mpc23s17.h # ObsÅ‚uga ekspandera portu + ${LIB_DIR}/mcp3008.c ${LIB_DIR}/include/mcp3008.h # ObsÅ‚uga przetwornika A/C + ${LIB_DIR}/mcp4150.c ${LIB_DIR}/include/mcp4150.h # ObsÅ‚uga przetwornika A/C + ${LIB_DIR}/ds1305.c ${LIB_DIR}/include/ds1305.h # ObsÅ‚uga zegara RTC + ${LIB_DIR}/enc28j60.c ${LIB_DIR}/include/enc28j60.h # ObsÅ‚uga sterownika ethernetowego + ${LIB_DIR}/sd_diskio.c ${LIB_DIR}/include/sd_diskio.h # ObsÅ‚uga karty SD + ) + +add_custom_target(NetworkStack DEPENDS + ${LIB_NET_DIR}/nic.c ${LIB_NET_DIR}/include/nic.h # Hardware abstraction + ${LIB_NET_DIR}/net.c ${LIB_NET_DIR}/include/net.h # Network frames, packets, etc. + ${LIB_NET_DIR}/ip.c ${LIB_NET_DIR}/include/ip.h # IPv4 support + ${LIB_NET_DIR}/arp.c ${LIB_NET_DIR}/include/arp.h # Arp support + ${LIB_NET_DIR}/icmp.c ${LIB_NET_DIR}/include/icmp.h # Ping + ${LIB_NET_DIR}/tcp.c ${LIB_NET_DIR}/include/tcp.h # Tcp protocol + ${LIB_NET_DIR}/udp.c ${LIB_NET_DIR}/include/udp.h # Udp protocol + ) + +add_custom_target(Filesystem DEPENDS + ${LIB_DIR}/ramdysk.c ${LIB_DIR}/include/ramdysk.h # ObsÅ‚uga systemu plików Fat8 + ${LIB_DIR}/ff.c ${LIB_DIR}/include/ff.h # ObsÅ‚uga systemu plików Fat32 + ${LIB_DIR}/include/integer.h + ) + +ADD_CUSTOM_COMMAND( + OUTPUT ${IMAGENAME}.hex + COMMAND avr-objcopy -O ${FORMAT} -R .eeprom ${IMAGENAME} ${IMAGENAME}.hex + DEPENDS ${IMAGENAME} +) + +ADD_CUSTOM_COMMAND( + OUTPUT ${IMAGENAME}.eep + COMMAND avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ${FORMAT} ${IMAGENAME} ${IMAGENAME}.eep + DEPENDS ${IMAGENAME} +) + +add_custom_target(install + COMMAND avr-objcopy -O ${FORMAT} -R .eeprom ${IMAGENAME} ${IMAGENAME}.hex + COMMAND avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ${FORMAT} ${IMAGENAME} ${IMAGENAME}.eep + COMMAND avrdude -p ${MCU} -P ${PROGRAMMER_DEV} -c jtag1 -U flash:w:${IMAGENAME}.hex -U eeprom:w:${IMAGENAME}.eep + DEPENDS ${IMAGENAME} + COMMENT "Upload firmware to microcontroller" +) diff --git a/Projects/DidacticSystem/Adam/MainController/Doc/XMODMCRC.TXT b/Projects/DidacticSystem/Adam/MainController/Doc/XMODMCRC.TXT new file mode 100644 index 0000000..741dce7 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Doc/XMODMCRC.TXT @@ -0,0 +1,139 @@ +Perception presents: +---------- Understanding The X-Modem CRC File Transfer Protocol -------------- + + by Em Decay + +This has to be one of the most internationally accepted protocols for upload- + ing and downloading binary and text files. It is fairly straight-forward as + to how it is set up and there are some error checking capablities. + + +--- Before you begin --- + +Look at my XMODEM.TXT text file for a general understanding of the X-Modem + file transfer protocol and the terms used in it. + +New things you need to know beforehand... + +One word is the same as two bytes. If you want the high byte and the low + byte of a word, simply do the following. + High byte = word DIV 256 (DIV is the same as divide except the answer is + truncated) + Low byte = $00ff AND word (AND refers to AND logic) + +To get a word from a high byte and a low byte, simply multiply the high byte + by 256 (or shift it left 8 bits, if you know assembly) and add the low byte + to it. + +CRC stands for Cyclical Redundancy Check. In X-Modem CRC, it is also refer- + red to as CRC-16 since there are 16 bits (1 word) at the end of the block + that contain the CRC. This 1 word CRC replaces the 1 byte checksum in + X-Modem. +CRC-16 guarantees detection of all single and double bit errors, all errors + with an odd number of bits and over 99.9969% of all burst errors (you don't + have to know what all these things are :). +The easiest and fastest way to calculate the CRC is to use a lookup table. + +Here is some source code about making a lookup table. Call this procedure + at the very beginning of the program. Make crctable an global variable. + It is an array [0..255] of word. + + procedure initcrc; + + var + i:integer; + + function calctable(data,genpoly,accum:word):word; + + var + j:word; + + begin + data:=data shl 8; + for j:=8 downto 1 do + begin + if ((data xor accum) and $8000)<>0 then + accum:=(accum shl 1) xor genpoly + else + accum:=accum shl 1; + data:=data shl1; + end; + calctable:=accum; + end; + + begin + for i:=0 to 255 do + crctable[i]:=calctable(i,4129,0); + end; + +The CRC starts with a value of zero at the beginning of each block. Now to + update the CRC, with each byte in the 128 byte packet simply do this (the + oldcrc is the crc value to be updated, data is the current byte): + CRC:=(oldcrc shl 8) xor (crctable[(oldcrc shr 8) xor data]); +The final value of the CRC (after all 128 bytes) is what is being sent in the + X-Modem CRC protocol. + +If you have somewhat understood what has just been described then you catch + on a lot faster than I did :) If you just use + + +--- The Actual Transfer --- + +As in X-Modem, the uploader waits for the downloader to send the NCGbyte. + The NCGbyte for X-Modem CRC is chr(67) or the capital letter C (unlike + X-Modem where the NCGbyte is chr(21), the NAK). If the downloader takes too + long or an error occurs then the uploader will stop waiting or "Time Out". + If this happens, then the file transfer must restart. + +With each packet sent... + + The uploader sends: + + 1. an SOH byte {1 byte} + 2. the packet number {1 byte} + 3. the 1's complement of the packet number {1 byte} + 4. the packet {128 bytes} + 5. the high byte of the CRC-16 {1 byte} + 6. the low byte of the CRC-16 {1 byte} + + These six things make up the block. + + The downloader: + + 1. ensures that the packet number sent matches the actual packet number + that it is (If the third block sent has a '4' as the second byte, + something is wrong --> CANCEL TRANSFER (send CAN byte)) + 2. adds the packet number and the 1's complement of the packet number + together to make sure that they add up to 255. if they don't --> + CANCEL TRANSFER + 3. sets the CRC to zero + 4. updates the CRC as each byte in the packet is sent + 5. compares the calculated CRC to the CRC that is sent + 6. if everything looks ok (calculated CRC=sent CRC), then the downloader + appends the bytes in the packet to the file being created (sent). + The downloader then sends an ACK byte which tells the uploader to + send the next block. + if the CRCs do not match, then the downloader sends a NAK byte which + tells the uploader to send the same block it just sent over again. + +When the uploader sends an EOT byte instead of an SOH byte, the downloader + sends a NAK byte. If the uploader sends another EOT immediately after that, + the downloader sends an ACK byte and the transfer is complete. + +Another thing, the downloader can cancel the transfer at any time by sending + a CAN byte. The uploadered can cancel only between blocks by sending a CAN + byte. It is recommended that you send between 2 and 8 consecutive CAN bytes + as some communication programs will not allow you to cancel with only 1 CAN + byte. + + +--- Wrap Up --- + +Hopefully, you were able to follow along. :) If not, you can e-mail me at + em_decay@norlink.net and I will try to clarify it for you. Have fun :) + +Perception: Em Decay -- Mark Korhonen + Cmf ------- Chris Fillion + +Written on Jan.3/95 + diff --git a/Projects/DidacticSystem/Adam/MainController/Doc/protRs485 b/Projects/DidacticSystem/Adam/MainController/Doc/protRs485 new file mode 100644 index 0000000..dd8d88d --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Doc/protRs485 @@ -0,0 +1,17 @@ +#ifndef PROT485_H +#define PROT485_H + +#include +#include "main.h" + +#define Rs485TxStart() (PORTG |= 0x10) +#define Rs485TxStop() (PORTG &= 0xEF) + + +/** + * Inicjalizacja sprzÄ™tu + */ +void hardwareInit(void); + + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/FreeRTOSConfig.h b/Projects/DidacticSystem/Adam/MainController/FreeRTOSConfig.h new file mode 100644 index 0000000..db081e7 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 32000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 100 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 3100 ) ) +//2800 +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 700 +#define STACK_SIZE_ENC 500 +#define STACK_SIZE_SENSORS 500 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Adam/MainController/Makefile b/Projects/DidacticSystem/Adam/MainController/Makefile new file mode 100644 index 0000000..40dc7a2 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Makefile @@ -0,0 +1,474 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega128 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../Lib +LIB_NET_DIR = ../../Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/mcp4150.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../Lib/include -I../../Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +AVRDUDE_PROGRAMMER_2= usbMultiToolV2jtag +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS_2 = -p $(MCU) -C avrdude.conf -c $(AVRDUDE_PROGRAMMER_2) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +program2: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + + +programfuses2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset2: + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_READ_FUSES_L) + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Adam/MainController/Makefile64 b/Projects/DidacticSystem/Adam/MainController/Makefile64 new file mode 100644 index 0000000..e8946d3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Makefile64 @@ -0,0 +1,454 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega64 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../freeRtos/Lib +LIB_NET_DIR = ../../freeRtos/Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../freeRtos/Lib/include -I../../freeRtos/Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git "a/Projects/DidacticSystem/Adam/MainController/Opis zada\305\204" "b/Projects/DidacticSystem/Adam/MainController/Opis zada\305\204" new file mode 100644 index 0000000..74a6ea8 --- /dev/null +++ "b/Projects/DidacticSystem/Adam/MainController/Opis zada\305\204" @@ -0,0 +1,4 @@ +1) Modyfikacja bibliotek. Zrezygnować ze wskaźników do funkcji. Zastosować __attribute__(weak) +2) Dodać możliwość tworzenia buforów cyklicznych, których tablica pamiÄ™ci umieszczona jest w zewnÄ™trznej pamiÄ™ci +3) Dodać obsÅ‚ugÄ™ specjalnych koment VTY (odpowiednia interpretacja nowych linii, itd) +4) Uruchomić sokety \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/Rs485_prot_en.h b/Projects/DidacticSystem/Adam/MainController/Rs485_prot_en.h new file mode 100644 index 0000000..558da24 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Rs485_prot_en.h @@ -0,0 +1,10 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT EN + +#include + +const char statusRollerDescStr[] PROGMEM = " %d roller driver: roller 1 position %d, roller 2 position %d"; +const char statusRollerDescStrConf[] PROGMEM = " config %x"; +const char statusRollerDescStr2[] PROGMEM = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/Rs485_prot_pl.h b/Projects/DidacticSystem/Adam/MainController/Rs485_prot_pl.h new file mode 100644 index 0000000..37be016 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/Rs485_prot_pl.h @@ -0,0 +1,7 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT PL + +prog_char statusRollerDescStr[] = " %d sterownik rolet: pozycja rolety 1 %d, pozycja rolety 2 %d"; +prog_char statusRollerDescStr2[] = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/avrdude.conf b/Projects/DidacticSystem/Adam/MainController/avrdude.conf new file mode 100644 index 0000000..4165040 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/avrdude.conf @@ -0,0 +1,14888 @@ +# $Id: avrdude.conf.in 1360 2015-10-31 20:50:52Z joerg_wunsch $ -*- text -*- +# +# AVRDUDE Configuration File +# +# This file contains configuration data used by AVRDUDE which describes +# the programming hardware pinouts and also provides part definitions. +# AVRDUDE's "-C" command line option specifies the location of the +# configuration file. The "-c" option names the programmer configuration +# which must match one of the entry's "id" parameter. The "-p" option +# identifies which part AVRDUDE is going to be programming and must match +# one of the parts' "id" parameter. +# +# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next +# time a "make install" is run. For user-specific additions, use the +# "-C +filename" commandline option. +# +# Possible entry formats are: +# +# programmer +# parent # optional parent +# id = [, [, ] ...] ; # are quoted strings +# desc = ; # quoted string +# type = ; # programmer type, quoted string +# # supported programmer types can be listed by "-c ?type" +# connection_type = parallel | serial | usb +# baudrate = ; # baudrate for avr910-programmer +# vcc = [, ... ] ; # pin number(s) +# buff = [, ... ] ; # pin number(s) +# reset = ; # pin number +# sck = ; # pin number +# mosi = ; # pin number +# miso = ; # pin number +# errled = ; # pin number +# rdyled = ; # pin number +# pgmled = ; # pin number +# vfyled = ; # pin number +# usbvid = ; # USB VID (Vendor ID) +# usbpid = [, ...] # USB PID (Product ID) (1) +# usbdev = ; # USB interface or other device info +# usbvendor = ; # USB Vendor Name +# usbproduct = ; # USB Product Name +# usbsn = ; # USB Serial Number +# +# To invert a bit, use = ~ , the spaces are important. +# For a pin list all pins must be inverted. +# A single pin can be specified as usual = ~ , for lists +# specify it as follows = ~ ( [, ... ] ) . +# +# (1) Not all programmer types can process a list of PIDs. +# ; +# +# part +# id = ; # quoted string +# desc = ; # quoted string +# has_jtag = ; # part has JTAG i/f +# has_debugwire = ; # part has debugWire i/f +# has_pdi = ; # part has PDI i/f +# has_tpi = ; # part has TPI i/f +# devicecode = ; # deprecated, use stk500_devcode +# stk500_devcode = ; # numeric +# avr910_devcode = ; # numeric +# signature = ; # signature bytes +# usbpid = ; # DFU USB PID +# chip_erase_delay = ; # micro-seconds +# reset = dedicated | io; +# retry_pulse = reset | sck; +# pgm_enable = ; +# chip_erase = ; +# chip_erase_delay = ; # chip erase delay (us) +# # STK500 parameters (parallel programming IO lines) +# pagel = ; # pin name in hex, i.e., 0xD7 +# bs2 = ; # pin name in hex, i.e., 0xA0 +# serial = ; # can use serial downloading +# parallel = ; # can use par. programming +# # STK500v2 parameters, to be taken from Atmel's XML files +# timeout = ; +# stabdelay = ; +# cmdexedelay = ; +# synchloops = ; +# bytedelay = ; +# pollvalue = ; +# pollindex = ; +# predelay = ; +# postdelay = ; +# pollmethod = ; +# mode = ; +# delay = ; +# blocksize = ; +# readsize = ; +# hvspcmdexedelay = ; +# # STK500v2 HV programming parameters, from XML +# pp_controlstack = , , ...; # PP only +# hvsp_controlstack = , , ...; # HVSP only +# hventerstabdelay = ; +# progmodedelay = ; # PP only +# latchcycles = ; +# togglevtg = ; +# poweroffdelay = ; +# resetdelayms = ; +# resetdelayus = ; +# hvleavestabdelay = ; +# resetdelay = ; +# synchcycles = ; # HVSP only +# chiperasepulsewidth = ; # PP only +# chiperasepolltimeout = ; +# chiperasetime = ; # HVSP only +# programfusepulsewidth = ; # PP only +# programfusepolltimeout = ; +# programlockpulsewidth = ; # PP only +# programlockpolltimeout = ; +# # JTAG ICE mkII parameters, also from XML files +# allowfullpagebitstream = ; +# enablepageprogramming = ; +# idr = ; # IO addr of IDR (OCD) reg. +# rampz = ; # IO addr of RAMPZ reg. +# spmcr = ; # mem addr of SPMC[S]R reg. +# eecr = ; # mem addr of EECR reg. +# # (only when != 0x3c) +# is_at90s1200 = ; # AT90S1200 part +# is_avr32 = ; # AVR32 part +# +# memory +# paged = ; # yes / no +# size = ; # bytes +# page_size = ; # bytes +# num_pages = ; # numeric +# min_write_delay = ; # micro-seconds +# max_write_delay = ; # micro-seconds +# readback_p1 = ; # byte value +# readback_p2 = ; # byte value +# pwroff_after_write = ; # yes / no +# read = ; +# write = ; +# read_lo = ; +# read_hi = ; +# write_lo = ; +# write_hi = ; +# loadpage_lo = ; +# loadpage_hi = ; +# writepage = ; +# ; +# ; +# +# If any of the above parameters are not specified, the default value +# of 0 is used for numerics or the empty string ("") for string +# values. If a required parameter is left empty, AVRDUDE will +# complain. +# +# Parts can also inherit parameters from previously defined parts +# using the following syntax. In this case specified integer and +# string values override parameter values from the parent part. New +# memory definitions are added to the definitions inherited from the +# parent. +# +# part parent # quoted string +# id = ; # quoted string +# +# ; +# +# NOTES: +# * 'devicecode' is the device code used by the STK500 (see codes +# listed below) +# * Not all memory types will implement all instructions. +# * AVR Fuse bits and Lock bits are implemented as a type of memory. +# * Example memory types are: +# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high +# fuse), "signature", "calibration", "lock" +# * The memory type specified on the avrdude command line must match +# one of the memory types defined for the specified chip. +# * The pwroff_after_write flag causes avrdude to attempt to +# power the device off and back on after an unsuccessful write to +# the affected memory area if VCC programmer pins are defined. If +# VCC pins are not defined for the programmer, a message +# indicating that the device needs a power-cycle is printed out. +# This flag was added to work around a problem with the +# at90s4433/2333's; see the at90s4433 errata at: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf +# +# INSTRUCTION FORMATS +# +# Instruction formats are specified as a comma seperated list of +# string values containing information (bit specifiers) about each +# of the 32 bits of the instruction. Bit specifiers may be one of +# the following formats: +# +# '1' = the bit is always set on input as well as output +# +# '0' = the bit is always clear on input as well as output +# +# 'x' = the bit is ignored on input and output +# +# 'a' = the bit is an address bit, the bit-number matches this bit +# specifier's position within the current instruction byte +# +# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12 +# is address bit 12 on input, a0 is address bit 0. +# +# 'i' = the bit is an input data bit +# +# 'o' = the bit is an output data bit +# +# Each instruction must be composed of 32 bit specifiers. The +# instruction specification closely follows the instruction data +# provided in Atmel's data sheets for their parts. +# +# See below for some examples. +# +# +# The following are STK500 part device codes to use for the +# "devicecode" field of the part. These came from Atmel's software +# section avr061.zip which accompanies the application note +# AVR061 available from: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf +# + +#define ATTINY10 0x10 /* the _old_ one that never existed! */ +#define ATTINY11 0x11 +#define ATTINY12 0x12 +#define ATTINY15 0x13 +#define ATTINY13 0x14 + +#define ATTINY22 0x20 +#define ATTINY26 0x21 +#define ATTINY28 0x22 +#define ATTINY2313 0x23 + +#define AT90S1200 0x33 + +#define AT90S2313 0x40 +#define AT90S2323 0x41 +#define AT90S2333 0x42 +#define AT90S2343 0x43 + +#define AT90S4414 0x50 +#define AT90S4433 0x51 +#define AT90S4434 0x52 +#define ATMEGA48 0x59 + +#define AT90S8515 0x60 +#define AT90S8535 0x61 +#define AT90C8534 0x62 +#define ATMEGA8515 0x63 +#define ATMEGA8535 0x64 + +#define ATMEGA8 0x70 +#define ATMEGA88 0x73 +#define ATMEGA168 0x86 + +#define ATMEGA161 0x80 +#define ATMEGA163 0x81 +#define ATMEGA16 0x82 +#define ATMEGA162 0x83 +#define ATMEGA169 0x84 + +#define ATMEGA323 0x90 +#define ATMEGA32 0x91 + +#define ATMEGA64 0xA0 + +#define ATMEGA103 0xB1 +#define ATMEGA128 0xB2 +#define AT90CAN128 0xB3 +#define AT90CAN64 0xB3 +#define AT90CAN32 0xB3 + +#define AT86RF401 0xD0 + +#define AT89START 0xE0 +#define AT89S51 0xE0 +#define AT89S52 0xE1 + +# The following table lists the devices in the original AVR910 +# appnote: +# |Device |Signature | Code | +# +-------+----------+------+ +# |tiny12 | 1E 90 05 | 0x55 | +# |tiny15 | 1E 90 06 | 0x56 | +# | | | | +# | S1200 | 1E 90 01 | 0x13 | +# | | | | +# | S2313 | 1E 91 01 | 0x20 | +# | S2323 | 1E 91 02 | 0x48 | +# | S2333 | 1E 91 05 | 0x34 | +# | S2343 | 1E 91 03 | 0x4C | +# | | | | +# | S4414 | 1E 92 01 | 0x28 | +# | S4433 | 1E 92 03 | 0x30 | +# | S4434 | 1E 92 02 | 0x6C | +# | | | | +# | S8515 | 1E 93 01 | 0x38 | +# | S8535 | 1E 93 03 | 0x68 | +# | | | | +# |mega32 | 1E 95 01 | 0x72 | +# |mega83 | 1E 93 05 | 0x65 | +# |mega103| 1E 97 01 | 0x41 | +# |mega161| 1E 94 01 | 0x60 | +# |mega163| 1E 94 02 | 0x64 | + +# Appnote AVR109 also has a table of AVR910 device codes, which +# lists: +# dev avr910 signature +# ATmega8 0x77 0x1E 0x93 0x07 +# ATmega8515 0x3B 0x1E 0x93 0x06 +# ATmega8535 0x6A 0x1E 0x93 0x08 +# ATmega16 0x75 0x1E 0x94 0x03 +# ATmega162 0x63 0x1E 0x94 0x04 +# ATmega163 0x66 0x1E 0x94 0x02 +# ATmega169 0x79 0x1E 0x94 0x05 +# ATmega32 0x7F 0x1E 0x95 0x02 +# ATmega323 0x73 0x1E 0x95 0x01 +# ATmega64 0x46 0x1E 0x96 0x02 +# ATmega128 0x44 0x1E 0x97 0x02 +# +# These codes refer to "BOOT" device codes which are apparently +# different than standard device codes, for whatever reasons +# (often one above the standard code). + +# There are several extended versions of AVR910 implementations around +# in the Internet. These add the following codes (only devices that +# actually exist are listed): + +# ATmega8515 0x3A +# ATmega128 0x43 +# ATmega64 0x45 +# ATtiny26 0x5E +# ATmega8535 0x69 +# ATmega32 0x72 +# ATmega16 0x74 +# ATmega8 0x76 +# ATmega169 0x78 + +# +# Overall avrdude defaults; suitable for ~/.avrduderc +# +default_parallel = "/dev/parport0"; +default_serial = "/dev/ttyS0"; +# default_bitclock = 2.5; + +# Turn off safemode by default +#default_safemode = no; + + +# +# PROGRAMMER DEFINITIONS +# + +# http://wiring.org.co/ +# Basically STK500v2 protocol, with some glue to trigger the +# bootloader. +programmer + id = "wiring"; + desc = "Wiring"; + type = "wiring"; + connection_type = serial; +; + +programmer + id = "arduino"; + desc = "Arduino"; + type = "arduino"; + connection_type = serial; +; +# this will interface with the chips on these programmers: +# +# http://real.kiev.ua/old/avreal/en/adapters +# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml +# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html +# http://www.ethernut.de/en/hardware/turtelizer/index.html +# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html +# http://dangerousprototypes.com/docs/FT2232_breakout_board +# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H +# http://flashrom.org/FT2232SPI_Programmer +# +# The drivers will look for a specific device and use the first one found. +# If you have mulitple devices, then look for unique information (like SN) +# And fill that in here. +# +# Note that the pin numbers for the main ISP signals (reset, sck, +# mosi, miso) are fixed and cannot be changed, since they must match +# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of +# these FTDI ICs has been designed. + +programmer + id = "avrftdi"; + desc = "FT2232D based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x6010; + usbvendor = ""; + usbproduct = ""; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ADBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +#LED SIGNALs - higher ADBUS-Nibble +# errled = 4; +# rdyled = 5; +# pgmled = 6; +# vfyled = 7; +#Buffer Signal - ACBUS - Nibble +# buff = 8; +; +# This is an implementation of the above with a buffer IC (74AC244) and +# 4 LEDs directly attached, all active low. +programmer + id = "2232HIO"; + desc = "FT2232H based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is reserved for generic H devices and +# should be programmed into the EEPROM +# usbpid = 0x8A48; + usbpid = 0x6010; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + reset = 3; + sck = 0; + mosi = 1; + miso = 2; + buff = ~4; +#LED SIGNALs + errled = ~ 11; + rdyled = ~ 14; + pgmled = ~ 13; + vfyled = ~ 12; +; + +#The FT4232H can be treated as FT2232H, but it has a different USB +#device ID of 0x6011. +programmer parent "avrftdi" + id = "4232h"; + desc = "FT4232H based generic programmer"; + usbpid = 0x6011; +; + +programmer parent "4232h" + id = "usbMultiToolV2spi"; + desc = "Avr MultiTool v2 SPI"; + usbdev = "B"; +; + +programmer + id = "usbMultiToolV2jtag"; + desc = "Avr MultiTool v2 JTAG"; + type = "avrftdi" ; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x6011; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; + reset = 3; # TMS 7 violet + sck = 0; # TCK 9 white + mosi = 1; # TDI 5 green + miso = 2; # TDO 13 orange + reset = 3; # TMS 7 violet +# TCK = 0; +# TDI = 1; +# TDO = 2; +# TMS = 3; +; + +programmer + id = "jtagkey"; + desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is used in all JTAGKey variants + usbpid = 0xCFF8; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals => 20 - Pin connector on JTAGKey + reset = 3; # TMS 7 violet + sck = 0; # TCK 9 white + mosi = 1; # TDI 5 green + miso = 2; # TDO 13 orange + buff = ~4; +# VTG VREF 1 brown with red tip +# GND GND 20 black +# The colors are on the 20 pin breakout cable +# from Amontec +; + +# UM232H module from FTDI and Glyn.com.au. +# See helix.air.net.au for detailed usage information. +# J1: Connect pin 2 and 3 for USB power. +# J2: Connect pin 2 and 3 for USB power. +# J2: Pin 7 is SCK +# : Pin 8 is MOSI +# : Pin 9 is MISO +# : Pin 11 is RST +# : Pin 6 is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "UM232H"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + +# C232HM module from FTDI and Glyn.com.au. +# : Orange is SCK +# : Yellow is MOSI +# : Green is MISO +# : Brown is RST +# : Black is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "C232HM"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + + +# On the adapter you can read "O-Link". On the PCB is printed " reset = 3; # TMS 7 violet +# You can find it as "OpenJTAG ARM JTAG USB" in the internet. +# (But there are also several projects called Open JTAG, eg. +# http://www.openjtag.org, which are completely different.) +# http://www.100ask.net/shop/english.html (website seems to be outdated) +# http://item.taobao.com/item.htm?id=1559277013 +# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!) +# some other sources which call it O-Link +# http://www.andahammer.com/olink/ +# http://www.developmentboard.net/31-o-link-debugger.html +# http://armwerks.com/catalog/o-link-debugger-copy/ +# or just have a look at ebay ... +# It is basically the same entry as jtagkey with different usb ids. +programmer parent "jtagkey" + id = "o-link"; + desc = "O-Link, OpenJTAG from www.100ask.net"; + usbvid = 0x1457; + usbpid = 0x5118; + usbvendor = "www.100ask.net"; + usbproduct = "USB<=>JTAG&RS232"; +; + +# http://wiki.openmoko.org/wiki/Debug_Board_v3 +programmer + id = "openmoko"; + desc = "Openmoko debug board (v3)"; + type = "avrftdi"; + usbvid = 0x1457; + usbpid = 0x5118; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; + reset = 3; # TMS 7 + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 +; + +# Only Rev. A boards. +# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf +programmer + id = "lm3s811"; + desc = "Luminary Micro LM3S811 Eval Board (Rev. A)"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0xbcd9; + usbvendor = "LMI"; + usbproduct = "LM3S811 Evaluation Board"; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ACBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +# Enable correct buffers + buff = 7; +; + +# submitted as bug #46020 +programmer + id = "tumpa"; + desc = "TIAO USB Multi-Protocol Adapter"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x8A98; + usbdev = "A"; + usbvendor = "TIAO"; + usbproduct = ""; + usbsn = ""; + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 + reset = 3; # TMS 7 +; + +programmer + id = "avrisp"; + desc = "Atmel AVR ISP"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "avrispv2"; + desc = "Atmel AVR ISP V2"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "avrispmkII"; + desc = "Atmel AVR ISP mkII"; + type = "stk500v2"; + connection_type = usb; +; + +programmer parent "avrispmkII" + id = "avrisp2"; +; + +programmer + id = "buspirate"; + desc = "The Bus Pirate"; + type = "buspirate"; + connection_type = serial; +; + +programmer + id = "buspirate_bb"; + desc = "The Bus Pirate (bitbang interface, supports TPI)"; + type = "buspirate_bb"; + connection_type = serial; + # pins are bits in bitbang byte (numbers are 87654321) + # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS + reset = 1; + sck = 3; + mosi = 4; + miso = 2; + #vcc = 7; This is internally set independent of this setting. +; + +# This is supposed to be the "default" STK500 entry. +# Attempts to select the correct firmware version +# by probing for it. Better use one of the entries +# below instead. +programmer + id = "stk500"; + desc = "Atmel STK500"; + type = "stk500generic"; + connection_type = serial; +; + +programmer + id = "stk500v1"; + desc = "Atmel STK500 Version 1.x firmware"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "mib510"; + desc = "Crossbow MIB510 programming board"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "stk500v2"; + desc = "Atmel STK500 Version 2.x firmware"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "stk500pp"; + desc = "Atmel STK500 V2 in parallel programming mode"; + type = "stk500pp"; + connection_type = serial; +; + +programmer + id = "stk500hvsp"; + desc = "Atmel STK500 V2 in high-voltage serial programming mode"; + type = "stk500hvsp"; + connection_type = serial; +; + +programmer + id = "stk600"; + desc = "Atmel STK600"; + type = "stk600"; + connection_type = usb; +; + +programmer + id = "stk600pp"; + desc = "Atmel STK600 in parallel programming mode"; + type = "stk600pp"; + connection_type = usb; +; + +programmer + id = "stk600hvsp"; + desc = "Atmel STK600 in high-voltage serial programming mode"; + type = "stk600hvsp"; + connection_type = usb; +; + +programmer + id = "avr910"; + desc = "Atmel Low Cost Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "ft245r"; + desc = "FT245R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # D1 + sck = 0; # D0 + mosi = 2; # D2 + reset = 4; # D4 +; + +programmer + id = "ft232r"; + desc = "FT232R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # RxD + sck = 0; # TxD + mosi = 2; # RTS + reset = 4; # DTR +; + +# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega +programmer + id = "bwmega"; + desc = "BitWizard ftdi_atmega builtin programmer"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 5; # DSR + sck = 6; # DCD + mosi = 3; # CTS + reset = 7; # RI +; + +# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html +# Note: pins are numbered from 1! +programmer + id = "arduino-ft232r"; + desc = "Arduino: FT232R connected to ISP"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # CTS X3(1) + sck = 5; # DSR X3(2) + mosi = 6; # DCD X3(3) + reset = 7; # RI X3(4) +; + +# website mentioned above uses this id +programmer parent "arduino-ft232r" + id = "diecimila"; + desc = "alias for arduino-ft232r"; +; + +# There is a ATmega328P kit PCB called "uncompatino". +# This board allows ISP via its on-board FT232R. +# This is designed like Arduino Duemilanove but has no standard ICPS header. +# Its 4 pairs of pins are shorted to enable ftdi_syncbb. +# http://akizukidenshi.com/catalog/g/gP-07487/ +# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf +programmer + id = "uncompatino"; + desc = "uncompatino with all pairs of pins shorted"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # cts + sck = 5; # dsr + mosi = 6; # dcd + reset = 7; # ri +; + +# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP +# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm +# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf +# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf +# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...) +# TTL-232R GND 1 Black -> ICPS GND (pin 6) +# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4) +# TTL-232R VCC 3 Red -> ICPS VCC (pin 2) +# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5) +# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3) +# TTL-232R RTS 6 Green -> ICPS MISO (pin 1) +# Except for VCC and GND, you can connect arbitual pairs as long as +# the following table is adjusted. +programmer + id = "ttl232r"; + desc = "FTDI TTL232R-5V with ICSP adapter"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 2; # rts + sck = 1; # rxd + mosi = 3; # cts + reset = 0; # txd +; + +programmer + id = "usbasp"; + desc = "USBasp, http://www.fischl.de/usbasp/"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + usbvendor = "www.fischl.de"; + usbproduct = "USBasp"; + + # following variants are autodetected for id "usbasp" + + # original usbasp from fischl.de + # see above "usbasp" + + # old usbasp from fischl.de + #usbvid = 0x03EB; # ATMEL + #usbpid = 0xC7B4; # (unoffical) USBasp + #usbvendor = "www.fischl.de"; + #usbproduct = "USBasp"; + + # NIBObee (only if -P nibobee is given on command line) + # see below "nibobee" +; + +programmer + id = "nibobee"; + desc = "NIBObee"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x092F; # NIBObee PID + usbvendor = "www.nicai-systems.com"; + usbproduct = "NIBObee"; +; + +programmer + id = "usbasp-clone"; + desc = "Any usbasp clone with correct VID/PID"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + #usbvendor = ""; + #usbproduct = ""; +; + +programmer + id = "usbtiny"; + desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + type = "usbtiny"; + connection_type = usb; + usbvid = 0x1781; + usbpid = 0x0c9f; +; + +programmer + id = "butterfly"; + desc = "Atmel Butterfly Development Board"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr911"; + desc = "Atmel AppNote AVR911 AVROSP"; + type = "butterfly"; + connection_type = serial; +; + +# suggested in http://forum.mikrokopter.de/topic-post48317.html +programmer + id = "mkbutterfly"; + desc = "Mikrokopter.de Butterfly"; + type = "butterfly_mk"; + connection_type = serial; +; + +programmer parent "mkbutterfly" + id = "butterfly_mk"; +; + +programmer + id = "jtagmkI"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 115200; # default is 115200 + type = "jtagmki"; + connection_type = serial; +; + +# easier to type +programmer parent "jtagmkI" + id = "jtag1"; +; + +# easier to type +programmer parent "jtag1" + id = "jtag1slow"; + baudrate = 19200; +; + +# The JTAG ICE mkII has both, serial and USB connectivity. As it is +# mostly used through USB these days (AVR Studio 5 only supporting it +# that way), we make connection_type = usb the default. Users are +# still free to use a serial port with the -P option. + +programmer + id = "jtagmkII"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 19200; # default is 19200 + type = "jtagmkii"; + connection_type = usb; +; + +# easier to type +programmer parent "jtagmkII" + id = "jtag2slow"; +; + +# JTAG ICE mkII @ 115200 Bd +programmer parent "jtag2slow" + id = "jtag2fast"; + baudrate = 115200; +; + +# make the fast one the default, people will love that +programmer parent "jtag2fast" + id = "jtag2"; +; + +# JTAG ICE mkII in ISP mode +programmer + id = "jtag2isp"; + desc = "Atmel JTAG ICE mkII in ISP mode"; + baudrate = 115200; + type = "jtagmkii_isp"; + connection_type = usb; +; + +# JTAG ICE mkII in debugWire mode +programmer + id = "jtag2dw"; + desc = "Atmel JTAG ICE mkII in debugWire mode"; + baudrate = 115200; + type = "jtagmkii_dw"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtagmkII_avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtag2avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in PDI mode +programmer + id = "jtag2pdi"; + desc = "Atmel JTAG ICE mkII PDI mode"; + baudrate = 115200; + type = "jtagmkii_pdi"; + connection_type = usb; +; + +# AVR Dragon in JTAG mode +programmer + id = "dragon_jtag"; + desc = "Atmel AVR Dragon in JTAG mode"; + baudrate = 115200; + type = "dragon_jtag"; + connection_type = usb; +; + +# AVR Dragon in ISP mode +programmer + id = "dragon_isp"; + desc = "Atmel AVR Dragon in ISP mode"; + baudrate = 115200; + type = "dragon_isp"; + connection_type = usb; +; + +# AVR Dragon in PP mode +programmer + id = "dragon_pp"; + desc = "Atmel AVR Dragon in PP mode"; + baudrate = 115200; + type = "dragon_pp"; + connection_type = usb; +; + +# AVR Dragon in HVSP mode +programmer + id = "dragon_hvsp"; + desc = "Atmel AVR Dragon in HVSP mode"; + baudrate = 115200; + type = "dragon_hvsp"; + connection_type = usb; +; + +# AVR Dragon in debugWire mode +programmer + id = "dragon_dw"; + desc = "Atmel AVR Dragon in debugWire mode"; + baudrate = 115200; + type = "dragon_dw"; + connection_type = usb; +; + +# AVR Dragon in PDI mode +programmer + id = "dragon_pdi"; + desc = "Atmel AVR Dragon in PDI mode"; + baudrate = 115200; + type = "dragon_pdi"; + connection_type = usb; +; + +programmer + id = "jtag3"; + desc = "Atmel AVR JTAGICE3 in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3pdi"; + desc = "Atmel AVR JTAGICE3 in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3dw"; + desc = "Atmel AVR JTAGICE3 in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3isp"; + desc = "Atmel AVR JTAGICE3 in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "xplainedpro"; + desc = "Atmel AVR XplainedPro in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2111; +; + +programmer + id = "atmelice"; + desc = "Atmel-ICE (ARM/AVR) in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_pdi"; + desc = "Atmel-ICE (ARM/AVR) in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_dw"; + desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_isp"; + desc = "Atmel-ICE (ARM/AVR) in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2141; +; + + +programmer + id = "pavr"; + desc = "Jason Kyle's pAVR Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "pickit2"; + desc = "MicroChip's PICkit2 Programmer"; + type = "pickit2"; + connection_type = usb; +; + +programmer + id = "flip1"; + desc = "FLIP USB DFU protocol version 1 (doc7618)"; + type = "flip1"; + connection_type = usb; +; + +programmer + id = "flip2"; + desc = "FLIP USB DFU protocol version 2 (AVR4023)"; + type = "flip2"; + connection_type = usb; +; + +# Parallel port programmers. + +programmer + id = "bsd"; + desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; +; + +programmer + id = "stk200"; + desc = "STK200"; + type = "par"; + connection_type = parallel; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; +; + +# The programming dongle used by the popular Ponyprog +# utility. It is almost similar to the STK200 one, +# except that there is a LED indicating that the +# programming is currently in progress. + +programmer parent "stk200" + id = "pony-stk200"; + desc = "Pony Prog STK200"; + pgmled = 8; +; + +programmer + id = "dt006"; + desc = "Dontronics DT006"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer parent "dt006" + id = "bascom"; + desc = "Bascom SAMPLE programming cable"; +; + +programmer + id = "alf"; + desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + buff = 6; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; + errled = 1; + rdyled = 14; + pgmled = 16; + vfyled = 17; +; + +programmer + id = "sp12"; + desc = "Steve Bolt's Programmer"; + type = "par"; + connection_type = parallel; + vcc = 4,5,6,7,8; + reset = 3; + sck = 2; + mosi = 9; + miso = 11; +; + +programmer + id = "picoweb"; + desc = "Picoweb Programming Cable, http://www.picoweb.net/"; + type = "par"; + connection_type = parallel; + reset = 2; + sck = 3; + mosi = 4; + miso = 13; +; + +programmer + id = "abcmini"; + desc = "ABCmini Board, aka Dick Smith HOTCHIP"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "futurlec"; + desc = "Futurlec.com programming cable."; + type = "par"; + connection_type = parallel; + reset = 3; + sck = 2; + mosi = 1; + miso = 10; +; + + +# From the contributor of the "xil" jtag cable: +# The "vcc" definition isn't really vcc (the cable gets its power from +# the programming circuit) but is necessary to switch one of the +# buffer lines (trying to add it to the "buff" lines doesn't work in +# avrdude versions before 5.5j). +# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK +# to SCK (plus vcc/gnd of course) +programmer + id = "xil"; + desc = "Xilinx JTAG cable"; + type = "par"; + connection_type = parallel; + mosi = 2; + sck = 3; + reset = 4; + buff = 5; + miso = 13; + vcc = 6; +; + + +programmer + id = "dapa"; + desc = "Direct AVR Parallel Access cable"; + type = "par"; + connection_type = parallel; + vcc = 3; + reset = 16; + sck = 1; + mosi = 2; + miso = 11; +; + +programmer + id = "atisp"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + type = "par"; + connection_type = parallel; + reset = ~6; + sck = ~8; + mosi = ~7; + miso = ~10; +; + +programmer + id = "ere-isp-avr"; + desc = "ERE ISP-AVR "; + type = "par"; + connection_type = parallel; + reset = ~4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "blaster"; + desc = "Altera ByteBlaster"; + type = "par"; + connection_type = parallel; + sck = 2; + miso = 11; + reset = 3; + mosi = 8; + buff = 14; +; + +# It is almost same as pony-stk200, except vcc on pin 5 to auto +# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27) +programmer parent "pony-stk200" + id = "frank-stk200"; + desc = "Frank STK200"; + buff = ; # delete buff pin assignment + vcc = 5; +; + +# The AT98ISP Cable is a simple parallel dongle for AT89 family. +# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +programmer + id = "89isp"; + desc = "Atmel at89isp cable"; + type = "par"; + connection_type = parallel; + reset = 17; + sck = 1; + mosi = 2; + miso = 10; +; + + +#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface +# +#To enable it set the configuration below to match the GPIO lines connected to the +#relevant ISP header pins and uncomment the entry definition. In case you don't +#have the required permissions to edit this system wide config file put the +#entry in a separate .conf file and use it with -C+.conf +#on the command line. +# +#To check if your avrdude build has support for the linuxgpio programmer compiled in, +#use -c?type on the command line and look for linuxgpio in the list. If it's not available +#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude. +# +#programmer +# id = "linuxgpio"; +# desc = "Use the Linux sysfs interface to bitbang GPIO lines"; +# type = "linuxgpio"; +# reset = ?; +# sck = ?; +# mosi = ?; +# miso = ?; +#; + +# some ultra cheap programmers use bitbanging on the +# serialport. +# +# PC - DB9 - Pins for RS232: +# +# GND 5 -- |O +# | O| <- 9 RI +# DTR 4 <- |O | +# | O| <- 8 CTS +# TXD 3 <- |O | +# | O| -> 7 RTS +# RXD 2 -> |O | +# | O| <- 6 DSR +# DCD 1 -> |O +# +# Using RXD is currently not supported. +# Using RI is not supported under Win32 but is supported under Posix. + +# serial ponyprog design (dasa2 in uisp) +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer + id = "ponyser"; + desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~3; + sck = 7; + mosi = 4; + miso = 8; +; + +# Same as above, different name +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer parent "ponyser" + id = "siprog"; + desc = "Lancos SI-Prog "; +; + +# unknown (dasa in uisp) +# reset=rts sck=dtr mosi=txd miso=cts + +programmer + id = "dasa"; + desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = 7; + sck = 4; + mosi = 3; + miso = 8; +; + +# unknown (dasa3 in uisp) +# reset=!dtr sck=rts mosi=txd miso=cts + +programmer + id = "dasa3"; + desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~4; + sck = 7; + mosi = 3; + miso = 8; +; + +# C2N232i (jumper configuration "auto") +# reset=dtr sck=!rts mosi=!txd miso=!cts + +programmer + id = "c2n232i"; + desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts"; + type = "serbb"; + connection_type = serial; + reset = 4; + sck = ~7; + mosi = ~3; + miso = ~8; +; + +# +# PART DEFINITIONS +# + +#------------------------------------------------------------ +# ATtiny11 +#------------------------------------------------------------ + +# This is an HVSP-only device. + +part + id = "t11"; + desc = "ATtiny11"; + stk500_devcode = 0x11; + signature = 0x1e 0x90 0x04; + chip_erase_delay = 20000; + + timeout = 200; + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + blocksize = 64; + readsize = 256; + delay = 5; + ; + + memory "flash" + size = 1024; + blocksize = 128; + readsize = 256; + delay = 3; + ; + + memory "signature" + size = 3; + ; + + memory "lock" + size = 1; + ; + + memory "calibration" + size = 1; + ; + + memory "fuse" + size = 1; + ; +; + +#------------------------------------------------------------ +# ATtiny12 +#------------------------------------------------------------ + +part + id = "t12"; + desc = "ATtiny12"; + stk500_devcode = 0x12; + avr910_devcode = 0x55; + signature = 0x1e 0x90 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 8; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4500; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# ATtiny13 +#------------------------------------------------------------ + +part + id = "t13"; + desc = "ATtiny13"; + has_debugwire = yes; + flash_instr = 0xB4, 0x0E, 0x1E; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; + signature = 0x1e 0x90 0x07; + chip_erase_delay = 4000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 90; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 0; + + memory "eeprom" + size = 64; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 1024; + page_size = 32; + num_pages = 32; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny15 +#------------------------------------------------------------ + +part + id = "t15"; + desc = "ATtiny15"; + stk500_devcode = 0x13; + avr910_devcode = 0x56; + signature = 0x1e 0x90 0x06; + chip_erase_delay = 8200; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 5; + synchcycles = 6; + latchcycles = 16; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 8200; + max_write_delay = 8200; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4100; + max_write_delay = 4100; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o x x o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i 1 1 i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# AT90s1200 +#------------------------------------------------------------ + +part + id = "1200"; + desc = "AT90S1200"; + is_at90s1200 = yes; + stk500_devcode = 0x33; + avr910_devcode = 0x13; + signature = 0x1e 0x90 0x01; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 1; + bytedelay = 0; + pollindex = 0; + pollvalue = 0xFF; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 32; + readsize = 256; + ; + memory "flash" + size = 1024; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x02; + delay = 15; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4414 +#------------------------------------------------------------ + +part + id = "4414"; + desc = "AT90S4414"; + stk500_devcode = 0x50; + avr910_devcode = 0x28; + signature = 0x1e 0x92 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2313 +#------------------------------------------------------------ + +part + id = "2313"; + desc = "AT90S2313"; + stk500_devcode = 0x40; + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2333 +#------------------------------------------------------------ + +part + id = "2333"; +##### WARNING: No XML file for device 'AT90S2333'! ##### + desc = "AT90S2333"; + stk500_devcode = 0x42; + avr910_devcode = 0x34; + signature = 0x1e 0x91 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s2343 (also AT90s2323 and ATtiny22) +#------------------------------------------------------------ + +part + id = "2343"; + desc = "AT90S2343"; + stk500_devcode = 0x43; + avr910_devcode = 0x4c; + signature = 0x1e 0x91 0x03; + chip_erase_delay = 18000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 0; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 128; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s4433 +#------------------------------------------------------------ + +part + id = "4433"; + desc = "AT90S4433"; + stk500_devcode = 0x51; + avr910_devcode = 0x30; + signature = 0x1e 0x92 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4434 +#------------------------------------------------------------ + +part + id = "4434"; +##### WARNING: No XML file for device 'AT90S4434'! ##### + desc = "AT90S4434"; + stk500_devcode = 0x52; + avr910_devcode = 0x6c; + signature = 0x1e 0x92 0x02; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8515 +#------------------------------------------------------------ + +part + id = "8515"; + desc = "AT90S8515"; + stk500_devcode = 0x60; + avr910_devcode = 0x38; + signature = 0x1e 0x93 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s8535 +#------------------------------------------------------------ + +part + id = "8535"; + desc = "AT90S8535"; + stk500_devcode = 0x61; + avr910_devcode = 0x68; + signature = 0x1e 0x93 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# ATmega103 +#------------------------------------------------------------ + +part + id = "m103"; + desc = "ATmega103"; + stk500_devcode = 0xB1; + avr910_devcode = 0x41; + signature = 0x1e 0x97 0x01; + chip_erase_delay = 112000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE, + 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE, + 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A, + 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 10; + + memory "eeprom" + size = 4096; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 22000; + max_write_delay = 56000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 70; + blocksize = 256; + readsize = 256; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o x o 1 o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega64 +#------------------------------------------------------------ + +part + id = "m64"; + desc = "ATmega64"; + has_jtag = yes; + stk500_devcode = 0xA0; + avr910_devcode = 0x45; + signature = 0x1e 0x96 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega128 +#------------------------------------------------------------ + +part + id = "m128"; + desc = "ATmega128"; + has_jtag = yes; + stk500_devcode = 0xB2; + avr910_devcode = 0x43; + signature = 0x1e 0x97 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + rampz = 0x3b; + allowfullpagebitstream = yes; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN128 +#------------------------------------------------------------ + +part + id = "c128"; + desc = "AT90CAN128"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x97 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN64 +#------------------------------------------------------------ + +part + id = "c64"; + desc = "AT90CAN64"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x96 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN32 +#------------------------------------------------------------ + +part + id = "c32"; + desc = "AT90CAN32"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x95 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 256; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega16 +#------------------------------------------------------------ + +part + id = "m16"; + desc = "ATmega16"; + has_jtag = yes; + stk500_devcode = 0x82; + avr910_devcode = 0x74; + signature = 0x1e 0x94 0x03; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 100; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "calibration" + size = 4; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega164P +#------------------------------------------------------------ + +# close to ATmega16 + +part parent "m16" + id = "m164p"; + desc = "ATmega164P"; + signature = 0x1e 0x94 0x0a; + + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + allowfullpagebitstream = no; + chip_erase_delay = 55000; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega324P +#------------------------------------------------------------ + +# similar to ATmega164P + +part + id = "m324p"; + desc = "ATmega324P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x95 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega324PA +#------------------------------------------------------------ + +# similar to ATmega324P + +part parent "m324p" + id = "m324pa"; + desc = "ATmega324PA"; + signature = 0x1e 0x95 0x11; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega644 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m644"; + desc = "ATmega644"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x96 0x09; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega644P +#------------------------------------------------------------ + +# similar to ATmega164p + +part parent "m644" + id = "m644p"; + desc = "ATmega644P"; + signature = 0x1e 0x96 0x0a; + + ocdrev = 3; + ; + + + +#------------------------------------------------------------ +# ATmega1284 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m1284"; + desc = "ATmega1284"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x06; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega1284P +#------------------------------------------------------------ + +# similar to ATmega164p + +part + id = "m1284p"; + desc = "ATmega1284P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x05; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega162 +#------------------------------------------------------------ + +part + id = "m162"; + desc = "ATmega162"; + has_jtag = yes; + stk500_devcode = 0x83; + avr910_devcode = 0x63; + signature = 0x1e 0x94 0x04; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + + idr = 0x04; + spmcr = 0x57; + allowfullpagebitstream = yes; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + ocdrev = 2; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + + ; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; +; + + + +#------------------------------------------------------------ +# ATmega163 +#------------------------------------------------------------ + +part + id = "m163"; + desc = "ATmega163"; + stk500_devcode = 0x81; + avr910_devcode = 0x64; + signature = 0x1e 0x94 0x02; + chip_erase_delay = 32000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 16000; + max_write_delay = 16000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 20; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o x x o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i 1 1 i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x 1 o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x 0 x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega169 +#------------------------------------------------------------ + +part + id = "m169"; + desc = "ATmega169"; + has_jtag = yes; + stk500_devcode = 0x85; + avr910_devcode = 0x78; + signature = 0x1e 0x94 0x05; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329 +#------------------------------------------------------------ + +part + id = "m329"; + desc = "ATmega329"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329P +#------------------------------------------------------------ +# Identical to ATmega329 except of the signature + +part parent "m329" + id = "m329p"; + desc = "ATmega329P"; + signature = 0x1e 0x95 0x0b; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290 +#------------------------------------------------------------ + +# identical to ATmega329 + +part parent "m329" + id = "m3290"; + desc = "ATmega3290"; + signature = 0x1e 0x95 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290P +#------------------------------------------------------------ + +# identical to ATmega3290 except of the signature + +part parent "m3290" + id = "m3290p"; + desc = "ATmega3290P"; + signature = 0x1e 0x95 0x0c; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega649 +#------------------------------------------------------------ + +part + id = "m649"; + desc = "ATmega649"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x96 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega6490 +#------------------------------------------------------------ + +# identical to ATmega649 + +part parent "m649" + id = "m6490"; + desc = "ATmega6490"; + signature = 0x1e 0x96 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega32 +#------------------------------------------------------------ + +part + id = "m32"; + desc = "ATmega32"; + has_jtag = yes; + stk500_devcode = 0x91; + avr910_devcode = 0x72; + signature = 0x1e 0x95 0x02; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega161 +#------------------------------------------------------------ + +part + id = "m161"; + desc = "ATmega161"; + stk500_devcode = 0x80; + avr910_devcode = 0x60; + signature = 0x1e 0x94 0x01; + chip_erase_delay = 28000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + memory "eeprom" + size = 512; + min_write_delay = 3400; + max_write_delay = 3400; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 14000; + max_write_delay = 14000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 16; + blocksize = 128; + readsize = 256; + ; + + memory "fuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x o x o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x 1 i 1 i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega8 +#------------------------------------------------------------ + +part + id = "m8"; + desc = "ATmega8"; + stk500_devcode = 0x70; + avr910_devcode = 0x76; + signature = 0x1e 0x93 0x07; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 10000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + page_size = 4; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega8515 +#------------------------------------------------------------ + +part + id = "m8515"; + desc = "ATmega8515"; + stk500_devcode = 0x63; + avr910_devcode = 0x3A; + signature = 0x1e 0x93 0x06; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega8535 +#------------------------------------------------------------ + +part + id = "m8535"; + desc = "ATmega8535"; + stk500_devcode = 0x64; + avr910_devcode = 0x69; + signature = 0x1e 0x93 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny26 +#------------------------------------------------------------ + +part + id = "t26"; + desc = "ATtiny26"; + stk500_devcode = 0x21; + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x09; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 16; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x x x x i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny261 +#------------------------------------------------------------ +# Close to ATtiny26 + +part + id = "t261"; + desc = "ATtiny261"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0c; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 128; + page_size = 4; + num_pages = 32; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny461 +#------------------------------------------------------------ +# Close to ATtiny261 + +part + id = "t461"; + desc = "ATtiny461"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x08; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 256; + page_size = 4; + num_pages = 64; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny861 +#------------------------------------------------------------ +# Close to ATtiny461 + +part + id = "t861"; + desc = "ATtiny861"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x93 0x0d; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 512; + num_pages = 128; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATmega48 +#------------------------------------------------------------ + +part + id = "m48"; + desc = "ATmega48"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x59; +# avr910_devcode = 0x; + signature = 0x1e 0x92 0x05; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 45000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega48P +#------------------------------------------------------------ + +part parent "m48" + id = "m48p"; + desc = "ATmega48P"; + signature = 0x1e 0x92 0x0a; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega88 +#------------------------------------------------------------ + +part + id = "m88"; + desc = "ATmega88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x0a; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega88P +#------------------------------------------------------------ + +part parent "m88" + id = "m88p"; + desc = "ATmega88P"; + signature = 0x1e 0x93 0x0f; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega168 +#------------------------------------------------------------ + +part + id = "m168"; + desc = "ATmega168"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x06; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega168P +#------------------------------------------------------------ + +part parent "m168" + id = "m168p"; + desc = "ATmega168P"; + signature = 0x1e 0x94 0x0b; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATtiny88 +#------------------------------------------------------------ + +part + id = "t88"; + desc = "ATtiny88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x11; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 64; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 64; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega328 +#------------------------------------------------------------ + +part + id = "m328"; + desc = "ATmega328"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x14; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 1024; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +part parent "m328" + id = "m328p"; + desc = "ATmega328P"; + signature = 0x1e 0x95 0x0F; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATmega32m1 +#------------------------------------------------------------ + +part parent "m328" + id = "m32m1"; + desc = "ATmega32M1"; + # stk500_devcode = 0x; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x84; + bs2 = 0xe2; + + memory "efuse" + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x i i i i i i"; + ; +; + +#------------------------------------------------------------ +# ATtiny2313 +#------------------------------------------------------------ + +part + id = "t2313"; + desc = "ATtiny2313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0a; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +# The Tiny2313 has calibration data for both 4 MHz and 8 MHz. +# The information in the data sheet of April/2004 is wrong, this works: + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny4313 +#------------------------------------------------------------ + +part + id = "t4313"; + desc = "ATtiny4313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x0d; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM2 +#------------------------------------------------------------ + +part + id = "pwm2"; + desc = "AT90PWM2"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x81; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; +# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM3 +#------------------------------------------------------------ + +# Completely identical to AT90PWM2 (including the signature!) + +part parent "pwm2" + id = "pwm3"; + desc = "AT90PWM3"; + ; + +#------------------------------------------------------------ +# AT90PWM2B +#------------------------------------------------------------ +# Same as AT90PWM2 but different signature. + +part parent "pwm2" + id = "pwm2b"; + desc = "AT90PWM2B"; + signature = 0x1e 0x93 0x83; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM3B +#------------------------------------------------------------ + +# Completely identical to AT90PWM2B (including the signature!) + +part parent "pwm2b" + id = "pwm3b"; + desc = "AT90PWM3B"; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM316 +#------------------------------------------------------------ + +# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM. + +part parent "pwm3b" + id = "pwm316"; + desc = "AT90PWM316"; + signature = 0x1e 0x94 0x83; + + ocdrev = 1; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# AT90PWM216 +#------------------------------------------------------------ +# Completely identical to AT90PWM316 (including the signature!) + +part parent "pwm316" + id = "pwm216"; + desc = "AT90PWM216"; + ; + +#------------------------------------------------------------ +# ATtiny25 +#------------------------------------------------------------ + +part + id = "t25"; + desc = "ATtiny25"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x08; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny45 +#------------------------------------------------------------ + +part + id = "t45"; + desc = "ATtiny45"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x06; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!) + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny85 +#------------------------------------------------------------ + +part + id = "t85"; + desc = "ATtiny85"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega640 +#------------------------------------------------------------ +# Almost same as ATmega1280, except for different memory sizes + +part + id = "m640"; + desc = "ATmega640"; + signature = 0x1e 0x96 0x08; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1280 +#------------------------------------------------------------ + +part + id = "m1280"; + desc = "ATmega1280"; + signature = 0x1e 0x97 0x03; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1281 +#------------------------------------------------------------ +# Identical to ATmega1280 + +part parent "m1280" + id = "m1281"; + desc = "ATmega1281"; + signature = 0x1e 0x97 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega2560 +#------------------------------------------------------------ + +part + id = "m2560"; + desc = "ATmega2560"; + signature = 0x1e 0x98 0x01; + has_jtag = yes; + stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 4; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega2561 +#------------------------------------------------------------ + +part parent "m2560" + id = "m2561"; + desc = "ATmega2561"; + signature = 0x1e 0x98 0x02; + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFA1 +#------------------------------------------------------------ +# Identical to ATmega2561 but half the ROM + +part parent "m2561" + id = "m128rfa1"; + desc = "ATmega128RFA1"; + signature = 0x1e 0xa7 0x01; + chip_erase_delay = 55000; + bs2 = 0xE2; + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# ATmega256RFR2 +#------------------------------------------------------------ + +part parent "m2561" + id = "m256rfr2"; + desc = "ATmega256RFR2"; + signature = 0x1e 0xa8 0x02; + chip_erase_delay = 18500; + bs2 = 0xE2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 8192; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m128rfr2"; + desc = "ATmega128RFR2"; + signature = 0x1e 0xa7 0x02; + + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega64RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m64rfr2"; + desc = "ATmega64RFR2"; + signature = 0x1e 0xa6 0x02; + + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ; + +#------------------------------------------------------------ +# ATmega2564RFR2 +#------------------------------------------------------------ + +part parent "m256rfr2" + id = "m2564rfr2"; + desc = "ATmega2564RFR2"; + signature = 0x1e 0xa8 0x03; + ; + +#------------------------------------------------------------ +# ATmega1284RFR2 +#------------------------------------------------------------ + +part parent "m128rfr2" + id = "m1284rfr2"; + desc = "ATmega1284RFR2"; + signature = 0x1e 0xa7 0x03; + ; + +#------------------------------------------------------------ +# ATmega644RFR2 +#------------------------------------------------------------ + +part parent "m64rfr2" + id = "m644rfr2"; + desc = "ATmega644RFR2"; + signature = 0x1e 0xa6 0x03; + ; + +#------------------------------------------------------------ +# ATtiny24 +#------------------------------------------------------------ + +part + id = "t24"; + desc = "ATtiny24"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny44 +#------------------------------------------------------------ + +part + id = "t44"; + desc = "ATtiny44"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x07; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny84 +#------------------------------------------------------------ + +part + id = "t84"; + desc = "ATtiny84"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0c; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny43U +#------------------------------------------------------------ + +part + id = "t43u"; + desc = "ATtiny43u"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x0C; + reset = io; + chip_erase_delay = 1000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E, + 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56, + 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 20; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + memory "eeprom" + size = 64; + paged = yes; + page_size = 4; + num_pages = 16; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " 0 0 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega32u4 +#------------------------------------------------------------ + +part + id = "m32u4"; + desc = "ATmega32U4"; + signature = 0x1e 0x95 0x87; + usbpid = 0x2ff4; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB646 +#------------------------------------------------------------ + +part + id = "usb646"; + desc = "AT90USB646"; + signature = 0x1e 0x96 0x82; + usbpid = 0x2ff9; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB647 +#------------------------------------------------------------ +# identical to AT90USB646 + +part parent "usb646" + id = "usb647"; + desc = "AT90USB647"; + signature = 0x1e 0x96 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB1286 +#------------------------------------------------------------ + +part + id = "usb1286"; + desc = "AT90USB1286"; + signature = 0x1e 0x97 0x82; + usbpid = 0x2ffb; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB1287 +#------------------------------------------------------------ +# identical to AT90USB1286 + +part parent "usb1286" + id = "usb1287"; + desc = "AT90USB1287"; + signature = 0x1e 0x97 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB162 +#------------------------------------------------------------ + +part + id = "usb162"; + desc = "AT90USB162"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x82; + usbpid = 0x2ffa; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB82 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 8192; +# num_pages = 64; + +part + id = "usb82"; + desc = "AT90USB82"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x82; + usbpid = 0x2ff7; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32U2 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 32768; +# num_pages = 256; +# memory "eeprom" +# size = 1024; +# num_pages = 256; +part + id = "m32u2"; + desc = "ATmega32U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x95 0x8a; + usbpid = 0x2ff0; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + num_pages = 256; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega16U2 +#------------------------------------------------------------ +# Changes against ATmega32U2 (beside IDs) +# memory "flash" +# size = 16384; +# num_pages = 128; +# memory "eeprom" +# size = 512; +# num_pages = 128; +part + id = "m16u2"; + desc = "ATmega16U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x89; + usbpid = 0x2fef; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega8U2 +#------------------------------------------------------------ +# Changes against ATmega16U2 (beside IDs) +# memory "flash" +# size = 8192; +# page_size = 64; +# blocksize = 64; + +part + id = "m8u2"; + desc = "ATmega8U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x89; + usbpid = 0x2fee; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega325 +#------------------------------------------------------------ + +part + id = "m325"; + desc = "ATmega325"; + signature = 0x1e 0x95 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega645 +#------------------------------------------------------------ + +part + id = "m645"; + desc = "ATmega645"; + signature = 0x1E 0x96 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3250 +#------------------------------------------------------------ + +part parent "m325" + id = "m3250"; + desc = "ATmega3250"; + signature = 0x1E 0x95 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega6450 +#------------------------------------------------------------ + +part parent "m645" + id = "m6450"; + desc = "ATmega6450"; + signature = 0x1E 0x96 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AVR XMEGA family common values +#------------------------------------------------------------ + +part + id = ".xmega"; + desc = "AVR XMEGA family common values"; + has_pdi = yes; + nvm_base = 0x01c0; + mcu_base = 0x0090; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "prodsig" + size = 0x32; + offset = 0x8e0200; + page_size = 0x32; + readsize = 0x32; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; + + memory "data" + # SRAM, only used to supply the offset + offset = 0x1000000; + ; +; + +#------------------------------------------------------------ +# ATxmega16A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16a4u"; + desc = "ATxmega16A4U"; + signature = 0x1e 0x94 0x41; + usbpid = 0x2fe3; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x803000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x804000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16C4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16c4"; + desc = "ATxmega16C4"; + signature = 0x1e 0x95 0x44; +; + +#------------------------------------------------------------ +# ATxmega16D4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16d4"; + desc = "ATxmega16D4"; + signature = 0x1e 0x94 0x42; +; + +#------------------------------------------------------------ +# ATxmega16A4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16a4"; + desc = "ATxmega16A4"; + signature = 0x1e 0x94 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega32A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32a4u"; + desc = "ATxmega32A4U"; + signature = 0x1e 0x95 0x41; + usbpid = 0x2fe4; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x807000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x808000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32C4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32c4"; + desc = "ATxmega32C4"; + signature = 0x1e 0x94 0x43; +; + +#------------------------------------------------------------ +# ATxmega32D4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32d4"; + desc = "ATxmega32D4"; + signature = 0x1e 0x95 0x42; +; + +#------------------------------------------------------------ +# ATxmega32A4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32a4"; + desc = "ATxmega32A4"; + signature = 0x1e 0x95 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x64a4u"; + desc = "ATxmega64A4U"; + signature = 0x1e 0x96 0x46; + usbpid = 0x2fe5; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x10000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x80f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x11000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega64C3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64c3"; + desc = "ATxmega64C3"; + signature = 0x1e 0x96 0x49; + usbpid = 0x2fd6; +; + +#------------------------------------------------------------ +# ATxmega64D3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d3"; + desc = "ATxmega64D3"; + signature = 0x1e 0x96 0x4a; +; + +#------------------------------------------------------------ +# ATxmega64D4 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d4"; + desc = "ATxmega64D4"; + signature = 0x1e 0x96 0x47; +; + +#------------------------------------------------------------ +# ATxmega64A1 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64a1"; + desc = "ATxmega64A1"; + signature = 0x1e 0x96 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A1U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a1u"; + desc = "ATxmega64A1U"; + signature = 0x1e 0x96 0x4e; + usbpid = 0x2fe8; +; + +#------------------------------------------------------------ +# ATxmega64A3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3"; + desc = "ATxmega64A3"; + signature = 0x1e 0x96 0x42; +; + +#------------------------------------------------------------ +# ATxmega64A3U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3u"; + desc = "ATxmega64A3U"; + signature = 0x1e 0x96 0x42; + usbpid = 0x2fe5; +; + +#------------------------------------------------------------ +# ATxmega64A4 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a4"; + desc = "ATxmega64A4"; + signature = 0x1e 0x96 0x46; +; + +#------------------------------------------------------------ +# ATxmega64B1 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b1"; + desc = "ATxmega64B1"; + signature = 0x1e 0x96 0x52; + usbpid = 0x2fe1; +; + +#------------------------------------------------------------ +# ATxmega64B3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b3"; + desc = "ATxmega64B3"; + signature = 0x1e 0x96 0x51; + usbpid = 0x2fdf; +; + +#------------------------------------------------------------ +# ATxmega128C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128c3"; + desc = "ATxmega128C3"; + signature = 0x1e 0x97 0x52; + usbpid = 0x2fd7; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128D3 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d3"; + desc = "ATxmega128D3"; + signature = 0x1e 0x97 0x48; +; + +#------------------------------------------------------------ +# ATxmega128D4 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d4"; + desc = "ATxmega128D4"; + signature = 0x1e 0x97 0x47; +; + +#------------------------------------------------------------ +# ATxmega128A1 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128a1"; + desc = "ATxmega128A1"; + signature = 0x1e 0x97 0x4c; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A1 revision D +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1d"; + desc = "ATxmega128A1revD"; + signature = 0x1e 0x97 0x41; +; + +#------------------------------------------------------------ +# ATxmega128A1U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1u"; + desc = "ATxmega128A1U"; + signature = 0x1e 0x97 0x4c; + usbpid = 0x2fed; +; + +#------------------------------------------------------------ +# ATxmega128A3 +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3"; + desc = "ATxmega128A3"; + signature = 0x1e 0x97 0x42; +; + +#------------------------------------------------------------ +# ATxmega128A3U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3u"; + desc = "ATxmega128A3U"; + signature = 0x1e 0x97 0x42; + usbpid = 0x2fe6; +; + +#------------------------------------------------------------ +# ATxmega128A4 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4"; + desc = "ATxmega128A4"; + signature = 0x1e 0x97 0x46; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4u"; + desc = "ATxmega128A4U"; + signature = 0x1e 0x97 0x46; + usbpid = 0x2fde; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128B1 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128b1"; + desc = "ATxmega128B1"; + signature = 0x1e 0x97 0x4d; + usbpid = 0x2fea; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128B3 +#------------------------------------------------------------ + +part parent "x128b1" + id = "x128b3"; + desc = "ATxmega128B3"; + signature = 0x1e 0x97 0x4b; + usbpid = 0x2fe0; +; + +#------------------------------------------------------------ +# ATxmega192C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x192c3"; + desc = "ATxmega192C3"; + signature = 0x1e 0x97 0x51; + # usbpid = 0x2f??; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x30000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x82e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x830000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x32000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega192D3 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192d3"; + desc = "ATxmega192D3"; + signature = 0x1e 0x97 0x49; +; + +#------------------------------------------------------------ +# ATxmega192A1 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192a1"; + desc = "ATxmega192A1"; + signature = 0x1e 0x97 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega192A3 +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3"; + desc = "ATxmega192A3"; + signature = 0x1e 0x97 0x44; +; + +#------------------------------------------------------------ +# ATxmega192A3U +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3u"; + desc = "ATxmega192A3U"; + signature = 0x1e 0x97 0x44; + usbpid = 0x2fe7; +; + +#------------------------------------------------------------ +# ATxmega256C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x256c3"; + desc = "ATxmega256C3"; + signature = 0x1e 0x98 0x46; + usbpid = 0x2fda; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x40000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x83e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x840000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x42000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega256D3 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256d3"; + desc = "ATxmega256D3"; + signature = 0x1e 0x98 0x44; +; + +#------------------------------------------------------------ +# ATxmega256A1 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256a1"; + desc = "ATxmega256A1"; + signature = 0x1e 0x98 0x46; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega256A3 +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3"; + desc = "ATxmega256A3"; + signature = 0x1e 0x98 0x42; +; + +#------------------------------------------------------------ +# ATxmega256A3U +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3u"; + desc = "ATxmega256A3U"; + signature = 0x1e 0x98 0x42; + usbpid = 0x2fec; +; + +#------------------------------------------------------------ +# ATxmega256A3B +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3b"; + desc = "ATxmega256A3B"; + signature = 0x1e 0x98 0x43; +; + +#------------------------------------------------------------ +# ATxmega256A3BU +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3bu"; + desc = "ATxmega256A3BU"; + signature = 0x1e 0x98 0x43; + usbpid = 0x2fe2; +; + +#------------------------------------------------------------ +# ATxmega384C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x384c3"; + desc = "ATxmega384C3"; + signature = 0x1e 0x98 0x45; + usbpid = 0x2fdb; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x60000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x85e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x860000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x62000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega384D3 +#------------------------------------------------------------ + +part parent "x384c3" + id = "x384d3"; + desc = "ATxmega384D3"; + signature = 0x1e 0x98 0x47; +; + +#------------------------------------------------------------ +# ATxmega8E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x8e5"; + desc = "ATxmega8E5"; + signature = 0x1e 0x93 0x41; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x2000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x800; + offset = 0x00801800; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x800; + offset = 0x00802000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x2800; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16e5"; + desc = "ATxmega16E5"; + signature = 0x1e 0x94 0x45; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00803000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00804000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32e5"; + desc = "ATxmega32E5"; + signature = 0x1e 0x95 0x4c; + + memory "eeprom" + size = 0x0400; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00807000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00808000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# AVR32UC3A0512 +#------------------------------------------------------------ + +part + id = "uc3a0512"; + desc = "AT32UC3A0512"; + signature = 0xED 0xC0 0x3F; + has_jtag = yes; + is_avr32 = yes; + + memory "flash" + paged = yes; + page_size = 512; # bytes + readsize = 512; # bytes + num_pages = 1024; # could be set dynamicly + size = 0x00080000; # could be set dynamicly + offset = 0x80000000; + ; +; + +part parent "uc3a0512" + id = "ucr2"; + desc = "deprecated, use 'uc3a0512'"; +; + +#------------------------------------------------------------ +# ATtiny1634. +#------------------------------------------------------------ + +part + id = "t1634"; + desc = "ATtiny1634"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x12; + pagel = 0xB3; + bs2 = 0xB1; + reset = io; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 32; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 1 1 1 1 i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# Common values for reduced core tinys (4/5/9/10/20/40) +#------------------------------------------------------------ + +part + id = ".reduced_core_tiny"; + desc = "Common values for reduced core tinys"; + has_tpi = yes; + + memory "signature" + size = 3; + offset = 0x3fc0; + page_size = 16; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + page_size = 16; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + page_size = 16; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + page_size = 16; + ; +; + +#------------------------------------------------------------ +# ATtiny4 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t4"; + desc = "ATtiny4"; + signature = 0x1e 0x8f 0x0a; + + memory "flash" + size = 512; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny5 +#------------------------------------------------------------ + +part parent "t4" + id = "t5"; + desc = "ATtiny5"; + signature = 0x1e 0x8f 0x09; +; + +#------------------------------------------------------------ +# ATtiny9 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t9"; + desc = "ATtiny9"; + signature = 0x1e 0x90 0x08; + + memory "flash" + size = 1024; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny10 +#------------------------------------------------------------ + +part parent "t9" + id = "t10"; + desc = "ATtiny10"; + signature = 0x1e 0x90 0x03; +; + +#------------------------------------------------------------ +# ATtiny20 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t20"; + desc = "ATtiny20"; + signature = 0x1e 0x91 0x0F; + + memory "flash" + size = 2048; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny40 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t40"; + desc = "ATtiny40"; + signature = 0x1e 0x92 0x0E; + + memory "flash" + size = 4096; + offset = 0x4000; + page_size = 64; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATmega406 +#------------------------------------------------------------ + +part + id = "m406"; + desc = "ATMEGA406"; + has_jtag = yes; + signature = 0x1e 0x95 0x07; + + # STK500 parameters (parallel programming IO lines) + pagel = 0xa7; + bs2 = 0xa0; + serial = no; + parallel = yes; + + # STK500v2 HV programming parameters, from XML + pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f, + 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f, + 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b, + 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + + # JTAG ICE mkII parameters, also from XML files + allowfullpagebitstream = no; + enablepageprogramming = yes; + idr = 0x51; + rampz = 0x00; + spmcr = 0x57; + eecr = 0x3f; + + memory "eeprom" + paged = no; + size = 512; + page_size = 4; + blocksize = 4; + readsize = 4; + num_pages = 128; + ; + + memory "flash" + paged = yes; + size = 40960; + page_size = 128; + blocksize = 128; + readsize = 128; + num_pages = 320; + ; + + memory "hfuse" + size = 1; + ; + + memory "lfuse" + size = 1; + ; + + memory "lockbits" + size = 1; + ; + + memory "signature" + size = 3; + ; +; + + diff --git a/Projects/DidacticSystem/Adam/MainController/cli_task.c b/Projects/DidacticSystem/Adam/MainController/cli_task.c new file mode 100644 index 0000000..e006e08 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/cli_task.c @@ -0,0 +1,32 @@ +#include "cli_task.h" + +void vTaskVTYusb(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + +void vTaskVTYsocket(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + + char znak; + for( ;; ) + { + znak = 0; + znak = fgetc(state->myStdInOut); + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } +} diff --git a/Projects/DidacticSystem/Adam/MainController/cli_task.h b/Projects/DidacticSystem/Adam/MainController/cli_task.h new file mode 100644 index 0000000..944283c --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/cli_task.h @@ -0,0 +1,30 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsÅ‚ugÄ™ VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowujÄ…cej stan interpretera poleceÅ„ + */ +void vTaskVTYusb(void *cliStatePtr); + + +/** + * Proces odpowiedzialny za obsÅ‚ugÄ™ VTY + * Kod uniwersalny dla dowolnego strumienai FILE + * @param *cliStatePtr wskaźnik do struktury przechowujÄ…cej stan interpretera poleceÅ„ + */ +void vTaskVTYsocket(void *cliStatePtr); + + +#endif /* CLI_TASK_H */ \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/cli_task.lst b/Projects/DidacticSystem/Adam/MainController/cli_task.lst new file mode 100644 index 0000000..0f4ae5d --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/cli_task.lst @@ -0,0 +1,153 @@ + 1 .file "cli_task.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 147 .global vTaskVTYusb + 149 vTaskVTYusb: + 150 .stabd 46,0,0 + 1:cli_task.c **** #include "cli_task.h" + 2:cli_task.c **** + 3:cli_task.c **** void vTaskVTYusb(void *cliStatePtr) + 4:cli_task.c **** { + 152 .LM0: + 153 .LFBB1: + 154 0000 CF93 push r28 + 155 0002 DF93 push r29 + 156 0004 1F92 push __zero_reg__ + 157 0006 CDB7 in r28,__SP_L__ + 158 0008 DEB7 in r29,__SP_H__ + 159 /* prologue: function */ + 160 /* frame size = 1 */ + 161 /* stack size = 3 */ + 162 .L__stack_usage = 3 + 163 000a 8C01 movw r16,r24 + 5:cli_task.c **** cmdState_t *state = (cmdState_t *)(cliStatePtr); + 6:cli_task.c **** fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + 165 .LM1: + 166 000c 80E0 ldi r24,lo8(__c.2010) + 167 000e 90E0 ldi r25,hi8(__c.2010) + 168 0010 9F93 push r25 + 169 0012 8F93 push r24 + 170 0014 F801 movw r30,r16 + 171 0016 838D ldd r24,Z+27 + 172 0018 8F93 push r24 + 173 001a 828D ldd r24,Z+26 + 174 001c 8F93 push r24 + 175 001e 0E94 0000 call fprintf_P + 7:cli_task.c **** cmdlineInputFunc('\r', state); + 177 .LM2: + 178 0022 B801 movw r22,r16 + 179 0024 8DE0 ldi r24,lo8(13) + 180 0026 0E94 0000 call cmdlineInputFunc + 181 002a 0F90 pop __tmp_reg__ + 182 002c 0F90 pop __tmp_reg__ + 183 002e 0F90 pop __tmp_reg__ + 184 0030 0F90 pop __tmp_reg__ + 185 .L2: + 8:cli_task.c **** + 9:cli_task.c **** char znak; + 10:cli_task.c **** for( ;; ) + 11:cli_task.c **** { + 12:cli_task.c **** if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + 187 .LM3: + 188 0032 20E0 ldi r18,0 + 189 0034 4FEF ldi r20,lo8(-1) + 190 0036 5FEF ldi r21,lo8(-1) + 191 0038 BE01 movw r22,r28 + 192 003a 6F5F subi r22,-1 + 193 003c 7F4F sbci r23,-1 + 194 003e 8091 0000 lds r24,xVtyRec + 195 0042 9091 0000 lds r25,xVtyRec+1 + 196 0046 0E94 0000 call xQueueGenericReceive + 197 004a 8823 tst r24 + 198 004c 01F0 breq .L2 + 13:cli_task.c **** { + 14:cli_task.c **** cmdlineInputFunc((char)znak, state); + 200 .LM4: + 201 004e B801 movw r22,r16 + 202 0050 8981 ldd r24,Y+1 + 203 0052 0E94 0000 call cmdlineInputFunc + 15:cli_task.c **** cmdlineMainLoop(state); + 205 .LM5: + 206 0056 C801 movw r24,r16 + 207 0058 0E94 0000 call cmdlineMainLoop + 208 005c 00C0 rjmp .L2 + 213 .Lscope1: + 215 .stabd 78,0,0 + 218 .global vTaskVTYsocket + 220 vTaskVTYsocket: + 221 .stabd 46,0,0 + 16:cli_task.c **** } + 17:cli_task.c **** } + 18:cli_task.c **** } + 19:cli_task.c **** + 20:cli_task.c **** void vTaskVTYsocket(void *cliStatePtr) + 21:cli_task.c **** { + 223 .LM6: + 224 .LFBB2: + 225 /* prologue: function */ + 226 /* frame size = 0 */ + 227 /* stack size = 0 */ + 228 .L__stack_usage = 0 + 229 005e EC01 movw r28,r24 + 230 .L8: + 22:cli_task.c **** cmdState_t *state = (cmdState_t *)(cliStatePtr); + 23:cli_task.c **** + 24:cli_task.c **** char znak; + 25:cli_task.c **** for( ;; ) + 26:cli_task.c **** { + 27:cli_task.c **** znak = 0; + 28:cli_task.c **** znak = fgetc(state->myStdInOut); + 232 .LM7: + 233 0060 8A8D ldd r24,Y+26 + 234 0062 9B8D ldd r25,Y+27 + 235 0064 0E94 0000 call fgetc + 29:cli_task.c **** cmdlineInputFunc((char)znak, state); + 237 .LM8: + 238 0068 BE01 movw r22,r28 + 239 006a 0E94 0000 call cmdlineInputFunc + 30:cli_task.c **** cmdlineMainLoop(state); + 241 .LM9: + 242 006e CE01 movw r24,r28 + 243 0070 0E94 0000 call cmdlineMainLoop + 31:cli_task.c **** } + 245 .LM10: + 246 0074 00C0 rjmp .L8 + 248 .Lscope2: + 250 .stabd 78,0,0 + 251 .section .progmem.data,"a",@progbits + 254 __c.2010: + 255 0000 5265 7374 .string "Restart\r\n" + 255 6172 740D + 255 0A00 + 256 .comm wwwport,1,1 + 258 .text + 260 .Letext0: + 261 .ident "GCC: (GNU) 4.9.2" + 262 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 cli_task.c + /tmp/ccs4022F.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccs4022F.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccs4022F.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccs4022F.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccs4022F.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccs4022F.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccs4022F.s:149 .text:0000000000000000 vTaskVTYusb + /tmp/ccs4022F.s:254 .progmem.data:0000000000000000 __c.2010 + /tmp/ccs4022F.s:220 .text:000000000000005e vTaskVTYsocket + *COM*:0000000000000001 wwwport + +UNDEFINED SYMBOLS +fprintf_P +cmdlineInputFunc +xVtyRec +xQueueGenericReceive +cmdlineMainLoop +fgetc +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/configuration.c b/Projects/DidacticSystem/Adam/MainController/configuration.c new file mode 100644 index 0000000..5b30668 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/configuration.c @@ -0,0 +1,34 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" +#include "nic.h" + + +static struct lockerSensor lockerSensorsEEP[4] __attribute__((section (".eeprom"))) = {{LOCK_SENS_1_ENA, LOCK_SENS_1_THR, 0, 0}, + {LOCK_SENS_2_ENA, LOCK_SENS_2_THR, 0, 0}, + {LOCK_SENS_3_ENA, LOCK_SENS_3_THR, 0, 0}, + {LOCK_SENS_4_ENA, LOCK_SENS_4_THR, 0, 0}}; + +uint32_t udpIpDst_eep __attribute__((section (".eeprom"))); +uint16_t udpPortDstEep __attribute__((section (".eeprom"))); +uint16_t udpPortSrcEep __attribute__((section (".eeprom"))); + + +void loadConfiguration(void) +{ + eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); +} + +void saveConfiguration(void) +{ + //saveNic(); + ipSaveConfig(); + udpSaveConfig(); +} + +void saveNic() +{ + +} diff --git a/Projects/DidacticSystem/Adam/MainController/configuration.h b/Projects/DidacticSystem/Adam/MainController/configuration.h new file mode 100644 index 0000000..2120ad7 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/configuration.h @@ -0,0 +1,19 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "enc28j60.h" +#include "hardware.h" +#include "ip.h" +#include "nic.h" +#include "sensors_task.h" +#include "udp.h" + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + +void saveNic(void); + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/configuration.lst b/Projects/DidacticSystem/Adam/MainController/configuration.lst new file mode 100644 index 0000000..0d44999 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/configuration.lst @@ -0,0 +1,164 @@ + 1 .file "configuration.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 271 .global loadConfiguration + 273 loadConfiguration: + 274 .stabd 46,0,0 + 1:configuration.c **** #include "configuration.h" + 2:configuration.c **** #include + 3:configuration.c **** #include "hardware.h" + 4:configuration.c **** #include "hardwareConfig.h" + 5:configuration.c **** #include "softwareConfig.h" + 6:configuration.c **** #include "nic.h" + 7:configuration.c **** + 8:configuration.c **** + 9:configuration.c **** static struct lockerSensor lockerSensorsEEP[4] __attribute__((section (".eeprom"))) = {{LOCK_SENS_1 + 10:configuration.c **** {LOCK_SENS_2 + 11:configuration.c **** {LOCK_SENS_3 + 12:configuration.c **** {LOCK_SENS_4 + 13:configuration.c **** + 14:configuration.c **** uint32_t udpIpDst_eep __attribute__((section (".eeprom"))); + 15:configuration.c **** uint16_t udpPortDstEep __attribute__((section (".eeprom"))); + 16:configuration.c **** uint16_t udpPortSrcEep __attribute__((section (".eeprom"))); + 17:configuration.c **** + 18:configuration.c **** + 19:configuration.c **** void loadConfiguration(void) + 20:configuration.c **** { + 276 .LM0: + 277 .LFBB1: + 278 /* prologue: function */ + 279 /* frame size = 0 */ + 280 /* stack size = 0 */ + 281 .L__stack_usage = 0 + 21:configuration.c **** eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); + 283 .LM1: + 284 0000 48E1 ldi r20,lo8(24) + 285 0002 50E0 ldi r21,0 + 286 0004 60E0 ldi r22,lo8(lockerSensorsEEP) + 287 0006 70E0 ldi r23,hi8(lockerSensorsEEP) + 288 0008 8091 0000 lds r24,lockSensors + 289 000c 9091 0000 lds r25,lockSensors+1 + 290 0010 0C94 0000 jmp eeprom_read_block + 292 .Lscope1: + 294 .stabd 78,0,0 + 296 .global saveConfiguration + 298 saveConfiguration: + 299 .stabd 46,0,0 + 22:configuration.c **** } + 23:configuration.c **** + 24:configuration.c **** void saveConfiguration(void) + 25:configuration.c **** { + 301 .LM2: + 302 .LFBB2: + 303 /* prologue: function */ + 304 /* frame size = 0 */ + 305 /* stack size = 0 */ + 306 .L__stack_usage = 0 + 26:configuration.c **** //saveNic(); + 27:configuration.c **** ipSaveConfig(); + 308 .LM3: + 309 0014 0E94 0000 call ipSaveConfig + 28:configuration.c **** udpSaveConfig(); + 311 .LM4: + 312 0018 0C94 0000 jmp udpSaveConfig + 314 .Lscope2: + 316 .stabd 78,0,0 + 317 .global udpPortSrcEep + 318 .section .eeprom,"aw",@progbits + 321 udpPortSrcEep: + 322 0000 0000 .zero 2 + 323 .global udpPortDstEep + 326 udpPortDstEep: + 327 0002 0000 .zero 2 + 328 .global udpIpDst_eep + 331 udpIpDst_eep: + 332 0004 0000 0000 .zero 4 + 335 lockerSensorsEEP: + 336 0008 00 .byte 0 + 337 0009 BC02 .word 700 + 338 000b 0000 .word 0 + 339 000d 00 .byte 0 + 340 000e 01 .byte 1 + 341 000f EE02 .word 750 + 342 0011 0000 .word 0 + 343 0013 00 .byte 0 + 344 0014 00 .byte 0 + 345 0015 BC02 .word 700 + 346 0017 0000 .word 0 + 347 0019 00 .byte 0 + 348 001a 01 .byte 1 + 349 001b 8403 .word 900 + 350 001d 0000 .word 0 + 351 001f 00 .byte 0 + 352 .comm czasRtc,7,1 + 353 .comm sockets,2,1 + 354 .comm tcpDebugLevel,1,1 + 355 .comm tcpDebugStream,2,1 + 356 .comm IpMyConfig,15,1 + 357 .comm udpDbgLevel,1,1 + 358 .comm udpDbgStream,2,1 + 359 .comm udpSocket,2,1 + 360 .comm icmpDebugLevel,1,1 + 361 .comm icmpDebug,2,1 + 362 .comm arpDebugLevel,1,1 + 363 .comm arpDebug,2,1 + 364 .comm nicState,14,1 + 365 .comm xSemaphoreRs485,2,1 + 366 .comm lockSensors,2,1 + 367 .comm portB,1,1 + 368 .comm portA,1,1 + 369 .comm xSemaphoreSpiSS,2,1 + 370 .comm rollers,2,1 + 371 .comm wwwport,1,1 + 372 .comm klastry,128,1 + 398 .text + 400 .Letext0: + 401 .ident "GCC: (GNU) 4.9.2" + 402 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 configuration.c + /tmp/ccJ5Lj4f.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccJ5Lj4f.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccJ5Lj4f.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccJ5Lj4f.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccJ5Lj4f.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccJ5Lj4f.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccJ5Lj4f.s:273 .text:0000000000000000 loadConfiguration + /tmp/ccJ5Lj4f.s:335 .eeprom:0000000000000008 lockerSensorsEEP + *COM*:0000000000000002 lockSensors + /tmp/ccJ5Lj4f.s:298 .text:0000000000000014 saveConfiguration + /tmp/ccJ5Lj4f.s:321 .eeprom:0000000000000000 udpPortSrcEep + /tmp/ccJ5Lj4f.s:326 .eeprom:0000000000000002 udpPortDstEep + /tmp/ccJ5Lj4f.s:331 .eeprom:0000000000000004 udpIpDst_eep + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +eeprom_read_block +ipSaveConfig +udpSaveConfig +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/ffconf.h b/Projects/DidacticSystem/Adam/MainController/ffconf.h new file mode 100644 index 0000000..36ca220 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/ffconf.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1250 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. */ + + +#define _FS_RPATH 0 /* 0:Disable or 1:Enable */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0:Single parition or 1:Multiple partition */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* Include a header file here to define O/S system calls */ +/* #include , , or ohters. */ + +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONFIG */ diff --git a/Projects/DidacticSystem/Adam/MainController/firmware.eep b/Projects/DidacticSystem/Adam/MainController/firmware.eep new file mode 100644 index 0000000..ffc0ac8 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/firmware.eep @@ -0,0 +1,5 @@ +:10000000000000000000000000BC0200000001EE43 +:100010000200000000BC0200000001840300000098 +:10002000123456789ABCC0A80001FFFFFF00C0A898 +:020030000002CC +:00000001FF diff --git a/Projects/DidacticSystem/Adam/MainController/firmware.lss b/Projects/DidacticSystem/Adam/MainController/firmware.lss new file mode 100644 index 0000000..c48ce66 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/firmware.lss @@ -0,0 +1,27325 @@ + +firmware.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .data 00000088 00800100 0000a7b4 0000a868 2**0 + CONTENTS, ALLOC, LOAD, DATA + 1 .text 0000a7b4 00000000 00000000 000000b4 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .bss 00000e5a 00800188 00800188 0000a8f0 2**0 + ALLOC + 3 .eeprom 00000032 00810000 00810000 0000a8f0 2**0 + CONTENTS, ALLOC, LOAD, DATA + 4 .stab 0001a6c4 00000000 00000000 0000a924 2**2 + CONTENTS, READONLY, DEBUGGING + 5 .stabstr 0000be97 00000000 00000000 00024fe8 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .comment 00000011 00000000 00000000 00030e7f 2**0 + CONTENTS, READONLY + 7 .note.gnu.avr.deviceinfo 0000003c 00000000 00000000 00030e90 2**2 + CONTENTS, READONLY + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 0c 94 11 0a jmp 0x1422 ; 0x1422 <__ctors_end> + 4: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 8: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 10: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 14: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 18: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 1c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 20: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 24: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 28: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 2c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 30: 0c 94 35 4c jmp 0x986a ; 0x986a <__vector_12> + 34: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 38: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 3c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 40: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 44: 0c 94 5d 0f jmp 0x1eba ; 0x1eba <__vector_17> + 48: 0c 94 e8 0b jmp 0x17d0 ; 0x17d0 <__vector_18> + 4c: 0c 94 4c 0c jmp 0x1898 ; 0x1898 <__vector_19> + 50: 0c 94 8f 0c jmp 0x191e ; 0x191e <__vector_20> + 54: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 58: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 5c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 60: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 64: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 68: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 6c: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 70: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 74: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 78: 0c 94 db 0c jmp 0x19b6 ; 0x19b6 <__vector_30> + 7c: 0c 94 3f 0d jmp 0x1a7e ; 0x1a7e <__vector_31> + 80: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 84: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + 88: 0c 94 56 0b jmp 0x16ac ; 0x16ac <__bad_interrupt> + +0000008c <__trampolines_end>: + 8c: 20 28 or r2, r0 + 8e: 74 68 ori r23, 0x84 ; 132 + 90: 72 65 ori r23, 0x52 ; 82 + 92: 73 68 ori r23, 0x83 ; 131 + 94: 6f 6c ori r22, 0xCF ; 207 + 96: 64 20 and r6, r4 + 98: 25 64 ori r18, 0x45 ; 69 + 9a: 2c 20 and r2, r12 + 9c: 41 43 sbci r20, 0x31 ; 49 + 9e: 20 76 andi r18, 0x60 ; 96 + a0: 61 6c ori r22, 0xC1 ; 193 + a2: 75 65 ori r23, 0x55 ; 85 + a4: 20 25 eor r18, r0 + a6: 64 29 or r22, r4 + a8: 0d 0a sbc r0, r29 + ... + +000000ab : + ab: 20 6c 6f 63 6b 65 64 20 00 locked . + +000000b4 : + b4: 20 6f 70 65 6e 20 20 20 00 open . + +000000bd : + bd: 20 6c 6f 63 6b 65 72 20 25 64 00 locker %d. + +000000c8 <__c.3634>: + c8: 0d 0a 00 ... + +000000cb <__c.3632>: + cb: 0d 0a 00 ... + +000000ce <__c.3630>: + ce: 0d 0a 00 ... + +000000d1 <__c.3628>: + d1: 0d 0a 00 ... + +000000d4 <__c.3625>: + d4: 46 72 65 65 52 74 6f 73 2b 20 76 65 72 20 30 2e FreeRtos+ ver 0. + e4: 33 31 20 62 75 69 6c 64 3a 20 41 75 67 20 31 38 31 build: Aug 18 + f4: 20 32 30 31 37 2c 20 31 36 3a 31 32 3a 34 34 0d 2017, 16:12:44. + 104: 0a 00 .. + +00000106 <__c.3674>: + 106: 75 64 70 00 udp. + +0000010a <__c.3672>: + 10a: 74 63 70 00 tcp. + +0000010e <__c.3670>: + 10e: 69 63 6d 70 00 icmp. + +00000113 <__c.3668>: + 113: 69 70 00 ip. + +00000116 <__c.3666>: + 116: 61 72 70 00 arp. + +0000011a <__c.3664>: + 11a: 75 64 70 00 udp. + +0000011e <__c.3662>: + 11e: 74 63 70 00 tcp. + +00000122 <__c.3660>: + 122: 69 63 6d 70 00 icmp. + +00000127 <__c.3658>: + 127: 69 70 00 ip. + +0000012a <__c.3656>: + 12a: 61 72 70 00 arp. + +0000012e <__c.3768>: + 12e: 58 6d 6f 64 65 6d 3a 20 72 6f 7a 70 6f 63 7a 79 Xmodem: rozpoczy + 13e: 6e 61 6e 69 65 20 6f 64 62 69 6f 72 75 0d 0a 00 nanie odbioru... + +0000014e <__c.3718>: + 14e: 57 61 72 74 6f 73 63 20 70 72 6f 62 6b 69 20 6e Wartosc probki n + 15e: 61 20 77 65 6a 73 63 69 75 20 25 64 3a 20 25 64 a wejsciu %d: %d + 16e: 0d 0a 00 ... + +00000171 <__c.3649>: + 171: 41 6b 74 75 61 6c 6e 79 20 63 7a 61 73 20 25 64 Aktualny czas %d + 181: 3a 25 64 3a 25 64 0d 0a 00 :%d:%d... + +0000018a : + 18a: 04 08 f2 07 db 10 eb 07 b4 07 40 19 8d 07 82 07 ..........@..... + 19a: 8d 10 e9 04 c7 04 0d 11 66 04 43 04 e3 16 ec 03 ........f.C..... + 1aa: dc 03 c3 16 d9 03 b1 03 74 16 3f 04 f1 03 01 16 ........t.?..... + 1ba: ad 03 7f 03 ca 15 7a 03 67 03 fc 11 9d 04 91 04 ......z.g....... + 1ca: d3 0f 89 04 7f 04 e3 0f 00 00 00 00 00 00 .............. + +000001d8 : + 1d8: 04 08 f2 07 db 10 eb 07 b4 07 40 19 ac 07 92 07 ..........@..... + 1e8: f4 11 8d 07 82 07 8d 10 7c 07 33 07 f7 14 2d 07 ........|.3...-. + 1f8: 07 07 6e 17 02 07 d1 06 ff 0f cc 06 a6 06 44 13 ..n...........D. + 208: a0 06 7d 06 01 12 76 06 3e 06 d0 17 38 06 24 06 ..}...v.>...8.$. + 218: 85 10 20 06 04 06 b3 17 fc 05 d7 05 9d 17 d0 05 .. ............. + 228: a6 05 df 12 9f 05 75 05 09 10 72 05 4c 05 79 12 ......u...r.L.y. + 238: 47 05 1f 05 9b 11 1b 05 08 05 89 11 04 05 f1 04 G............... + 248: 77 11 62 03 45 03 68 12 e9 04 c7 04 0d 11 c4 04 w.b.E.h......... + 258: a4 04 e0 10 89 04 7f 04 e3 0f 78 04 69 04 ef 0f ..........x.i... + 268: 40 03 23 03 4b 12 1d 03 fa 02 3a 12 00 00 00 00 @.#.K.....:..... + ... + +0000027a : + 27a: 04 08 f2 07 db 10 eb 07 b4 07 40 19 8d 07 82 07 ..........@..... + 28a: 8d 10 2d 07 07 07 6e 17 02 07 d1 06 ff 0f 38 06 ..-...n.......8. + 29a: 24 06 85 10 9f 05 75 05 09 10 9d 04 91 04 d3 0f $.....u......... + 2aa: 00 00 00 00 00 00 ...... + +000002b0 : + 2b0: 74 0b 6a 0b 67 0b 64 0b 61 0b 5e 0b 4b 0b 24 0b t.j.g.d.a.^.K.$. + 2c0: 05 0b e2 0a c3 0a ae 0a ........ + +000002c8 : + 2c8: 21 21 21 20 57 20 62 75 64 6f 72 7a 65 20 52 73 !!! W budorze Rs + 2d8: 34 38 35 20 70 6f 7a 6f 73 74 61 6c 6f 20 25 64 485 pozostalo %d + 2e8: 20 62 61 6a 74 6f 77 0d 0a 00 bajtow... + +000002f2 : + 2f2: 0d 0a 00 ... + +000002f5 : + 2f5: 4f 4b 0d 0a 00 OK... + +000002fa : + 2fa: 5b 41 5d 20 73 61 76 65 20 65 78 65 63 75 74 69 [A] save executi + 30a: 6f 6e 20 6d 6f 64 75 6c 65 20 73 65 74 74 69 6e on module settin + 31a: 67 73 00 gs. + +0000031d : + 31d: 72 73 61 76 65 00 rsave. + +00000323 : + 323: 5b 41 5d 20 5b 43 5d 20 73 65 74 20 65 78 65 63 [A] [C] set exec + 333: 75 74 69 6f 6e 20 6d 6f 64 75 6c 65 00 ution module. + +00000340 : + 340: 72 73 65 74 00 rset. + +00000345 : + 345: 5b 76 61 6c 75 65 5d 20 73 65 74 20 72 65 73 69 [value] set resi + 355: 73 74 61 6e 63 65 20 76 61 6c 75 65 00 stance value. + +00000362 : + 362: 73 65 74 72 00 setr. + +00000367 : + 367: 53 61 76 65 20 63 6f 6e 66 69 67 75 72 61 74 69 Save configurati + 377: 6f 6e 00 on. + +0000037a : + 37a: 73 61 76 65 00 save. + +0000037f : + 37f: 5b 41 31 5d 20 5b 41 32 5d 20 5b 41 33 5d 20 5b [A1] [A2] [A3] [ + 38f: 41 34 5d 20 5b 41 35 5d 20 5b 41 36 5d 20 73 65 A4] [A5] [A6] se + 39f: 74 20 4d 41 43 20 61 64 64 72 65 73 73 00 t MAC address. + +000003ad : + 3ad: 6d 61 63 00 mac. + +000003b1 : + 3b1: 5b 41 31 5d 20 5b 41 32 5d 20 5b 41 33 5d 20 5b [A1] [A2] [A3] [ + 3c1: 41 34 5d 20 73 65 74 20 64 65 66 61 75 6c 74 20 A4] set default + 3d1: 67 61 74 65 77 61 79 00 gateway. + +000003d9 : + 3d9: 67 77 00 gw. + +000003dc : + 3dc: 5b 6d 61 73 6b 5d 20 73 65 74 20 6d 61 73 6b 00 [mask] set mask. + +000003ec : + 3ec: 6d 61 73 6b 00 mask. + +000003f1 : + 3f1: 5b 41 31 5d 20 5b 41 32 5d 20 5b 41 33 5d 20 5b [A1] [A2] [A3] [ + 401: 41 34 5d 20 5b 73 72 63 20 70 6f 72 74 5d 20 7b A4] [src port] { + 411: 64 73 74 20 70 6f 72 74 7d 20 73 65 74 20 75 64 dst port} set ud + 421: 70 20 63 6c 69 65 6e 74 20 49 50 20 61 64 64 72 p client IP addr + 431: 65 73 73 20 61 6e 64 20 70 6f 72 74 73 00 ess and ports. + +0000043f : + 43f: 75 64 70 00 udp. + +00000443 : + 443: 5b 41 31 5d 20 5b 41 32 5d 20 5b 41 33 5d 20 5b [A1] [A2] [A3] [ + 453: 41 34 5d 20 73 65 74 20 49 50 20 61 64 64 72 65 A4] set IP addre + 463: 73 73 00 ss. + +00000466 : + 466: 69 70 00 ip. + +00000469 : + 469: 43 6f 6e 66 69 67 75 72 65 20 6d 6f 64 65 00 Configure mode. + +00000478 : + 478: 63 6f 6e 66 69 67 00 config. + +0000047f : + 47f: 56 69 65 77 20 6d 6f 64 65 00 View mode. + +00000489 : + 489: 64 69 73 61 62 6c 65 00 disable. + +00000491 : + 491: 45 6e 61 62 6c 65 20 6d 6f 64 65 00 Enable mode. + +0000049d : + 49d: 65 6e 61 62 6c 65 00 enable. + +000004a4 : + 4a4: 5b 63 68 61 6e 6e 65 6c 20 30 2d 37 5d 20 72 65 [channel 0-7] re + 4b4: 61 64 20 61 6e 61 6c 6f 67 20 76 61 6c 75 65 00 ad analog value. + +000004c4 : + 4c4: 61 63 00 ac. + +000004c7 : + 4c7: 5b 68 5d 20 5b 6d 5d 20 5b 73 5d 20 73 65 74 20 [h] [m] [s] set + 4d7: 74 69 6d 65 20 28 32 34 68 20 66 6f 72 6d 61 74 time (24h format + 4e7: 29 00 ). + +000004e9 : + 4e9: 73 65 74 74 69 6d 65 00 settime. + +000004f1 : + 4f1: 5b 76 61 6c 75 65 5d 20 73 65 74 20 70 6f 72 74 [value] set port + 501: 20 42 00 B. + +00000504 : + 504: 73 70 62 00 spb. + +00000508 : + 508: 5b 76 61 6c 75 65 5d 20 73 65 74 20 70 6f 72 74 [value] set port + 518: 20 41 00 A. + +0000051b : + 51b: 73 70 61 00 spa. + +0000051f : + 51f: 5b 64 72 69 76 65 72 20 6e 6f 5d 20 5b 63 68 61 [driver no] [cha + 52f: 6e 6e 65 6c 5d 20 7b 76 61 6c 75 65 7d 20 6d 6f nnel] {value} mo + 53f: 76 65 20 64 6f 77 6e 00 ve down. + +00000547 : + 547: 64 6f 77 6e 00 down. + +0000054c : + 54c: 5b 64 72 69 76 65 72 20 6e 6f 5d 20 5b 63 68 61 [driver no] [cha + 55c: 6e 6e 65 6c 5d 20 7b 76 61 6c 75 65 7d 20 6d 6f nnel] {value} mo + 56c: 76 65 20 75 70 00 ve up. + +00000572 : + 572: 75 70 00 up. + +00000575 : + 575: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 72 65 61 64 [file name] read + 585: 20 66 69 6c 65 20 6c 6f 63 61 74 65 64 20 6f 6e file located on + 595: 20 72 61 6d 20 64 69 73 6b 00 ram disk. + +0000059f : + 59f: 72 65 61 64 72 66 00 readrf. + +000005a6 : + 5a6: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 65 64 69 74 [file name] edit + 5b6: 20 66 69 6c 65 20 6c 6f 63 61 74 65 64 20 6f 6e file located on + 5c6: 20 72 61 6d 20 64 69 73 6b 00 ram disk. + +000005d0 : + 5d0: 65 64 69 74 72 66 00 editrf. + +000005d7 : + 5d7: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 65 72 61 73 [file name] eras + 5e7: 65 20 66 69 6c 65 20 66 72 6f 6d 20 72 61 6d 20 e file from ram + 5f7: 64 69 73 6b 00 disk. + +000005fc : + 5fc: 65 72 61 73 65 72 66 00 eraserf. + +00000604 : + 604: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 63 72 65 61 [file name] crea + 614: 74 65 20 72 61 6d 20 66 69 6c 65 00 te ram file. + +00000620 : + 620: 63 72 66 00 crf. + +00000624 : + 624: 50 72 69 6e 74 20 72 61 6d 64 69 73 6b 20 66 69 Print ramdisk fi + 634: 6c 65 73 00 les. + +00000638 : + 638: 64 69 72 72 66 00 dirrf. + +0000063e : + 63e: 5b 64 65 76 69 63 65 20 6e 6f 5d 20 5b 66 69 6c [device no] [fil + 64e: 65 20 6e 61 6d 65 5d 20 66 6c 61 73 68 20 64 65 e name] flash de + 65e: 76 69 63 65 20 63 6f 6e 6e 65 63 74 65 64 20 74 vice connected t + 66e: 6f 20 52 73 34 38 35 00 o Rs485. + +00000676 : + 676: 78 66 6c 61 73 68 00 xflash. + +0000067d : + 67d: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 73 65 6e 64 [file name] send + 68d: 20 66 69 6c 65 20 75 73 69 6e 67 20 78 4d 6f 64 file using xMod + 69d: 65 6d 00 em. + +000006a0 : + 6a0: 78 73 65 6e 64 00 xsend. + +000006a6 : + 6a6: 5b 66 69 6c 65 20 6e 61 6d 65 5d 20 72 65 63 65 [file name] rece + 6b6: 69 76 65 20 66 69 6c 65 20 75 73 69 6e 67 20 78 ive file using x + 6c6: 4d 6f 64 65 6d 00 Modem. + +000006cc : + 6cc: 78 72 65 63 00 xrec. + +000006d1 : + 6d1: 5b 41 31 5d 20 5b 41 32 5d 20 5b 41 33 5d 20 5b [A1] [A2] [A3] [ + 6e1: 41 34 5d 20 53 65 6e 64 73 20 70 69 6e 67 20 74 A4] Sends ping t + 6f1: 68 72 6f 75 67 68 74 20 65 74 68 65 72 6e 65 74 hrought ethernet + ... + +00000702 : + 702: 70 69 6e 67 00 ping. + +00000707 : + 707: 5b 44 65 76 69 63 65 20 6e 6f 5d 20 53 65 6e 64 [Device no] Send + 717: 20 70 69 6e 67 20 74 6f 20 52 73 34 38 35 20 64 ping to Rs485 d + 727: 65 76 69 63 65 00 evice. + +0000072d : + 72d: 72 70 69 6e 67 00 rping. + +00000733 : + 733: 5b 61 72 70 7c 69 63 6d 70 7c 69 70 7c 74 63 70 [arp|icmp|ip|tcp + 743: 7c 75 64 70 5d 20 5b 6c 65 76 65 6c 5d 20 77 72 |udp] [level] wr + 753: 69 74 65 20 64 65 62 75 67 20 69 6e 66 6f 2e 20 ite debug info. + 763: 4c 65 76 65 6c 20 30 20 64 69 73 61 62 6c 65 20 Level 0 disable + 773: 64 65 62 75 67 69 6e 67 00 debuging. + +0000077c : + 77c: 64 65 62 75 67 00 debug. + +00000782 : + 782: 50 72 69 6e 74 20 74 69 6d 65 00 Print time. + +0000078d : + 78d: 74 69 6d 65 00 time. + +00000792 : + 792: 50 72 69 6e 74 20 45 6e 63 20 32 38 6a 36 30 20 Print Enc 28j60 + 7a2: 72 65 67 69 73 74 65 72 73 00 registers. + +000007ac : + 7ac: 65 6e 63 73 74 61 74 00 encstat. + +000007b4 : + 7b4: 7b 66 69 6c 65 6e 61 6d 65 7d 20 50 72 69 6e 74 {filename} Print + 7c4: 20 64 65 76 69 63 65 20 73 74 61 74 75 73 20 6f device status o + 7d4: 6e 20 56 54 59 20 6f 72 20 77 72 69 74 65 20 74 n VTY or write t + 7e4: 6f 20 66 69 6c 65 00 o file. + +000007eb : + 7eb: 73 74 61 74 75 73 00 status. + +000007f2 : + 7f2: 50 72 69 6e 74 20 68 65 6c 70 20 73 74 72 69 6e Print help strin + 802: 67 00 g. + +00000804 : + 804: 68 65 6c 70 00 help. + +00000809 : + 809: 44 69 73 61 62 6c 65 64 20 25 73 20 64 65 62 75 Disabled %s debu + 819: 67 0d 0a 00 g... + +0000081d : + 81d: 45 6e 61 62 6c 65 64 20 25 73 20 64 65 62 75 67 Enabled %s debug + 82d: 0d 0a 00 ... + +00000830 : + 830: 09 70 6f 7a 79 63 6a 61 20 20 20 25 64 0d 0a 00 .pozycja %d... + +00000840 : + 840: 4f 70 75 73 7a 63 7a 61 6e 69 65 20 72 6f 6c 65 Opuszczanie role + 850: 74 79 0d 0a 09 73 74 65 72 6f 77 6e 69 6b 20 25 ty...sterownik % + 860: 64 0d 0a 09 72 6f 6c 65 74 61 20 20 20 20 25 64 d...roleta %d + 870: 0d 0a 00 ... + +00000873 : + 873: 50 6f 64 6e 6f 73 7a 65 6e 69 65 20 72 6f 6c 65 Podnoszenie role + 883: 74 79 0d 0a 09 73 74 65 72 6f 77 6e 69 6b 20 25 ty...sterownik % + 893: 64 0d 0a 09 72 6f 6c 65 74 61 20 20 20 20 25 64 d...roleta %d + 8a3: 0d 0a 00 ... + +000008a6 : + 8a6: 58 6d 6f 64 65 6d 3a 20 54 72 61 6e 73 6d 69 73 Xmodem: Transmis + 8b6: 73 69 6f 6e 20 73 74 61 72 74 0d 0a 00 sion start... + +000008c3 : + 8c3: 46 69 6c 65 20 6c 65 6e 67 74 68 3a 20 25 64 0d File length: %d. + 8d3: 0a 00 .. + +000008d5 : + 8d5: 57 72 69 74 69 6e 67 20 74 6f 20 66 69 6c 65 2e Writing to file. + 8e5: 20 50 72 65 73 73 20 43 54 52 4c 2b 43 20 74 6f Press CTRL+C to + 8f5: 20 71 75 69 74 0d 0a 00 quit... + +000008fd : + 8fd: 20 20 4c 6f 63 6b 65 72 20 73 65 6e 73 6f 72 73 Locker sensors + 90d: 20 64 69 73 61 62 6c 65 64 0d 0a 00 disabled... + +00000919 : + 919: 4c 6f 63 6b 65 72 20 73 65 6e 73 6f 72 73 20 73 Locker sensors s + 929: 74 61 74 65 73 3a 0d 0a 00 tates:... + +00000932 : + 932: 20 20 43 61 6e 27 74 20 66 69 6e 64 20 61 6e 79 Can't find any + 942: 20 64 65 76 69 63 65 0d 0a 00 device... + +0000094c : + 94c: 44 65 74 65 63 74 65 64 20 52 53 20 34 38 35 20 Detected RS 485 + 95c: 64 65 76 69 63 65 73 3a 0d 0a 00 devices:... + +00000967 : + 967: 20 20 67 61 74 65 77 61 79 20 20 20 20 20 20 20 gateway + 977: 20 20 3a 20 00 : . + +0000097c : + 97c: 20 20 6d 61 73 6b 20 20 20 20 20 20 20 20 20 20 mask + 98c: 20 20 3a 20 00 : . + +00000991 : + 991: 20 20 49 50 20 61 64 64 72 65 73 73 20 20 20 20 IP address + 9a1: 20 20 3a 20 00 : . + +000009a6 : + 9a6: 20 20 4d 61 63 20 61 64 64 72 65 73 73 20 20 20 Mac address + 9b6: 20 20 3a 20 00 : . + +000009bb : + 9bb: 53 79 73 74 65 6d 20 73 65 74 74 69 6e 67 73 3a System settings: + 9cb: 0d 0a 00 ... + +000009ce : + 9ce: 20 20 56 6f 6c 74 61 67 65 20 20 20 20 20 20 20 Voltage + 9de: 20 20 3a 20 25 64 20 56 0d 0a 00 : %d V... + +000009e9 : + 9e9: 20 20 54 65 6d 70 65 72 61 74 75 72 65 20 20 20 Temperature + 9f9: 20 20 3a 20 25 64 20 43 0d 0a 00 : %d C... + +00000a04 : + a04: 20 20 52 61 6d 20 64 69 73 63 20 73 70 61 63 65 Ram disc space + a14: 20 20 3a 20 25 64 20 66 72 65 65 20 6f 66 20 25 : %d free of % + a24: 64 20 63 6c 75 73 74 65 72 73 0d 0a 00 d clusters... + +00000a31 : + a31: 20 20 4d 61 6c 6c 6f 63 20 68 65 61 70 20 20 20 Malloc heap + a41: 20 20 3a 20 25 64 20 66 72 65 65 20 6f 66 20 25 : %d free of % + a51: 64 20 62 79 74 65 73 0d 0a 00 d bytes... + +00000a5b : + a5b: 20 20 46 72 65 65 52 74 6f 73 20 68 65 61 70 20 FreeRtos heap + a6b: 20 20 3a 20 25 64 20 66 72 65 65 20 6f 66 20 25 : %d free of % + a7b: 64 20 62 79 74 65 73 0d 0a 00 d bytes... + +00000a85 : + a85: 20 20 4e 75 6d 62 65 72 20 6f 66 20 74 61 73 6b Number of task + a95: 73 20 3a 20 25 64 0d 0a 00 s : %d... + +00000a9e : + a9e: 53 79 73 74 65 6d 20 73 74 61 74 65 3a 0d 0a 00 System state:... + +00000aae : + aae: 43 61 6e 27 74 20 6f 70 65 6e 20 66 69 6c 65 20 Can't open file + abe: 25 73 0d 0a 00 %s... + +00000ac3 : + ac3: 42 6f 6f 74 6c 6f 61 64 65 72 20 69 73 20 6e 6f Bootloader is no + ad3: 74 20 72 65 73 70 6f 6e 64 69 6e 67 0d 0a 00 t responding... + +00000ae2 : + ae2: 44 65 76 69 63 65 20 25 64 20 69 73 20 6e 6f 74 Device %d is not + af2: 20 72 65 73 70 6f 6e 64 69 6e 67 20 28 25 64 29 responding (%d) + b02: 0d 0a 00 ... + +00000b05 : + b05: 78 4d 6f 64 65 6d 20 75 6e 6b 6e 6f 77 6e 20 72 xModem unknown r + b15: 65 73 70 6f 6e 73 65 20 30 78 25 78 0d 0a 00 esponse 0x%x... + +00000b24 : + b24: 52 65 6d 6f 74 65 20 73 69 64 65 20 63 61 6e 63 Remote side canc + b34: 65 6c 6c 65 64 20 61 74 20 66 72 61 6d 65 20 6e elled at frame n + b44: 6f 20 25 64 0d 0a 00 o %d... + +00000b4b : + b4b: 78 4d 6f 64 65 6d 20 43 52 43 20 65 72 72 6f 72 xModem CRC error + b5b: 0d 0a 00 ... + +00000b5e : + b5e: 0d 0a 00 ... + +00000b61 : + b61: 0d 0a 00 ... + +00000b64 : + b64: 0d 0a 00 ... + +00000b67 : + b67: 0d 0a 00 ... + +00000b6a : + b6a: 4e 6f 20 46 69 6c 65 0d 0a 00 No File... + +00000b74 : + b74: 41 6c 6c 20 4f 4b 0d 0a 00 All OK... + +00000b7d <__c.3427>: + b7d: 55 6e 6b 6e 6f 77 6e 20 70 61 63 6b 65 74 0d 0a Unknown packet.. + ... + +00000b8e <__c.2010>: + b8e: 52 65 73 74 61 72 74 0d 0a 00 Restart... + +00000b98 <__c.3649>: + b98: 0d 0a 00 ... + +00000b9b <__c.3647>: + b9b: 09 00 .. + +00000b9d <__c.3559>: + b9d: 4f 70 65 72 61 74 69 6f 6e 20 6e 6f 74 20 61 6c Operation not al + bad: 6c 6f 77 65 64 0d 0a 00 lowed... + +00000bb5 <__c.3556>: + bb5: 4f 70 65 72 61 74 69 6f 6e 20 66 61 69 6c 65 64 Operation failed + bc5: 0d 0a 00 ... + +00000bc8 <__c.3553>: + bc8: 0d 0a 00 ... + +00000bcb <__c.3551>: + bcb: 20 00 . + +00000bcd <__c.3549>: + bcd: 53 79 6e 74 61 78 20 45 72 72 6f 72 2e 20 55 73 Syntax Error. Us + bdd: 65 3a 20 00 e: . + +00000be1 <__c.3545>: + be1: 4f 4b 0d 0a 00 OK... + +00000be6 : + be6: 23 20 6e 6b 00 # nk. + +00000beb : + beb: 63 6d 64 6c 69 6e 65 3a 20 00 cmdline: . + +00000bf5 : + bf5: 44 6f 6d 4f 73 40 00 DomOs@. + +00000bfc : + bfc: 44 6f 6d 4f 73 23 00 DomOs#. + +00000c03 : + c03: 44 6f 6d 4f 73 3e 00 DomOs>. + +00000c0a <__c.3558>: + c0a: 09 4d 41 41 44 52 35 20 30 78 25 78 0d 0a 00 .MAADR5 0x%x... + +00000c19 <__c.3556>: + c19: 09 4d 41 41 44 52 34 20 30 78 25 78 0d 0a 00 .MAADR4 0x%x... + +00000c28 <__c.3554>: + c28: 09 4d 41 41 44 52 33 20 30 78 25 78 0d 0a 00 .MAADR3 0x%x... + +00000c37 <__c.3552>: + c37: 09 4d 41 41 44 52 32 20 30 78 25 78 0d 0a 00 .MAADR2 0x%x... + +00000c46 <__c.3550>: + c46: 09 4d 41 41 44 52 31 20 30 78 25 78 0d 0a 00 .MAADR1 0x%x... + +00000c55 <__c.3548>: + c55: 09 4d 41 41 44 52 30 20 30 78 25 78 0d 0a 00 .MAADR0 0x%x... + +00000c64 <__c.3546>: + c64: 45 4e 43 32 38 6a 36 30 20 73 74 61 6e 20 72 65 ENC28j60 stan re + c74: 6a 65 73 74 72 6f 77 3a 0d 0a 00 jestrow:... + +00000c7f <__c.2141>: + c7f: 4e 49 43 20 72 65 67 20 64 75 6d 70 20 6e 6f 74 NIC reg dump not + c8f: 20 69 6d 70 6c 65 6d 65 6e 74 65 64 0d 0a 00 implemented... + +00000c9e <__c.2004>: + c9e: 0d 0a 00 ... + +00000ca1 <__c.2002>: + ca1: 55 52 47 20 00 URG . + +00000ca6 <__c.2000>: + ca6: 41 43 4b 20 00 ACK . + +00000cab <__c.1998>: + cab: 50 53 48 20 00 PSH . + +00000cb0 <__c.1996>: + cb0: 52 53 54 20 00 RST . + +00000cb5 <__c.1994>: + cb5: 53 59 4e 20 00 SYN . + +00000cba <__c.1992>: + cba: 46 49 4e 20 00 FIN . + +00000cbf <__c.1990>: + cbf: 46 6c 61 67 73 20 20 20 3a 20 00 Flags : . + +00000cca <__c.1988>: + cca: 41 63 6b 20 4e 75 6d 20 3a 20 30 78 25 78 0d 0a Ack Num : 0x%x.. + ... + +00000cdb <__c.1986>: + cdb: 53 65 71 20 4e 75 6d 20 3a 20 30 78 25 78 00 Seq Num : 0x%x. + +00000cea <__c.1984>: + cea: 44 73 74 20 50 6f 72 74 3a 20 25 64 0d 0a 00 Dst Port: %d... + +00000cf9 <__c.1982>: + cf9: 53 72 63 20 50 6f 72 74 3a 20 25 64 0d 0a 00 Src Port: %d... + +00000d08 <__c.1980>: + d08: 54 43 50 20 48 65 61 64 65 72 0d 0a 00 TCP Header... + +00000d15 <__c.1974>: + d15: 0d 0a 00 ... + +00000d18 <__c.1972>: + d18: 44 65 73 74 20 20 49 50 3a 20 00 Dest IP: . + +00000d23 <__c.1970>: + d23: 0d 0a 00 ... + +00000d26 <__c.1968>: + d26: 53 6f 75 72 63 65 49 50 3a 20 00 SourceIP: . + +00000d31 <__c.1966>: + d31: 50 72 6f 74 6f 63 6f 6c 3a 20 25 64 0d 0a 00 Protocol: %d... + +00000d40 <__c.1964>: + d40: 50 72 6f 74 6f 63 6f 6c 3a 20 55 44 50 0d 0a 00 Protocol: UDP... + +00000d50 <__c.1962>: + d50: 50 72 6f 74 6f 63 6f 6c 3a 20 54 43 50 0d 0a 00 Protocol: TCP... + +00000d60 <__c.1960>: + d60: 50 72 6f 74 6f 63 6f 6c 3a 20 49 43 4d 50 0d 0a Protocol: ICMP.. + ... + +00000d71 <__c.1958>: + d71: 4c 65 6e 67 74 68 20 20 3a 20 25 64 0d 0a 00 Length : %d... + +00000d80 <__c.1956>: + d80: 56 65 72 20 20 20 20 20 3a 20 25 64 0d 0a 00 Ver : %d... + +00000d8f <__c.1954>: + d8f: 49 50 20 48 65 61 64 65 72 0d 0a 00 IP Header... + +00000d9b <__c.1948>: + d9b: 2d 3e 44 53 54 3a 00 ->DST:. + +00000da2 <__c.1946>: + da2: 20 53 52 43 3a 00 SRC:. + +00000da8 <__c.1944>: + da8: 45 74 68 20 50 61 63 6b 65 74 20 54 79 70 65 3a Eth Packet Type: + db8: 20 30 78 25 78 00 0x%x. + +00000dbe <__c.1938>: + dbe: 25 64 2e 25 64 2e 25 64 2e 25 64 00 %d.%d.%d.%d. + +00000dca <__c.1932>: + dca: 25 30 32 78 3a 25 30 32 78 3a 25 30 32 78 3a 25 %02x:%02x:%02x:% + dda: 30 32 78 3a 25 30 32 78 3a 25 30 32 78 00 02x:%02x:%02x. + +00000de8 <__c.2542>: + de8: 0d 0a 00 ... + +00000deb <__c.2540>: + deb: 47 61 74 65 77 61 79 20 3a 20 00 Gateway : . + +00000df6 <__c.2538>: + df6: 0d 0a 00 ... + +00000df9 <__c.2536>: + df9: 4e 65 74 6d 61 73 6b 20 3a 20 00 Netmask : . + +00000e04 <__c.2534>: + e04: 0d 0a 00 ... + +00000e07 <__c.2532>: + e07: 49 50 20 41 64 64 72 20 3a 20 00 IP Addr : . + +00000e12 <__c.2526>: + e12: 64 65 62 75 67 50 72 69 6e 74 48 65 78 54 61 62 debugPrintHexTab + e22: 6c 65 28 6c 65 6e 2d 45 54 48 5f 48 45 41 44 45 le(len-ETH_HEADE + e32: 52 5f 4c 45 4e 2c 20 26 64 61 74 61 5b 45 54 48 R_LEN, &data[ETH + e42: 5f 48 45 41 44 45 52 5f 4c 45 4e 5d 29 3b 00 _HEADER_LEN]);. + +00000e51 <__c.2524>: + e51: 64 65 62 75 67 50 72 69 6e 74 48 65 78 54 61 62 debugPrintHexTab + e61: 6c 65 28 45 54 48 5f 48 45 41 44 45 52 5f 4c 45 le(ETH_HEADER_LE + e71: 4e 2c 20 26 64 61 74 61 5b 30 5d 29 3b 00 N, &data[0]);. + +00000e7f <__c.2522>: + e7f: 53 65 6e 64 69 6e 67 20 49 50 20 70 61 63 6b 65 Sending IP packe + e8f: 74 20 74 6f 20 67 61 74 65 77 61 79 0d 0a 00 t to gateway... + +00000e9e <__c.2520>: + e9e: 53 65 6e 64 69 6e 67 20 49 50 20 70 61 63 6b 65 Sending IP packe + eae: 74 20 6f 6e 20 6c 6f 63 61 6c 20 6e 65 74 0d 0a t on local net.. + ... + +00000ebf <__c.2492>: + ebf: 4e 45 54 20 52 78 3a 20 55 6e 6b 6e 6f 77 6e 20 NET Rx: Unknown + ecf: 49 50 20 70 61 63 6b 65 74 0d 0a 00 IP packet... + +00000edb <__c.2490>: + edb: 4e 45 54 20 52 78 3a 20 55 44 50 2f 49 50 20 70 NET Rx: UDP/IP p + eeb: 61 63 6b 65 74 0d 0a 00 acket... + +00000ef3 <__c.2488>: + ef3: 4e 45 54 20 52 78 3a 20 49 43 4d 50 2f 49 50 20 NET Rx: ICMP/IP + f03: 70 61 63 6b 65 74 0d 0a 00 packet... + +00000f0c <__c.2514>: + f0c: 43 6f 64 65 20 20 20 3a 20 30 78 25 78 0d 0a 00 Code : 0x%x... + +00000f1c <__c.2512>: + f1c: 54 79 70 65 3a 20 30 78 25 78 20 20 20 20 00 Type: 0x%x . + +00000f2b <__c.2510>: + f2b: 0d 0a 00 ... + +00000f2e <__c.2508>: + f2e: 44 73 74 49 70 41 64 64 72 3a 20 00 DstIpAddr: . + +00000f3a <__c.2506>: + f3a: 0d 0a 00 ... + +00000f3d <__c.2504>: + f3d: 53 72 63 49 70 41 64 64 72 3a 20 00 SrcIpAddr: . + +00000f49 <__c.2502>: + f49: 49 43 4d 50 20 50 61 63 6b 65 74 3a 0d 0a 00 ICMP Packet:... + +00000f58 <__c.2491>: + f58: 53 65 6e 64 69 6e 67 20 49 43 4d 50 20 50 4f 4e Sending ICMP PON + f68: 47 0d 0a 00 G... + +00000f6c <__c.2488>: + f6c: 52 65 63 65 69 76 65 64 20 49 43 4d 50 20 72 65 Received ICMP re + f7c: 71 75 65 73 74 3a 20 00 quest: . + +00000f84 <__c.2483>: + f84: 55 6e 6b 6e 6f 77 6e 20 49 43 4d 50 20 74 79 70 Unknown ICMP typ + f94: 65 52 65 63 65 69 76 65 64 20 49 43 4d 50 20 72 eReceived ICMP r + fa4: 65 71 75 65 73 74 3a 20 00 equest: . + +00000fad <__c.2574>: + fad: 0d 0a 00 ... + +00000fb0 <__c.2572>: + fb0: 20 20 00 . + +00000fb3 <__c.2570>: + fb3: 25 33 64 20 20 00 %3d . + +00000fb9 <__c.2567>: + fb9: 0d 0a 00 ... + +00000fbc <__c.2565>: + fbc: 20 20 00 . + +00000fbf <__c.2563>: + fbf: 20 4d 59 20 20 00 MY . + +00000fc5 <__c.2561>: + fc5: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ---------------- + fd5: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ---------------- + fe5: 2d 2d 2d 0d 0a 00 ---... + +00000feb <__c.2559>: + feb: 54 69 6d 65 20 45 74 68 20 41 64 64 72 65 73 73 Time Eth Address + ffb: 20 20 20 20 20 20 20 20 49 50 20 41 64 64 72 65 IP Addre + 100b: 73 73 0d 0a 00 ss... + +00001010 <__c.2553>: + 1010: 0d 0a 00 ... + +00001013 <__c.2551>: + 1013: 44 73 74 50 72 6f 74 6f 41 64 64 72 3a 20 00 DstProtoAddr: . + +00001022 <__c.2549>: + 1022: 0d 0a 00 ... + +00001025 <__c.2547>: + 1025: 44 73 74 48 77 41 64 64 72 20 20 20 3a 20 00 DstHwAddr : . + +00001034 <__c.2545>: + 1034: 0d 0a 00 ... + +00001037 <__c.2543>: + 1037: 53 72 63 50 72 6f 74 6f 41 64 64 72 3a 20 00 SrcProtoAddr: . + +00001046 <__c.2541>: + 1046: 0d 0a 00 ... + +00001049 <__c.2539>: + 1049: 53 72 63 48 77 41 64 64 72 20 20 20 3a 20 00 SrcHwAddr : . + +00001058 <__c.2537>: + 1058: 0d 0a 00 ... + +0000105b <__c.2535>: + 105b: 55 4e 4b 4e 4f 57 4e 00 UNKNOWN. + +00001063 <__c.2533>: + 1063: 52 45 50 4c 59 00 REPLY. + +00001069 <__c.2531>: + 1069: 52 45 51 55 45 53 54 00 REQUEST. + +00001071 <__c.2529>: + 1071: 4f 70 65 72 61 74 69 6f 6e 20 20 20 3a 20 00 Operation : . + +00001080 <__c.2527>: + 1080: 41 52 50 20 50 61 63 6b 65 74 3a 0d 0a 00 ARP Packet:... + +0000108e <__c.2499>: + 108e: 0d 0a 00 ... + +00001091 <__c.2497>: + 1091: 20 49 50 3a 20 00 IP: . + +00001097 <__c.2495>: + 1097: 41 52 50 20 49 50 20 69 6e 20 4d 41 43 3a 20 00 ARP IP in MAC: . + +000010a7 <__c.2490>: + 10a7: 53 65 6e 64 69 6e 67 20 41 52 50 20 52 65 70 6c Sending ARP Repl + 10b7: 79 0d 0a 00 y... + +000010bb <__c.2488>: + 10bb: 52 65 63 65 69 76 65 64 20 41 52 50 20 52 65 71 Received ARP Req + 10cb: 75 65 73 74 0d 0a 00 uest... + +000010d2 <__c.2723>: + 10d2: 48 54 54 50 20 6e 6f 74 20 69 6d 70 6c 65 6d 65 HTTP not impleme + 10e2: 6e 74 65 64 0d 0a 00 nted... + +000010e9 <__c.2692>: + 10e9: 43 61 6e 27 74 20 66 69 6e 64 20 54 43 50 20 73 Can't find TCP s + 10f9: 6f 63 6b 65 74 20 77 69 74 68 20 6c 6f 63 61 6c ocket with local + 1109: 50 6f 72 74 20 25 64 0d 0a 00 Port %d... + +00001113 <__c.2687>: + 1113: 46 6f 75 6e 64 20 54 43 50 20 73 6f 63 6b 65 74 Found TCP socket + 1123: 20 6e 6f 20 25 64 20 73 74 61 74 65 20 4c 49 53 no %d state LIS + 1133: 54 45 4e 0d 0a 00 TEN... + +00001139 <__c.2682>: + 1139: 46 6f 75 6e 64 20 54 43 50 20 73 6f 63 6b 65 74 Found TCP socket + 1149: 20 73 74 61 74 65 20 25 64 0d 0a 00 state %d... + +00001155 <__c.2707>: + 1155: 4f 70 65 6e 69 6e 67 20 54 43 50 20 63 6f 6e 6e Opening TCP conn + 1165: 65 63 74 69 6f 6e 20 45 52 52 4f 52 3a 20 61 63 ection ERROR: ac + 1175: 6b 20 66 6c 61 67 20 77 61 73 6e 27 74 20 73 65 k flag wasn't se + 1185: 74 0d 0a 00 t... + +00001189 <__c.2705>: + 1189: 4f 70 65 6e 69 6e 67 20 54 43 50 20 63 6f 6e 6e Opening TCP conn + 1199: 65 63 74 69 6f 6e 20 73 6f 63 6b 65 74 20 73 74 ection socket st + 11a9: 61 74 65 20 63 68 61 6e 67 65 20 53 59 4e 5f 52 ate change SYN_R + 11b9: 45 43 45 49 56 45 44 2d 3e 45 53 54 41 42 49 4c ECEIVED->ESTABIL + 11c9: 49 53 48 45 44 0d 0a 00 ISHED... + +000011d1 <__c.2703>: + 11d1: 4f 70 65 6e 69 6e 67 20 54 43 50 20 63 6f 6e 6e Opening TCP conn + 11e1: 65 63 74 69 6f 6e 20 45 52 52 4f 52 3a 20 73 79 ection ERROR: sy + 11f1: 6e 20 66 6c 61 67 20 77 61 73 6e 27 74 20 73 65 n flag wasn't se + 1201: 74 0d 0a 00 t... + +00001205 <__c.2701>: + 1205: 4f 70 65 6e 69 6e 67 20 54 43 50 20 63 6f 6e 6e Opening TCP conn + 1215: 65 63 74 69 6f 6e 20 73 6f 63 6b 65 74 20 73 74 ection socket st + 1225: 61 74 65 20 63 68 61 6e 67 65 20 4c 49 53 54 45 ate change LISTE + 1235: 4e 2d 3e 53 59 4e 5f 52 45 43 45 49 56 45 44 0d N->SYN_RECEIVED. + 1245: 0a 00 .. + +00001247 <__c.2535>: + 1247: 25 64 0d 0a 00 %d... + +0000124c <__c.2533>: + 124c: 41 4e 59 0d 0a 00 ANY... + +00001252 <__c.2531>: + 1252: 0d 0a 20 20 73 72 63 20 70 6f 72 74 20 20 20 20 .. src port + 1262: 3a 20 25 64 0d 0a 20 20 64 73 74 20 70 6f 72 74 : %d.. dst port + 1272: 20 20 20 20 3a 20 00 : . + +00001279 <__c.2529>: + 1279: 0d 0a 20 20 49 50 20 20 20 20 20 20 20 20 20 20 .. IP + 1289: 3a 20 00 : . + +0000128c <__c.2527>: + 128c: 55 44 50 20 63 6f 6e 66 69 67 3a 00 UDP config:. + +00001298 <__c.2511>: + 1298: 52 65 63 65 69 76 65 64 20 55 44 50 20 70 61 63 Received UDP pac + 12a8: 6b 65 74 20 28 6c 65 6e 20 25 64 29 0d 0a 00 ket (len %d)... + +000012b7 <__c.2509>: + 12b7: 0d 0a 00 ... + +000012ba <__c.2504>: + 12ba: 55 44 50 20 54 58 20 62 75 66 66 65 72 20 62 75 UDP TX buffer bu + 12ca: 73 79 0d 0a 00 sy... + +000012cf <__c.2502>: + 12cf: 20 30 78 25 32 78 00 0x%2x. + +000012d6 <__c.2500>: + 12d6: 52 65 63 65 69 76 65 64 20 55 44 50 20 64 61 74 Received UDP dat + 12e6: 61 3a 00 a:. + +000012e9 <__c.2497>: + 12e9: 53 6b 69 70 70 69 6e 67 2c 20 77 72 6f 6e 67 20 Skipping, wrong + 12f9: 70 6f 72 74 73 20 25 64 20 25 64 0d 0a 00 ports %d %d... + +00001307 <__c.2495>: + 1307: 50 72 6f 63 2e 20 55 44 50 20 70 61 63 6b 65 74 Proc. UDP packet + 1317: 20 28 64 61 74 61 20 6c 65 6e 67 74 68 20 25 64 (data length %d + 1327: 29 00 ). + +00001329 <__c.2488>: + 1329: 55 44 50 20 74 78 20 25 64 20 62 79 74 65 73 0d UDP tx %d bytes. + 1339: 0a 00 .. + +0000133b <__c.2486>: + 133b: 53 65 6e 64 69 6e 67 20 55 44 50 20 70 61 63 6b Sending UDP pack + 134b: 65 74 20 28 64 61 74 61 20 6c 65 6e 67 74 68 20 et (data length + 135b: 25 64 29 0d 0a 00 %d)... + +00001361 <__c.3530>: + 1361: 62 6f 6f 74 6c 6f 61 64 65 72 20 6e 69 65 20 72 bootloader nie r + 1371: 6f 7a 70 6f 63 7a 61 6c 20 6f 64 62 69 6f 72 75 ozpoczal odbioru + 1381: 20 64 61 6e 79 63 68 0d 0a 00 danych... + +0000138b <__c.3528>: + 138b: 6e 61 20 75 72 7a 61 64 7a 65 6e 69 75 20 77 67 na urzadzeniu wg + 139b: 72 61 6e 79 20 6a 65 73 74 20 74 79 6c 6b 6f 20 rany jest tylko + 13ab: 62 6f 6f 74 6c 6f 61 64 65 72 0d 0a 00 bootloader... + +000013b8 <__c.3526>: + 13b8: 72 46 4c 41 53 48 20 74 69 6d 65 6f 75 74 0d 0a rFLASH timeout.. + ... + +000013c9 : + 13c9: 2c 20 66 69 72 6d 77 61 72 65 20 25 73 0d 0a 00 , firmware %s... + +000013d9 : + 13d9: 20 63 6f 6e 66 69 67 20 25 78 00 config %x. + +000013e4 : + 13e4: 20 25 64 20 72 6f 6c 6c 65 72 20 64 72 69 76 65 %d roller drive + 13f4: 72 3a 20 72 6f 6c 6c 65 72 20 31 20 70 6f 73 69 r: roller 1 posi + 1404: 74 69 6f 6e 20 25 64 2c 20 72 6f 6c 6c 65 72 20 tion %d, roller + 1414: 32 20 70 6f 73 69 74 69 6f 6e 20 25 64 00 2 position %d. + +00001422 <__ctors_end>: + 1422: 11 24 eor r1, r1 + 1424: 1f be out 0x3f, r1 ; 63 + 1426: cf ef ldi r28, 0xFF ; 255 + 1428: d0 e1 ldi r29, 0x10 ; 16 + 142a: de bf out 0x3e, r29 ; 62 + 142c: cd bf out 0x3d, r28 ; 61 + +0000142e : +xTaskHandle xHandleEnc; +xTaskHandle xHandleSensors; + +void initExternalMem(void) +{ + MCUCR |= _BV(SRE); //WÅ‚Ä…czenie pamiÄ™ci zewnÄ™trznej + 142e: 85 b7 in r24, 0x35 ; 53 + 1430: 80 68 ori r24, 0x80 ; 128 + 1432: 85 bf out 0x35, r24 ; 53 + MCUCR |= 0x0E; + 1434: 85 b7 in r24, 0x35 ; 53 + 1436: 8e 60 ori r24, 0x0E ; 14 + 1438: 85 bf out 0x35, r24 ; 53 +#define testZewPamiec 1 +#if testZewPamiec == 1 +#define SND(DTA) UDR1=DTA; \ + while( ! (UCSR1A & (1< + 1458: 8a e0 ldi r24, 0x0A ; 10 + 145a: 80 93 9c 00 sts 0x009C, r24 + 145e: 80 91 9b 00 lds r24, 0x009B + 1462: 85 ff sbrs r24, 5 + 1464: fc cf rjmp .-8 ; 0x145e + 1466: 8d e4 ldi r24, 0x4D ; 77 + 1468: 80 93 9c 00 sts 0x009C, r24 + 146c: 80 91 9b 00 lds r24, 0x009B + 1470: 85 ff sbrs r24, 5 + 1472: fc cf rjmp .-8 ; 0x146c + 1474: 85 e6 ldi r24, 0x65 ; 101 + 1476: 80 93 9c 00 sts 0x009C, r24 + 147a: 80 91 9b 00 lds r24, 0x009B + 147e: 85 ff sbrs r24, 5 + 1480: fc cf rjmp .-8 ; 0x147a + 1482: 8d e6 ldi r24, 0x6D ; 109 + 1484: 80 93 9c 00 sts 0x009C, r24 + 1488: 80 91 9b 00 lds r24, 0x009B + 148c: 85 ff sbrs r24, 5 + 148e: fc cf rjmp .-8 ; 0x1488 + 1490: 8f e6 ldi r24, 0x6F ; 111 + 1492: 80 93 9c 00 sts 0x009C, r24 + 1496: 80 91 9b 00 lds r24, 0x009B + 149a: 85 ff sbrs r24, 5 + 149c: fc cf rjmp .-8 ; 0x1496 + 149e: 82 e7 ldi r24, 0x72 ; 114 + 14a0: 80 93 9c 00 sts 0x009C, r24 + 14a4: 80 91 9b 00 lds r24, 0x009B + 14a8: 85 ff sbrs r24, 5 + 14aa: fc cf rjmp .-8 ; 0x14a4 + 14ac: 89 e7 ldi r24, 0x79 ; 121 + 14ae: 80 93 9c 00 sts 0x009C, r24 + 14b2: 80 91 9b 00 lds r24, 0x009B + 14b6: 85 ff sbrs r24, 5 + 14b8: fc cf rjmp .-8 ; 0x14b2 + 14ba: 84 e7 ldi r24, 0x74 ; 116 + 14bc: 80 93 9c 00 sts 0x009C, r24 + 14c0: 80 91 9b 00 lds r24, 0x009B + 14c4: 85 ff sbrs r24, 5 + 14c6: fc cf rjmp .-8 ; 0x14c0 + 14c8: 85 e6 ldi r24, 0x65 ; 101 + 14ca: 80 93 9c 00 sts 0x009C, r24 + 14ce: 80 91 9b 00 lds r24, 0x009B + 14d2: 85 ff sbrs r24, 5 + 14d4: fc cf rjmp .-8 ; 0x14ce + 14d6: 83 e7 ldi r24, 0x73 ; 115 + 14d8: 80 93 9c 00 sts 0x009C, r24 + 14dc: 80 91 9b 00 lds r24, 0x009B + 14e0: 85 ff sbrs r24, 5 + 14e2: fc cf rjmp .-8 ; 0x14dc + 14e4: 84 e7 ldi r24, 0x74 ; 116 + 14e6: 80 93 9c 00 sts 0x009C, r24 + 14ea: 80 91 9b 00 lds r24, 0x009B + 14ee: 85 ff sbrs r24, 5 + 14f0: fc cf rjmp .-8 ; 0x14ea + 14f2: 8d e0 ldi r24, 0x0D ; 13 + 14f4: 80 93 9c 00 sts 0x009C, r24 + 14f8: 80 91 9b 00 lds r24, 0x009B + 14fc: 85 ff sbrs r24, 5 + 14fe: fc cf rjmp .-8 ; 0x14f8 + 1500: 8a e0 ldi r24, 0x0A ; 10 + 1502: 80 93 9c 00 sts 0x009C, r24 + 1506: 80 91 9b 00 lds r24, 0x009B + 150a: 85 ff sbrs r24, 5 + 150c: fc cf rjmp .-8 ; 0x1506 + 150e: 81 e1 ldi r24, 0x11 ; 17 + 1510: 90 e0 ldi r25, 0x00 ; 0 + uint8_t znLo = (hiAddr & 0x0F); + + znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + + SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + 1512: 6d e0 ldi r22, 0x0D ; 13 + 1514: 70 e3 ldi r23, 0x30 ; 48 + 1516: c8 e7 ldi r28, 0x78 ; 120 + 1518: 4a e2 ldi r20, 0x2A ; 42 + 151a: d0 e2 ldi r29, 0x20 ; 32 + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 151c: 16 e4 ldi r17, 0x46 ; 70 + 151e: 01 e4 ldi r16, 0x41 ; 65 + 1520: 39 e4 ldi r19, 0x49 ; 73 + 1522: d3 2e mov r13, r19 + 1524: 5c e4 ldi r21, 0x4C ; 76 + 1526: c5 2e mov r12, r21 + 1528: 5a e0 ldi r21, 0x0A ; 10 + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + 152a: ef e4 ldi r30, 0x4F ; 79 + 152c: be 2e mov r11, r30 + 152e: fb e4 ldi r31, 0x4B ; 75 + 1530: af 2e mov r10, r31 + SND('\r') SND('\n') SND('M') SND('e') SND('m') SND('o') SND('r') SND('y') SND('t') SND('e') SND('s') SND('t') SND('\r') SND('\n') + + uint8_t hiAddr; + for (hiAddr = 0x11; hiAddr < 0xFF; hiAddr++) + { + uint8_t znHi = (hiAddr>>4 & 0x0F); + 1532: 38 2f mov r19, r24 + 1534: 32 95 swap r19 + 1536: 3f 70 andi r19, 0x0F ; 15 + uint8_t znLo = (hiAddr & 0x0F); + 1538: 28 2f mov r18, r24 + 153a: 2f 70 andi r18, 0x0F ; 15 + + znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + 153c: 3a 30 cpi r19, 0x0A ; 10 + 153e: 10 f4 brcc .+4 ; 0x1544 + 1540: 30 5d subi r19, 0xD0 ; 208 + 1542: 01 c0 rjmp .+2 ; 0x1546 + 1544: 39 5c subi r19, 0xC9 ; 201 + znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + 1546: 2a 30 cpi r18, 0x0A ; 10 + 1548: 10 f4 brcc .+4 ; 0x154e + 154a: 20 5d subi r18, 0xD0 ; 208 + 154c: 01 c0 rjmp .+2 ; 0x1550 + 154e: 29 5c subi r18, 0xC9 ; 201 + + SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + 1550: 60 93 9c 00 sts 0x009C, r22 + 1554: e0 91 9b 00 lds r30, 0x009B + 1558: e5 ff sbrs r30, 5 + 155a: fc cf rjmp .-8 ; 0x1554 + 155c: 70 93 9c 00 sts 0x009C, r23 + 1560: e0 91 9b 00 lds r30, 0x009B + 1564: e5 ff sbrs r30, 5 + 1566: fc cf rjmp .-8 ; 0x1560 + 1568: c0 93 9c 00 sts 0x009C, r28 + 156c: e0 91 9b 00 lds r30, 0x009B + 1570: e5 ff sbrs r30, 5 + 1572: fc cf rjmp .-8 ; 0x156c + 1574: 30 93 9c 00 sts 0x009C, r19 + 1578: 30 91 9b 00 lds r19, 0x009B + 157c: 35 ff sbrs r19, 5 + 157e: fc cf rjmp .-8 ; 0x1578 + 1580: 20 93 9c 00 sts 0x009C, r18 + 1584: 20 91 9b 00 lds r18, 0x009B + 1588: 25 ff sbrs r18, 5 + 158a: fc cf rjmp .-8 ; 0x1584 + 158c: 40 93 9c 00 sts 0x009C, r20 + 1590: 20 91 9b 00 lds r18, 0x009B + 1594: 25 ff sbrs r18, 5 + 1596: fc cf rjmp .-8 ; 0x1590 + 1598: 40 93 9c 00 sts 0x009C, r20 + 159c: 20 91 9b 00 lds r18, 0x009B + 15a0: 25 ff sbrs r18, 5 + 15a2: fc cf rjmp .-8 ; 0x159c + 15a4: d0 93 9c 00 sts 0x009C, r29 + 15a8: 20 91 9b 00 lds r18, 0x009B + 15ac: 25 ff sbrs r18, 5 + 15ae: fc cf rjmp .-8 ; 0x15a8 + + uint16_t addr; + uint16_t startAddr = hiAddr<<8; + 15b0: f8 2f mov r31, r24 + 15b2: ee 27 eor r30, r30 + uint16_t stopAddr = startAddr + 0xFF; + 15b4: 9f 01 movw r18, r30 + 15b6: 21 50 subi r18, 0x01 ; 1 + 15b8: 3f 4f sbci r19, 0xFF ; 255 + + for (addr = startAddr; addr <= stopAddr; addr++) + 15ba: df 01 movw r26, r30 + 15bc: 04 c0 rjmp .+8 ; 0x15c6 + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + 15be: 7d 01 movw r14, r26 + 15c0: f6 94 lsr r15 + 15c2: e7 94 ror r14 + 15c4: ed 92 st X+, r14 + + uint16_t addr; + uint16_t startAddr = hiAddr<<8; + uint16_t stopAddr = startAddr + 0xFF; + + for (addr = startAddr; addr <= stopAddr; addr++) + 15c6: 2a 17 cp r18, r26 + 15c8: 3b 07 cpc r19, r27 + 15ca: c8 f7 brcc .-14 ; 0x15be + 15cc: 99 24 eor r9, r9 + 15ce: 93 94 inc r9 + 15d0: 09 c0 rjmp .+18 ; 0x15e4 + 15d2: df 01 movw r26, r30 + 15d4: 11 96 adiw r26, 0x01 ; 1 + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + 15d6: 7f 01 movw r14, r30 + 15d8: f6 94 lsr r15 + 15da: e7 94 ror r14 + 15dc: e0 81 ld r30, Z + 15de: ee 11 cpse r30, r14 + isOK = 0; + 15e0: 91 2c mov r9, r1 + 15e2: fd 01 movw r30, r26 + + for (addr = startAddr; addr <= stopAddr; addr++) + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + 15e4: 2e 17 cp r18, r30 + 15e6: 3f 07 cpc r19, r31 + 15e8: a0 f7 brcc .-24 ; 0x15d2 + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + 15ea: 21 e0 ldi r18, 0x01 ; 1 + 15ec: 92 12 cpse r9, r18 + 15ee: 18 c0 rjmp .+48 ; 0x1620 + 15f0: b0 92 9c 00 sts 0x009C, r11 + 15f4: 20 91 9b 00 lds r18, 0x009B + 15f8: 25 ff sbrs r18, 5 + 15fa: fc cf rjmp .-8 ; 0x15f4 + 15fc: a0 92 9c 00 sts 0x009C, r10 + 1600: 20 91 9b 00 lds r18, 0x009B + 1604: 25 ff sbrs r18, 5 + 1606: fc cf rjmp .-8 ; 0x1600 + 1608: 50 93 9c 00 sts 0x009C, r21 + 160c: 20 91 9b 00 lds r18, 0x009B + 1610: 25 ff sbrs r18, 5 + 1612: fc cf rjmp .-8 ; 0x160c + 1614: 01 96 adiw r24, 0x01 ; 1 + UCSR1B = 1< + 161c: 8a cf rjmp .-236 ; 0x1532 + 161e: 1f c0 rjmp .+62 ; 0x165e + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 1620: 10 93 9c 00 sts 0x009C, r17 + 1624: 20 91 9b 00 lds r18, 0x009B + 1628: 25 ff sbrs r18, 5 + 162a: fc cf rjmp .-8 ; 0x1624 + 162c: 00 93 9c 00 sts 0x009C, r16 + 1630: 20 91 9b 00 lds r18, 0x009B + 1634: 25 ff sbrs r18, 5 + 1636: fc cf rjmp .-8 ; 0x1630 + 1638: d0 92 9c 00 sts 0x009C, r13 + 163c: 20 91 9b 00 lds r18, 0x009B + 1640: 25 ff sbrs r18, 5 + 1642: fc cf rjmp .-8 ; 0x163c + 1644: c0 92 9c 00 sts 0x009C, r12 + 1648: 20 91 9b 00 lds r18, 0x009B + 164c: 25 ff sbrs r18, 5 + 164e: fc cf rjmp .-8 ; 0x1648 + 1650: 50 93 9c 00 sts 0x009C, r21 + 1654: 20 91 9b 00 lds r18, 0x009B + 1658: 25 ff sbrs r18, 5 + 165a: fc cf rjmp .-8 ; 0x1654 + 165c: db cf rjmp .-74 ; 0x1614 + } + SND ('\r') SND ('\n') + 165e: 8d e0 ldi r24, 0x0D ; 13 + 1660: 80 93 9c 00 sts 0x009C, r24 + 1664: 80 91 9b 00 lds r24, 0x009B + 1668: 85 ff sbrs r24, 5 + 166a: fc cf rjmp .-8 ; 0x1664 + 166c: 8a e0 ldi r24, 0x0A ; 10 + 166e: 80 93 9c 00 sts 0x009C, r24 + 1672: 80 91 9b 00 lds r24, 0x009B + 1676: 85 ff sbrs r24, 5 + 1678: fc cf rjmp .-8 ; 0x1672 + +0000167a <__do_copy_data>: +#undef SND +#endif +} + 167a: 11 e0 ldi r17, 0x01 ; 1 + 167c: a0 e0 ldi r26, 0x00 ; 0 + 167e: b1 e0 ldi r27, 0x01 ; 1 + 1680: e4 eb ldi r30, 0xB4 ; 180 + 1682: f7 ea ldi r31, 0xA7 ; 167 + 1684: 00 e0 ldi r16, 0x00 ; 0 + 1686: 0b bf out 0x3b, r16 ; 59 + 1688: 02 c0 rjmp .+4 ; 0x168e <__do_copy_data+0x14> + 168a: 07 90 elpm r0, Z+ + 168c: 0d 92 st X+, r0 + 168e: a8 38 cpi r26, 0x88 ; 136 + 1690: b1 07 cpc r27, r17 + 1692: d9 f7 brne .-10 ; 0x168a <__do_copy_data+0x10> + +00001694 <__do_clear_bss>: + 1694: 2f e0 ldi r18, 0x0F ; 15 + 1696: a8 e8 ldi r26, 0x88 ; 136 + 1698: b1 e0 ldi r27, 0x01 ; 1 + 169a: 01 c0 rjmp .+2 ; 0x169e <.do_clear_bss_start> + +0000169c <.do_clear_bss_loop>: + 169c: 1d 92 st X+, r1 + +0000169e <.do_clear_bss_start>: + 169e: a2 3e cpi r26, 0xE2 ; 226 + 16a0: b2 07 cpc r27, r18 + 16a2: e1 f7 brne .-8 ; 0x169c <.do_clear_bss_loop> + 16a4: 0e 94 5d 4c call 0x98ba ; 0x98ba
+ 16a8: 0c 94 d8 53 jmp 0xa7b0 ; 0xa7b0 <_exit> + +000016ac <__bad_interrupt>: + 16ac: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> + +000016b0 : + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + 16b0: 0e 94 88 49 call 0x9310 ; 0x9310 + } + 16b4: fd cf rjmp .-6 ; 0x16b0 + +000016b6 : +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + 16b6: 80 91 00 01 lds r24, 0x0100 + 16ba: 81 50 subi r24, 0x01 ; 1 + 16bc: 19 f0 breq .+6 ; 0x16c4 + 16be: 80 93 00 01 sts 0x0100, r24 + 16c2: 08 95 ret + { + tickCntr = configTICK_RATE_HZ; + 16c4: 84 e6 ldi r24, 0x64 ; 100 + 16c6: 80 93 00 01 sts 0x0100, r24 + arpTimer(); + 16ca: 0c 94 84 30 jmp 0x6108 ; 0x6108 + +000016ce : +uint16_t udpPortSrcEep __attribute__((section (".eeprom"))); + + +void loadConfiguration(void) +{ + eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); + 16ce: 48 e1 ldi r20, 0x18 ; 24 + 16d0: 50 e0 ldi r21, 0x00 ; 0 + 16d2: 68 e0 ldi r22, 0x08 ; 8 + 16d4: 70 e0 ldi r23, 0x00 ; 0 + 16d6: 80 91 a0 0e lds r24, 0x0EA0 + 16da: 90 91 a1 0e lds r25, 0x0EA1 + 16de: 0c 94 3d 53 jmp 0xa67a ; 0xa67a + +000016e2 : +} + +void saveConfiguration(void) +{ + //saveNic(); + ipSaveConfig(); + 16e2: 0e 94 31 2d call 0x5a62 ; 0x5a62 + udpSaveConfig(); + 16e6: 0c 94 50 38 jmp 0x70a0 ; 0x70a0 + +000016ea : + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + 16ea: cf 93 push r28 + 16ec: df 93 push r29 + 16ee: 1f 92 push r1 + 16f0: cd b7 in r28, 0x3d ; 61 + 16f2: de b7 in r29, 0x3e ; 62 + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + 16f4: 20 e0 ldi r18, 0x00 ; 0 + 16f6: 4f ef ldi r20, 0xFF ; 255 + 16f8: 5f ef ldi r21, 0xFF ; 255 + 16fa: be 01 movw r22, r28 + 16fc: 6f 5f subi r22, 0xFF ; 255 + 16fe: 7f 4f sbci r23, 0xFF ; 255 + 1700: 80 91 ac 0e lds r24, 0x0EAC + 1704: 90 91 ad 0e lds r25, 0x0EAD + 1708: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 170c: 88 23 and r24, r24 + 170e: 19 f0 breq .+6 ; 0x1716 + return EOF; + return c; + 1710: 89 81 ldd r24, Y+1 ; 0x01 + 1712: 90 e0 ldi r25, 0x00 ; 0 + 1714: 02 c0 rjmp .+4 ; 0x171a +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + 1716: 8f ef ldi r24, 0xFF ; 255 + 1718: 9f ef ldi r25, 0xFF ; 255 + return c; +} + 171a: 0f 90 pop r0 + 171c: df 91 pop r29 + 171e: cf 91 pop r28 + 1720: 08 95 ret + +00001722 : +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + 1722: fc 01 movw r30, r24 + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + 1724: 8a e3 ldi r24, 0x3A ; 58 + 1726: 9d e0 ldi r25, 0x0D ; 13 + 1728: 91 87 std Z+9, r25 ; 0x09 + 172a: 80 87 std Z+8, r24 ; 0x08 + 172c: 85 e7 ldi r24, 0x75 ; 117 + 172e: 9b e0 ldi r25, 0x0B ; 11 + 1730: 93 87 std Z+11, r25 ; 0x0b + 1732: 82 87 std Z+10, r24 ; 0x0a + 1734: 83 e0 ldi r24, 0x03 ; 3 + 1736: 83 83 std Z+3, r24 ; 0x03 + 1738: 15 86 std Z+13, r1 ; 0x0d + 173a: 14 86 std Z+12, r1 ; 0x0c + 173c: 08 95 ret + +0000173e : + return 0; +} + +void xSerialPortInitMinimal(void) +{ + portENTER_CRITICAL(); + 173e: 0f b6 in r0, 0x3f ; 63 + 1740: f8 94 cli + 1742: 0f 92 push r0 + { + xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + 1744: 61 e0 ldi r22, 0x01 ; 1 + 1746: 80 e4 ldi r24, 0x40 ; 64 + 1748: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 174c: 90 93 ad 0e sts 0x0EAD, r25 + 1750: 80 93 ac 0e sts 0x0EAC, r24 + xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + 1754: 61 e0 ldi r22, 0x01 ; 1 + 1756: 80 e2 ldi r24, 0x20 ; 32 + 1758: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 175c: 90 93 7c 0e sts 0x0E7C, r25 + 1760: 80 93 7b 0e sts 0x0E7B, r24 + xRs485Rec = xQueueCreate( 16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + 1764: 61 e0 ldi r22, 0x01 ; 1 + 1766: 80 e1 ldi r24, 0x10 ; 16 + 1768: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 176c: 90 93 9d 0e sts 0x0E9D, r25 + 1770: 80 93 9c 0e sts 0x0E9C, r24 + xRs485Tx = xQueueCreate( 4, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + 1774: 61 e0 ldi r22, 0x01 ; 1 + 1776: 84 e0 ldi r24, 0x04 ; 4 + 1778: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 177c: 90 93 c4 0e sts 0x0EC4, r25 + 1780: 80 93 c3 0e sts 0x0EC3, r24 + + vSemaphoreCreateBinary(xSemaphoreRs485); + 1784: 60 e0 ldi r22, 0x00 ; 0 + 1786: 81 e0 ldi r24, 0x01 ; 1 + 1788: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 178c: 90 93 b0 0e sts 0x0EB0, r25 + 1790: 80 93 af 0e sts 0x0EAF, r24 + 1794: 00 97 sbiw r24, 0x00 ; 0 + 1796: 39 f0 breq .+14 ; 0x17a6 + 1798: 20 e0 ldi r18, 0x00 ; 0 + 179a: 40 e0 ldi r20, 0x00 ; 0 + 179c: 50 e0 ldi r21, 0x00 ; 0 + 179e: 60 e0 ldi r22, 0x00 ; 0 + 17a0: 70 e0 ldi r23, 0x00 ; 0 + 17a2: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + } + portEXIT_CRITICAL(); + 17a6: 0f 90 pop r0 + 17a8: 0f be out 0x3f, r0 ; 63 + + UBRR0L = 7; + 17aa: 87 e0 ldi r24, 0x07 ; 7 + 17ac: 89 b9 out 0x09, r24 ; 9 + UBRR0H = 0; + 17ae: 10 92 90 00 sts 0x0090, r1 + + UBRR1L = 7; + 17b2: 80 93 99 00 sts 0x0099, r24 + UBRR1H = 0; + 17b6: 10 92 98 00 sts 0x0098, r1 + + UCSR0B = ((1<: + return; +} + +/*-----------------------------------------------------------*/ +ISR(USART0_RX_vect) +{ + 17d0: 1f 92 push r1 + 17d2: 0f 92 push r0 + 17d4: 0f b6 in r0, 0x3f ; 63 + 17d6: 0f 92 push r0 + 17d8: 11 24 eor r1, r1 + 17da: 0b b6 in r0, 0x3b ; 59 + 17dc: 0f 92 push r0 + 17de: 2f 93 push r18 + 17e0: 3f 93 push r19 + 17e2: 4f 93 push r20 + 17e4: 5f 93 push r21 + 17e6: 6f 93 push r22 + 17e8: 7f 93 push r23 + 17ea: 8f 93 push r24 + 17ec: 9f 93 push r25 + 17ee: af 93 push r26 + 17f0: bf 93 push r27 + 17f2: ef 93 push r30 + 17f4: ff 93 push r31 + 17f6: cf 93 push r28 + 17f8: df 93 push r29 + 17fa: 1f 92 push r1 + 17fc: cd b7 in r28, 0x3d ; 61 + 17fe: de b7 in r29, 0x3e ; 62 + static signed portBASE_TYPE xHigherPriorityTaskWoken = pdTRUE; + signed portCHAR cChar; + + cChar = UDR0; + 1800: 8c b1 in r24, 0x0c ; 12 + 1802: 89 83 std Y+1, r24 ; 0x01 + + xHigherPriorityTaskWoken = pdFALSE; + 1804: 10 92 01 01 sts 0x0101, r1 + +// xQueueSendFromISR( xRs485Rec, &cChar, NULL); + xQueueSendFromISR( xRs485Rec, &cChar, &xHigherPriorityTaskWoken ); + 1808: 20 e0 ldi r18, 0x00 ; 0 + 180a: 41 e0 ldi r20, 0x01 ; 1 + 180c: 51 e0 ldi r21, 0x01 ; 1 + 180e: be 01 movw r22, r28 + 1810: 6f 5f subi r22, 0xFF ; 255 + 1812: 7f 4f sbci r23, 0xFF ; 255 + 1814: 80 91 9c 0e lds r24, 0x0E9C + 1818: 90 91 9d 0e lds r25, 0x0E9D + 181c: 0e 94 36 47 call 0x8e6c ; 0x8e6c + if( xHigherPriorityTaskWoken ) + 1820: 80 91 01 01 lds r24, 0x0101 + 1824: 81 11 cpse r24, r1 + { + taskYIELD(); + 1826: 0e 94 81 4b call 0x9702 ; 0x9702 + } +} + 182a: 0f 90 pop r0 + 182c: df 91 pop r29 + 182e: cf 91 pop r28 + 1830: ff 91 pop r31 + 1832: ef 91 pop r30 + 1834: bf 91 pop r27 + 1836: af 91 pop r26 + 1838: 9f 91 pop r25 + 183a: 8f 91 pop r24 + 183c: 7f 91 pop r23 + 183e: 6f 91 pop r22 + 1840: 5f 91 pop r21 + 1842: 4f 91 pop r20 + 1844: 3f 91 pop r19 + 1846: 2f 91 pop r18 + 1848: 0f 90 pop r0 + 184a: 0b be out 0x3b, r0 ; 59 + 184c: 0f 90 pop r0 + 184e: 0f be out 0x3f, r0 ; 63 + 1850: 0f 90 pop r0 + 1852: 1f 90 pop r1 + 1854: 18 95 reti + +00001856 : + +void uartRs485SendByte(uint8_t data) +{ + 1856: cf 93 push r28 + 1858: df 93 push r29 + 185a: 1f 92 push r1 + 185c: cd b7 in r28, 0x3d ; 61 + 185e: de b7 in r29, 0x3e ; 62 + 1860: 89 83 std Y+1, r24 ; 0x01 + xQueueSend(xRs485Tx, &data, portMAX_DELAY); + 1862: 20 e0 ldi r18, 0x00 ; 0 + 1864: 4f ef ldi r20, 0xFF ; 255 + 1866: 5f ef ldi r21, 0xFF ; 255 + 1868: be 01 movw r22, r28 + 186a: 6f 5f subi r22, 0xFF ; 255 + 186c: 7f 4f sbci r23, 0xFF ; 255 + 186e: 80 91 c3 0e lds r24, 0x0EC3 + 1872: 90 91 c4 0e lds r25, 0x0EC4 + 1876: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + vInterruptRs485On(); + 187a: 55 9a sbi 0x0a, 5 ; 10 +} + 187c: 0f 90 pop r0 + 187e: df 91 pop r29 + 1880: cf 91 pop r28 + 1882: 08 95 ret + +00001884 : + +uint8_t rs485Receive(uint8_t *c, uint8_t timeout) +{ + return xQueueReceive(xRs485Rec, c, timeout); + 1884: 46 2f mov r20, r22 + 1886: 50 e0 ldi r21, 0x00 ; 0 + 1888: 20 e0 ldi r18, 0x00 ; 0 + 188a: bc 01 movw r22, r24 + 188c: 80 91 9c 0e lds r24, 0x0E9C + 1890: 90 91 9d 0e lds r25, 0x0E9D + 1894: 0c 94 5e 47 jmp 0x8ebc ; 0x8ebc + +00001898 <__vector_19>: +} + +ISR(USART0_UDRE_vect) +{ + 1898: 1f 92 push r1 + 189a: 0f 92 push r0 + 189c: 0f b6 in r0, 0x3f ; 63 + 189e: 0f 92 push r0 + 18a0: 11 24 eor r1, r1 + 18a2: 0b b6 in r0, 0x3b ; 59 + 18a4: 0f 92 push r0 + 18a6: 2f 93 push r18 + 18a8: 3f 93 push r19 + 18aa: 4f 93 push r20 + 18ac: 5f 93 push r21 + 18ae: 6f 93 push r22 + 18b0: 7f 93 push r23 + 18b2: 8f 93 push r24 + 18b4: 9f 93 push r25 + 18b6: af 93 push r26 + 18b8: bf 93 push r27 + 18ba: ef 93 push r30 + 18bc: ff 93 push r31 + static signed portBASE_TYPE xHigherPriorityTaskWoken; + static char data; + if(xQueueReceiveFromISR(xRs485Tx, (void *)(&data), &xHigherPriorityTaskWoken) == pdTRUE) + 18be: 4c e8 ldi r20, 0x8C ; 140 + 18c0: 51 e0 ldi r21, 0x01 ; 1 + 18c2: 6d e8 ldi r22, 0x8D ; 141 + 18c4: 71 e0 ldi r23, 0x01 ; 1 + 18c6: 80 91 c3 0e lds r24, 0x0EC3 + 18ca: 90 91 c4 0e lds r25, 0x0EC4 + 18ce: 0e 94 02 48 call 0x9004 ; 0x9004 + 18d2: 81 30 cpi r24, 0x01 ; 1 + 18d4: 49 f4 brne .+18 ; 0x18e8 <__vector_19+0x50> + { + Rs485TxStart(); + 18d6: 80 91 65 00 lds r24, 0x0065 + 18da: 80 61 ori r24, 0x10 ; 16 + 18dc: 80 93 65 00 sts 0x0065, r24 + UDR0 = data; + 18e0: 80 91 8d 01 lds r24, 0x018D + 18e4: 8c b9 out 0x0c, r24 ; 12 + 18e6: 03 c0 rjmp .+6 ; 0x18ee <__vector_19+0x56> + } + else + { + xHigherPriorityTaskWoken = pdFALSE; + 18e8: 10 92 8c 01 sts 0x018C, r1 + vInterruptRs485Off(); + 18ec: 55 98 cbi 0x0a, 5 ; 10 + } + if( xHigherPriorityTaskWoken ) + 18ee: 80 91 8c 01 lds r24, 0x018C + 18f2: 81 11 cpse r24, r1 + { + taskYIELD(); + 18f4: 0e 94 81 4b call 0x9702 ; 0x9702 + } +} + 18f8: ff 91 pop r31 + 18fa: ef 91 pop r30 + 18fc: bf 91 pop r27 + 18fe: af 91 pop r26 + 1900: 9f 91 pop r25 + 1902: 8f 91 pop r24 + 1904: 7f 91 pop r23 + 1906: 6f 91 pop r22 + 1908: 5f 91 pop r21 + 190a: 4f 91 pop r20 + 190c: 3f 91 pop r19 + 190e: 2f 91 pop r18 + 1910: 0f 90 pop r0 + 1912: 0b be out 0x3b, r0 ; 59 + 1914: 0f 90 pop r0 + 1916: 0f be out 0x3f, r0 ; 63 + 1918: 0f 90 pop r0 + 191a: 1f 90 pop r1 + 191c: 18 95 reti + +0000191e <__vector_20>: + +ISR(USART0_TX_vect) +{ + 191e: 1f 92 push r1 + 1920: 0f 92 push r0 + 1922: 0f b6 in r0, 0x3f ; 63 + 1924: 0f 92 push r0 + 1926: 11 24 eor r1, r1 + 1928: 8f 93 push r24 + if (!vIsInterruptRs485On()) + 192a: 55 99 sbic 0x0a, 5 ; 10 + 192c: 05 c0 rjmp .+10 ; 0x1938 <__vector_20+0x1a> + Rs485TxStop(); + 192e: 80 91 65 00 lds r24, 0x0065 + 1932: 8f 7e andi r24, 0xEF ; 239 + 1934: 80 93 65 00 sts 0x0065, r24 +} + 1938: 8f 91 pop r24 + 193a: 0f 90 pop r0 + 193c: 0f be out 0x3f, r0 ; 63 + 193e: 0f 90 pop r0 + 1940: 1f 90 pop r1 + 1942: 18 95 reti + +00001944 : + +uint8_t flushRs485RecBuffer(void) +{ + 1944: 1f 93 push r17 + 1946: cf 93 push r28 + 1948: df 93 push r29 + 194a: 1f 92 push r1 + 194c: cd b7 in r28, 0x3d ; 61 + 194e: de b7 in r29, 0x3e ; 62 + uint8_t temp; + uint8_t wynik = 0; + 1950: 10 e0 ldi r17, 0x00 ; 0 + while(xQueueReceive(xRs485Rec, &temp, 10) == pdTRUE) + 1952: 20 e0 ldi r18, 0x00 ; 0 + 1954: 4a e0 ldi r20, 0x0A ; 10 + 1956: 50 e0 ldi r21, 0x00 ; 0 + 1958: be 01 movw r22, r28 + 195a: 6f 5f subi r22, 0xFF ; 255 + 195c: 7f 4f sbci r23, 0xFF ; 255 + 195e: 80 91 9c 0e lds r24, 0x0E9C + 1962: 90 91 9d 0e lds r25, 0x0E9D + 1966: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 196a: 81 30 cpi r24, 0x01 ; 1 + 196c: 11 f4 brne .+4 ; 0x1972 + wynik++; + 196e: 1f 5f subi r17, 0xFF ; 255 + 1970: f0 cf rjmp .-32 ; 0x1952 + + return wynik; +} + 1972: 81 2f mov r24, r17 + 1974: 0f 90 pop r0 + 1976: df 91 pop r29 + 1978: cf 91 pop r28 + 197a: 1f 91 pop r17 + 197c: 08 95 ret + +0000197e : + +void takeRs485(void) +{ + xSemaphoreTake(xSemaphoreRs485, portMAX_DELAY); + 197e: 20 e0 ldi r18, 0x00 ; 0 + 1980: 4f ef ldi r20, 0xFF ; 255 + 1982: 5f ef ldi r21, 0xFF ; 255 + 1984: 60 e0 ldi r22, 0x00 ; 0 + 1986: 70 e0 ldi r23, 0x00 ; 0 + 1988: 80 91 af 0e lds r24, 0x0EAF + 198c: 90 91 b0 0e lds r25, 0x0EB0 + 1990: 0c 94 5e 47 jmp 0x8ebc ; 0x8ebc + +00001994 : +} + +void releaseRs485(void) +{ + xSemaphoreGive(xSemaphoreRs485); + 1994: 20 e0 ldi r18, 0x00 ; 0 + 1996: 40 e0 ldi r20, 0x00 ; 0 + 1998: 50 e0 ldi r21, 0x00 ; 0 + 199a: 60 e0 ldi r22, 0x00 ; 0 + 199c: 70 e0 ldi r23, 0x00 ; 0 + 199e: 80 91 af 0e lds r24, 0x0EAF + 19a2: 90 91 b0 0e lds r25, 0x0EB0 + 19a6: 0c 94 a2 46 jmp 0x8d44 ; 0x8d44 + +000019aa : +} + +void InterruptVtyOn(void) +{ + unsigned portCHAR ucByte; + ucByte = UCSR1B; + 19aa: ea e9 ldi r30, 0x9A ; 154 + 19ac: f0 e0 ldi r31, 0x00 ; 0 + 19ae: 80 81 ld r24, Z + ucByte |= serDATA_INT_ENABLE; + 19b0: 80 62 ori r24, 0x20 ; 32 + UCSR1B = ucByte; + 19b2: 80 83 st Z, r24 + 19b4: 08 95 ret + +000019b6 <__vector_30>: +} + +/*-----------------------------------------------------------*/ +ISR(USART1_RX_vect) +{ + 19b6: 1f 92 push r1 + 19b8: 0f 92 push r0 + 19ba: 0f b6 in r0, 0x3f ; 63 + 19bc: 0f 92 push r0 + 19be: 11 24 eor r1, r1 + 19c0: 0b b6 in r0, 0x3b ; 59 + 19c2: 0f 92 push r0 + 19c4: 2f 93 push r18 + 19c6: 3f 93 push r19 + 19c8: 4f 93 push r20 + 19ca: 5f 93 push r21 + 19cc: 6f 93 push r22 + 19ce: 7f 93 push r23 + 19d0: 8f 93 push r24 + 19d2: 9f 93 push r25 + 19d4: af 93 push r26 + 19d6: bf 93 push r27 + 19d8: ef 93 push r30 + 19da: ff 93 push r31 + 19dc: cf 93 push r28 + 19de: df 93 push r29 + 19e0: 1f 92 push r1 + 19e2: cd b7 in r28, 0x3d ; 61 + 19e4: de b7 in r29, 0x3e ; 62 + static signed portBASE_TYPE xHigherPriorityTaskWoken; + signed portCHAR cChar; + + cChar = UDR1; + 19e6: 80 91 9c 00 lds r24, 0x009C + 19ea: 89 83 std Y+1, r24 ; 0x01 +// xQueueSendFromISR(xVtyRec, &cChar, NULL); + + xHigherPriorityTaskWoken = pdFALSE; + 19ec: 10 92 8b 01 sts 0x018B, r1 + xQueueSendFromISR(xVtyRec, &cChar, &xHigherPriorityTaskWoken); + 19f0: 20 e0 ldi r18, 0x00 ; 0 + 19f2: 4b e8 ldi r20, 0x8B ; 139 + 19f4: 51 e0 ldi r21, 0x01 ; 1 + 19f6: be 01 movw r22, r28 + 19f8: 6f 5f subi r22, 0xFF ; 255 + 19fa: 7f 4f sbci r23, 0xFF ; 255 + 19fc: 80 91 ac 0e lds r24, 0x0EAC + 1a00: 90 91 ad 0e lds r25, 0x0EAD + 1a04: 0e 94 36 47 call 0x8e6c ; 0x8e6c + if( xHigherPriorityTaskWoken ) + 1a08: 80 91 8b 01 lds r24, 0x018B + 1a0c: 81 11 cpse r24, r1 + { + taskYIELD(); + 1a0e: 0e 94 81 4b call 0x9702 ; 0x9702 + } +} + 1a12: 0f 90 pop r0 + 1a14: df 91 pop r29 + 1a16: cf 91 pop r28 + 1a18: ff 91 pop r31 + 1a1a: ef 91 pop r30 + 1a1c: bf 91 pop r27 + 1a1e: af 91 pop r26 + 1a20: 9f 91 pop r25 + 1a22: 8f 91 pop r24 + 1a24: 7f 91 pop r23 + 1a26: 6f 91 pop r22 + 1a28: 5f 91 pop r21 + 1a2a: 4f 91 pop r20 + 1a2c: 3f 91 pop r19 + 1a2e: 2f 91 pop r18 + 1a30: 0f 90 pop r0 + 1a32: 0b be out 0x3b, r0 ; 59 + 1a34: 0f 90 pop r0 + 1a36: 0f be out 0x3f, r0 ; 63 + 1a38: 0f 90 pop r0 + 1a3a: 1f 90 pop r1 + 1a3c: 18 95 reti + +00001a3e : + +void uartVtySendByte(uint8_t data) +{ + 1a3e: cf 93 push r28 + 1a40: df 93 push r29 + 1a42: 1f 92 push r1 + 1a44: cd b7 in r28, 0x3d ; 61 + 1a46: de b7 in r29, 0x3e ; 62 + 1a48: 89 83 std Y+1, r24 ; 0x01 + xQueueSend(xVtyTx, &data, portMAX_DELAY); + 1a4a: 20 e0 ldi r18, 0x00 ; 0 + 1a4c: 4f ef ldi r20, 0xFF ; 255 + 1a4e: 5f ef ldi r21, 0xFF ; 255 + 1a50: be 01 movw r22, r28 + 1a52: 6f 5f subi r22, 0xFF ; 255 + 1a54: 7f 4f sbci r23, 0xFF ; 255 + 1a56: 80 91 7b 0e lds r24, 0x0E7B + 1a5a: 90 91 7c 0e lds r25, 0x0E7C + 1a5e: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + vInterruptVtyOn(); + 1a62: ea e9 ldi r30, 0x9A ; 154 + 1a64: f0 e0 ldi r31, 0x00 ; 0 + 1a66: 80 81 ld r24, Z + 1a68: 80 62 ori r24, 0x20 ; 32 + 1a6a: 80 83 st Z, r24 +} + 1a6c: 0f 90 pop r0 + 1a6e: df 91 pop r29 + 1a70: cf 91 pop r28 + 1a72: 08 95 ret + +00001a74 : +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + 1a74: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + return 0; +} + 1a78: 80 e0 ldi r24, 0x00 ; 0 + 1a7a: 90 e0 ldi r25, 0x00 ; 0 + 1a7c: 08 95 ret + +00001a7e <__vector_31>: + xQueueSend(xVtyTx, &data, portMAX_DELAY); + vInterruptVtyOn(); +} + +ISR(USART1_UDRE_vect) +{ + 1a7e: 1f 92 push r1 + 1a80: 0f 92 push r0 + 1a82: 0f b6 in r0, 0x3f ; 63 + 1a84: 0f 92 push r0 + 1a86: 11 24 eor r1, r1 + 1a88: 0b b6 in r0, 0x3b ; 59 + 1a8a: 0f 92 push r0 + 1a8c: 2f 93 push r18 + 1a8e: 3f 93 push r19 + 1a90: 4f 93 push r20 + 1a92: 5f 93 push r21 + 1a94: 6f 93 push r22 + 1a96: 7f 93 push r23 + 1a98: 8f 93 push r24 + 1a9a: 9f 93 push r25 + 1a9c: af 93 push r26 + 1a9e: bf 93 push r27 + 1aa0: ef 93 push r30 + 1aa2: ff 93 push r31 + static signed portBASE_TYPE xHigherPriorityTaskWoken; + static char data; + if(xQueueReceiveFromISR(xVtyTx, &data, &xHigherPriorityTaskWoken) == pdTRUE) + 1aa4: 49 e8 ldi r20, 0x89 ; 137 + 1aa6: 51 e0 ldi r21, 0x01 ; 1 + 1aa8: 6a e8 ldi r22, 0x8A ; 138 + 1aaa: 71 e0 ldi r23, 0x01 ; 1 + 1aac: 80 91 7b 0e lds r24, 0x0E7B + 1ab0: 90 91 7c 0e lds r25, 0x0E7C + 1ab4: 0e 94 02 48 call 0x9004 ; 0x9004 + 1ab8: 81 30 cpi r24, 0x01 ; 1 + 1aba: 29 f4 brne .+10 ; 0x1ac6 <__vector_31+0x48> + { + UDR1 = data; + 1abc: 80 91 8a 01 lds r24, 0x018A + 1ac0: 80 93 9c 00 sts 0x009C, r24 + 1ac4: 07 c0 rjmp .+14 ; 0x1ad4 <__vector_31+0x56> + } + else + { + xHigherPriorityTaskWoken = pdFALSE; + 1ac6: 10 92 89 01 sts 0x0189, r1 + vInterruptVtyOff(); + 1aca: 80 91 9a 00 lds r24, 0x009A + 1ace: 8f 7d andi r24, 0xDF ; 223 + 1ad0: 80 93 9a 00 sts 0x009A, r24 + } + if( xHigherPriorityTaskWoken ) + 1ad4: 80 91 89 01 lds r24, 0x0189 + 1ad8: 81 11 cpse r24, r1 + { + taskYIELD(); + 1ada: 0e 94 81 4b call 0x9702 ; 0x9702 + } +} + 1ade: ff 91 pop r31 + 1ae0: ef 91 pop r30 + 1ae2: bf 91 pop r27 + 1ae4: af 91 pop r26 + 1ae6: 9f 91 pop r25 + 1ae8: 8f 91 pop r24 + 1aea: 7f 91 pop r23 + 1aec: 6f 91 pop r22 + 1aee: 5f 91 pop r21 + 1af0: 4f 91 pop r20 + 1af2: 3f 91 pop r19 + 1af4: 2f 91 pop r18 + 1af6: 0f 90 pop r0 + 1af8: 0b be out 0x3b, r0 ; 59 + 1afa: 0f 90 pop r0 + 1afc: 0f be out 0x3f, r0 ; 63 + 1afe: 0f 90 pop r0 + 1b00: 1f 90 pop r1 + 1b02: 18 95 reti + +00001b04 : +xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisjÄ™ do czasu zakoÅ„czenia wysyÅ‚ania poprzedniego bajtu + +void hardwareInit(void) +{ + //DDRA = 0x00; //External Memory + portENTER_CRITICAL(); + 1b04: 0f b6 in r0, 0x3f ; 63 + 1b06: f8 94 cli + 1b08: 0f 92 push r0 + xSpiRx = xQueueCreate(1, 1); + 1b0a: 61 e0 ldi r22, 0x01 ; 1 + 1b0c: 81 e0 ldi r24, 0x01 ; 1 + 1b0e: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 1b12: 90 93 61 0f sts 0x0F61, r25 + 1b16: 80 93 60 0f sts 0x0F60, r24 + portEXIT_CRITICAL(); + 1b1a: 0f 90 pop r0 + 1b1c: 0f be out 0x3f, r0 ; 63 + + DDRB = 0xF7; + 1b1e: 87 ef ldi r24, 0xF7 ; 247 + 1b20: 87 bb out 0x17, r24 ; 23 + PORTB = 0xD1; + 1b22: 81 ed ldi r24, 0xD1 ; 209 + 1b24: 88 bb out 0x18, r24 ; 24 + 7 - External SPI ASR 7 (MPC23S17) 0 - on; 1 - off + */ + + //DDRC = 0x00; //External Memory + + DDRD = 0x00; + 1b26: 11 ba out 0x11, r1 ; 17 + 5 - External SPI ASR 1 + 6 - External SPI ASR 2 + 7 - External SPI ASR 3 + */ + + DDRE = 0x0E; + 1b28: 8e e0 ldi r24, 0x0E ; 14 + 1b2a: 82 b9 out 0x02, r24 ; 2 + PORTE = 0x0C; + 1b2c: 8c e0 ldi r24, 0x0C ; 12 + 1b2e: 83 b9 out 0x03, r24 ; 3 + 4 - INT 4 + 5 - INT 5 + 6 - INT 6 + 7 - INT Enc28j60 + */ + DDRF = 0x00; //JTAG and A/C + 1b30: 10 92 61 00 sts 0x0061, r1 + DDRG = 0x1F; + 1b34: 8f e1 ldi r24, 0x1F ; 31 + 1b36: 80 93 64 00 sts 0x0064, r24 + 1b3a: 08 95 ret + +00001b3c : + */ +} + +void LockersMemInit(void) +{ + lockSensors = xmalloc(4 * sizeof(struct lockerSensor)); + 1b3c: 88 e1 ldi r24, 0x18 ; 24 + 1b3e: 90 e0 ldi r25, 0x00 ; 0 + 1b40: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 1b44: 90 93 a1 0e sts 0x0EA1, r25 + 1b48: 80 93 a0 0e sts 0x0EA0, r24 + 1b4c: 08 95 ret + +00001b4e : +} + +uint8_t printLockers(FILE *stream) +{ + 1b4e: 5f 92 push r5 + 1b50: 6f 92 push r6 + 1b52: 7f 92 push r7 + 1b54: 8f 92 push r8 + 1b56: 9f 92 push r9 + 1b58: af 92 push r10 + 1b5a: bf 92 push r11 + 1b5c: cf 92 push r12 + 1b5e: df 92 push r13 + 1b60: ef 92 push r14 + 1b62: ff 92 push r15 + 1b64: 0f 93 push r16 + 1b66: 1f 93 push r17 + 1b68: cf 93 push r28 + 1b6a: df 93 push r29 + 1b6c: 78 2e mov r7, r24 + 1b6e: 69 2e mov r6, r25 + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + 1b70: c0 91 a0 0e lds r28, 0x0EA0 + 1b74: d0 91 a1 0e lds r29, 0x0EA1 + 1b78: 01 e0 ldi r16, 0x01 ; 1 + 1b7a: 10 e0 ldi r17, 0x00 ; 0 +} + +uint8_t printLockers(FILE *stream) +{ + uint8_t i; + uint8_t result = 0; + 1b7c: 51 2c mov r5, r1 + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + { + if (tmpLock->enabled) + { + fprintf_P(stream, statusLockerSensDescStr, i); + 1b7e: 8d eb ldi r24, 0xBD ; 189 + 1b80: e8 2e mov r14, r24 + 1b82: 80 e0 ldi r24, 0x00 ; 0 + 1b84: f8 2e mov r15, r24 + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + else + fprintf_P(stream, statusLockerCloseStr); + fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + 1b86: 9c e8 ldi r25, 0x8C ; 140 + 1b88: c9 2e mov r12, r25 + 1b8a: 90 e0 ldi r25, 0x00 ; 0 + 1b8c: d9 2e mov r13, r25 + { + fprintf_P(stream, statusLockerSensDescStr, i); + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + else + fprintf_P(stream, statusLockerCloseStr); + 1b8e: 2b ea ldi r18, 0xAB ; 171 + 1b90: a2 2e mov r10, r18 + 1b92: 20 e0 ldi r18, 0x00 ; 0 + 1b94: b2 2e mov r11, r18 + { + if (tmpLock->enabled) + { + fprintf_P(stream, statusLockerSensDescStr, i); + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + 1b96: 34 eb ldi r19, 0xB4 ; 180 + 1b98: 83 2e mov r8, r19 + 1b9a: 30 e0 ldi r19, 0x00 ; 0 + 1b9c: 93 2e mov r9, r19 + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + { + if (tmpLock->enabled) + 1b9e: 88 81 ld r24, Y + 1ba0: 88 23 and r24, r24 + 1ba2: c9 f1 breq .+114 ; 0x1c16 + { + fprintf_P(stream, statusLockerSensDescStr, i); + 1ba4: 1f 93 push r17 + 1ba6: 0f 93 push r16 + 1ba8: ff 92 push r15 + 1baa: ef 92 push r14 + 1bac: 6f 92 push r6 + 1bae: 7f 92 push r7 + 1bb0: 0e 94 1a 50 call 0xa034 ; 0xa034 + if (tmpLock->threshold > tmpLock->acVal) + 1bb4: 0f 90 pop r0 + 1bb6: 0f 90 pop r0 + 1bb8: 0f 90 pop r0 + 1bba: 0f 90 pop r0 + 1bbc: 0f 90 pop r0 + 1bbe: 0f 90 pop r0 + 1bc0: 29 81 ldd r18, Y+1 ; 0x01 + 1bc2: 3a 81 ldd r19, Y+2 ; 0x02 + 1bc4: 8b 81 ldd r24, Y+3 ; 0x03 + 1bc6: 9c 81 ldd r25, Y+4 ; 0x04 + 1bc8: 82 17 cp r24, r18 + 1bca: 93 07 cpc r25, r19 + 1bcc: 18 f4 brcc .+6 ; 0x1bd4 + fprintf_P(stream, statusLockerOpenStr); + 1bce: 9f 92 push r9 + 1bd0: 8f 92 push r8 + 1bd2: 02 c0 rjmp .+4 ; 0x1bd8 + else + fprintf_P(stream, statusLockerCloseStr); + 1bd4: bf 92 push r11 + 1bd6: af 92 push r10 + 1bd8: 6f 92 push r6 + 1bda: 7f 92 push r7 + 1bdc: 0e 94 1a 50 call 0xa034 ; 0xa034 + 1be0: 0f 90 pop r0 + 1be2: 0f 90 pop r0 + 1be4: 0f 90 pop r0 + 1be6: 0f 90 pop r0 + fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + 1be8: 8c 81 ldd r24, Y+4 ; 0x04 + 1bea: 8f 93 push r24 + 1bec: 8b 81 ldd r24, Y+3 ; 0x03 + 1bee: 8f 93 push r24 + 1bf0: 8a 81 ldd r24, Y+2 ; 0x02 + 1bf2: 8f 93 push r24 + 1bf4: 89 81 ldd r24, Y+1 ; 0x01 + 1bf6: 8f 93 push r24 + 1bf8: df 92 push r13 + 1bfa: cf 92 push r12 + 1bfc: 6f 92 push r6 + 1bfe: 7f 92 push r7 + 1c00: 0e 94 1a 50 call 0xa034 ; 0xa034 + result++; + 1c04: 53 94 inc r5 + 1c06: 8d b7 in r24, 0x3d ; 61 + 1c08: 9e b7 in r25, 0x3e ; 62 + 1c0a: 08 96 adiw r24, 0x08 ; 8 + 1c0c: 0f b6 in r0, 0x3f ; 63 + 1c0e: f8 94 cli + 1c10: 9e bf out 0x3e, r25 ; 62 + 1c12: 0f be out 0x3f, r0 ; 63 + 1c14: 8d bf out 0x3d, r24 ; 61 + } + tmpLock++; + 1c16: 26 96 adiw r28, 0x06 ; 6 + 1c18: 0f 5f subi r16, 0xFF ; 255 + 1c1a: 1f 4f sbci r17, 0xFF ; 255 +uint8_t printLockers(FILE *stream) +{ + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + 1c1c: 05 30 cpi r16, 0x05 ; 5 + 1c1e: 11 05 cpc r17, r1 + 1c20: 09 f0 breq .+2 ; 0x1c24 + 1c22: bd cf rjmp .-134 ; 0x1b9e + result++; + } + tmpLock++; + } + return result; +} + 1c24: 85 2d mov r24, r5 + 1c26: df 91 pop r29 + 1c28: cf 91 pop r28 + 1c2a: 1f 91 pop r17 + 1c2c: 0f 91 pop r16 + 1c2e: ff 90 pop r15 + 1c30: ef 90 pop r14 + 1c32: df 90 pop r13 + 1c34: cf 90 pop r12 + 1c36: bf 90 pop r11 + 1c38: af 90 pop r10 + 1c3a: 9f 90 pop r9 + 1c3c: 8f 90 pop r8 + 1c3e: 7f 90 pop r7 + 1c40: 6f 90 pop r6 + 1c42: 5f 90 pop r5 + 1c44: 08 95 ret + +00001c46 : + +void checkLockerSensors(void) +{ + 1c46: cf 93 push r28 + 1c48: df 93 push r29 + if (lockSensors[0].enabled) + 1c4a: e0 91 a0 0e lds r30, 0x0EA0 + 1c4e: f0 91 a1 0e lds r31, 0x0EA1 + 1c52: 80 81 ld r24, Z + 1c54: 88 23 and r24, r24 + 1c56: 39 f1 breq .+78 ; 0x1ca6 + { + MPC23s17SetBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + 1c58: 60 e0 ldi r22, 0x00 ; 0 + 1c5a: 80 e4 ldi r24, 0x40 ; 64 + 1c5c: 0e 94 12 26 call 0x4c24 ; 0x4c24 + vTaskDelay(30); + 1c60: 8e e1 ldi r24, 0x1E ; 30 + 1c62: 90 e0 ldi r25, 0x00 ; 0 + 1c64: 0e 94 81 43 call 0x8702 ; 0x8702 + lockSensors[0].acVal = MCP3008_getSampleSingle(LOCK_SENS_1_AC_IN); + 1c68: c0 91 a0 0e lds r28, 0x0EA0 + 1c6c: d0 91 a1 0e lds r29, 0x0EA1 + 1c70: 84 e0 ldi r24, 0x04 ; 4 + 1c72: 0e 94 08 27 call 0x4e10 ; 0x4e10 + 1c76: 9c 83 std Y+4, r25 ; 0x04 + 1c78: 8b 83 std Y+3, r24 ; 0x03 + MPC23s17ClearBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + 1c7a: 60 e0 ldi r22, 0x00 ; 0 + 1c7c: 80 e4 ldi r24, 0x40 ; 64 + 1c7e: 0e 94 2f 26 call 0x4c5e ; 0x4c5e + lockSensors[0].locked = (lockSensors[0].acVal > lockSensors[0].threshold) ? 1 : 0; + 1c82: e0 91 a0 0e lds r30, 0x0EA0 + 1c86: f0 91 a1 0e lds r31, 0x0EA1 + 1c8a: 81 e0 ldi r24, 0x01 ; 1 + 1c8c: 43 81 ldd r20, Z+3 ; 0x03 + 1c8e: 54 81 ldd r21, Z+4 ; 0x04 + 1c90: 21 81 ldd r18, Z+1 ; 0x01 + 1c92: 32 81 ldd r19, Z+2 ; 0x02 + 1c94: 24 17 cp r18, r20 + 1c96: 35 07 cpc r19, r21 + 1c98: 08 f0 brcs .+2 ; 0x1c9c + 1c9a: 80 e0 ldi r24, 0x00 ; 0 + 1c9c: 85 83 std Z+5, r24 ; 0x05 + vTaskDelay(10); + 1c9e: 8a e0 ldi r24, 0x0A ; 10 + 1ca0: 90 e0 ldi r25, 0x00 ; 0 + 1ca2: 0e 94 81 43 call 0x8702 ; 0x8702 + } + + if (lockSensors[1].enabled) + 1ca6: e0 91 a0 0e lds r30, 0x0EA0 + 1caa: f0 91 a1 0e lds r31, 0x0EA1 + 1cae: 86 81 ldd r24, Z+6 ; 0x06 + 1cb0: 88 23 and r24, r24 + 1cb2: 39 f1 breq .+78 ; 0x1d02 + { + MPC23s17SetBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + 1cb4: 60 e0 ldi r22, 0x00 ; 0 + 1cb6: 80 e2 ldi r24, 0x20 ; 32 + 1cb8: 0e 94 12 26 call 0x4c24 ; 0x4c24 + vTaskDelay(30); + 1cbc: 8e e1 ldi r24, 0x1E ; 30 + 1cbe: 90 e0 ldi r25, 0x00 ; 0 + 1cc0: 0e 94 81 43 call 0x8702 ; 0x8702 + lockSensors[1].acVal = MCP3008_getSampleSingle(LOCK_SENS_2_AC_IN); + 1cc4: c0 91 a0 0e lds r28, 0x0EA0 + 1cc8: d0 91 a1 0e lds r29, 0x0EA1 + 1ccc: 85 e0 ldi r24, 0x05 ; 5 + 1cce: 0e 94 08 27 call 0x4e10 ; 0x4e10 + 1cd2: 9a 87 std Y+10, r25 ; 0x0a + 1cd4: 89 87 std Y+9, r24 ; 0x09 + MPC23s17ClearBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + 1cd6: 60 e0 ldi r22, 0x00 ; 0 + 1cd8: 80 e2 ldi r24, 0x20 ; 32 + 1cda: 0e 94 2f 26 call 0x4c5e ; 0x4c5e + lockSensors[1].locked = (lockSensors[1].acVal > lockSensors[1].threshold) ? 1 : 0; + 1cde: e0 91 a0 0e lds r30, 0x0EA0 + 1ce2: f0 91 a1 0e lds r31, 0x0EA1 + 1ce6: 81 e0 ldi r24, 0x01 ; 1 + 1ce8: 41 85 ldd r20, Z+9 ; 0x09 + 1cea: 52 85 ldd r21, Z+10 ; 0x0a + 1cec: 27 81 ldd r18, Z+7 ; 0x07 + 1cee: 30 85 ldd r19, Z+8 ; 0x08 + 1cf0: 24 17 cp r18, r20 + 1cf2: 35 07 cpc r19, r21 + 1cf4: 08 f0 brcs .+2 ; 0x1cf8 + 1cf6: 80 e0 ldi r24, 0x00 ; 0 + 1cf8: 83 87 std Z+11, r24 ; 0x0b + vTaskDelay(10); + 1cfa: 8a e0 ldi r24, 0x0A ; 10 + 1cfc: 90 e0 ldi r25, 0x00 ; 0 + 1cfe: 0e 94 81 43 call 0x8702 ; 0x8702 + } + + if (lockSensors[2].enabled) + 1d02: e0 91 a0 0e lds r30, 0x0EA0 + 1d06: f0 91 a1 0e lds r31, 0x0EA1 + 1d0a: 84 85 ldd r24, Z+12 ; 0x0c + 1d0c: 88 23 and r24, r24 + 1d0e: 39 f1 breq .+78 ; 0x1d5e + { + MPC23s17SetBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + 1d10: 60 e0 ldi r22, 0x00 ; 0 + 1d12: 80 e1 ldi r24, 0x10 ; 16 + 1d14: 0e 94 12 26 call 0x4c24 ; 0x4c24 + vTaskDelay(30); + 1d18: 8e e1 ldi r24, 0x1E ; 30 + 1d1a: 90 e0 ldi r25, 0x00 ; 0 + 1d1c: 0e 94 81 43 call 0x8702 ; 0x8702 + lockSensors[2].acVal = MCP3008_getSampleSingle(LOCK_SENS_3_AC_IN); + 1d20: c0 91 a0 0e lds r28, 0x0EA0 + 1d24: d0 91 a1 0e lds r29, 0x0EA1 + 1d28: 86 e0 ldi r24, 0x06 ; 6 + 1d2a: 0e 94 08 27 call 0x4e10 ; 0x4e10 + 1d2e: 98 8b std Y+16, r25 ; 0x10 + 1d30: 8f 87 std Y+15, r24 ; 0x0f + MPC23s17ClearBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + 1d32: 60 e0 ldi r22, 0x00 ; 0 + 1d34: 80 e1 ldi r24, 0x10 ; 16 + 1d36: 0e 94 2f 26 call 0x4c5e ; 0x4c5e + lockSensors[2].locked = (lockSensors[2].acVal > lockSensors[2].threshold) ? 1 : 0; + 1d3a: e0 91 a0 0e lds r30, 0x0EA0 + 1d3e: f0 91 a1 0e lds r31, 0x0EA1 + 1d42: 81 e0 ldi r24, 0x01 ; 1 + 1d44: 47 85 ldd r20, Z+15 ; 0x0f + 1d46: 50 89 ldd r21, Z+16 ; 0x10 + 1d48: 25 85 ldd r18, Z+13 ; 0x0d + 1d4a: 36 85 ldd r19, Z+14 ; 0x0e + 1d4c: 24 17 cp r18, r20 + 1d4e: 35 07 cpc r19, r21 + 1d50: 08 f0 brcs .+2 ; 0x1d54 + 1d52: 80 e0 ldi r24, 0x00 ; 0 + 1d54: 81 8b std Z+17, r24 ; 0x11 + vTaskDelay(10); + 1d56: 8a e0 ldi r24, 0x0A ; 10 + 1d58: 90 e0 ldi r25, 0x00 ; 0 + 1d5a: 0e 94 81 43 call 0x8702 ; 0x8702 + } + + if (lockSensors[3].enabled) + 1d5e: e0 91 a0 0e lds r30, 0x0EA0 + 1d62: f0 91 a1 0e lds r31, 0x0EA1 + 1d66: 82 89 ldd r24, Z+18 ; 0x12 + 1d68: 88 23 and r24, r24 + 1d6a: 49 f1 breq .+82 ; 0x1dbe + { + MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + 1d6c: 60 e0 ldi r22, 0x00 ; 0 + 1d6e: 88 e0 ldi r24, 0x08 ; 8 + 1d70: 0e 94 12 26 call 0x4c24 ; 0x4c24 + vTaskDelay(30); + 1d74: 8e e1 ldi r24, 0x1E ; 30 + 1d76: 90 e0 ldi r25, 0x00 ; 0 + 1d78: 0e 94 81 43 call 0x8702 ; 0x8702 + lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + 1d7c: c0 91 a0 0e lds r28, 0x0EA0 + 1d80: d0 91 a1 0e lds r29, 0x0EA1 + 1d84: 87 e0 ldi r24, 0x07 ; 7 + 1d86: 0e 94 08 27 call 0x4e10 ; 0x4e10 + 1d8a: 9e 8b std Y+22, r25 ; 0x16 + 1d8c: 8d 8b std Y+21, r24 ; 0x15 + MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + 1d8e: 60 e0 ldi r22, 0x00 ; 0 + 1d90: 88 e0 ldi r24, 0x08 ; 8 + 1d92: 0e 94 2f 26 call 0x4c5e ; 0x4c5e + lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + 1d96: e0 91 a0 0e lds r30, 0x0EA0 + 1d9a: f0 91 a1 0e lds r31, 0x0EA1 + 1d9e: 81 e0 ldi r24, 0x01 ; 1 + 1da0: 45 89 ldd r20, Z+21 ; 0x15 + 1da2: 56 89 ldd r21, Z+22 ; 0x16 + 1da4: 23 89 ldd r18, Z+19 ; 0x13 + 1da6: 34 89 ldd r19, Z+20 ; 0x14 + 1da8: 24 17 cp r18, r20 + 1daa: 35 07 cpc r19, r21 + 1dac: 08 f0 brcs .+2 ; 0x1db0 + 1dae: 80 e0 ldi r24, 0x00 ; 0 + 1db0: 87 8b std Z+23, r24 ; 0x17 + vTaskDelay(10); + 1db2: 8a e0 ldi r24, 0x0A ; 10 + 1db4: 90 e0 ldi r25, 0x00 ; 0 + } +} + 1db6: df 91 pop r29 + 1db8: cf 91 pop r28 + MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + vTaskDelay(30); + lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + vTaskDelay(10); + 1dba: 0c 94 81 43 jmp 0x8702 ; 0x8702 + } +} + 1dbe: df 91 pop r29 + 1dc0: cf 91 pop r28 + 1dc2: 08 95 ret + +00001dc4 : + + +uint8_t spiSend(uint8_t data) +{ + 1dc4: cf 93 push r28 + 1dc6: df 93 push r29 + 1dc8: 1f 92 push r1 + 1dca: cd b7 in r28, 0x3d ; 61 + 1dcc: de b7 in r29, 0x3e ; 62 + uint8_t result; + SPDR = data; + 1dce: 8f b9 out 0x0f, r24 ; 15 + xQueueReceive(xSpiRx, &result, 10); + 1dd0: 20 e0 ldi r18, 0x00 ; 0 + 1dd2: 4a e0 ldi r20, 0x0A ; 10 + 1dd4: 50 e0 ldi r21, 0x00 ; 0 + 1dd6: be 01 movw r22, r28 + 1dd8: 6f 5f subi r22, 0xFF ; 255 + 1dda: 7f 4f sbci r23, 0xFF ; 255 + 1ddc: 80 91 60 0f lds r24, 0x0F60 + 1de0: 90 91 61 0f lds r25, 0x0F61 + 1de4: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + return result; +} + 1de8: 89 81 ldd r24, Y+1 ; 0x01 + 1dea: 0f 90 pop r0 + 1dec: df 91 pop r29 + 1dee: cf 91 pop r28 + 1df0: 08 95 ret + +00001df2 : + +uint8_t spiSendENC(uint8_t data) +{ + 1df2: cf 93 push r28 + 1df4: df 93 push r29 + 1df6: 1f 92 push r1 + 1df8: cd b7 in r28, 0x3d ; 61 + 1dfa: de b7 in r29, 0x3e ; 62 + uint8_t result; + SPDR = data; + 1dfc: 8f b9 out 0x0f, r24 ; 15 + xQueueReceive(xSpiRx, &result, 10); + 1dfe: 20 e0 ldi r18, 0x00 ; 0 + 1e00: 4a e0 ldi r20, 0x0A ; 10 + 1e02: 50 e0 ldi r21, 0x00 ; 0 + 1e04: be 01 movw r22, r28 + 1e06: 6f 5f subi r22, 0xFF ; 255 + 1e08: 7f 4f sbci r23, 0xFF ; 255 + 1e0a: 80 91 60 0f lds r24, 0x0F60 + 1e0e: 90 91 61 0f lds r25, 0x0F61 + 1e12: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + return result; +} + 1e16: 89 81 ldd r24, Y+1 ; 0x01 + 1e18: 0f 90 pop r0 + 1e1a: df 91 pop r29 + 1e1c: cf 91 pop r28 + 1e1e: 08 95 ret + +00001e20 : + +uint8_t spiSendSpinBlock(uint8_t data) +{ + SPDR = data; + 1e20: 8f b9 out 0x0f, r24 ; 15 + SPCR &= ~(1< + data = SPSR; //Clearing interrupt flag + 1e28: 8e b1 in r24, 0x0e ; 14 + data = SPDR; //Resfing DPI buffer register + 1e2a: 8f b1 in r24, 0x0f ; 15 + SPCR |= (1<: + +uint8_t spiSendENCSpinBlock(uint8_t data) +{ + SPDR = data; + 1e30: 8f b9 out 0x0f, r24 ; 15 + SPCR &= ~(1< + data = SPSR; //Clearing interrupt flag + 1e38: 8e b1 in r24, 0x0e ; 14 + data = SPDR; //Resfing DPI buffer register + 1e3a: 8f b1 in r24, 0x0f ; 15 + SPCR |= (1<: +#error Port A is memory bus + PORTA &= disableSpiPORTA_AND; +#endif + +#if disableSpiPORTB_OR != 0 + PORTB |= disableSpiPORTB_OR; + 1e40: 88 b3 in r24, 0x18 ; 24 + 1e42: 80 6c ori r24, 0xC0 ; 192 + 1e44: 88 bb out 0x18, r24 ; 24 +#endif +#if disableSpiPORTB_AND != 0xFF + PORTB &= disableSpiPORTB_AND; + 1e46: c5 98 cbi 0x18, 5 ; 24 +#endif +#if disableSpiPORTD_AND != 0xFF + PORTD &= disableSpiPORTD_AND; +#endif +#if disableSpiPORTE_OR != 0 + PORTE |= disableSpiPORTE_OR; + 1e48: 1b 9a sbi 0x03, 3 ; 3 +#if disableSpiPORTF_AND != 0xFF + PORTF &= disableSpiPORTF_AND; +#endif + +#if disableSpiPORTG_OR != 0 + PORTG |= disableSpiPORTG_OR; + 1e4a: e5 e6 ldi r30, 0x65 ; 101 + 1e4c: f0 e0 ldi r31, 0x00 ; 0 + 1e4e: 80 81 ld r24, Z + 1e50: 88 60 ori r24, 0x08 ; 8 + 1e52: 80 83 st Z, r24 + 1e54: 08 95 ret + +00001e56 : +{ +#if ENC_SPI_CS_EN_MASK_OR != 0 + ENC_SPI_CS_PORT |= ENC_SPI_CS_EN_MASK_OR; +#endif +#if ENC_SPI_CS_EN_MASK_AND != 0xFF + ENC_SPI_CS_PORT &= ENC_SPI_CS_EN_MASK_AND; + 1e56: 1b 98 cbi 0x03, 3 ; 3 + 1e58: 08 95 ret + +00001e5a : +{ +#if ENC_SPI_CS_EN_MASK_OR != 0 + ENC_SPI_CS_PORT &= (~ENC_SPI_CS_EN_MASK_OR); +#endif +#if ENC_SPI_CS_EN_MASK_AND != 0xFF + ENC_SPI_CS_PORT |= (~ENC_SPI_CS_EN_MASK_AND); + 1e5a: 1b 9a sbi 0x03, 3 ; 3 + 1e5c: 08 95 ret + +00001e5e : +{ +#if SD_SPI_CS_EN_MASK_OR != 0 + SD_SPI_CS_PORT |= SD_SPI_CS_EN_MASK_OR; +#endif +#if SD_SPI_CS_EN_MASK_AND != 0xFF + SD_SPI_CS_PORT &= SD_SPI_CS_EN_MASK_AND; + 1e5e: e5 e6 ldi r30, 0x65 ; 101 + 1e60: f0 e0 ldi r31, 0x00 ; 0 + 1e62: 80 81 ld r24, Z + 1e64: 87 7f andi r24, 0xF7 ; 247 + 1e66: 80 83 st Z, r24 + 1e68: 08 95 ret + +00001e6a : +{ +#if SD_SPI_CS_EN_MASK_OR != 0 + SD_SPI_CS_PORT &= (~SD_SPI_CS_EN_MASK_OR); +#endif +#if SD_SPI_CS_EN_MASK_AND != 0xFF + SD_SPI_CS_PORT |= (~SD_SPI_CS_EN_MASK_AND); + 1e6a: e5 e6 ldi r30, 0x65 ; 101 + 1e6c: f0 e0 ldi r31, 0x00 ; 0 + 1e6e: 80 81 ld r24, Z + 1e70: 88 60 ori r24, 0x08 ; 8 + 1e72: 80 83 st Z, r24 + 1e74: 08 95 ret + +00001e76 : +{ +#if MCP23S17_SPI_CS_EN_MASK_OR != 0 + MCP23S17_SPI_CS_PORT |= MCP23S17_SPI_CS_EN_MASK_OR; +#endif +#if MCP23S17_SPI_CS_EN_MASK_AND != 0xFF + MPC23S17_SPI_CS_PORT &= MPC23S17_SPI_CS_EN_MASK_AND; + 1e76: c7 98 cbi 0x18, 7 ; 24 + 1e78: 08 95 ret + +00001e7a : +{ +#if MCP23S17_SPI_CS_EN_MASK_OR != 0 + MCP23S17_SPI_CS_PORT &= (~MCP23S17_SPI_CS_EN_MASK_OR); +#endif +#if MCP23S17_SPI_CS_EN_MASK_AND != 0xFF + MPC23S17_SPI_CS_PORT |= (~MPC23S17_SPI_CS_EN_MASK_AND); + 1e7a: c7 9a sbi 0x18, 7 ; 24 + 1e7c: 08 95 ret + +00001e7e : +} + +#define MCP3008_SPCR_OR_MASK ((1<: + +} + +void disableSpiMCP3008(void) +{ + SPCR &= ~MCP3008_SPCR_OR_MASK; + 1e88: 8d b1 in r24, 0x0d ; 13 + 1e8a: 8c 7f andi r24, 0xFC ; 252 + 1e8c: 8d b9 out 0x0d, r24 ; 13 + #if MCP3008_SPI_CS_EN_MASK_OR != 0 + MCP3008_SPI_CS_PORT &= (~MCP3008_SPI_CS_EN_MASK_OR); +#endif +#if MCP3008_SPI_CS_EN_MASK_AND != 0xFF + MCP3008_SPI_CS_PORT |= (~MCP3008_SPI_CS_EN_MASK_AND); + 1e8e: c6 9a sbi 0x18, 6 ; 24 + 1e90: 08 95 ret + +00001e92 : + + +#define MCP4150_SPCR_OR_MASK ((1<: +#endif +} +void disableSpiMCP4150(void) +{ + SPCR &= ~MCP4150_SPCR_OR_MASK; + 1e9c: 8d b1 in r24, 0x0d ; 13 + 1e9e: 8c 7f andi r24, 0xFC ; 252 + 1ea0: 8d b9 out 0x0d, r24 ; 13 + #if MCP4150_SPI_CS_EN_MASK_OR != 0 + MCP4150_SPI_CS_PORT &= (~MCP4150_SPI_CS_EN_MASK_OR); +#endif +#if MCP4150_SPI_CS_EN_MASK_AND != 0xFF + MCP4150_SPI_CS_PORT |= (~MCP4150_SPI_CS_EN_MASK_AND); + 1ea2: c6 9a sbi 0x18, 6 ; 24 + 1ea4: 08 95 ret + +00001ea6 : + +#define DS_SPCR_OR_MASK ((1<: +#endif +} + +void spiDisableDS1305(void) +{ + SPCR &= (~(DS_SPCR_OR_MASK)); + 1eb0: 8d b1 in r24, 0x0d ; 13 + 1eb2: 8a 7f andi r24, 0xFA ; 250 + 1eb4: 8d b9 out 0x0d, r24 ; 13 +#if DS1305_SPI_CS_EN_MASK_OR != 0 + DS1305_SPI_CS_PORT &= (~(DS1305_SPI_CS_EN_MASK_OR)); + 1eb6: c5 98 cbi 0x18, 5 ; 24 + 1eb8: 08 95 ret + +00001eba <__vector_17>: + DS1305_SPI_CS_PORT |= (~(DS1305_SPI_CS_EN_MASK_AND)); +#endif +} + +ISR(SPI_STC_vect) +{ + 1eba: 1f 92 push r1 + 1ebc: 0f 92 push r0 + 1ebe: 0f b6 in r0, 0x3f ; 63 + 1ec0: 0f 92 push r0 + 1ec2: 11 24 eor r1, r1 + 1ec4: 0b b6 in r0, 0x3b ; 59 + 1ec6: 0f 92 push r0 + 1ec8: 2f 93 push r18 + 1eca: 3f 93 push r19 + 1ecc: 4f 93 push r20 + 1ece: 5f 93 push r21 + 1ed0: 6f 93 push r22 + 1ed2: 7f 93 push r23 + 1ed4: 8f 93 push r24 + 1ed6: 9f 93 push r25 + 1ed8: af 93 push r26 + 1eda: bf 93 push r27 + 1edc: ef 93 push r30 + 1ede: ff 93 push r31 + static signed portBASE_TYPE xHigherPriorityTaskWoken; + + static uint8_t data; + data = SPDR; + 1ee0: 8f b1 in r24, 0x0f ; 15 + 1ee2: 80 93 8f 01 sts 0x018F, r24 + + xQueueSendFromISR(xSpiRx, &data, &xHigherPriorityTaskWoken); + 1ee6: 20 e0 ldi r18, 0x00 ; 0 + 1ee8: 4e e8 ldi r20, 0x8E ; 142 + 1eea: 51 e0 ldi r21, 0x01 ; 1 + 1eec: 6f e8 ldi r22, 0x8F ; 143 + 1eee: 71 e0 ldi r23, 0x01 ; 1 + 1ef0: 80 91 60 0f lds r24, 0x0F60 + 1ef4: 90 91 61 0f lds r25, 0x0F61 + 1ef8: 0e 94 36 47 call 0x8e6c ; 0x8e6c + + if( xHigherPriorityTaskWoken ) + 1efc: 80 91 8e 01 lds r24, 0x018E + 1f00: 81 11 cpse r24, r1 + { + taskYIELD(); + 1f02: 0e 94 81 4b call 0x9702 ; 0x9702 + } + + //clear SPI interrupt SPI |= 1; +} + 1f06: ff 91 pop r31 + 1f08: ef 91 pop r30 + 1f0a: bf 91 pop r27 + 1f0c: af 91 pop r26 + 1f0e: 9f 91 pop r25 + 1f10: 8f 91 pop r24 + 1f12: 7f 91 pop r23 + 1f14: 6f 91 pop r22 + 1f16: 5f 91 pop r21 + 1f18: 4f 91 pop r20 + 1f1a: 3f 91 pop r19 + 1f1c: 2f 91 pop r18 + 1f1e: 0f 90 pop r0 + 1f20: 0b be out 0x3b, r0 ; 59 + 1f22: 0f 90 pop r0 + 1f24: 0f be out 0x3f, r0 ; 63 + 1f26: 0f 90 pop r0 + 1f28: 1f 90 pop r1 + 1f2a: 18 95 reti + +00001f2c : + + + +void sensorsTaskInit(void) +{ + LockersMemInit(); + 1f2c: 0e 94 9e 0d call 0x1b3c ; 0x1b3c + rollersMemInit(); + 1f30: 0c 94 f4 38 jmp 0x71e8 ; 0x71e8 + +00001f34 : +{ + (void) pvParameters; + uint8_t addr = 255; +// uint8_t i; + + MPC23s17SetDirA(0x00, 0); + 1f34: 60 e0 ldi r22, 0x00 ; 0 + 1f36: 80 e0 ldi r24, 0x00 ; 0 + 1f38: 0e 94 ba 25 call 0x4b74 ; 0x4b74 + + MPC23s17SetDirB(0x00, 0); + 1f3c: 60 e0 ldi r22, 0x00 ; 0 + 1f3e: 80 e0 ldi r24, 0x00 ; 0 + 1f40: 0e 94 d4 25 call 0x4ba8 ; 0x4ba8 + voltage = (uint8_t)(tmp>>5); + vTaskDelay(10); + + //Read temperature inside chasis + tmp = MCP3008_getSampleSingle(1); + tmp *=10; + 1f44: da e0 ldi r29, 0x0A ; 10 + temperature = (uint8_t)(tmp / 24); + 1f46: 08 e1 ldi r16, 0x18 ; 24 + 1f48: 10 e0 ldi r17, 0x00 ; 0 + + for( ; ; ) + { + uint16_t tmp; + //Read power suply voltage + tmp = MCP3008_getSampleSingle(0); + 1f4a: 80 e0 ldi r24, 0x00 ; 0 + 1f4c: 0e 94 08 27 call 0x4e10 ; 0x4e10 + voltage = (uint8_t)(tmp>>5); + 1f50: 25 e0 ldi r18, 0x05 ; 5 + 1f52: 96 95 lsr r25 + 1f54: 87 95 ror r24 + 1f56: 2a 95 dec r18 + 1f58: e1 f7 brne .-8 ; 0x1f52 + 1f5a: 80 93 ae 0e sts 0x0EAE, r24 + vTaskDelay(10); + 1f5e: 8a e0 ldi r24, 0x0A ; 10 + 1f60: 90 e0 ldi r25, 0x00 ; 0 + 1f62: 0e 94 81 43 call 0x8702 ; 0x8702 + + //Read temperature inside chasis + tmp = MCP3008_getSampleSingle(1); + 1f66: 81 e0 ldi r24, 0x01 ; 1 + 1f68: 0e 94 08 27 call 0x4e10 ; 0x4e10 + tmp *=10; + 1f6c: 9c 01 movw r18, r24 + 1f6e: d2 9f mul r29, r18 + 1f70: c0 01 movw r24, r0 + 1f72: d3 9f mul r29, r19 + 1f74: 90 0d add r25, r0 + 1f76: 11 24 eor r1, r1 + temperature = (uint8_t)(tmp / 24); + 1f78: b8 01 movw r22, r16 + 1f7a: 0e 94 e3 4c call 0x99c6 ; 0x99c6 <__udivmodhi4> + 1f7e: 60 93 a4 0e sts 0x0EA4, r22 + vTaskDelay(10); + 1f82: 8a e0 ldi r24, 0x0A ; 10 + 1f84: 90 e0 ldi r25, 0x00 ; 0 + 1f86: 0e 94 81 43 call 0x8702 ; 0x8702 + + //read lock + checkLockerSensors(); + 1f8a: 0e 94 23 0e call 0x1c46 ; 0x1c46 + + for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + 1f8e: c1 e0 ldi r28, 0x01 ; 1 + { + rs485rollerHello(addr); + 1f90: 8c 2f mov r24, r28 + 1f92: 0e 94 41 3a call 0x7482 ; 0x7482 + vTaskDelay(10); + 1f96: 8a e0 ldi r24, 0x0A ; 10 + 1f98: 90 e0 ldi r25, 0x00 ; 0 + 1f9a: 0e 94 81 43 call 0x8702 ; 0x8702 + vTaskDelay(10); + + //read lock + checkLockerSensors(); + + for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + 1f9e: cf 5f subi r28, 0xFF ; 255 + 1fa0: c0 32 cpi r28, 0x20 ; 32 + 1fa2: b1 f7 brne .-20 ; 0x1f90 + 1fa4: d2 cf rjmp .-92 ; 0x1f4a + +00001fa6 : + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + 1fa6: fc 01 movw r30, r24 + if (state->cliMode != RESTRICTED_NORMAL) + 1fa8: 80 a1 ldd r24, Z+32 ; 0x20 + 1faa: 83 30 cpi r24, 0x03 ; 3 + 1fac: 49 f0 breq .+18 ; 0x1fc0 + { + state->cmdList = cmdListEnable; + 1fae: 88 ed ldi r24, 0xD8 ; 216 + 1fb0: 91 e0 ldi r25, 0x01 ; 1 + 1fb2: 92 a3 std Z+34, r25 ; 0x22 + 1fb4: 81 a3 std Z+33, r24 ; 0x21 + state->cliMode = NR_ENABLE; + 1fb6: 81 e0 ldi r24, 0x01 ; 1 + 1fb8: 80 a3 std Z+32, r24 ; 0x20 + return OK_SILENT; + 1fba: 80 e0 ldi r24, 0x00 ; 0 + 1fbc: 90 e0 ldi r25, 0x00 ; 0 + 1fbe: 08 95 ret + } + return ERROR_OPERATION_NOT_ALLOWED; + 1fc0: 85 e0 ldi r24, 0x05 ; 5 + 1fc2: 90 e0 ldi r25, 0x00 ; 0 +} + 1fc4: 08 95 ret + +00001fc6 : +static cliExRes_t disableFunction(cmdState_t *state) +{ + 1fc6: fc 01 movw r30, r24 + state->cmdList = cmdListNormal; + 1fc8: 8a e7 ldi r24, 0x7A ; 122 + 1fca: 92 e0 ldi r25, 0x02 ; 2 + 1fcc: 92 a3 std Z+34, r25 ; 0x22 + 1fce: 81 a3 std Z+33, r24 ; 0x21 + if (state->cliMode != RESTRICTED_NORMAL) + 1fd0: 80 a1 ldd r24, Z+32 ; 0x20 + 1fd2: 83 30 cpi r24, 0x03 ; 3 + 1fd4: 09 f0 breq .+2 ; 0x1fd8 + { + state->cliMode = NR_NORMAL; + 1fd6: 10 a2 std Z+32, r1 ; 0x20 + } + return OK_SILENT; +} + 1fd8: 80 e0 ldi r24, 0x00 ; 0 + 1fda: 90 e0 ldi r25, 0x00 ; 0 + 1fdc: 08 95 ret + +00001fde : +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + 1fde: fc 01 movw r30, r24 + if (state->cliMode == NR_ENABLE) + 1fe0: 80 a1 ldd r24, Z+32 ; 0x20 + 1fe2: 81 30 cpi r24, 0x01 ; 1 + 1fe4: 49 f4 brne .+18 ; 0x1ff8 + { + state->cmdList = cmdListConfigure; + 1fe6: 8a e8 ldi r24, 0x8A ; 138 + 1fe8: 91 e0 ldi r25, 0x01 ; 1 + 1fea: 92 a3 std Z+34, r25 ; 0x22 + 1fec: 81 a3 std Z+33, r24 ; 0x21 + state->cliMode = NR_CONFIGURE; + 1fee: 82 e0 ldi r24, 0x02 ; 2 + 1ff0: 80 a3 std Z+32, r24 ; 0x20 + return OK_SILENT; + 1ff2: 80 e0 ldi r24, 0x00 ; 0 + 1ff4: 90 e0 ldi r25, 0x00 ; 0 + 1ff6: 08 95 ret + } + return ERROR_OPERATION_NOT_ALLOWED; + 1ff8: 85 e0 ldi r24, 0x05 ; 5 + 1ffa: 90 e0 ldi r25, 0x00 ; 0 +} + 1ffc: 08 95 ret + +00001ffe : + return OK_SILENT; +} + +static cliExRes_t pingFunction(cmdState_t *state) +{ + if (state->argc < 4) + 1ffe: fc 01 movw r30, r24 + 2000: 81 8d ldd r24, Z+25 ; 0x19 + 2002: 84 30 cpi r24, 0x04 ; 4 + 2004: 18 f0 brcs .+6 ; 0x200c + //ip[1] = (uint8_t)(cmdlineGetArgInt(2, state)); + //ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + //ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + //Ipv4Ping(*((uint32_t *)(ip))); + + return OK_SILENT; + 2006: 80 e0 ldi r24, 0x00 ; 0 + 2008: 90 e0 ldi r25, 0x00 ; 0 + 200a: 08 95 ret +} + +static cliExRes_t pingFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + 200c: 82 e0 ldi r24, 0x02 ; 2 + 200e: 90 e0 ldi r25, 0x00 ; 0 + //ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + //ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + //Ipv4Ping(*((uint32_t *)(ip))); + + return OK_SILENT; +} + 2010: 08 95 ret + +00002012 : + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t readRamFIleFunction(cmdState_t *state) //TODO move this code to fat8 +{ + 2012: ff 92 push r15 + 2014: 0f 93 push r16 + 2016: 1f 93 push r17 + 2018: cf 93 push r28 + 201a: df 93 push r29 + 201c: 1f 92 push r1 + 201e: cd b7 in r28, 0x3d ; 61 + 2020: de b7 in r29, 0x3e ; 62 + 2022: 8c 01 movw r16, r24 + uint8_t rezultat; + uint8_t znak = ' '; + 2024: 80 e2 ldi r24, 0x20 ; 32 + 2026: 89 83 std Y+1, r24 ; 0x01 + if ((rezultat = ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty)) != 0) + 2028: b8 01 movw r22, r16 + 202a: 81 e0 ldi r24, 0x01 ; 1 + 202c: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2030: 62 e6 ldi r22, 0x62 ; 98 + 2032: 7f e0 ldi r23, 0x0F ; 15 + 2034: 0e 94 bd 1b call 0x377a ; 0x377a + 2038: 88 23 and r24, r24 + 203a: d1 f0 breq .+52 ; 0x2070 + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 203c: b8 01 movw r22, r16 + 203e: 81 e0 ldi r24, 0x01 ; 1 + 2040: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2044: 9f 93 push r25 + 2046: 8f 93 push r24 + 2048: 8e ea ldi r24, 0xAE ; 174 + 204a: 9a e0 ldi r25, 0x0A ; 10 + 204c: 9f 93 push r25 + 204e: 8f 93 push r24 + 2050: f8 01 movw r30, r16 + 2052: 83 8d ldd r24, Z+27 ; 0x1b + 2054: 8f 93 push r24 + 2056: 82 8d ldd r24, Z+26 ; 0x1a + 2058: 8f 93 push r24 + 205a: 0e 94 1a 50 call 0xa034 ; 0xa034 + return ERROR_INFORM; + 205e: 0f 90 pop r0 + 2060: 0f 90 pop r0 + 2062: 0f 90 pop r0 + 2064: 0f 90 pop r0 + 2066: 0f 90 pop r0 + 2068: 0f 90 pop r0 + 206a: 84 e0 ldi r24, 0x04 ; 4 + 206c: 90 e0 ldi r25, 0x00 ; 0 + 206e: 46 c0 rjmp .+140 ; 0x20fc + } + uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + 2070: e0 91 66 0f lds r30, 0x0F66 + 2074: f0 91 67 0f lds r31, 0x0F67 + 2078: 82 81 ldd r24, Z+2 ; 0x02 + 207a: 90 e0 ldi r25, 0x00 ; 0 + 207c: 98 2f mov r25, r24 + 207e: 88 27 eor r24, r24 + 2080: 21 81 ldd r18, Z+1 ; 0x01 + 2082: 82 0f add r24, r18 + 2084: 91 1d adc r25, r1 + fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + 2086: 9f 93 push r25 + 2088: 8f 93 push r24 + 208a: 83 ec ldi r24, 0xC3 ; 195 + 208c: 98 e0 ldi r25, 0x08 ; 8 + 208e: 9f 93 push r25 + 2090: 8f 93 push r24 + 2092: f8 01 movw r30, r16 + 2094: 83 8d ldd r24, Z+27 ; 0x1b + 2096: 8f 93 push r24 + 2098: 82 8d ldd r24, Z+26 ; 0x1a + 209a: 8f 93 push r24 + 209c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 20a0: 0f 90 pop r0 + 20a2: 0f 90 pop r0 + 20a4: 0f 90 pop r0 + 20a6: 0f 90 pop r0 + 20a8: 0f 90 pop r0 + 20aa: 0f 90 pop r0 + while (rezultat == 0) + { + rezultat = ramDyskCzytajBajtZPliku(&fdVty, &znak); + 20ac: be 01 movw r22, r28 + 20ae: 6f 5f subi r22, 0xFF ; 255 + 20b0: 7f 4f sbci r23, 0xFF ; 255 + 20b2: 82 e6 ldi r24, 0x62 ; 98 + 20b4: 9f e0 ldi r25, 0x0F ; 15 + 20b6: 0e 94 74 1c call 0x38e8 ; 0x38e8 + 20ba: f8 2e mov r15, r24 + + uartVtySendByte(znak); + 20bc: 89 81 ldd r24, Y+1 ; 0x01 + 20be: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + if (znak == '\r') + 20c2: 89 81 ldd r24, Y+1 ; 0x01 + 20c4: 8d 30 cpi r24, 0x0D ; 13 + 20c6: 19 f4 brne .+6 ; 0x20ce + uartVtySendByte('\n'); + 20c8: 8a e0 ldi r24, 0x0A ; 10 + 20ca: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + while (rezultat == 0) + 20ce: ff 20 and r15, r15 + 20d0: 69 f3 breq .-38 ; 0x20ac + + uartVtySendByte(znak); + if (znak == '\r') + uartVtySendByte('\n'); + } + fprintf_P(state->myStdInOut, nlStr); + 20d2: 82 ef ldi r24, 0xF2 ; 242 + 20d4: 92 e0 ldi r25, 0x02 ; 2 + 20d6: 9f 93 push r25 + 20d8: 8f 93 push r24 + 20da: f8 01 movw r30, r16 + 20dc: 83 8d ldd r24, Z+27 ; 0x1b + 20de: 8f 93 push r24 + 20e0: 82 8d ldd r24, Z+26 ; 0x1a + 20e2: 8f 93 push r24 + 20e4: 0e 94 1a 50 call 0xa034 ; 0xa034 + ramDyskZamknijPlik(&fdVty); + 20e8: 82 e6 ldi r24, 0x62 ; 98 + 20ea: 9f e0 ldi r25, 0x0F ; 15 + 20ec: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + return OK_SILENT; + 20f0: 0f 90 pop r0 + 20f2: 0f 90 pop r0 + 20f4: 0f 90 pop r0 + 20f6: 0f 90 pop r0 + 20f8: 80 e0 ldi r24, 0x00 ; 0 + 20fa: 90 e0 ldi r25, 0x00 ; 0 +} + 20fc: 0f 90 pop r0 + 20fe: df 91 pop r29 + 2100: cf 91 pop r28 + 2102: 1f 91 pop r17 + 2104: 0f 91 pop r16 + 2106: ff 90 pop r15 + 2108: 08 95 ret + +0000210a : + return ERROR_INFORM; +} + +static cliExRes_t writeRamFileFunction(cmdState_t *state) +{ + ramDyskDir(state->myStdInOut); + 210a: fc 01 movw r30, r24 + 210c: 82 8d ldd r24, Z+26 ; 0x1a + 210e: 93 8d ldd r25, Z+27 ; 0x1b + 2110: 0e 94 be 1e call 0x3d7c ; 0x3d7c + return OK_SILENT; +} + 2114: 80 e0 ldi r24, 0x00 ; 0 + 2116: 90 e0 ldi r25, 0x00 ; 0 + 2118: 08 95 ret + +0000211a : + nicRegDump(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + 211a: cf 93 push r28 + 211c: df 93 push r29 + 211e: ec 01 movw r28, r24 + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + 2120: 83 eb ldi r24, 0xB3 ; 179 + 2122: 9e e0 ldi r25, 0x0E ; 14 + 2124: 0e 94 1a 25 call 0x4a34 ; 0x4a34 + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + 2128: e5 eb ldi r30, 0xB5 ; 181 + 212a: fe e0 ldi r31, 0x0E ; 14 + 212c: 90 81 ld r25, Z + 212e: 96 95 lsr r25 + 2130: 96 95 lsr r25 + 2132: 96 95 lsr r25 + 2134: 80 81 ld r24, Z + 2136: 8f 70 andi r24, 0x0F ; 15 + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 2138: e4 eb ldi r30, 0xB4 ; 180 + 213a: fe e0 ldi r31, 0x0E ; 14 + 213c: 20 81 ld r18, Z + 213e: 26 95 lsr r18 + 2140: 26 95 lsr r18 + 2142: 26 95 lsr r18 + 2144: 40 81 ld r20, Z + 2146: 4f 70 andi r20, 0x0F ; 15 + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + 2148: e3 eb ldi r30, 0xB3 ; 179 + 214a: fe e0 ldi r31, 0x0E ; 14 + 214c: 30 81 ld r19, Z + 214e: 36 95 lsr r19 + 2150: 36 95 lsr r19 + 2152: 36 95 lsr r19 + 2154: 50 81 ld r21, Z + 2156: 5f 70 andi r21, 0x0F ; 15 + 2158: 3e 70 andi r19, 0x0E ; 14 + 215a: 63 2f mov r22, r19 + 215c: 66 0f add r22, r22 + 215e: 66 0f add r22, r22 + 2160: 36 0f add r19, r22 + 2162: 35 0f add r19, r21 + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + 2164: 1f 92 push r1 + 2166: 3f 93 push r19 + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 2168: 2e 70 andi r18, 0x0E ; 14 + 216a: 32 2f mov r19, r18 + 216c: 33 0f add r19, r19 + 216e: 33 0f add r19, r19 + 2170: 23 0f add r18, r19 + 2172: 24 0f add r18, r20 + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + 2174: 1f 92 push r1 + 2176: 2f 93 push r18 +} + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + 2178: 96 70 andi r25, 0x06 ; 6 + 217a: 29 2f mov r18, r25 + 217c: 22 0f add r18, r18 + 217e: 22 0f add r18, r18 + 2180: 92 0f add r25, r18 + 2182: 98 0f add r25, r24 + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + 2184: 1f 92 push r1 + 2186: 9f 93 push r25 + 2188: 81 e7 ldi r24, 0x71 ; 113 + 218a: 91 e0 ldi r25, 0x01 ; 1 + 218c: 9f 93 push r25 + 218e: 8f 93 push r24 + 2190: 8b 8d ldd r24, Y+27 ; 0x1b + 2192: 8f 93 push r24 + 2194: 8a 8d ldd r24, Y+26 ; 0x1a + 2196: 8f 93 push r24 + 2198: 0e 94 1a 50 call 0xa034 ; 0xa034 + return OK_SILENT; + 219c: 8d b7 in r24, 0x3d ; 61 + 219e: 9e b7 in r25, 0x3e ; 62 + 21a0: 0a 96 adiw r24, 0x0a ; 10 + 21a2: 0f b6 in r0, 0x3f ; 63 + 21a4: f8 94 cli + 21a6: 9e bf out 0x3e, r25 ; 62 + 21a8: 0f be out 0x3f, r0 ; 63 + 21aa: 8d bf out 0x3d, r24 ; 61 +} + 21ac: 80 e0 ldi r24, 0x00 ; 0 + 21ae: 90 e0 ldi r25, 0x00 ; 0 + 21b0: df 91 pop r29 + 21b2: cf 91 pop r28 + 21b4: 08 95 ret + +000021b6 : + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + 21b6: 0e 94 2d 24 call 0x485a ; 0x485a + return OK_SILENT; +} + 21ba: 80 e0 ldi r24, 0x00 ; 0 + 21bc: 90 e0 ldi r25, 0x00 ; 0 + 21be: 08 95 ret + +000021c0 : + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + +static cliExRes_t czytajAC_Function(cmdState_t *state) +{ + 21c0: 0f 93 push r16 + 21c2: 1f 93 push r17 + 21c4: cf 93 push r28 + 21c6: df 93 push r29 + 21c8: 1f 92 push r1 + 21ca: cd b7 in r28, 0x3d ; 61 + 21cc: de b7 in r29, 0x3e ; 62 + 21ce: 8c 01 movw r16, r24 + uint8_t nrWejscia = cmdlineGetArgInt(1, state); + 21d0: bc 01 movw r22, r24 + 21d2: 81 e0 ldi r24, 0x01 ; 1 + 21d4: 0e 94 07 24 call 0x480e ; 0x480e + uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + 21d8: 86 2f mov r24, r22 + 21da: 69 83 std Y+1, r22 ; 0x01 + 21dc: 0e 94 08 27 call 0x4e10 ; 0x4e10 + fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + 21e0: 9f 93 push r25 + 21e2: 8f 93 push r24 + 21e4: 1f 92 push r1 + 21e6: 69 81 ldd r22, Y+1 ; 0x01 + 21e8: 6f 93 push r22 + 21ea: 8e e4 ldi r24, 0x4E ; 78 + 21ec: 91 e0 ldi r25, 0x01 ; 1 + 21ee: 9f 93 push r25 + 21f0: 8f 93 push r24 + 21f2: f8 01 movw r30, r16 + 21f4: 83 8d ldd r24, Z+27 ; 0x1b + 21f6: 8f 93 push r24 + 21f8: 82 8d ldd r24, Z+26 ; 0x1a + 21fa: 8f 93 push r24 + 21fc: 0e 94 1a 50 call 0xa034 ; 0xa034 + return OK_SILENT; + 2200: 0f b6 in r0, 0x3f ; 63 + 2202: f8 94 cli + 2204: de bf out 0x3e, r29 ; 62 + 2206: 0f be out 0x3f, r0 ; 63 + 2208: cd bf out 0x3d, r28 ; 61 +} + 220a: 80 e0 ldi r24, 0x00 ; 0 + 220c: 90 e0 ldi r25, 0x00 ; 0 + 220e: 0f 90 pop r0 + 2210: df 91 pop r29 + 2212: cf 91 pop r28 + 2214: 1f 91 pop r17 + 2216: 0f 91 pop r16 + 2218: 08 95 ret + +0000221a : + return SYNTAX_ERROR; +} + + +static cliExRes_t setTimeFunction(cmdState_t *state) +{ + 221a: ef 92 push r14 + 221c: ff 92 push r15 + 221e: 1f 93 push r17 + 2220: cf 93 push r28 + 2222: df 93 push r29 + 2224: 7c 01 movw r14, r24 + uint8_t godzina = cmdlineGetArgInt(1, state); + 2226: bc 01 movw r22, r24 + 2228: 81 e0 ldi r24, 0x01 ; 1 + 222a: 0e 94 07 24 call 0x480e ; 0x480e + 222e: 16 2f mov r17, r22 + uint8_t minuta = cmdlineGetArgInt(2, state); + 2230: b7 01 movw r22, r14 + 2232: 82 e0 ldi r24, 0x02 ; 2 + 2234: 0e 94 07 24 call 0x480e ; 0x480e + 2238: d6 2f mov r29, r22 + uint8_t sekunda = cmdlineGetArgInt(3, state); + 223a: b7 01 movw r22, r14 + 223c: 83 e0 ldi r24, 0x03 ; 3 + 223e: 0e 94 07 24 call 0x480e ; 0x480e + 2242: c6 2f mov r28, r22 + + ds1305start(); + 2244: 0e 94 3f 25 call 0x4a7e ; 0x4a7e + + uint8_t cDzies = godzina/10; + 2248: 4a e0 ldi r20, 0x0A ; 10 + 224a: 81 2f mov r24, r17 + 224c: 64 2f mov r22, r20 + 224e: 0e 94 d7 4c call 0x99ae ; 0x99ae <__udivmodqi4> + uint8_t cJedn = godzina - cDzies*10; + czasRtc.hours.syst24.cDzies = cDzies; + 2252: 98 2f mov r25, r24 + 2254: 93 70 andi r25, 0x03 ; 3 + 2256: e5 eb ldi r30, 0xB5 ; 181 + 2258: fe e0 ldi r31, 0x0E ; 14 + 225a: 29 2f mov r18, r25 + 225c: 22 95 swap r18 + 225e: 20 7f andi r18, 0xF0 ; 240 + 2260: 90 81 ld r25, Z + 2262: 9f 7c andi r25, 0xCF ; 207 + 2264: 92 2b or r25, r18 + 2266: 90 83 st Z, r25 + uint8_t sekunda = cmdlineGetArgInt(3, state); + + ds1305start(); + + uint8_t cDzies = godzina/10; + uint8_t cJedn = godzina - cDzies*10; + 2268: 36 ef ldi r19, 0xF6 ; 246 + 226a: 83 9f mul r24, r19 + 226c: 10 0d add r17, r0 + 226e: 11 24 eor r1, r1 + czasRtc.hours.syst24.cDzies = cDzies; + czasRtc.hours.syst24.cJedn = cJedn; + 2270: 81 2f mov r24, r17 + 2272: 8f 70 andi r24, 0x0F ; 15 + 2274: 10 81 ld r17, Z + 2276: 10 7f andi r17, 0xF0 ; 240 + 2278: 18 2b or r17, r24 + 227a: 10 83 st Z, r17 + + cDzies = minuta/10; + 227c: 8d 2f mov r24, r29 + 227e: 0e 94 d7 4c call 0x99ae ; 0x99ae <__udivmodqi4> + cJedn = minuta - cDzies * 10; + czasRtc.minutes.cDzies = cDzies; + 2282: 98 2f mov r25, r24 + 2284: 97 70 andi r25, 0x07 ; 7 + 2286: e4 eb ldi r30, 0xB4 ; 180 + 2288: fe e0 ldi r31, 0x0E ; 14 + 228a: 29 2f mov r18, r25 + 228c: 22 95 swap r18 + 228e: 20 7f andi r18, 0xF0 ; 240 + 2290: 90 81 ld r25, Z + 2292: 9f 78 andi r25, 0x8F ; 143 + 2294: 92 2b or r25, r18 + 2296: 90 83 st Z, r25 + uint8_t cJedn = godzina - cDzies*10; + czasRtc.hours.syst24.cDzies = cDzies; + czasRtc.hours.syst24.cJedn = cJedn; + + cDzies = minuta/10; + cJedn = minuta - cDzies * 10; + 2298: 83 9f mul r24, r19 + 229a: d0 0d add r29, r0 + 229c: 11 24 eor r1, r1 + czasRtc.minutes.cDzies = cDzies; + czasRtc.minutes.cJedn = cJedn; + 229e: 8d 2f mov r24, r29 + 22a0: 8f 70 andi r24, 0x0F ; 15 + 22a2: d0 81 ld r29, Z + 22a4: d0 7f andi r29, 0xF0 ; 240 + 22a6: d8 2b or r29, r24 + 22a8: d0 83 st Z, r29 + + cDzies = sekunda/10; + 22aa: 8c 2f mov r24, r28 + 22ac: 0e 94 d7 4c call 0x99ae ; 0x99ae <__udivmodqi4> + cJedn = sekunda - cDzies * 10; + czasRtc.seconds.cDzies = cDzies; + 22b0: 98 2f mov r25, r24 + 22b2: 97 70 andi r25, 0x07 ; 7 + 22b4: e3 eb ldi r30, 0xB3 ; 179 + 22b6: fe e0 ldi r31, 0x0E ; 14 + 22b8: 29 2f mov r18, r25 + 22ba: 22 95 swap r18 + 22bc: 20 7f andi r18, 0xF0 ; 240 + 22be: 90 81 ld r25, Z + 22c0: 9f 78 andi r25, 0x8F ; 143 + 22c2: 92 2b or r25, r18 + 22c4: 90 83 st Z, r25 + cJedn = minuta - cDzies * 10; + czasRtc.minutes.cDzies = cDzies; + czasRtc.minutes.cJedn = cJedn; + + cDzies = sekunda/10; + cJedn = sekunda - cDzies * 10; + 22c6: 83 9f mul r24, r19 + 22c8: c0 0d add r28, r0 + 22ca: 11 24 eor r1, r1 + czasRtc.seconds.cDzies = cDzies; + czasRtc.seconds.cJedn = cJedn; + 22cc: 8c 2f mov r24, r28 + 22ce: 8f 70 andi r24, 0x0F ; 15 + 22d0: c0 81 ld r28, Z + 22d2: c0 7f andi r28, 0xF0 ; 240 + 22d4: c8 2b or r28, r24 + 22d6: c0 83 st Z, r28 + + setTimeDecoded((timeDecoded_t *)(&czasRtc)); + 22d8: cf 01 movw r24, r30 + 22da: 0e 94 3b 25 call 0x4a76 ; 0x4a76 + return OK_SILENT; +} + 22de: 80 e0 ldi r24, 0x00 ; 0 + 22e0: 90 e0 ldi r25, 0x00 ; 0 + 22e2: df 91 pop r29 + 22e4: cf 91 pop r28 + 22e6: 1f 91 pop r17 + 22e8: ff 90 pop r15 + 22ea: ef 90 pop r14 + 22ec: 08 95 ret + +000022ee : + MPC23s17SetPortA(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortExtBFunction(cmdState_t *state) +{ + 22ee: cf 93 push r28 + uint8_t wyjscie = cmdlineGetArgInt(1, state); + 22f0: bc 01 movw r22, r24 + 22f2: 81 e0 ldi r24, 0x01 ; 1 + 22f4: 0e 94 07 24 call 0x480e ; 0x480e + 22f8: c6 2f mov r28, r22 + MPC23s17SetDirB(0x00, 0); + 22fa: 60 e0 ldi r22, 0x00 ; 0 + 22fc: 80 e0 ldi r24, 0x00 ; 0 + 22fe: 0e 94 d4 25 call 0x4ba8 ; 0x4ba8 + MPC23s17SetPortB(wyjscie, 0); + 2302: 60 e0 ldi r22, 0x00 ; 0 + 2304: 8c 2f mov r24, r28 + 2306: 0e 94 4d 26 call 0x4c9a ; 0x4c9a + return OK_SILENT; +} + 230a: 80 e0 ldi r24, 0x00 ; 0 + 230c: 90 e0 ldi r25, 0x00 ; 0 + 230e: cf 91 pop r28 + 2310: 08 95 ret + +00002312 : + + return ERROR_SILENT; +} + +static cliExRes_t ustawPortExtAFunction(cmdState_t *state) +{ + 2312: cf 93 push r28 + uint8_t wyjscie = cmdlineGetArgInt(1, state); + 2314: bc 01 movw r22, r24 + 2316: 81 e0 ldi r24, 0x01 ; 1 + 2318: 0e 94 07 24 call 0x480e ; 0x480e + 231c: c6 2f mov r28, r22 + MPC23s17SetDirA(0x00, 0); + 231e: 60 e0 ldi r22, 0x00 ; 0 + 2320: 80 e0 ldi r24, 0x00 ; 0 + 2322: 0e 94 ba 25 call 0x4b74 ; 0x4b74 + MPC23s17SetPortA(wyjscie, 0); + 2326: 60 e0 ldi r22, 0x00 ; 0 + 2328: 8c 2f mov r24, r28 + 232a: 0e 94 ee 25 call 0x4bdc ; 0x4bdc + return OK_SILENT; +} + 232e: 80 e0 ldi r24, 0x00 ; 0 + 2330: 90 e0 ldi r25, 0x00 ; 0 + 2332: cf 91 pop r28 + 2334: 08 95 ret + +00002336 : + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t curtainDownFunction(cmdState_t *state) +{ + 2336: ff 92 push r15 + 2338: 0f 93 push r16 + 233a: 1f 93 push r17 + 233c: cf 93 push r28 + 233e: df 93 push r29 + 2340: ec 01 movw r28, r24 + uint8_t nrRolety; + uint8_t nrSterownika; + uint8_t wartosc; + + nrSterownika = cmdlineGetArgInt(1, state); + 2342: bc 01 movw r22, r24 + 2344: 81 e0 ldi r24, 0x01 ; 1 + 2346: 0e 94 07 24 call 0x480e ; 0x480e + 234a: f6 2e mov r15, r22 + nrRolety = cmdlineGetArgInt(2, state); + 234c: be 01 movw r22, r28 + 234e: 82 e0 ldi r24, 0x02 ; 2 + 2350: 0e 94 07 24 call 0x480e ; 0x480e + nrRolety &= 0x01; + 2354: 16 2f mov r17, r22 + 2356: 11 70 andi r17, 0x01 ; 1 + wartosc = cmdlineGetArgInt(3, state); + 2358: be 01 movw r22, r28 + 235a: 83 e0 ldi r24, 0x03 ; 3 + 235c: 0e 94 07 24 call 0x480e ; 0x480e + 2360: 06 2f mov r16, r22 + + fprintf_P(state->myStdInOut,movingCurtainDownStr, nrSterownika, nrRolety+1); + 2362: 21 2f mov r18, r17 + 2364: 30 e0 ldi r19, 0x00 ; 0 + 2366: 2f 5f subi r18, 0xFF ; 255 + 2368: 3f 4f sbci r19, 0xFF ; 255 + 236a: 3f 93 push r19 + 236c: 2f 93 push r18 + 236e: 1f 92 push r1 + 2370: ff 92 push r15 + 2372: 80 e4 ldi r24, 0x40 ; 64 + 2374: 98 e0 ldi r25, 0x08 ; 8 + 2376: 9f 93 push r25 + 2378: 8f 93 push r24 + 237a: 8b 8d ldd r24, Y+27 ; 0x1b + 237c: 8f 93 push r24 + 237e: 8a 8d ldd r24, Y+26 ; 0x1a + 2380: 8f 93 push r24 + 2382: 0e 94 1a 50 call 0xa034 ; 0xa034 + + if ((wartosc > 0) && (wartosc <=100)) + 2386: 8f ef ldi r24, 0xFF ; 255 + 2388: 80 0f add r24, r16 + 238a: 2d b7 in r18, 0x3d ; 61 + 238c: 3e b7 in r19, 0x3e ; 62 + 238e: 28 5f subi r18, 0xF8 ; 248 + 2390: 3f 4f sbci r19, 0xFF ; 255 + 2392: 0f b6 in r0, 0x3f ; 63 + 2394: f8 94 cli + 2396: 3e bf out 0x3e, r19 ; 62 + 2398: 0f be out 0x3f, r0 ; 63 + 239a: 2d bf out 0x3d, r18 ; 61 + 239c: 84 36 cpi r24, 0x64 ; 100 + 239e: 90 f4 brcc .+36 ; 0x23c4 + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 23a0: 1f 92 push r1 + 23a2: 0f 93 push r16 + 23a4: 80 e3 ldi r24, 0x30 ; 48 + 23a6: 98 e0 ldi r25, 0x08 ; 8 + 23a8: 9f 93 push r25 + 23aa: 8f 93 push r24 + 23ac: 8b 8d ldd r24, Y+27 ; 0x1b + 23ae: 8f 93 push r24 + 23b0: 8a 8d ldd r24, Y+26 ; 0x1a + 23b2: 8f 93 push r24 + 23b4: 0e 94 1a 50 call 0xa034 ; 0xa034 + 23b8: 0f 90 pop r0 + 23ba: 0f 90 pop r0 + 23bc: 0f 90 pop r0 + 23be: 0f 90 pop r0 + 23c0: 0f 90 pop r0 + 23c2: 0f 90 pop r0 + + uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + 23c4: 40 2f mov r20, r16 + 23c6: 61 2f mov r22, r17 + 23c8: 8f 2d mov r24, r15 + 23ca: 0e 94 99 3e call 0x7d32 ; 0x7d32 + + if (result == 0) + 23ce: 88 23 and r24, r24 + 23d0: 19 f0 breq .+6 ; 0x23d8 + return OK_INFORM; + + return ERROR_SILENT; + 23d2: 83 e0 ldi r24, 0x03 ; 3 + 23d4: 90 e0 ldi r25, 0x00 ; 0 + 23d6: 02 c0 rjmp .+4 ; 0x23dc + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + 23d8: 81 e0 ldi r24, 0x01 ; 1 + 23da: 90 e0 ldi r25, 0x00 ; 0 + + return ERROR_SILENT; +} + 23dc: df 91 pop r29 + 23de: cf 91 pop r28 + 23e0: 1f 91 pop r17 + 23e2: 0f 91 pop r16 + 23e4: ff 90 pop r15 + 23e6: 08 95 ret + +000023e8 : + return OK_SILENT; +} + +static cliExRes_t statusEncFunction(cmdState_t *state) +{ + nicRegDump(state->myStdInOut); + 23e8: fc 01 movw r30, r24 + 23ea: 82 8d ldd r24, Z+26 ; 0x1a + 23ec: 93 8d ldd r25, Z+27 ; 0x1b + 23ee: 0e 94 c6 29 call 0x538c ; 0x538c + return OK_SILENT; +} + 23f2: 80 e0 ldi r24, 0x00 ; 0 + 23f4: 90 e0 ldi r25, 0x00 ; 0 + 23f6: 08 95 ret + +000023f8 : +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + 23f8: 0e 94 71 0b call 0x16e2 ; 0x16e2 + return OK_SILENT; +} + 23fc: 80 e0 ldi r24, 0x00 ; 0 + 23fe: 90 e0 ldi r25, 0x00 ; 0 + 2400: 08 95 ret + +00002402 : + + return OK_SILENT; +} + +static cliExRes_t goXmodemWyslijFunction(cmdState_t *state) // TODO add code in xModem +{ + 2402: cf 93 push r28 + 2404: df 93 push r29 + 2406: ec 01 movw r28, r24 + fprintf_P(state->myStdInOut, xwyslijStartStr); + 2408: 86 ea ldi r24, 0xA6 ; 166 + 240a: 98 e0 ldi r25, 0x08 ; 8 + 240c: 9f 93 push r25 + 240e: 8f 93 push r24 + 2410: 8b 8d ldd r24, Y+27 ; 0x1b + 2412: 8f 93 push r24 + 2414: 8a 8d ldd r24, Y+26 ; 0x1a + 2416: 8f 93 push r24 + 2418: 0e 94 1a 50 call 0xa034 ; 0xa034 + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 241c: be 01 movw r22, r28 + 241e: 81 e0 ldi r24, 0x01 ; 1 + 2420: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2424: 62 e6 ldi r22, 0x62 ; 98 + 2426: 7f e0 ldi r23, 0x0F ; 15 + 2428: 0e 94 bd 1b call 0x377a ; 0x377a + 242c: 0f 90 pop r0 + 242e: 0f 90 pop r0 + 2430: 0f 90 pop r0 + 2432: 0f 90 pop r0 + 2434: 88 23 and r24, r24 + 2436: c9 f0 breq .+50 ; 0x246a + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 2438: be 01 movw r22, r28 + 243a: 81 e0 ldi r24, 0x01 ; 1 + 243c: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2440: 9f 93 push r25 + 2442: 8f 93 push r24 + 2444: 8e ea ldi r24, 0xAE ; 174 + 2446: 9a e0 ldi r25, 0x0A ; 10 + 2448: 9f 93 push r25 + 244a: 8f 93 push r24 + 244c: 8b 8d ldd r24, Y+27 ; 0x1b + 244e: 8f 93 push r24 + 2450: 8a 8d ldd r24, Y+26 ; 0x1a + 2452: 8f 93 push r24 + 2454: 0e 94 1a 50 call 0xa034 ; 0xa034 + 2458: 0f 90 pop r0 + 245a: 0f 90 pop r0 + 245c: 0f 90 pop r0 + 245e: 0f 90 pop r0 + 2460: 0f 90 pop r0 + 2462: 0f 90 pop r0 + 2464: 84 e0 ldi r24, 0x04 ; 4 + 2466: 90 e0 ldi r25, 0x00 ; 0 + 2468: 02 c0 rjmp .+4 ; 0x246e + return ERROR_INFORM; + } + return OK_SILENT; + 246a: 80 e0 ldi r24, 0x00 ; 0 + 246c: 90 e0 ldi r25, 0x00 ; 0 +} + 246e: df 91 pop r29 + 2470: cf 91 pop r28 + 2472: 08 95 ret + +00002474 : + + return OK_SILENT; +} +static cliExRes_t zapiszModWykFunction(cmdState_t *state) +{ + if (state->argc < 1) + 2474: fc 01 movw r30, r24 + 2476: 21 8d ldd r18, Z+25 ; 0x19 + 2478: 22 23 and r18, r18 + 247a: 51 f0 breq .+20 ; 0x2490 + 247c: bc 01 movw r22, r24 + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + 247e: 81 e0 ldi r24, 0x01 ; 1 + 2480: 0e 94 07 24 call 0x480e ; 0x480e + 2484: 86 2f mov r24, r22 + saveSettings(adres); + 2486: 0e 94 61 3e call 0x7cc2 ; 0x7cc2 + 248a: 80 e0 ldi r24, 0x00 ; 0 + 248c: 90 e0 ldi r25, 0x00 ; 0 + 248e: 08 95 ret + return OK_SILENT; +} +static cliExRes_t zapiszModWykFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + 2490: 82 e0 ldi r24, 0x02 ; 2 + 2492: 90 e0 ldi r25, 0x00 ; 0 + + uint8_t adres = cmdlineGetArgInt(1, state); + saveSettings(adres); + return OK_SILENT; +} + 2494: 08 95 ret + +00002496 : + ipSetConfigGw(gw); + return OK_SILENT; +} + +static cliExRes_t ustawModWykFunction(cmdState_t *state) +{ + 2496: 1f 93 push r17 + 2498: cf 93 push r28 + 249a: df 93 push r29 + if (state->argc < 2) + 249c: fc 01 movw r30, r24 + 249e: 21 8d ldd r18, Z+25 ; 0x19 + 24a0: 22 30 cpi r18, 0x02 ; 2 + 24a2: 80 f0 brcs .+32 ; 0x24c4 + 24a4: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + 24a6: bc 01 movw r22, r24 + 24a8: 81 e0 ldi r24, 0x01 ; 1 + 24aa: 0e 94 07 24 call 0x480e ; 0x480e + 24ae: 16 2f mov r17, r22 + uint8_t wartosc = cmdlineGetArgHex(2, state); + 24b0: be 01 movw r22, r28 + 24b2: 82 e0 ldi r24, 0x02 ; 2 + 24b4: 0e 94 1a 24 call 0x4834 ; 0x4834 + + sendSettings(adres, wartosc); + 24b8: 81 2f mov r24, r17 + 24ba: 0e 94 1e 3e call 0x7c3c ; 0x7c3c + 24be: 80 e0 ldi r24, 0x00 ; 0 + 24c0: 90 e0 ldi r25, 0x00 ; 0 + 24c2: 02 c0 rjmp .+4 ; 0x24c8 +} + +static cliExRes_t ustawModWykFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + 24c4: 82 e0 ldi r24, 0x02 ; 2 + 24c6: 90 e0 ldi r25, 0x00 ; 0 + uint8_t wartosc = cmdlineGetArgHex(2, state); + + sendSettings(adres, wartosc); + + return OK_SILENT; +} + 24c8: df 91 pop r29 + 24ca: cf 91 pop r28 + 24cc: 1f 91 pop r17 + 24ce: 08 95 ret + +000024d0 : + return OK_SILENT; +} + +static cliExRes_t ustawPortRezystor(cmdState_t *state) +{ + if (state->argc < 1) + 24d0: fc 01 movw r30, r24 + 24d2: 21 8d ldd r18, Z+25 ; 0x19 + 24d4: 22 23 and r18, r18 + 24d6: 51 f0 breq .+20 ; 0x24ec + 24d8: bc 01 movw r22, r24 + return SYNTAX_ERROR; + + uint8_t wartosc = cmdlineGetArgInt(1, state); + 24da: 81 e0 ldi r24, 0x01 ; 1 + 24dc: 0e 94 07 24 call 0x480e ; 0x480e + 24e0: 86 2f mov r24, r22 + + MCP4150_setValue(wartosc); + 24e2: 0e 94 2b 27 call 0x4e56 ; 0x4e56 + 24e6: 80 e0 ldi r24, 0x00 ; 0 + 24e8: 90 e0 ldi r25, 0x00 ; 0 + 24ea: 08 95 ret +} + +static cliExRes_t ustawPortRezystor(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + 24ec: 82 e0 ldi r24, 0x02 ; 2 + 24ee: 90 e0 ldi r25, 0x00 ; 0 + uint8_t wartosc = cmdlineGetArgInt(1, state); + + MCP4150_setValue(wartosc); + + return OK_SILENT; +} + 24f0: 08 95 ret + +000024f2 : + + return ERROR_SILENT; +} + +static cliExRes_t curtainUpFunction(cmdState_t *state) +{ + 24f2: ff 92 push r15 + 24f4: 0f 93 push r16 + 24f6: 1f 93 push r17 + 24f8: cf 93 push r28 + 24fa: df 93 push r29 + if (state->argc < 2) + 24fc: fc 01 movw r30, r24 + 24fe: 21 8d ldd r18, Z+25 ; 0x19 + 2500: 22 30 cpi r18, 0x02 ; 2 + 2502: 08 f4 brcc .+2 ; 0x2506 + 2504: 51 c0 rjmp .+162 ; 0x25a8 + 2506: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + 2508: bc 01 movw r22, r24 + 250a: 81 e0 ldi r24, 0x01 ; 1 + 250c: 0e 94 07 24 call 0x480e ; 0x480e + 2510: 16 2f mov r17, r22 + 2512: 1f 73 andi r17, 0x3F ; 63 + uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + 2514: be 01 movw r22, r28 + 2516: 82 e0 ldi r24, 0x02 ; 2 + 2518: 0e 94 07 24 call 0x480e ; 0x480e + 251c: 06 2f mov r16, r22 + 251e: 01 70 andi r16, 0x01 ; 1 + uint8_t wartosc = 255; + if (state->argc > 2) + 2520: 89 8d ldd r24, Y+25 ; 0x19 + 2522: 83 30 cpi r24, 0x03 ; 3 + 2524: 30 f0 brcs .+12 ; 0x2532 + wartosc = cmdlineGetArgInt(3, state); + 2526: be 01 movw r22, r28 + 2528: 83 e0 ldi r24, 0x03 ; 3 + 252a: 0e 94 07 24 call 0x480e ; 0x480e + 252e: f6 2e mov r15, r22 + 2530: 02 c0 rjmp .+4 ; 0x2536 + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + uint8_t wartosc = 255; + 2532: ff 24 eor r15, r15 + 2534: fa 94 dec r15 + if (state->argc > 2) + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut, movingCurtainUpStr, nrSterownika, nrRolety+1); + 2536: 80 2f mov r24, r16 + 2538: 90 e0 ldi r25, 0x00 ; 0 + 253a: 01 96 adiw r24, 0x01 ; 1 + 253c: 9f 93 push r25 + 253e: 8f 93 push r24 + 2540: 1f 92 push r1 + 2542: 1f 93 push r17 + 2544: 83 e7 ldi r24, 0x73 ; 115 + 2546: 98 e0 ldi r25, 0x08 ; 8 + 2548: 9f 93 push r25 + 254a: 8f 93 push r24 + 254c: 8b 8d ldd r24, Y+27 ; 0x1b + 254e: 8f 93 push r24 + 2550: 8a 8d ldd r24, Y+26 ; 0x1a + 2552: 8f 93 push r24 + 2554: 0e 94 1a 50 call 0xa034 ; 0xa034 + if ((wartosc > 0) && (wartosc <=100)) + 2558: 8d b7 in r24, 0x3d ; 61 + 255a: 9e b7 in r25, 0x3e ; 62 + 255c: 08 96 adiw r24, 0x08 ; 8 + 255e: 0f b6 in r0, 0x3f ; 63 + 2560: f8 94 cli + 2562: 9e bf out 0x3e, r25 ; 62 + 2564: 0f be out 0x3f, r0 ; 63 + 2566: 8d bf out 0x3d, r24 ; 61 + 2568: 8f ef ldi r24, 0xFF ; 255 + 256a: 8f 0d add r24, r15 + 256c: 84 36 cpi r24, 0x64 ; 100 + 256e: 90 f4 brcc .+36 ; 0x2594 + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 2570: 1f 92 push r1 + 2572: ff 92 push r15 + 2574: 80 e3 ldi r24, 0x30 ; 48 + 2576: 98 e0 ldi r25, 0x08 ; 8 + 2578: 9f 93 push r25 + 257a: 8f 93 push r24 + 257c: 8b 8d ldd r24, Y+27 ; 0x1b + 257e: 8f 93 push r24 + 2580: 8a 8d ldd r24, Y+26 ; 0x1a + 2582: 8f 93 push r24 + 2584: 0e 94 1a 50 call 0xa034 ; 0xa034 + 2588: 0f 90 pop r0 + 258a: 0f 90 pop r0 + 258c: 0f 90 pop r0 + 258e: 0f 90 pop r0 + 2590: 0f 90 pop r0 + 2592: 0f 90 pop r0 + + uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + 2594: 4f 2d mov r20, r15 + 2596: 60 2f mov r22, r16 + 2598: 81 2f mov r24, r17 + 259a: 0e 94 8a 3d call 0x7b14 ; 0x7b14 + + if (result == 0) + 259e: 88 23 and r24, r24 + 25a0: 31 f0 breq .+12 ; 0x25ae + return OK_INFORM; + + return ERROR_SILENT; + 25a2: 83 e0 ldi r24, 0x03 ; 3 + 25a4: 90 e0 ldi r25, 0x00 ; 0 + 25a6: 05 c0 rjmp .+10 ; 0x25b2 +} + +static cliExRes_t curtainUpFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + 25a8: 82 e0 ldi r24, 0x02 ; 2 + 25aa: 90 e0 ldi r25, 0x00 ; 0 + 25ac: 02 c0 rjmp .+4 ; 0x25b2 + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + 25ae: 81 e0 ldi r24, 0x01 ; 1 + 25b0: 90 e0 ldi r25, 0x00 ; 0 + + return ERROR_SILENT; +} + 25b2: df 91 pop r29 + 25b4: cf 91 pop r28 + 25b6: 1f 91 pop r17 + 25b8: 0f 91 pop r16 + 25ba: ff 90 pop r15 + 25bc: 08 95 ret + +000025be : + ramDyskDir(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t editRamFileFunction(cmdState_t *state) +{ + 25be: 0f 93 push r16 + 25c0: 1f 93 push r17 + 25c2: cf 93 push r28 + 25c4: df 93 push r29 + 25c6: 1f 92 push r1 + 25c8: cd b7 in r28, 0x3d ; 61 + 25ca: de b7 in r29, 0x3e ; 62 + 25cc: 8c 01 movw r16, r24 + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 25ce: bc 01 movw r22, r24 + 25d0: 81 e0 ldi r24, 0x01 ; 1 + 25d2: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 25d6: 62 e6 ldi r22, 0x62 ; 98 + 25d8: 7f e0 ldi r23, 0x0F ; 15 + 25da: 0e 94 bd 1b call 0x377a ; 0x377a + 25de: 88 23 and r24, r24 + 25e0: d1 f0 breq .+52 ; 0x2616 + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 25e2: b8 01 movw r22, r16 + 25e4: 81 e0 ldi r24, 0x01 ; 1 + 25e6: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 25ea: 9f 93 push r25 + 25ec: 8f 93 push r24 + 25ee: 8e ea ldi r24, 0xAE ; 174 + 25f0: 9a e0 ldi r25, 0x0A ; 10 + 25f2: 9f 93 push r25 + 25f4: 8f 93 push r24 + 25f6: f8 01 movw r30, r16 + 25f8: 83 8d ldd r24, Z+27 ; 0x1b + 25fa: 8f 93 push r24 + 25fc: 82 8d ldd r24, Z+26 ; 0x1a + 25fe: 8f 93 push r24 + 2600: 0e 94 1a 50 call 0xa034 ; 0xa034 + return ERROR_INFORM; + 2604: 0f 90 pop r0 + 2606: 0f 90 pop r0 + 2608: 0f 90 pop r0 + 260a: 0f 90 pop r0 + 260c: 0f 90 pop r0 + 260e: 0f 90 pop r0 + 2610: 84 e0 ldi r24, 0x04 ; 4 + 2612: 90 e0 ldi r25, 0x00 ; 0 + 2614: 33 c0 rjmp .+102 ; 0x267c + } + ramDyskUstawWskaznikNaKoniec(&fdVty); + 2616: 82 e6 ldi r24, 0x62 ; 98 + 2618: 9f e0 ldi r25, 0x0F ; 15 + 261a: 0e 94 3a 1e call 0x3c74 ; 0x3c74 + uint8_t znak = 0; + 261e: 19 82 std Y+1, r1 ; 0x01 + fprintf_P(state->myStdInOut, editRamFileIntroStr); + 2620: 85 ed ldi r24, 0xD5 ; 213 + 2622: 98 e0 ldi r25, 0x08 ; 8 + 2624: 9f 93 push r25 + 2626: 8f 93 push r24 + 2628: f8 01 movw r30, r16 + 262a: 83 8d ldd r24, Z+27 ; 0x1b + 262c: 8f 93 push r24 + 262e: 82 8d ldd r24, Z+26 ; 0x1a + 2630: 8f 93 push r24 + 2632: 0e 94 1a 50 call 0xa034 ; 0xa034 + 2636: 0f 90 pop r0 + 2638: 0f 90 pop r0 + 263a: 0f 90 pop r0 + 263c: 0f 90 pop r0 + while(1) + { + if(!xQueueReceive( xVtyRec, &znak, portMAX_DELAY)) + 263e: 20 e0 ldi r18, 0x00 ; 0 + 2640: 4f ef ldi r20, 0xFF ; 255 + 2642: 5f ef ldi r21, 0xFF ; 255 + 2644: be 01 movw r22, r28 + 2646: 6f 5f subi r22, 0xFF ; 255 + 2648: 7f 4f sbci r23, 0xFF ; 255 + 264a: 80 91 ac 0e lds r24, 0x0EAC + 264e: 90 91 ad 0e lds r25, 0x0EAD + 2652: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 2656: 88 23 and r24, r24 + 2658: 91 f3 breq .-28 ; 0x263e + continue; + + if (znak == 0x03) // ^C + 265a: 89 81 ldd r24, Y+1 ; 0x01 + 265c: 83 30 cpi r24, 0x03 ; 3 + 265e: 41 f0 breq .+16 ; 0x2670 + break; + + uartVtySendByte(znak); //Echo + 2660: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + ramDyskZapiszBajtDoPliku(&fdVty, znak); + 2664: 69 81 ldd r22, Y+1 ; 0x01 + 2666: 82 e6 ldi r24, 0x62 ; 98 + 2668: 9f e0 ldi r25, 0x0F ; 15 + 266a: 0e 94 2e 1c call 0x385c ; 0x385c + 266e: e7 cf rjmp .-50 ; 0x263e + } + ramDyskZamknijPlik(&fdVty); + 2670: 82 e6 ldi r24, 0x62 ; 98 + 2672: 9f e0 ldi r25, 0x0F ; 15 + 2674: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + 2678: 80 e0 ldi r24, 0x00 ; 0 + 267a: 90 e0 ldi r25, 0x00 ; 0 + return OK_SILENT; +} + 267c: 0f 90 pop r0 + 267e: df 91 pop r29 + 2680: cf 91 pop r28 + 2682: 1f 91 pop r17 + 2684: 0f 91 pop r16 + 2686: 08 95 ret + +00002688 : + } + return OK_SILENT; +} + +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state) //TODO move to xmodem +{ + 2688: 8f 92 push r8 + 268a: 9f 92 push r9 + 268c: af 92 push r10 + 268e: bf 92 push r11 + 2690: cf 92 push r12 + 2692: df 92 push r13 + 2694: ef 92 push r14 + 2696: ff 92 push r15 + 2698: 0f 93 push r16 + 269a: 1f 93 push r17 + 269c: cf 93 push r28 + 269e: df 93 push r29 + 26a0: 00 d0 rcall .+0 ; 0x26a2 + 26a2: 00 d0 rcall .+0 ; 0x26a4 + 26a4: 00 d0 rcall .+0 ; 0x26a6 + 26a6: cd b7 in r28, 0x3d ; 61 + 26a8: de b7 in r29, 0x3e ; 62 + 26aa: 8c 01 movw r16, r24 + fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + 26ac: 8e e2 ldi r24, 0x2E ; 46 + 26ae: 91 e0 ldi r25, 0x01 ; 1 + 26b0: 9f 93 push r25 + 26b2: 8f 93 push r24 + 26b4: f8 01 movw r30, r16 + 26b6: 83 8d ldd r24, Z+27 ; 0x1b + 26b8: 8f 93 push r24 + 26ba: 82 8d ldd r24, Z+26 ; 0x1a + 26bc: 8f 93 push r24 + 26be: 0e 94 1a 50 call 0xa034 ; 0xa034 + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 26c2: b8 01 movw r22, r16 + 26c4: 81 e0 ldi r24, 0x01 ; 1 + 26c6: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 26ca: 62 e6 ldi r22, 0x62 ; 98 + 26cc: 7f e0 ldi r23, 0x0F ; 15 + 26ce: 0e 94 bd 1b call 0x377a ; 0x377a + 26d2: 0f 90 pop r0 + 26d4: 0f 90 pop r0 + 26d6: 0f 90 pop r0 + 26d8: 0f 90 pop r0 + 26da: 88 23 and r24, r24 + 26dc: c1 f0 breq .+48 ; 0x270e + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 26de: b8 01 movw r22, r16 + 26e0: 81 e0 ldi r24, 0x01 ; 1 + 26e2: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 26e6: 9f 93 push r25 + 26e8: 8f 93 push r24 + 26ea: 8e ea ldi r24, 0xAE ; 174 + 26ec: 9a e0 ldi r25, 0x0A ; 10 + 26ee: 9f 93 push r25 + 26f0: 8f 93 push r24 + 26f2: f8 01 movw r30, r16 + 26f4: 83 8d ldd r24, Z+27 ; 0x1b + 26f6: 8f 93 push r24 + 26f8: 82 8d ldd r24, Z+26 ; 0x1a + 26fa: 8f 93 push r24 + 26fc: 0e 94 1a 50 call 0xa034 ; 0xa034 + return ERROR_INFORM; + 2700: 0f 90 pop r0 + 2702: 0f 90 pop r0 + 2704: 0f 90 pop r0 + 2706: 0f 90 pop r0 + 2708: 0f 90 pop r0 + 270a: 0f 90 pop r0 + 270c: 2b c0 rjmp .+86 ; 0x2764 + uint8_t nrBlokuZdalnyNeg; + + uint8_t crcHi; + uint8_t crcLo; + + state->err1=0; + 270e: f8 01 movw r30, r16 + 2710: 16 8e std Z+30, r1 ; 0x1e + 2712: 15 8e std Z+29, r1 ; 0x1d + state->err2=0; + 2714: 17 8e std Z+31, r1 ; 0x1f + 2716: 74 e1 ldi r23, 0x14 ; 20 + 2718: f7 2e mov r15, r23 + liczbaProb = 20; + for ( ; ; ) + { + fputc('C' , state->myStdInOut); + 271a: f8 01 movw r30, r16 + 271c: 62 8d ldd r22, Z+26 ; 0x1a + 271e: 73 8d ldd r23, Z+27 ; 0x1b + 2720: 83 e4 ldi r24, 0x43 ; 67 + 2722: 90 e0 ldi r25, 0x00 ; 0 + 2724: 0e 94 37 50 call 0xa06e ; 0xa06e + while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + 2728: 80 91 9b 00 lds r24, 0x009B + 272c: 86 ff sbrs r24, 6 + 272e: fc cf rjmp .-8 ; 0x2728 + + if(xQueueReceive(xVtyRec, &c, 100)) + 2730: 20 e0 ldi r18, 0x00 ; 0 + 2732: 44 e6 ldi r20, 0x64 ; 100 + 2734: 50 e0 ldi r21, 0x00 ; 0 + 2736: be 01 movw r22, r28 + 2738: 6b 5f subi r22, 0xFB ; 251 + 273a: 7f 4f sbci r23, 0xFF ; 255 + 273c: 80 91 ac 0e lds r24, 0x0EAC + 2740: 90 91 ad 0e lds r25, 0x0EAD + 2744: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 2748: 88 23 and r24, r24 + 274a: 19 f0 breq .+6 ; 0x2752 + if (c == SOH) + 274c: 8d 81 ldd r24, Y+5 ; 0x05 + 274e: 81 30 cpi r24, 0x01 ; 1 + 2750: 61 f0 breq .+24 ; 0x276a + 2752: fa 94 dec r15 + break; //Rozpoczynamy transmisje + + liczbaProb--; + if (liczbaProb == 0) + 2754: f1 10 cpse r15, r1 + 2756: e1 cf rjmp .-62 ; 0x271a + { + ramDyskZamknijPlik(&fdVty); + 2758: 82 e6 ldi r24, 0x62 ; 98 + 275a: 9f e0 ldi r25, 0x0F ; 15 + 275c: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + state->errno = (uint8_t)(AllOK); + 2760: f8 01 movw r30, r16 + 2762: 14 8e std Z+28, r1 ; 0x1c + return ERROR_INFORM; + 2764: 84 e0 ldi r24, 0x04 ; 4 + 2766: 90 e0 ldi r25, 0x00 ; 0 + 2768: 2f c1 rjmp .+606 ; 0x29c8 + } + + nrBloku = 1; + liczbaProb = 10; + + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 276a: 61 e0 ldi r22, 0x01 ; 1 + 276c: 70 e0 ldi r23, 0x00 ; 0 + 276e: 82 e6 ldi r24, 0x62 ; 98 + 2770: 9f e0 ldi r25, 0x0F ; 15 + 2772: 0e 94 63 1e call 0x3cc6 ; 0x3cc6 + 2776: 4c 01 movw r8, r24 + state->errno = (uint8_t)(AllOK); + return ERROR_INFORM; + } + } + + nrBloku = 1; + 2778: ee 24 eor r14, r14 + 277a: e3 94 inc r14 + liczbaProb = 10; + 277c: 5a e0 ldi r21, 0x0A ; 10 + 277e: b5 2e mov r11, r21 + { + if(xQueueReceive(xVtyRec, &c, 10)) + *(zapPtr++) = c; + else + { + state->errno = (uint8_t)(xModemByteSendTimeout); + 2780: 63 e0 ldi r22, 0x03 ; 3 + 2782: a6 2e mov r10, r22 + + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + for ( ; ; ) + { + if (!xQueueReceive(xVtyRec, &nrBlokuZdalny, 100)) + 2784: 20 e0 ldi r18, 0x00 ; 0 + 2786: 44 e6 ldi r20, 0x64 ; 100 + 2788: 50 e0 ldi r21, 0x00 ; 0 + 278a: be 01 movw r22, r28 + 278c: 6c 5f subi r22, 0xFC ; 252 + 278e: 7f 4f sbci r23, 0xFF ; 255 + 2790: 80 91 ac 0e lds r24, 0x0EAC + 2794: 90 91 ad 0e lds r25, 0x0EAD + 2798: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 279c: 81 11 cpse r24, r1 + 279e: 02 c0 rjmp .+4 ; 0x27a4 + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + 27a0: 82 e0 ldi r24, 0x02 ; 2 + 27a2: 0f c0 rjmp .+30 ; 0x27c2 + break; + } + + if (!xQueueReceive(xVtyRec, &nrBlokuZdalnyNeg, 1)) + 27a4: 20 e0 ldi r18, 0x00 ; 0 + 27a6: 41 e0 ldi r20, 0x01 ; 1 + 27a8: 50 e0 ldi r21, 0x00 ; 0 + 27aa: be 01 movw r22, r28 + 27ac: 6d 5f subi r22, 0xFD ; 253 + 27ae: 7f 4f sbci r23, 0xFF ; 255 + 27b0: 80 91 ac 0e lds r24, 0x0EAC + 27b4: 90 91 ad 0e lds r25, 0x0EAD + 27b8: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 27bc: 81 11 cpse r24, r1 + 27be: 03 c0 rjmp .+6 ; 0x27c6 + { + state->errno = (uint8_t)(xModemByteSendTimeout); + 27c0: 83 e0 ldi r24, 0x03 ; 3 + 27c2: f8 01 movw r30, r16 + 27c4: d7 c0 rjmp .+430 ; 0x2974 + break; + } + + //1 Sprawdzanie, czy pasuje numer bloku z numerem bloku w usupeÅ‚nieniu bitowym do 1 + c = 255-nrBlokuZdalnyNeg; + 27c6: 2b 81 ldd r18, Y+3 ; 0x03 + 27c8: 82 2f mov r24, r18 + 27ca: 80 95 com r24 + 27cc: 8d 83 std Y+5, r24 ; 0x05 + if (nrBlokuZdalny != c) + 27ce: fc 80 ldd r15, Y+4 ; 0x04 + 27d0: f8 16 cp r15, r24 + 27d2: 49 f0 breq .+18 ; 0x27e6 + { + state->errno = (uint8_t)(xModemFrameFrameNoCorrectionNotMatch); + 27d4: 85 e0 ldi r24, 0x05 ; 5 + 27d6: f8 01 movw r30, r16 + 27d8: 84 8f std Z+28, r24 ; 0x1c + state->err1 = nrBlokuZdalny; + 27da: 8f 2d mov r24, r15 + 27dc: 90 e0 ldi r25, 0x00 ; 0 + 27de: 96 8f std Z+30, r25 ; 0x1e + 27e0: 85 8f std Z+29, r24 ; 0x1d + state->err2 = nrBlokuZdalnyNeg; + 27e2: 27 8f std Z+31, r18 ; 0x1f + 27e4: eb c0 rjmp .+470 ; 0x29bc + break; + } + + //Sprawdzenie, czy nie jest wznowiona transmisja poprzedniego bloku lub nie zaczęła siÄ™ od bloku 0 + c = nrBloku-1; + 27e6: 8f ef ldi r24, 0xFF ; 255 + 27e8: 8e 0d add r24, r14 + 27ea: 8d 83 std Y+5, r24 ; 0x05 + if (nrBlokuZdalny == c) + 27ec: f8 12 cpse r15, r24 + 27ee: 08 c0 rjmp .+16 ; 0x2800 + { + nrBloku = c; //CofniÄ™cie nr aktualnego bloku o 1 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 27f0: 6f 2d mov r22, r15 + 27f2: 70 e0 ldi r23, 0x00 ; 0 + 27f4: 82 e6 ldi r24, 0x62 ; 98 + 27f6: 9f e0 ldi r25, 0x0F ; 15 + 27f8: 0e 94 63 1e call 0x3cc6 ; 0x3cc6 + 27fc: 4c 01 movw r8, r24 + 27fe: ef 2c mov r14, r15 + zapPtrKopia = zapPtr; + } + + //2 Sprawdzanie, czy pasuje numer bloku + if (nrBlokuZdalny != nrBloku) + 2800: fc 80 ldd r15, Y+4 ; 0x04 + 2802: fe 14 cp r15, r14 + 2804: 49 f0 breq .+18 ; 0x2818 + { + state->errno = (uint8_t)(xModemWrongFrameNo); + 2806: 84 e0 ldi r24, 0x04 ; 4 + 2808: f8 01 movw r30, r16 + 280a: 84 8f std Z+28, r24 ; 0x1c + state->err1 = nrBlokuZdalnyNeg; + 280c: 8b 81 ldd r24, Y+3 ; 0x03 + 280e: 90 e0 ldi r25, 0x00 ; 0 + 2810: 96 8f std Z+30, r25 ; 0x1e + 2812: 85 8f std Z+29, r24 ; 0x1d + state->err2 = nrBloku; + 2814: e7 8e std Z+31, r14 ; 0x1f + 2816: d2 c0 rjmp .+420 ; 0x29bc + 2818: 64 01 movw r12, r8 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + } + + //2 Sprawdzanie, czy pasuje numer bloku + if (nrBlokuZdalny != nrBloku) + 281a: e1 2c mov r14, r1 + break; + } + + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + { + if(xQueueReceive(xVtyRec, &c, 10)) + 281c: 20 e0 ldi r18, 0x00 ; 0 + 281e: 4a e0 ldi r20, 0x0A ; 10 + 2820: 50 e0 ldi r21, 0x00 ; 0 + 2822: be 01 movw r22, r28 + 2824: 6b 5f subi r22, 0xFB ; 251 + 2826: 7f 4f sbci r23, 0xFF ; 255 + 2828: 80 91 ac 0e lds r24, 0x0EAC + 282c: 90 91 ad 0e lds r25, 0x0EAD + 2830: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 2834: 88 23 and r24, r24 + 2836: 49 f0 breq .+18 ; 0x284a + *(zapPtr++) = c; + 2838: 8d 81 ldd r24, Y+5 ; 0x05 + 283a: f4 01 movw r30, r8 + 283c: 81 93 st Z+, r24 + 283e: 4f 01 movw r8, r30 + state->err1 = nrBlokuZdalnyNeg; + state->err2 = nrBloku; + break; + } + + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + 2840: e3 94 inc r14 + 2842: f0 e8 ldi r31, 0x80 ; 128 + 2844: ef 12 cpse r14, r31 + 2846: ea cf rjmp .-44 ; 0x281c + 2848: 02 c0 rjmp .+4 ; 0x284e + { + if(xQueueReceive(xVtyRec, &c, 10)) + *(zapPtr++) = c; + else + { + state->errno = (uint8_t)(xModemByteSendTimeout); + 284a: f8 01 movw r30, r16 + 284c: a4 8e std Z+28, r10 ; 0x1c + break; + } + } + if (!xQueueReceive(xVtyRec, &crcHi, 10)) + 284e: 20 e0 ldi r18, 0x00 ; 0 + 2850: 4a e0 ldi r20, 0x0A ; 10 + 2852: 50 e0 ldi r21, 0x00 ; 0 + 2854: be 01 movw r22, r28 + 2856: 6e 5f subi r22, 0xFE ; 254 + 2858: 7f 4f sbci r23, 0xFF ; 255 + 285a: 80 91 ac 0e lds r24, 0x0EAC + 285e: 90 91 ad 0e lds r25, 0x0EAD + 2862: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 2866: 81 11 cpse r24, r1 + 2868: 06 c0 rjmp .+12 ; 0x2876 + { + state->errno = (uint8_t)(xModemFrameCrc); + 286a: 86 e0 ldi r24, 0x06 ; 6 + 286c: f8 01 movw r30, r16 + 286e: 84 8f std Z+28, r24 ; 0x1c + state->err1 = 2; + 2870: 82 e0 ldi r24, 0x02 ; 2 + 2872: 90 e0 ldi r25, 0x00 ; 0 + 2874: a1 c0 rjmp .+322 ; 0x29b8 + break; + } + if (!xQueueReceive(xVtyRec, &crcLo, 10)) + 2876: 20 e0 ldi r18, 0x00 ; 0 + 2878: 4a e0 ldi r20, 0x0A ; 10 + 287a: 50 e0 ldi r21, 0x00 ; 0 + 287c: be 01 movw r22, r28 + 287e: 6f 5f subi r22, 0xFF ; 255 + 2880: 7f 4f sbci r23, 0xFF ; 255 + 2882: 80 91 ac 0e lds r24, 0x0EAC + 2886: 90 91 ad 0e lds r25, 0x0EAD + 288a: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 288e: 81 11 cpse r24, r1 + 2890: 06 c0 rjmp .+12 ; 0x289e + { + state->errno = (uint8_t)(xModemFrameCrc); + 2892: 86 e0 ldi r24, 0x06 ; 6 + 2894: f8 01 movw r30, r16 + 2896: 84 8f std Z+28, r24 ; 0x1c + state->err1 = 1; + 2898: 81 e0 ldi r24, 0x01 ; 1 + 289a: 90 e0 ldi r25, 0x00 ; 0 + 289c: 8d c0 rjmp .+282 ; 0x29b8 + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 2; + break; + } + if (!xQueueReceive(xVtyRec, &crcLo, 10)) + 289e: 30 e0 ldi r19, 0x00 ; 0 + 28a0: 80 e0 ldi r24, 0x00 ; 0 + 28a2: 90 e0 ldi r25, 0x00 ; 0 + //3 Zerowanie CRC + crcLokalne=0; + + //4 Obliczanie CRC + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + 28a4: f6 01 movw r30, r12 + 28a6: 21 91 ld r18, Z+ + 28a8: 6f 01 movw r12, r30 + uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + uint8_t __tmp1; /* %1 */ + uint8_t __tmp2; /* %2 */ + /* %3 __data */ + + __asm__ __volatile__ ( + 28aa: 92 27 eor r25, r18 + 28ac: 09 2e mov r0, r25 + 28ae: 02 94 swap r0 + 28b0: 20 2d mov r18, r0 + 28b2: 2f 70 andi r18, 0x0F ; 15 + 28b4: 29 27 eor r18, r25 + 28b6: 49 2f mov r20, r25 + 28b8: 40 25 eor r20, r0 + 28ba: 44 0f add r20, r20 + 28bc: 40 7e andi r20, 0xE0 ; 224 + 28be: 24 27 eor r18, r20 + 28c0: 40 2d mov r20, r0 + 28c2: 49 27 eor r20, r25 + 28c4: 40 7f andi r20, 0xF0 ; 240 + 28c6: 46 95 lsr r20 + 28c8: 09 2e mov r0, r25 + 28ca: 00 0c add r0, r0 + 28cc: 44 1f adc r20, r20 + 28ce: 96 95 lsr r25 + 28d0: 96 95 lsr r25 + 28d2: 96 95 lsr r25 + 28d4: 9f 71 andi r25, 0x1F ; 31 + 28d6: 94 27 eor r25, r20 + 28d8: 98 27 eor r25, r24 + 28da: 82 2f mov r24, r18 + + //3 Zerowanie CRC + crcLokalne=0; + + //4 Obliczanie CRC + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + 28dc: 3f 5f subi r19, 0xFF ; 255 + 28de: 30 38 cpi r19, 0x80 ; 128 + 28e0: 09 f7 brne .-62 ; 0x28a4 + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + + //5 Srawdzanie CRC + if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + 28e2: 2a 81 ldd r18, Y+2 ; 0x02 + 28e4: 30 e0 ldi r19, 0x00 ; 0 + 28e6: 49 2f mov r20, r25 + 28e8: 55 27 eor r21, r21 + 28ea: 24 17 cp r18, r20 + 28ec: 35 07 cpc r19, r21 + 28ee: 61 f4 brne .+24 ; 0x2908 + 28f0: 29 81 ldd r18, Y+1 ; 0x01 + 28f2: 30 e0 ldi r19, 0x00 ; 0 + 28f4: 99 27 eor r25, r25 + 28f6: 28 17 cp r18, r24 + 28f8: 39 07 cpc r19, r25 + 28fa: 31 f4 brne .+12 ; 0x2908 + { + liczbaProb = 10; + uartVtySendByte(ACK); + 28fc: 86 e0 ldi r24, 0x06 ; 6 + 28fe: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + + //5 Srawdzanie CRC + if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + { + liczbaProb = 10; + 2902: 8a e0 ldi r24, 0x0A ; 10 + 2904: b8 2e mov r11, r24 + 2906: 0f c0 rjmp .+30 ; 0x2926 + uartVtySendByte(ACK); + } + else + { + liczbaProb--; + 2908: ba 94 dec r11 + nrBloku--; + 290a: fa 94 dec r15 + uartVtySendByte(NAK); + 290c: 85 e1 ldi r24, 0x15 ; 21 + 290e: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + } + + if (liczbaProb == 0) + 2912: b1 10 cpse r11, r1 + 2914: 08 c0 rjmp .+16 ; 0x2926 + { + state->err1 = nrBlokuZdalny; + 2916: 8c 81 ldd r24, Y+4 ; 0x04 + 2918: 90 e0 ldi r25, 0x00 ; 0 + 291a: f8 01 movw r30, r16 + 291c: 96 8f std Z+30, r25 ; 0x1e + 291e: 85 8f std Z+29, r24 ; 0x1d + state->err2 = nrBloku; + 2920: f7 8e std Z+31, r15 ; 0x1f + state->errno = (uint8_t)(xModemWrongFrameNo); + 2922: 84 e0 ldi r24, 0x04 ; 4 + 2924: 27 c0 rjmp .+78 ; 0x2974 + break; + } + + if (!xQueueReceive(xVtyRec, &temp1, 100)) + 2926: 20 e0 ldi r18, 0x00 ; 0 + 2928: 44 e6 ldi r20, 0x64 ; 100 + 292a: 50 e0 ldi r21, 0x00 ; 0 + 292c: be 01 movw r22, r28 + 292e: 6a 5f subi r22, 0xFA ; 250 + 2930: 7f 4f sbci r23, 0xFF ; 255 + 2932: 80 91 ac 0e lds r24, 0x0EAC + 2936: 90 91 ad 0e lds r25, 0x0EAD + 293a: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 293e: 88 23 and r24, r24 + 2940: 09 f4 brne .+2 ; 0x2944 + 2942: 2e cf rjmp .-420 ; 0x27a0 + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (temp1 == SOH) + 2944: 8e 81 ldd r24, Y+6 ; 0x06 + 2946: 81 30 cpi r24, 0x01 ; 1 + 2948: 69 f4 brne .+26 ; 0x2964 + { + nrBloku++; + 294a: ee 24 eor r14, r14 + 294c: e3 94 inc r14 + 294e: ef 0c add r14, r15 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 2950: 6e 2d mov r22, r14 + 2952: 70 e0 ldi r23, 0x00 ; 0 + 2954: 82 e6 ldi r24, 0x62 ; 98 + 2956: 9f e0 ldi r25, 0x0F ; 15 + 2958: 0e 94 63 1e call 0x3cc6 ; 0x3cc6 + 295c: 4c 01 movw r8, r24 + zapPtrKopia = zapPtr; + state->errno = (uint8_t)(AllOK); + 295e: f8 01 movw r30, r16 + 2960: 14 8e std Z+28, r1 ; 0x1c + 2962: 10 cf rjmp .-480 ; 0x2784 + continue; + } + + if (temp1 == CAN) + 2964: 88 31 cpi r24, 0x18 ; 24 + 2966: 41 f4 brne .+16 ; 0x2978 + { + state->err1 = nrBloku; + 2968: 8f 2d mov r24, r15 + 296a: 90 e0 ldi r25, 0x00 ; 0 + 296c: f8 01 movw r30, r16 + 296e: 96 8f std Z+30, r25 ; 0x1e + 2970: 85 8f std Z+29, r24 ; 0x1d + state->errno = (uint8_t)(xModemRemoteSideCan); + 2972: 87 e0 ldi r24, 0x07 ; 7 + 2974: 84 8f std Z+28, r24 ; 0x1c + 2976: 22 c0 rjmp .+68 ; 0x29bc + break; + } + if (temp1 == EOT) + 2978: 84 30 cpi r24, 0x04 ; 4 + 297a: d1 f4 brne .+52 ; 0x29b0 + { + uartVtySendByte(NAK); + 297c: 85 e1 ldi r24, 0x15 ; 21 + 297e: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + if (xQueueReceive(xVtyRec, &temp1, 10)) + 2982: 20 e0 ldi r18, 0x00 ; 0 + 2984: 4a e0 ldi r20, 0x0A ; 10 + 2986: 50 e0 ldi r21, 0x00 ; 0 + 2988: be 01 movw r22, r28 + 298a: 6a 5f subi r22, 0xFA ; 250 + 298c: 7f 4f sbci r23, 0xFF ; 255 + 298e: 80 91 ac 0e lds r24, 0x0EAC + 2992: 90 91 ad 0e lds r25, 0x0EAD + 2996: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 299a: 88 23 and r24, r24 + 299c: 31 f0 breq .+12 ; 0x29aa + { + if (temp1 == EOT) + 299e: 8e 81 ldd r24, Y+6 ; 0x06 + 29a0: 84 30 cpi r24, 0x04 ; 4 + 29a2: 19 f4 brne .+6 ; 0x29aa + uartVtySendByte(ACK); + 29a4: 86 e0 ldi r24, 0x06 ; 6 + 29a6: 0e 94 1f 0d call 0x1a3e ; 0x1a3e + } + state->errno = (uint8_t)(AllOK); + 29aa: f8 01 movw r30, r16 + 29ac: 14 8e std Z+28, r1 ; 0x1c + 29ae: 06 c0 rjmp .+12 ; 0x29bc + break; + } + state->errno = (uint8_t)(xModemUnknownResponse); + 29b0: 98 e0 ldi r25, 0x08 ; 8 + 29b2: f8 01 movw r30, r16 + 29b4: 94 8f std Z+28, r25 ; 0x1c + state->err1 = temp1; + 29b6: 90 e0 ldi r25, 0x00 ; 0 + 29b8: 96 8f std Z+30, r25 ; 0x1e + 29ba: 85 8f std Z+29, r24 ; 0x1d + break; + } + ramDyskZamknijPlik(&fdVty); + 29bc: 82 e6 ldi r24, 0x62 ; 98 + 29be: 9f e0 ldi r25, 0x0F ; 15 + 29c0: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + return OK_SILENT; + 29c4: 80 e0 ldi r24, 0x00 ; 0 + 29c6: 90 e0 ldi r25, 0x00 ; 0 +} + 29c8: 26 96 adiw r28, 0x06 ; 6 + 29ca: 0f b6 in r0, 0x3f ; 63 + 29cc: f8 94 cli + 29ce: de bf out 0x3e, r29 ; 62 + 29d0: 0f be out 0x3f, r0 ; 63 + 29d2: cd bf out 0x3d, r28 ; 61 + 29d4: df 91 pop r29 + 29d6: cf 91 pop r28 + 29d8: 1f 91 pop r17 + 29da: 0f 91 pop r16 + 29dc: ff 90 pop r15 + 29de: ef 90 pop r14 + 29e0: df 90 pop r13 + 29e2: cf 90 pop r12 + 29e4: bf 90 pop r11 + 29e6: af 90 pop r10 + 29e8: 9f 90 pop r9 + 29ea: 8f 90 pop r8 + 29ec: 08 95 ret + +000029ee : + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + return OK_SILENT; +} + +static cliExRes_t debugFunction (cmdState_t *state) +{ + 29ee: ff 92 push r15 + 29f0: 0f 93 push r16 + 29f2: 1f 93 push r17 + 29f4: cf 93 push r28 + 29f6: df 93 push r29 + if (state->argc < 2) + 29f8: fc 01 movw r30, r24 + 29fa: 21 8d ldd r18, Z+25 ; 0x19 + 29fc: 22 30 cpi r18, 0x02 ; 2 + 29fe: 18 f4 brcc .+6 ; 0x2a06 + return SYNTAX_ERROR; + 2a00: 82 e0 ldi r24, 0x02 ; 2 + 2a02: 90 e0 ldi r25, 0x00 ; 0 + 2a04: c1 c0 rjmp .+386 ; 0x2b88 + 2a06: ec 01 movw r28, r24 + + uint8_t level = cmdlineGetArgInt(2, state); + 2a08: bc 01 movw r22, r24 + 2a0a: 82 e0 ldi r24, 0x02 ; 2 + 2a0c: 0e 94 07 24 call 0x480e ; 0x480e + 2a10: f6 2e mov r15, r22 + const char *str = (const char*)cmdlineGetArgStr(1, state); + 2a12: be 01 movw r22, r28 + 2a14: 81 e0 ldi r24, 0x01 ; 1 + 2a16: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2a1a: 18 2f mov r17, r24 + 2a1c: 09 2f mov r16, r25 + if (level == 0) + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + 2a1e: 43 e0 ldi r20, 0x03 ; 3 + 2a20: 50 e0 ldi r21, 0x00 ; 0 + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t level = cmdlineGetArgInt(2, state); + const char *str = (const char*)cmdlineGetArgStr(1, state); + if (level == 0) + 2a22: f1 10 cpse r15, r1 + 2a24: 51 c0 rjmp .+162 ; 0x2ac8 + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + 2a26: 6a e2 ldi r22, 0x2A ; 42 + 2a28: 71 e0 ldi r23, 0x01 ; 1 + 2a2a: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2a2e: 89 2b or r24, r25 + 2a30: 31 f4 brne .+12 ; 0x2a3e + { + setArpDebug(NULL, 0); + 2a32: 60 e0 ldi r22, 0x00 ; 0 + 2a34: 80 e0 ldi r24, 0x00 ; 0 + 2a36: 90 e0 ldi r25, 0x00 ; 0 + 2a38: 0e 94 6b 30 call 0x60d6 ; 0x60d6 + 2a3c: 2f c0 rjmp .+94 ; 0x2a9c + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + 2a3e: 42 e0 ldi r20, 0x02 ; 2 + 2a40: 50 e0 ldi r21, 0x00 ; 0 + 2a42: 67 e2 ldi r22, 0x27 ; 39 + 2a44: 71 e0 ldi r23, 0x01 ; 1 + 2a46: 81 2f mov r24, r17 + 2a48: 90 2f mov r25, r16 + 2a4a: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2a4e: 89 2b or r24, r25 + 2a50: 31 f4 brne .+12 ; 0x2a5e + { + setIpDebug(NULL, 0); + 2a52: 60 e0 ldi r22, 0x00 ; 0 + 2a54: 80 e0 ldi r24, 0x00 ; 0 + 2a56: 90 e0 ldi r25, 0x00 ; 0 + 2a58: 0e 94 dd 2d call 0x5bba ; 0x5bba + 2a5c: 1f c0 rjmp .+62 ; 0x2a9c + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + 2a5e: 42 e0 ldi r20, 0x02 ; 2 + 2a60: 50 e0 ldi r21, 0x00 ; 0 + 2a62: 62 e2 ldi r22, 0x22 ; 34 + 2a64: 71 e0 ldi r23, 0x01 ; 1 + 2a66: 81 2f mov r24, r17 + 2a68: 90 2f mov r25, r16 + 2a6a: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2a6e: 89 2b or r24, r25 + 2a70: 31 f4 brne .+12 ; 0x2a7e + { + setIcmpDebug(NULL, 0); + 2a72: 60 e0 ldi r22, 0x00 ; 0 + 2a74: 80 e0 ldi r24, 0x00 ; 0 + 2a76: 90 e0 ldi r25, 0x00 ; 0 + 2a78: 0e 94 58 2f call 0x5eb0 ; 0x5eb0 + 2a7c: 0f c0 rjmp .+30 ; 0x2a9c + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + 2a7e: 42 e0 ldi r20, 0x02 ; 2 + 2a80: 50 e0 ldi r21, 0x00 ; 0 + 2a82: 6e e1 ldi r22, 0x1E ; 30 + 2a84: 71 e0 ldi r23, 0x01 ; 1 + 2a86: 81 2f mov r24, r17 + 2a88: 90 2f mov r25, r16 + 2a8a: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2a8e: 89 2b or r24, r25 + 2a90: 51 f4 brne .+20 ; 0x2aa6 + { + setTcpDebug(NULL, 0); + 2a92: 60 e0 ldi r22, 0x00 ; 0 + 2a94: 80 e0 ldi r24, 0x00 ; 0 + 2a96: 90 e0 ldi r25, 0x00 ; 0 + 2a98: 0e 94 46 36 call 0x6c8c ; 0x6c8c + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2a9c: 0f 93 push r16 + 2a9e: 1f 93 push r17 + 2aa0: 89 e0 ldi r24, 0x09 ; 9 + 2aa2: 98 e0 ldi r25, 0x08 ; 8 + 2aa4: 61 c0 rjmp .+194 ; 0x2b68 + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + 2aa6: 42 e0 ldi r20, 0x02 ; 2 + 2aa8: 50 e0 ldi r21, 0x00 ; 0 + 2aaa: 6a e1 ldi r22, 0x1A ; 26 + 2aac: 71 e0 ldi r23, 0x01 ; 1 + 2aae: 81 2f mov r24, r17 + 2ab0: 90 2f mov r25, r16 + 2ab2: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2ab6: 89 2b or r24, r25 + 2ab8: 09 f0 breq .+2 ; 0x2abc + 2aba: a2 cf rjmp .-188 ; 0x2a00 + { + setUdpDebug(NULL, 0); + 2abc: 60 e0 ldi r22, 0x00 ; 0 + 2abe: 80 e0 ldi r24, 0x00 ; 0 + 2ac0: 90 e0 ldi r25, 0x00 ; 0 + 2ac2: 0e 94 94 36 call 0x6d28 ; 0x6d28 + 2ac6: ea cf rjmp .-44 ; 0x2a9c + + + } + else //level > 0 + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + 2ac8: 66 e1 ldi r22, 0x16 ; 22 + 2aca: 71 e0 ldi r23, 0x01 ; 1 + 2acc: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2ad0: 89 2b or r24, r25 + 2ad2: 31 f4 brne .+12 ; 0x2ae0 + { + setArpDebug(state->myStdInOut, level); + 2ad4: 6f 2d mov r22, r15 + 2ad6: 8a 8d ldd r24, Y+26 ; 0x1a + 2ad8: 9b 8d ldd r25, Y+27 ; 0x1b + 2ada: 0e 94 6b 30 call 0x60d6 ; 0x60d6 + 2ade: 40 c0 rjmp .+128 ; 0x2b60 + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + 2ae0: 42 e0 ldi r20, 0x02 ; 2 + 2ae2: 50 e0 ldi r21, 0x00 ; 0 + 2ae4: 63 e1 ldi r22, 0x13 ; 19 + 2ae6: 71 e0 ldi r23, 0x01 ; 1 + 2ae8: 81 2f mov r24, r17 + 2aea: 90 2f mov r25, r16 + 2aec: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2af0: 89 2b or r24, r25 + 2af2: 31 f4 brne .+12 ; 0x2b00 + { + setIpDebug(state->myStdInOut, level); + 2af4: 6f 2d mov r22, r15 + 2af6: 8a 8d ldd r24, Y+26 ; 0x1a + 2af8: 9b 8d ldd r25, Y+27 ; 0x1b + 2afa: 0e 94 dd 2d call 0x5bba ; 0x5bba + 2afe: 30 c0 rjmp .+96 ; 0x2b60 + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + 2b00: 42 e0 ldi r20, 0x02 ; 2 + 2b02: 50 e0 ldi r21, 0x00 ; 0 + 2b04: 6e e0 ldi r22, 0x0E ; 14 + 2b06: 71 e0 ldi r23, 0x01 ; 1 + 2b08: 81 2f mov r24, r17 + 2b0a: 90 2f mov r25, r16 + 2b0c: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2b10: 89 2b or r24, r25 + 2b12: 31 f4 brne .+12 ; 0x2b20 + { + setIcmpDebug(state->myStdInOut, level); + 2b14: 6f 2d mov r22, r15 + 2b16: 8a 8d ldd r24, Y+26 ; 0x1a + 2b18: 9b 8d ldd r25, Y+27 ; 0x1b + 2b1a: 0e 94 58 2f call 0x5eb0 ; 0x5eb0 + 2b1e: 20 c0 rjmp .+64 ; 0x2b60 + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + 2b20: 42 e0 ldi r20, 0x02 ; 2 + 2b22: 50 e0 ldi r21, 0x00 ; 0 + 2b24: 6a e0 ldi r22, 0x0A ; 10 + 2b26: 71 e0 ldi r23, 0x01 ; 1 + 2b28: 81 2f mov r24, r17 + 2b2a: 90 2f mov r25, r16 + 2b2c: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2b30: 89 2b or r24, r25 + 2b32: 31 f4 brne .+12 ; 0x2b40 + { + setTcpDebug(state->myStdInOut, level); + 2b34: 6f 2d mov r22, r15 + 2b36: 8a 8d ldd r24, Y+26 ; 0x1a + 2b38: 9b 8d ldd r25, Y+27 ; 0x1b + 2b3a: 0e 94 46 36 call 0x6c8c ; 0x6c8c + 2b3e: 10 c0 rjmp .+32 ; 0x2b60 + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + 2b40: 42 e0 ldi r20, 0x02 ; 2 + 2b42: 50 e0 ldi r21, 0x00 ; 0 + 2b44: 66 e0 ldi r22, 0x06 ; 6 + 2b46: 71 e0 ldi r23, 0x01 ; 1 + 2b48: 81 2f mov r24, r17 + 2b4a: 90 2f mov r25, r16 + 2b4c: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 2b50: 89 2b or r24, r25 + 2b52: 09 f0 breq .+2 ; 0x2b56 + 2b54: 55 cf rjmp .-342 ; 0x2a00 + { + setUdpDebug(state->myStdInOut, level); + 2b56: 6f 2d mov r22, r15 + 2b58: 8a 8d ldd r24, Y+26 ; 0x1a + 2b5a: 9b 8d ldd r25, Y+27 ; 0x1b + 2b5c: 0e 94 94 36 call 0x6d28 ; 0x6d28 + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2b60: 0f 93 push r16 + 2b62: 1f 93 push r17 + 2b64: 8d e1 ldi r24, 0x1D ; 29 + 2b66: 98 e0 ldi r25, 0x08 ; 8 + 2b68: 9f 93 push r25 + 2b6a: 8f 93 push r24 + 2b6c: 8b 8d ldd r24, Y+27 ; 0x1b + 2b6e: 8f 93 push r24 + 2b70: 8a 8d ldd r24, Y+26 ; 0x1a + 2b72: 8f 93 push r24 + 2b74: 0e 94 1a 50 call 0xa034 ; 0xa034 + 2b78: 0f 90 pop r0 + 2b7a: 0f 90 pop r0 + 2b7c: 0f 90 pop r0 + 2b7e: 0f 90 pop r0 + 2b80: 0f 90 pop r0 + 2b82: 0f 90 pop r0 + return OK_SILENT; + 2b84: 80 e0 ldi r24, 0x00 ; 0 + 2b86: 90 e0 ldi r25, 0x00 ; 0 + } + } + + return SYNTAX_ERROR; +} + 2b88: df 91 pop r29 + 2b8a: cf 91 pop r28 + 2b8c: 1f 91 pop r17 + 2b8e: 0f 91 pop r16 + 2b90: ff 90 pop r15 + 2b92: 08 95 ret + +00002b94 : + saveSettings(adres); + return OK_SILENT; +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + 2b94: cf 93 push r28 + 2b96: df 93 push r29 + if (state->argc < 6) + 2b98: fc 01 movw r30, r24 + 2b9a: 21 8d ldd r18, Z+25 ; 0x19 + 2b9c: 26 30 cpi r18, 0x06 ; 6 + 2b9e: 60 f1 brcs .+88 ; 0x2bf8 + 2ba0: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + 2ba2: bc 01 movw r22, r24 + 2ba4: 81 e0 ldi r24, 0x01 ; 1 + 2ba6: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2baa: 60 93 80 0e sts 0x0E80, r22 + nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + 2bae: be 01 movw r22, r28 + 2bb0: 82 e0 ldi r24, 0x02 ; 2 + 2bb2: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2bb6: 60 93 81 0e sts 0x0E81, r22 + nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + 2bba: be 01 movw r22, r28 + 2bbc: 83 e0 ldi r24, 0x03 ; 3 + 2bbe: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2bc2: 60 93 82 0e sts 0x0E82, r22 + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + 2bc6: be 01 movw r22, r28 + 2bc8: 84 e0 ldi r24, 0x04 ; 4 + 2bca: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2bce: 60 93 83 0e sts 0x0E83, r22 + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + 2bd2: be 01 movw r22, r28 + 2bd4: 85 e0 ldi r24, 0x05 ; 5 + 2bd6: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2bda: 60 93 84 0e sts 0x0E84, r22 + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + 2bde: be 01 movw r22, r28 + 2be0: 86 e0 ldi r24, 0x06 ; 6 + 2be2: 0e 94 1a 24 call 0x4834 ; 0x4834 + 2be6: 60 93 85 0e sts 0x0E85, r22 + nicSetMacAddress(nicState.mac.addr); + 2bea: 80 e8 ldi r24, 0x80 ; 128 + 2bec: 9e e0 ldi r25, 0x0E ; 14 + 2bee: 0e 94 f9 28 call 0x51f2 ; 0x51f2 + 2bf2: 80 e0 ldi r24, 0x00 ; 0 + 2bf4: 90 e0 ldi r25, 0x00 ; 0 + 2bf6: 02 c0 rjmp .+4 ; 0x2bfc +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + if (state->argc < 6) + return SYNTAX_ERROR; + 2bf8: 82 e0 ldi r24, 0x02 ; 2 + 2bfa: 90 e0 ldi r25, 0x00 ; 0 + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + 2bfc: df 91 pop r29 + 2bfe: cf 91 pop r28 + 2c00: 08 95 ret + +00002c02 : + ipSetConfigIp(ip); + return OK_SILENT; +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + 2c02: 8f 92 push r8 + 2c04: 9f 92 push r9 + 2c06: af 92 push r10 + 2c08: bf 92 push r11 + 2c0a: cf 92 push r12 + 2c0c: df 92 push r13 + 2c0e: ef 92 push r14 + 2c10: ff 92 push r15 + 2c12: cf 93 push r28 + 2c14: df 93 push r29 + if (state->argc < 5) + 2c16: fc 01 movw r30, r24 + 2c18: 21 8d ldd r18, Z+25 ; 0x19 + 2c1a: 25 30 cpi r18, 0x05 ; 5 + 2c1c: 08 f4 brcc .+2 ; 0x2c20 + 2c1e: 54 c0 rjmp .+168 ; 0x2cc8 + 2c20: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + 2c22: bc 01 movw r22, r24 + 2c24: 81 e0 ldi r24, 0x01 ; 1 + 2c26: 0e 94 07 24 call 0x480e ; 0x480e + 2c2a: 6b 01 movw r12, r22 + 2c2c: 7c 01 movw r14, r24 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2c2e: be 01 movw r22, r28 + 2c30: 82 e0 ldi r24, 0x02 ; 2 + 2c32: 0e 94 07 24 call 0x480e ; 0x480e + 2c36: 4b 01 movw r8, r22 + 2c38: 5c 01 movw r10, r24 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2c3a: be 01 movw r22, r28 + 2c3c: 83 e0 ldi r24, 0x03 ; 3 + 2c3e: 0e 94 07 24 call 0x480e ; 0x480e +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2c42: ba 2c mov r11, r10 + 2c44: a9 2c mov r10, r9 + 2c46: 98 2c mov r9, r8 + 2c48: 88 24 eor r8, r8 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2c4a: 55 27 eor r21, r21 + 2c4c: 44 27 eor r20, r20 + 2c4e: d5 01 movw r26, r10 + 2c50: c4 01 movw r24, r8 + 2c52: 84 0f add r24, r20 + 2c54: 95 1f adc r25, r21 + 2c56: a6 1f adc r26, r22 + 2c58: b7 1f adc r27, r23 +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2c5a: c8 0e add r12, r24 + 2c5c: d9 1e adc r13, r25 + 2c5e: ea 1e adc r14, r26 + 2c60: fb 1e adc r15, r27 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2c62: be 01 movw r22, r28 + 2c64: 84 e0 ldi r24, 0x04 ; 4 + 2c66: 0e 94 07 24 call 0x480e ; 0x480e + udpSocket->dstIp = ip; + 2c6a: e0 91 a2 0e lds r30, 0x0EA2 + 2c6e: f0 91 a3 0e lds r31, 0x0EA3 + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2c72: b6 2f mov r27, r22 + 2c74: aa 27 eor r26, r26 + 2c76: 99 27 eor r25, r25 + 2c78: 88 27 eor r24, r24 +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + 2c7a: 8c 0d add r24, r12 + 2c7c: 9d 1d adc r25, r13 + 2c7e: ae 1d adc r26, r14 + 2c80: bf 1d adc r27, r15 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + udpSocket->dstIp = ip; + 2c82: 86 83 std Z+6, r24 ; 0x06 + 2c84: 97 83 std Z+7, r25 ; 0x07 + 2c86: a0 87 std Z+8, r26 ; 0x08 + 2c88: b1 87 std Z+9, r27 ; 0x09 + + uint16_t port = cmdlineGetArgInt(5, state); + 2c8a: be 01 movw r22, r28 + 2c8c: 85 e0 ldi r24, 0x05 ; 5 + 2c8e: 0e 94 07 24 call 0x480e ; 0x480e + udpSocket->srcPort = htons(port); + 2c92: e0 90 a2 0e lds r14, 0x0EA2 + 2c96: f0 90 a3 0e lds r15, 0x0EA3 + 2c9a: cb 01 movw r24, r22 + 2c9c: 0e 94 cb 2a call 0x5596 ; 0x5596 + 2ca0: f7 01 movw r30, r14 + 2ca2: 95 83 std Z+5, r25 ; 0x05 + 2ca4: 84 83 std Z+4, r24 ; 0x04 + + if (state->argc > 5) + 2ca6: 89 8d ldd r24, Y+25 ; 0x19 + 2ca8: 86 30 cpi r24, 0x06 ; 6 + 2caa: 88 f0 brcs .+34 ; 0x2cce + { + port = cmdlineGetArgInt(6, state); + 2cac: be 01 movw r22, r28 + 2cae: 86 e0 ldi r24, 0x06 ; 6 + 2cb0: 0e 94 07 24 call 0x480e ; 0x480e + udpSocket->dstPort = htons(port); + 2cb4: c0 91 a2 0e lds r28, 0x0EA2 + 2cb8: d0 91 a3 0e lds r29, 0x0EA3 + 2cbc: cb 01 movw r24, r22 + 2cbe: 0e 94 cb 2a call 0x5596 ; 0x5596 + 2cc2: 9b 83 std Y+3, r25 ; 0x03 + 2cc4: 8a 83 std Y+2, r24 ; 0x02 + 2cc6: 03 c0 rjmp .+6 ; 0x2cce +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + 2cc8: 82 e0 ldi r24, 0x02 ; 2 + 2cca: 90 e0 ldi r25, 0x00 ; 0 + 2ccc: 02 c0 rjmp .+4 ; 0x2cd2 + udpSocket->dstIp = ip; + + uint16_t port = cmdlineGetArgInt(5, state); + udpSocket->srcPort = htons(port); + + if (state->argc > 5) + 2cce: 80 e0 ldi r24, 0x00 ; 0 + 2cd0: 90 e0 ldi r25, 0x00 ; 0 + { + port = cmdlineGetArgInt(6, state); + udpSocket->dstPort = htons(port); + } + return OK_SILENT; +} + 2cd2: df 91 pop r29 + 2cd4: cf 91 pop r28 + 2cd6: ff 90 pop r15 + 2cd8: ef 90 pop r14 + 2cda: df 90 pop r13 + 2cdc: cf 90 pop r12 + 2cde: bf 90 pop r11 + 2ce0: af 90 pop r10 + 2ce2: 9f 90 pop r9 + 2ce4: 8f 90 pop r8 + 2ce6: 08 95 ret + +00002ce8 : + return OK_SILENT; +} + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + 2ce8: 8f 92 push r8 + 2cea: 9f 92 push r9 + 2cec: af 92 push r10 + 2cee: bf 92 push r11 + 2cf0: cf 92 push r12 + 2cf2: df 92 push r13 + 2cf4: ef 92 push r14 + 2cf6: ff 92 push r15 + 2cf8: cf 93 push r28 + 2cfa: df 93 push r29 + if (state->argc < 4) + 2cfc: fc 01 movw r30, r24 + 2cfe: 21 8d ldd r18, Z+25 ; 0x19 + 2d00: 24 30 cpi r18, 0x04 ; 4 + 2d02: a0 f1 brcs .+104 ; 0x2d6c + 2d04: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + 2d06: bc 01 movw r22, r24 + 2d08: 81 e0 ldi r24, 0x01 ; 1 + 2d0a: 0e 94 07 24 call 0x480e ; 0x480e + 2d0e: 6b 01 movw r12, r22 + 2d10: 7c 01 movw r14, r24 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2d12: be 01 movw r22, r28 + 2d14: 82 e0 ldi r24, 0x02 ; 2 + 2d16: 0e 94 07 24 call 0x480e ; 0x480e + 2d1a: 4b 01 movw r8, r22 + 2d1c: 5c 01 movw r10, r24 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2d1e: be 01 movw r22, r28 + 2d20: 83 e0 ldi r24, 0x03 ; 3 + 2d22: 0e 94 07 24 call 0x480e ; 0x480e +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2d26: ba 2c mov r11, r10 + 2d28: a9 2c mov r10, r9 + 2d2a: 98 2c mov r9, r8 + 2d2c: 88 24 eor r8, r8 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2d2e: 55 27 eor r21, r21 + 2d30: 44 27 eor r20, r20 + 2d32: d5 01 movw r26, r10 + 2d34: c4 01 movw r24, r8 + 2d36: 84 0f add r24, r20 + 2d38: 95 1f adc r25, r21 + 2d3a: a6 1f adc r26, r22 + 2d3c: b7 1f adc r27, r23 +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2d3e: c8 0e add r12, r24 + 2d40: d9 1e adc r13, r25 + 2d42: ea 1e adc r14, r26 + 2d44: fb 1e adc r15, r27 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2d46: be 01 movw r22, r28 + 2d48: 84 e0 ldi r24, 0x04 ; 4 + 2d4a: 0e 94 07 24 call 0x480e ; 0x480e + 2d4e: b6 2f mov r27, r22 + 2d50: aa 27 eor r26, r26 + 2d52: 99 27 eor r25, r25 + 2d54: 88 27 eor r24, r24 +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + 2d56: bc 01 movw r22, r24 + 2d58: cd 01 movw r24, r26 + 2d5a: 6c 0d add r22, r12 + 2d5c: 7d 1d adc r23, r13 + 2d5e: 8e 1d adc r24, r14 + 2d60: 9f 1d adc r25, r15 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + 2d62: 0e 94 13 2e call 0x5c26 ; 0x5c26 + 2d66: 80 e0 ldi r24, 0x00 ; 0 + 2d68: 90 e0 ldi r25, 0x00 ; 0 + 2d6a: 02 c0 rjmp .+4 ; 0x2d70 + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + 2d6c: 82 e0 ldi r24, 0x02 ; 2 + 2d6e: 90 e0 ldi r25, 0x00 ; 0 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + return OK_SILENT; +} + 2d70: df 91 pop r29 + 2d72: cf 91 pop r28 + 2d74: ff 90 pop r15 + 2d76: ef 90 pop r14 + 2d78: df 90 pop r13 + 2d7a: cf 90 pop r12 + 2d7c: bf 90 pop r11 + 2d7e: af 90 pop r10 + 2d80: 9f 90 pop r9 + 2d82: 8f 90 pop r8 + 2d84: 08 95 ret + +00002d86 : +} + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + 2d86: fc 01 movw r30, r24 + 2d88: 21 8d ldd r18, Z+25 ; 0x19 + 2d8a: 22 23 and r18, r18 + 2d8c: c9 f0 breq .+50 ; 0x2dc0 + 2d8e: bc 01 movw r22, r24 + return SYNTAX_ERROR; + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + 2d90: 81 e0 ldi r24, 0x01 ; 1 + 2d92: 0e 94 07 24 call 0x480e ; 0x480e + 2d96: 20 e2 ldi r18, 0x20 ; 32 + 2d98: 30 e0 ldi r19, 0x00 ; 0 + 2d9a: 26 1b sub r18, r22 + 2d9c: 37 0b sbc r19, r23 + 2d9e: 8f ef ldi r24, 0xFF ; 255 + 2da0: 9f ef ldi r25, 0xFF ; 255 + 2da2: dc 01 movw r26, r24 + 2da4: bc 01 movw r22, r24 + 2da6: cd 01 movw r24, r26 + 2da8: 04 c0 rjmp .+8 ; 0x2db2 + 2daa: 96 95 lsr r25 + 2dac: 87 95 ror r24 + 2dae: 77 95 ror r23 + 2db0: 67 95 ror r22 + 2db2: 2a 95 dec r18 + 2db4: d2 f7 brpl .-12 ; 0x2daa + + ipSetConfigMask(mask); + 2db6: 0e 94 0a 2e call 0x5c14 ; 0x5c14 + 2dba: 80 e0 ldi r24, 0x00 ; 0 + 2dbc: 90 e0 ldi r25, 0x00 ; 0 + 2dbe: 08 95 ret + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + 2dc0: 82 e0 ldi r24, 0x02 ; 2 + 2dc2: 90 e0 ldi r25, 0x00 ; 0 + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + + ipSetConfigMask(mask); + return OK_SILENT; +} + 2dc4: 08 95 ret + +00002dc6 : + setTimeDecoded((timeDecoded_t *)(&czasRtc)); + return OK_SILENT; +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + 2dc6: 8f 92 push r8 + 2dc8: 9f 92 push r9 + 2dca: af 92 push r10 + 2dcc: bf 92 push r11 + 2dce: cf 92 push r12 + 2dd0: df 92 push r13 + 2dd2: ef 92 push r14 + 2dd4: ff 92 push r15 + 2dd6: cf 93 push r28 + 2dd8: df 93 push r29 + if (state->argc < 4) + 2dda: fc 01 movw r30, r24 + 2ddc: 21 8d ldd r18, Z+25 ; 0x19 + 2dde: 24 30 cpi r18, 0x04 ; 4 + 2de0: a0 f1 brcs .+104 ; 0x2e4a + 2de2: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + 2de4: bc 01 movw r22, r24 + 2de6: 81 e0 ldi r24, 0x01 ; 1 + 2de8: 0e 94 07 24 call 0x480e ; 0x480e + 2dec: 6b 01 movw r12, r22 + 2dee: 7c 01 movw r14, r24 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2df0: be 01 movw r22, r28 + 2df2: 82 e0 ldi r24, 0x02 ; 2 + 2df4: 0e 94 07 24 call 0x480e ; 0x480e + 2df8: 4b 01 movw r8, r22 + 2dfa: 5c 01 movw r10, r24 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2dfc: be 01 movw r22, r28 + 2dfe: 83 e0 ldi r24, 0x03 ; 3 + 2e00: 0e 94 07 24 call 0x480e ; 0x480e +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2e04: ba 2c mov r11, r10 + 2e06: a9 2c mov r10, r9 + 2e08: 98 2c mov r9, r8 + 2e0a: 88 24 eor r8, r8 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2e0c: 55 27 eor r21, r21 + 2e0e: 44 27 eor r20, r20 + 2e10: d5 01 movw r26, r10 + 2e12: c4 01 movw r24, r8 + 2e14: 84 0f add r24, r20 + 2e16: 95 1f adc r25, r21 + 2e18: a6 1f adc r26, r22 + 2e1a: b7 1f adc r27, r23 +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2e1c: c8 0e add r12, r24 + 2e1e: d9 1e adc r13, r25 + 2e20: ea 1e adc r14, r26 + 2e22: fb 1e adc r15, r27 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2e24: be 01 movw r22, r28 + 2e26: 84 e0 ldi r24, 0x04 ; 4 + 2e28: 0e 94 07 24 call 0x480e ; 0x480e + 2e2c: b6 2f mov r27, r22 + 2e2e: aa 27 eor r26, r26 + 2e30: 99 27 eor r25, r25 + 2e32: 88 27 eor r24, r24 +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + 2e34: bc 01 movw r22, r24 + 2e36: cd 01 movw r24, r26 + 2e38: 6c 0d add r22, r12 + 2e3a: 7d 1d adc r23, r13 + 2e3c: 8e 1d adc r24, r14 + 2e3e: 9f 1d adc r25, r15 + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + 2e40: 0e 94 01 2e call 0x5c02 ; 0x5c02 + 2e44: 80 e0 ldi r24, 0x00 ; 0 + 2e46: 90 e0 ldi r25, 0x00 ; 0 + 2e48: 02 c0 rjmp .+4 ; 0x2e4e +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + 2e4a: 82 e0 ldi r24, 0x02 ; 2 + 2e4c: 90 e0 ldi r25, 0x00 ; 0 + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + return OK_SILENT; +} + 2e4e: df 91 pop r29 + 2e50: cf 91 pop r28 + 2e52: ff 90 pop r15 + 2e54: ef 90 pop r14 + 2e56: df 90 pop r13 + 2e58: cf 90 pop r12 + 2e5a: bf 90 pop r11 + 2e5c: af 90 pop r10 + 2e5e: 9f 90 pop r9 + 2e60: 8f 90 pop r8 + 2e62: 08 95 ret + +00002e64 : + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + 2e64: ef 92 push r14 + 2e66: 0f 93 push r16 + 2e68: 1f 93 push r17 + 2e6a: 9b 01 movw r18, r22 + cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); + 2e6c: e1 2c mov r14, r1 + 2e6e: 0a e7 ldi r16, 0x7A ; 122 + 2e70: 12 e0 ldi r17, 0x02 ; 2 + 2e72: 40 e0 ldi r20, 0x00 ; 0 + 2e74: 51 e0 ldi r21, 0x01 ; 1 + 2e76: 60 e0 ldi r22, 0x00 ; 0 + 2e78: 78 e2 ldi r23, 0x28 ; 40 + 2e7a: 0e 94 1f 20 call 0x403e ; 0x403e +} + 2e7e: 1f 91 pop r17 + 2e80: 0f 91 pop r16 + 2e82: ef 90 pop r14 + 2e84: 08 95 ret + +00002e86 : + +void printErrorInfo(cmdState_t *state) +{ + 2e86: cf 93 push r28 + 2e88: df 93 push r29 + 2e8a: ec 01 movw r28, r24 + if (state->errno != 0) + 2e8c: ec 8d ldd r30, Y+28 ; 0x1c + 2e8e: ee 23 and r30, r30 + 2e90: f1 f0 breq .+60 ; 0x2ece + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + 2e92: f0 e0 ldi r31, 0x00 ; 0 + 2e94: ee 0f add r30, r30 + 2e96: ff 1f adc r31, r31 + 2e98: e0 55 subi r30, 0x50 ; 80 + 2e9a: fd 4f sbci r31, 0xFD ; 253 + 2e9c: 85 91 lpm r24, Z+ + 2e9e: 94 91 lpm r25, Z + 2ea0: 2f 8d ldd r18, Y+31 ; 0x1f + 2ea2: 1f 92 push r1 + 2ea4: 2f 93 push r18 + 2ea6: 2e 8d ldd r18, Y+30 ; 0x1e + 2ea8: 2f 93 push r18 + 2eaa: 2d 8d ldd r18, Y+29 ; 0x1d + 2eac: 2f 93 push r18 + 2eae: 9f 93 push r25 + 2eb0: 8f 93 push r24 + 2eb2: 8b 8d ldd r24, Y+27 ; 0x1b + 2eb4: 8f 93 push r24 + 2eb6: 8a 8d ldd r24, Y+26 ; 0x1a + 2eb8: 8f 93 push r24 + 2eba: 0e 94 1a 50 call 0xa034 ; 0xa034 + 2ebe: 8d b7 in r24, 0x3d ; 61 + 2ec0: 9e b7 in r25, 0x3e ; 62 + 2ec2: 08 96 adiw r24, 0x08 ; 8 + 2ec4: 0f b6 in r0, 0x3f ; 63 + 2ec6: f8 94 cli + 2ec8: 9e bf out 0x3e, r25 ; 62 + 2eca: 0f be out 0x3f, r0 ; 63 + 2ecc: 8d bf out 0x3d, r24 ; 61 + } + state->errno = 0; + 2ece: 1c 8e std Y+28, r1 ; 0x1c + state->err1 = 0; + 2ed0: 1e 8e std Y+30, r1 ; 0x1e + 2ed2: 1d 8e std Y+29, r1 ; 0x1d + state->err2 = 0; + 2ed4: 1f 8e std Y+31, r1 ; 0x1f +} + 2ed6: df 91 pop r29 + 2ed8: cf 91 pop r28 + 2eda: 08 95 ret + +00002edc : + + return OK_SILENT; +} + +static cliExRes_t rpingFunction(cmdState_t *state) +{ + 2edc: 0f 93 push r16 + 2ede: 1f 93 push r17 + 2ee0: cf 93 push r28 + 2ee2: df 93 push r29 + 2ee4: 1f 92 push r1 + 2ee6: cd b7 in r28, 0x3d ; 61 + 2ee8: de b7 in r29, 0x3e ; 62 + if (state->argc < 1) + 2eea: fc 01 movw r30, r24 + 2eec: 21 8d ldd r18, Z+25 ; 0x19 + 2eee: 22 23 and r18, r18 + 2ef0: c9 f0 breq .+50 ; 0x2f24 + 2ef2: 8c 01 movw r16, r24 + return SYNTAX_ERROR; + + uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + 2ef4: bc 01 movw r22, r24 + 2ef6: 81 e0 ldi r24, 0x01 ; 1 + 2ef8: 0e 94 07 24 call 0x480e ; 0x480e + if ((state->err2 = rs485ping(nrSterownika)) == 0) + 2efc: 86 2f mov r24, r22 + 2efe: 69 83 std Y+1, r22 ; 0x01 + 2f00: 0e 94 59 39 call 0x72b2 ; 0x72b2 + 2f04: f8 01 movw r30, r16 + 2f06: 87 8f std Z+31, r24 ; 0x1f + 2f08: 69 81 ldd r22, Y+1 ; 0x01 + 2f0a: 88 23 and r24, r24 + 2f0c: 71 f0 breq .+28 ; 0x2f2a + return OK_INFORM; + + state->errno = noRemoteDevice; + 2f0e: 89 e0 ldi r24, 0x09 ; 9 + 2f10: 84 8f std Z+28, r24 ; 0x1c + state->err1 = nrSterownika; + 2f12: 70 e0 ldi r23, 0x00 ; 0 + 2f14: 76 8f std Z+30, r23 ; 0x1e + 2f16: 65 8f std Z+29, r22 ; 0x1d + printErrorInfo(state); + 2f18: c8 01 movw r24, r16 + 2f1a: 0e 94 43 17 call 0x2e86 ; 0x2e86 + return OK_SILENT; + 2f1e: 80 e0 ldi r24, 0x00 ; 0 + 2f20: 90 e0 ldi r25, 0x00 ; 0 + 2f22: 05 c0 rjmp .+10 ; 0x2f2e +} + +static cliExRes_t rpingFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + 2f24: 82 e0 ldi r24, 0x02 ; 2 + 2f26: 90 e0 ldi r25, 0x00 ; 0 + 2f28: 02 c0 rjmp .+4 ; 0x2f2e + + uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + if ((state->err2 = rs485ping(nrSterownika)) == 0) + return OK_INFORM; + 2f2a: 81 e0 ldi r24, 0x01 ; 1 + 2f2c: 90 e0 ldi r25, 0x00 ; 0 + + state->errno = noRemoteDevice; + state->err1 = nrSterownika; + printErrorInfo(state); + return OK_SILENT; +} + 2f2e: 0f 90 pop r0 + 2f30: df 91 pop r29 + 2f32: cf 91 pop r28 + 2f34: 1f 91 pop r17 + 2f36: 0f 91 pop r16 + 2f38: 08 95 ret + +00002f3a : + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t eraseRamFileFunction(cmdState_t *state) +{ + 2f3a: cf 93 push r28 + 2f3c: df 93 push r29 + 2f3e: ec 01 movw r28, r24 + if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + 2f40: bc 01 movw r22, r24 + 2f42: 81 e0 ldi r24, 0x01 ; 1 + 2f44: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2f48: 0e 94 d3 1b call 0x37a6 ; 0x37a6 + 2f4c: 88 23 and r24, r24 + 2f4e: 31 f0 breq .+12 ; 0x2f5c + return OK_INFORM; + + printErrorInfo(state); + 2f50: ce 01 movw r24, r28 + 2f52: 0e 94 43 17 call 0x2e86 ; 0x2e86 + return ERROR_INFORM; + 2f56: 84 e0 ldi r24, 0x04 ; 4 + 2f58: 90 e0 ldi r25, 0x00 ; 0 + 2f5a: 02 c0 rjmp .+4 ; 0x2f60 +} + +static cliExRes_t eraseRamFileFunction(cmdState_t *state) +{ + if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + return OK_INFORM; + 2f5c: 81 e0 ldi r24, 0x01 ; 1 + 2f5e: 90 e0 ldi r25, 0x00 ; 0 + + printErrorInfo(state); + return ERROR_INFORM; +} + 2f60: df 91 pop r29 + 2f62: cf 91 pop r28 + 2f64: 08 95 ret + +00002f66 : + +static cliExRes_t dodajRamPlikFunction(cmdState_t *state) +{ + 2f66: cf 93 push r28 + 2f68: df 93 push r29 + if (state->argc != 1) + 2f6a: fc 01 movw r30, r24 + 2f6c: 21 8d ldd r18, Z+25 ; 0x19 + 2f6e: 21 30 cpi r18, 0x01 ; 1 + 2f70: 79 f4 brne .+30 ; 0x2f90 + 2f72: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + 2f74: bc 01 movw r22, r24 + 2f76: 81 e0 ldi r24, 0x01 ; 1 + 2f78: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2f7c: 0e 94 58 1b call 0x36b0 ; 0x36b0 + 2f80: 88 23 and r24, r24 + 2f82: 49 f0 breq .+18 ; 0x2f96 + { + return OK_INFORM; + } + printErrorInfo(state); + 2f84: ce 01 movw r24, r28 + 2f86: 0e 94 43 17 call 0x2e86 ; 0x2e86 + return ERROR_INFORM; + 2f8a: 84 e0 ldi r24, 0x04 ; 4 + 2f8c: 90 e0 ldi r25, 0x00 ; 0 + 2f8e: 05 c0 rjmp .+10 ; 0x2f9a +} + +static cliExRes_t dodajRamPlikFunction(cmdState_t *state) +{ + if (state->argc != 1) + return SYNTAX_ERROR; + 2f90: 82 e0 ldi r24, 0x02 ; 2 + 2f92: 90 e0 ldi r25, 0x00 ; 0 + 2f94: 02 c0 rjmp .+4 ; 0x2f9a + + if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + { + return OK_INFORM; + 2f96: 81 e0 ldi r24, 0x01 ; 1 + 2f98: 90 e0 ldi r25, 0x00 ; 0 + } + printErrorInfo(state); + return ERROR_INFORM; +} + 2f9a: df 91 pop r29 + 2f9c: cf 91 pop r28 + 2f9e: 08 95 ret + +00002fa0 : + return OK_SILENT; +} + + +static cliExRes_t flashExModuleFunction(cmdState_t *state) +{ + 2fa0: ff 92 push r15 + 2fa2: 0f 93 push r16 + 2fa4: 1f 93 push r17 + 2fa6: cf 93 push r28 + 2fa8: df 93 push r29 + if (state->argc != 2) + 2faa: fc 01 movw r30, r24 + 2fac: 21 8d ldd r18, Z+25 ; 0x19 + 2fae: 22 30 cpi r18, 0x02 ; 2 + 2fb0: 09 f0 breq .+2 ; 0x2fb4 + 2fb2: 43 c0 rjmp .+134 ; 0x303a + 2fb4: ec 01 movw r28, r24 + return SYNTAX_ERROR; + + uint8_t nrUrzadzenia = cmdlineGetArgInt(1, state); + 2fb6: bc 01 movw r22, r24 + 2fb8: 81 e0 ldi r24, 0x01 ; 1 + 2fba: 0e 94 07 24 call 0x480e ; 0x480e + 2fbe: 16 2f mov r17, r22 + char *nazwaPliku = cmdlineGetArgStr(2, state); + 2fc0: be 01 movw r22, r28 + 2fc2: 82 e0 ldi r24, 0x02 ; 2 + 2fc4: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 2fc8: 08 2f mov r16, r24 + 2fca: f9 2e mov r15, r25 + uint8_t blad; + + // Sprawdzanie, czy moduÅ‚ wykonawczy odpowiada + if (rs485ping(nrUrzadzenia) != 0) + 2fcc: 81 2f mov r24, r17 + 2fce: 0e 94 59 39 call 0x72b2 ; 0x72b2 + 2fd2: 88 23 and r24, r24 + 2fd4: 31 f0 breq .+12 ; 0x2fe2 + { + state->errno = noRemoteDevice; + 2fd6: 89 e0 ldi r24, 0x09 ; 9 + 2fd8: 8c 8f std Y+28, r24 ; 0x1c + printErrorInfo(state); + 2fda: ce 01 movw r24, r28 + 2fdc: 0e 94 43 17 call 0x2e86 ; 0x2e86 + 2fe0: 2f c0 rjmp .+94 ; 0x3040 + return ERROR_INFORM; + } + + //Sprawdzanie, czy istnieje odpowiedni plik z firmware + if (ramDyskOtworzPlik(nazwaPliku, &fdVty) != 0) + 2fe2: 62 e6 ldi r22, 0x62 ; 98 + 2fe4: 7f e0 ldi r23, 0x0F ; 15 + 2fe6: 80 2f mov r24, r16 + 2fe8: 9f 2d mov r25, r15 + 2fea: 0e 94 bd 1b call 0x377a ; 0x377a + 2fee: 88 23 and r24, r24 + 2ff0: 99 f0 breq .+38 ; 0x3018 + { + fprintf_P(state->myStdInOut, errorOpenFile, nazwaPliku); + 2ff2: ff 92 push r15 + 2ff4: 0f 93 push r16 + 2ff6: 8e ea ldi r24, 0xAE ; 174 + 2ff8: 9a e0 ldi r25, 0x0A ; 10 + 2ffa: 9f 93 push r25 + 2ffc: 8f 93 push r24 + 2ffe: 8b 8d ldd r24, Y+27 ; 0x1b + 3000: 8f 93 push r24 + 3002: 8a 8d ldd r24, Y+26 ; 0x1a + 3004: 8f 93 push r24 + 3006: 0e 94 1a 50 call 0xa034 ; 0xa034 + 300a: 0f 90 pop r0 + 300c: 0f 90 pop r0 + 300e: 0f 90 pop r0 + 3010: 0f 90 pop r0 + 3012: 0f 90 pop r0 + 3014: 0f 90 pop r0 + 3016: 14 c0 rjmp .+40 ; 0x3040 + return ERROR_INFORM; + } + + blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + 3018: 4a 8d ldd r20, Y+26 ; 0x1a + 301a: 5b 8d ldd r21, Y+27 ; 0x1b + 301c: 61 2f mov r22, r17 + 301e: 82 e6 ldi r24, 0x62 ; 98 + 3020: 9f e0 ldi r25, 0x0F ; 15 + 3022: 0e 94 6d 3b call 0x76da ; 0x76da + 3026: c8 2f mov r28, r24 + + ramDyskZamknijPlik(&fdVty); + 3028: 82 e6 ldi r24, 0x62 ; 98 + 302a: 9f e0 ldi r25, 0x0F ; 15 + 302c: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + + if (blad != 0) + 3030: c1 11 cpse r28, r1 + 3032: 06 c0 rjmp .+12 ; 0x3040 + return ERROR_INFORM; + + return OK_SILENT; + 3034: 80 e0 ldi r24, 0x00 ; 0 + 3036: 90 e0 ldi r25, 0x00 ; 0 + 3038: 05 c0 rjmp .+10 ; 0x3044 + + +static cliExRes_t flashExModuleFunction(cmdState_t *state) +{ + if (state->argc != 2) + return SYNTAX_ERROR; + 303a: 82 e0 ldi r24, 0x02 ; 2 + 303c: 90 e0 ldi r25, 0x00 ; 0 + 303e: 02 c0 rjmp .+4 ; 0x3044 + blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + + ramDyskZamknijPlik(&fdVty); + + if (blad != 0) + return ERROR_INFORM; + 3040: 84 e0 ldi r24, 0x04 ; 4 + 3042: 90 e0 ldi r25, 0x00 ; 0 + + return OK_SILENT; +} + 3044: df 91 pop r29 + 3046: cf 91 pop r28 + 3048: 1f 91 pop r17 + 304a: 0f 91 pop r16 + 304c: ff 90 pop r15 + 304e: 08 95 ret + +00003050 : + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + 3050: cf 93 push r28 + 3052: df 93 push r29 + 3054: d8 2f mov r29, r24 + 3056: c9 2f mov r28, r25 + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + 3058: 84 ed ldi r24, 0xD4 ; 212 + 305a: 90 e0 ldi r25, 0x00 ; 0 + 305c: 9f 93 push r25 + 305e: 8f 93 push r24 + 3060: cf 93 push r28 + 3062: df 93 push r29 + 3064: 0e 94 1a 50 call 0xa034 ; 0xa034 + //Print system state + fprintf_P(stream, systemStateStr); + 3068: 8e e9 ldi r24, 0x9E ; 158 + 306a: 9a e0 ldi r25, 0x0A ; 10 + 306c: 9f 93 push r25 + 306e: 8f 93 push r24 + 3070: cf 93 push r28 + 3072: df 93 push r29 + 3074: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + 3078: 0e 94 03 42 call 0x8406 ; 0x8406 + 307c: 1f 92 push r1 + 307e: 8f 93 push r24 + 3080: 85 e8 ldi r24, 0x85 ; 133 + 3082: 9a e0 ldi r25, 0x0A ; 10 + 3084: 9f 93 push r25 + 3086: 8f 93 push r24 + 3088: cf 93 push r28 + 308a: df 93 push r29 + 308c: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + 3090: 0e 94 d5 4a call 0x95aa ; 0x95aa + 3094: 2c e0 ldi r18, 0x0C ; 12 + 3096: 2f 93 push r18 + 3098: 2c e1 ldi r18, 0x1C ; 28 + 309a: 2f 93 push r18 + 309c: 9f 93 push r25 + 309e: 8f 93 push r24 + 30a0: 8b e5 ldi r24, 0x5B ; 91 + 30a2: 9a e0 ldi r25, 0x0A ; 10 + 30a4: 9f 93 push r25 + 30a6: 8f 93 push r24 + 30a8: cf 93 push r28 + 30aa: df 93 push r29 + 30ac: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + 30b0: 0e 94 60 1a call 0x34c0 ; 0x34c0 + 30b4: 27 e1 ldi r18, 0x17 ; 23 + 30b6: 2f 93 push r18 + 30b8: 1f 92 push r1 + 30ba: 9f 93 push r25 + 30bc: 8f 93 push r24 + 30be: 81 e3 ldi r24, 0x31 ; 49 + 30c0: 9a e0 ldi r25, 0x0A ; 10 + 30c2: 9f 93 push r25 + 30c4: 8f 93 push r24 + 30c6: cf 93 push r28 + 30c8: df 93 push r29 + 30ca: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, statusTemperatureStr, temperature); + 30ce: 80 91 a4 0e lds r24, 0x0EA4 + 30d2: 1f 92 push r1 + 30d4: 8f 93 push r24 + 30d6: 89 ee ldi r24, 0xE9 ; 233 + 30d8: 99 e0 ldi r25, 0x09 ; 9 + 30da: 9f 93 push r25 + 30dc: 8f 93 push r24 + 30de: cf 93 push r28 + 30e0: df 93 push r29 + 30e2: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, statusVoltageStr, voltage); + 30e6: 80 91 ae 0e lds r24, 0x0EAE + 30ea: 2d b7 in r18, 0x3d ; 61 + 30ec: 3e b7 in r19, 0x3e ; 62 + 30ee: 2c 5d subi r18, 0xDC ; 220 + 30f0: 3f 4f sbci r19, 0xFF ; 255 + 30f2: 0f b6 in r0, 0x3f ; 63 + 30f4: f8 94 cli + 30f6: 3e bf out 0x3e, r19 ; 62 + 30f8: 0f be out 0x3f, r0 ; 63 + 30fa: 2d bf out 0x3d, r18 ; 61 + 30fc: 1f 92 push r1 + 30fe: 8f 93 push r24 + 3100: 8e ec ldi r24, 0xCE ; 206 + 3102: 99 e0 ldi r25, 0x09 ; 9 + 3104: 9f 93 push r25 + 3106: 8f 93 push r24 + 3108: cf 93 push r28 + 310a: df 93 push r29 + 310c: 0e 94 1a 50 call 0xa034 ; 0xa034 + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + 3110: 0e 94 48 1f call 0x3e90 ; 0x3e90 + fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); + 3114: 1f 92 push r1 + 3116: 90 e8 ldi r25, 0x80 ; 128 + 3118: 9f 93 push r25 + 311a: 1f 92 push r1 + 311c: 8f 93 push r24 + 311e: 84 e0 ldi r24, 0x04 ; 4 + 3120: 9a e0 ldi r25, 0x0A ; 10 + 3122: 9f 93 push r25 + 3124: 8f 93 push r24 + 3126: cf 93 push r28 + 3128: df 93 push r29 + 312a: 0e 94 1a 50 call 0xa034 ; 0xa034 +// printErrorInfo(state); //TODO fix and uncomment + + //Print system configuration + fprintf_P(stream, systemRamConfigStr); + 312e: 8b eb ldi r24, 0xBB ; 187 + 3130: 99 e0 ldi r25, 0x09 ; 9 + 3132: 9f 93 push r25 + 3134: 8f 93 push r24 + 3136: cf 93 push r28 + 3138: df 93 push r29 + 313a: 0e 94 1a 50 call 0xa034 ; 0xa034 + + fprintf_P(stream, statusMacStr); + 313e: 86 ea ldi r24, 0xA6 ; 166 + 3140: 99 e0 ldi r25, 0x09 ; 9 + 3142: 9f 93 push r25 + 3144: 8f 93 push r24 + 3146: cf 93 push r28 + 3148: df 93 push r29 + 314a: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintEthAddr(stream, &nicState.mac); + 314e: 60 e8 ldi r22, 0x80 ; 128 + 3150: 7e e0 ldi r23, 0x0E ; 14 + 3152: 8d 2f mov r24, r29 + 3154: 9c 2f mov r25, r28 + 3156: 0e 94 05 2b call 0x560a ; 0x560a + fprintf_P(stream, PSTR("\r\n")); + 315a: 81 ed ldi r24, 0xD1 ; 209 + 315c: 90 e0 ldi r25, 0x00 ; 0 + 315e: 9f 93 push r25 + 3160: 8f 93 push r24 + 3162: cf 93 push r28 + 3164: df 93 push r29 + 3166: 0e 94 1a 50 call 0xa034 ; 0xa034 + + fprintf_P(stream, statusIpStr); + 316a: 81 e9 ldi r24, 0x91 ; 145 + 316c: 99 e0 ldi r25, 0x09 ; 9 + 316e: 9f 93 push r25 + 3170: 8f 93 push r24 + 3172: cf 93 push r28 + 3174: df 93 push r29 + 3176: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(stream, ipGetConfig()->ip); + 317a: 0e 94 1c 2e call 0x5c38 ; 0x5c38 + 317e: fc 01 movw r30, r24 + 3180: 40 81 ld r20, Z + 3182: 51 81 ldd r21, Z+1 ; 0x01 + 3184: 62 81 ldd r22, Z+2 ; 0x02 + 3186: 73 81 ldd r23, Z+3 ; 0x03 + 3188: 8d 2f mov r24, r29 + 318a: 9c 2f mov r25, r28 + 318c: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n")); + 3190: 8e ec ldi r24, 0xCE ; 206 + 3192: 90 e0 ldi r25, 0x00 ; 0 + 3194: 9f 93 push r25 + 3196: 8f 93 push r24 + 3198: cf 93 push r28 + 319a: df 93 push r29 + 319c: 0e 94 1a 50 call 0xa034 ; 0xa034 + + fprintf_P(stream, statusIpMaskStr); + 31a0: 2d b7 in r18, 0x3d ; 61 + 31a2: 3e b7 in r19, 0x3e ; 62 + 31a4: 2e 5d subi r18, 0xDE ; 222 + 31a6: 3f 4f sbci r19, 0xFF ; 255 + 31a8: 0f b6 in r0, 0x3f ; 63 + 31aa: f8 94 cli + 31ac: 3e bf out 0x3e, r19 ; 62 + 31ae: 0f be out 0x3f, r0 ; 63 + 31b0: 2d bf out 0x3d, r18 ; 61 + 31b2: 8c e7 ldi r24, 0x7C ; 124 + 31b4: 99 e0 ldi r25, 0x09 ; 9 + 31b6: 9f 93 push r25 + 31b8: 8f 93 push r24 + 31ba: cf 93 push r28 + 31bc: df 93 push r29 + 31be: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(stream, ipGetConfig()->netmask); + 31c2: 0e 94 1c 2e call 0x5c38 ; 0x5c38 + 31c6: fc 01 movw r30, r24 + 31c8: 44 81 ldd r20, Z+4 ; 0x04 + 31ca: 55 81 ldd r21, Z+5 ; 0x05 + 31cc: 66 81 ldd r22, Z+6 ; 0x06 + 31ce: 77 81 ldd r23, Z+7 ; 0x07 + 31d0: 8d 2f mov r24, r29 + 31d2: 9c 2f mov r25, r28 + 31d4: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n")); + 31d8: 8b ec ldi r24, 0xCB ; 203 + 31da: 90 e0 ldi r25, 0x00 ; 0 + 31dc: 9f 93 push r25 + 31de: 8f 93 push r24 + 31e0: cf 93 push r28 + 31e2: df 93 push r29 + 31e4: 0e 94 1a 50 call 0xa034 ; 0xa034 + + fprintf_P(stream, statusIpGwStr); + 31e8: 87 e6 ldi r24, 0x67 ; 103 + 31ea: 99 e0 ldi r25, 0x09 ; 9 + 31ec: 9f 93 push r25 + 31ee: 8f 93 push r24 + 31f0: cf 93 push r28 + 31f2: df 93 push r29 + 31f4: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(stream, ipGetConfig()->gateway); + 31f8: 0e 94 1c 2e call 0x5c38 ; 0x5c38 + 31fc: fc 01 movw r30, r24 + 31fe: 40 85 ldd r20, Z+8 ; 0x08 + 3200: 51 85 ldd r21, Z+9 ; 0x09 + 3202: 62 85 ldd r22, Z+10 ; 0x0a + 3204: 73 85 ldd r23, Z+11 ; 0x0b + 3206: 8d 2f mov r24, r29 + 3208: 9c 2f mov r25, r28 + 320a: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n")); + 320e: 88 ec ldi r24, 0xC8 ; 200 + 3210: 90 e0 ldi r25, 0x00 ; 0 + 3212: 9f 93 push r25 + 3214: 8f 93 push r24 + 3216: cf 93 push r28 + 3218: df 93 push r29 + 321a: 0e 94 1a 50 call 0xa034 ; 0xa034 + + //Print Rs485 Execitive modules + fprintf_P(stream, statusRs485listStr); + 321e: 8c e4 ldi r24, 0x4C ; 76 + 3220: 99 e0 ldi r25, 0x09 ; 9 + 3222: 9f 93 push r25 + 3224: 8f 93 push r24 + 3226: cf 93 push r28 + 3228: df 93 push r29 + 322a: 0e 94 1a 50 call 0xa034 ; 0xa034 +// tmp = printRs485devices(stream); +// if (tmp == 0) +// fprintf_P(stream, statusNoRs485Dev); + + //Print locker sensors + fprintf_P(stream, statusLockerSensorsStr); + 322e: 89 e1 ldi r24, 0x19 ; 25 + 3230: 99 e0 ldi r25, 0x09 ; 9 + 3232: 9f 93 push r25 + 3234: 8f 93 push r24 + 3236: cf 93 push r28 + 3238: df 93 push r29 + 323a: 0e 94 1a 50 call 0xa034 ; 0xa034 + tmp = printLockers(stream); + 323e: 8d 2f mov r24, r29 + 3240: 9c 2f mov r25, r28 + 3242: 0e 94 a7 0d call 0x1b4e ; 0x1b4e + if (tmp == 0) + 3246: 2d b7 in r18, 0x3d ; 61 + 3248: 3e b7 in r19, 0x3e ; 62 + 324a: 28 5e subi r18, 0xE8 ; 232 + 324c: 3f 4f sbci r19, 0xFF ; 255 + 324e: 0f b6 in r0, 0x3f ; 63 + 3250: f8 94 cli + 3252: 3e bf out 0x3e, r19 ; 62 + 3254: 0f be out 0x3f, r0 ; 63 + 3256: 2d bf out 0x3d, r18 ; 61 + 3258: 81 11 cpse r24, r1 + 325a: 0c c0 rjmp .+24 ; 0x3274 + fprintf_P(stream, statusLockerSensorsDisStr); + 325c: 8d ef ldi r24, 0xFD ; 253 + 325e: 98 e0 ldi r25, 0x08 ; 8 + 3260: 9f 93 push r25 + 3262: 8f 93 push r24 + 3264: cf 93 push r28 + 3266: df 93 push r29 + 3268: 0e 94 1a 50 call 0xa034 ; 0xa034 + 326c: 0f 90 pop r0 + 326e: 0f 90 pop r0 + 3270: 0f 90 pop r0 + 3272: 0f 90 pop r0 + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + + udpPrintStatus(stream); + 3274: 8d 2f mov r24, r29 + 3276: 9c 2f mov r25, r28 +// arpPrintTable(stream); +} + 3278: df 91 pop r29 + 327a: cf 91 pop r28 + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + + udpPrintStatus(stream); + 327c: 0c 94 70 38 jmp 0x70e0 ; 0x70e0 + +00003280 : + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + 3280: 0f 93 push r16 + 3282: 1f 93 push r17 + 3284: cf 93 push r28 + 3286: df 93 push r29 + 3288: cd b7 in r28, 0x3d ; 61 + 328a: de b7 in r29, 0x3e ; 62 + 328c: 2e 97 sbiw r28, 0x0e ; 14 + 328e: 0f b6 in r0, 0x3f ; 63 + 3290: f8 94 cli + 3292: de bf out 0x3e, r29 ; 62 + 3294: 0f be out 0x3f, r0 ; 63 + 3296: cd bf out 0x3d, r28 ; 61 + 3298: 8c 01 movw r16, r24 + if (state->argc < 1) + 329a: fc 01 movw r30, r24 + 329c: 81 8d ldd r24, Z+25 ; 0x19 + 329e: 81 11 cpse r24, r1 + 32a0: 05 c0 rjmp .+10 ; 0x32ac + { + printStatus(state->myStdInOut); + 32a2: 82 8d ldd r24, Z+26 ; 0x1a + 32a4: 93 8d ldd r25, Z+27 ; 0x1b + 32a6: 0e 94 28 18 call 0x3050 ; 0x3050 + 32aa: 30 c0 rjmp .+96 ; 0x330c + return OK_SILENT; + } + + FILE stream; + if (ramDyskOtworzPlikStdIo(cmdlineGetArgStr(1, state), &fdVty, &stream, __SWR | __SRD) != 0) + 32ac: b8 01 movw r22, r16 + 32ae: 81 e0 ldi r24, 0x01 ; 1 + 32b0: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 32b4: 23 e0 ldi r18, 0x03 ; 3 + 32b6: ae 01 movw r20, r28 + 32b8: 4f 5f subi r20, 0xFF ; 255 + 32ba: 5f 4f sbci r21, 0xFF ; 255 + 32bc: 62 e6 ldi r22, 0x62 ; 98 + 32be: 7f e0 ldi r23, 0x0F ; 15 + 32c0: 0e 94 55 1f call 0x3eaa ; 0x3eaa + 32c4: 88 23 and r24, r24 + 32c6: d1 f0 breq .+52 ; 0x32fc + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 32c8: b8 01 movw r22, r16 + 32ca: 81 e0 ldi r24, 0x01 ; 1 + 32cc: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 32d0: 9f 93 push r25 + 32d2: 8f 93 push r24 + 32d4: 8e ea ldi r24, 0xAE ; 174 + 32d6: 9a e0 ldi r25, 0x0A ; 10 + 32d8: 9f 93 push r25 + 32da: 8f 93 push r24 + 32dc: f8 01 movw r30, r16 + 32de: 83 8d ldd r24, Z+27 ; 0x1b + 32e0: 8f 93 push r24 + 32e2: 82 8d ldd r24, Z+26 ; 0x1a + 32e4: 8f 93 push r24 + 32e6: 0e 94 1a 50 call 0xa034 ; 0xa034 + 32ea: 0f 90 pop r0 + 32ec: 0f 90 pop r0 + 32ee: 0f 90 pop r0 + 32f0: 0f 90 pop r0 + 32f2: 0f 90 pop r0 + 32f4: 0f 90 pop r0 + 32f6: 84 e0 ldi r24, 0x04 ; 4 + 32f8: 90 e0 ldi r25, 0x00 ; 0 + 32fa: 0a c0 rjmp .+20 ; 0x3310 + return ERROR_INFORM; + } + + printStatus(&stream); + 32fc: ce 01 movw r24, r28 + 32fe: 01 96 adiw r24, 0x01 ; 1 + 3300: 0e 94 28 18 call 0x3050 ; 0x3050 + ramDyskZamknijPlikStdIo(&stream); + 3304: ce 01 movw r24, r28 + 3306: 01 96 adiw r24, 0x01 ; 1 + 3308: 0e 94 7a 1f call 0x3ef4 ; 0x3ef4 + return OK_SILENT; + 330c: 80 e0 ldi r24, 0x00 ; 0 + 330e: 90 e0 ldi r25, 0x00 ; 0 +} + 3310: 2e 96 adiw r28, 0x0e ; 14 + 3312: 0f b6 in r0, 0x3f ; 63 + 3314: f8 94 cli + 3316: de bf out 0x3e, r29 ; 62 + 3318: 0f be out 0x3f, r0 ; 63 + 331a: cd bf out 0x3d, r28 ; 61 + 331c: df 91 pop r29 + 331e: cf 91 pop r28 + 3320: 1f 91 pop r17 + 3322: 0f 91 pop r16 + 3324: 08 95 ret + +00003326 : +// return 0; +// } + + +void encTask ( void *pvParameters ) +{ + 3326: ec 01 movw r28, r24 + FILE *netstackDebug = (FILE *) pvParameters; + uint16_t plen; + + nicInit(); + 3328: 0e 94 8f 2a call 0x551e ; 0x551e + ipInit(); + 332c: 0e 94 0e 2d call 0x5a1c ; 0x5a1c + arpInit(); + 3330: 0e 94 78 30 call 0x60f0 ; 0x60f0 + icmpInit(); + 3334: 0e 94 51 2f call 0x5ea2 ; 0x5ea2 + } + else + { + if (netstackDebug != NULL) + { + fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + 3338: 0d e7 ldi r16, 0x7D ; 125 + 333a: 1b e0 ldi r17, 0x0B ; 11 + //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + + + for ( ; ; ) + { + vTaskDelay ( 0 ); //ZastÄ…pić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebrzeniu przerwania od ENC + 333c: 80 e0 ldi r24, 0x00 ; 0 + 333e: 90 e0 ldi r25, 0x00 ; 0 + 3340: 0e 94 81 43 call 0x8702 ; 0x8702 + + // get the next new packet: + plen = nicPoll(); + 3344: 0e 94 65 28 call 0x50ca ; 0x50ca + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + 3348: 89 2b or r24, r25 + 334a: 29 f4 brne .+10 ; 0x3356 + { + flushUdpQueues(); + 334c: 0e 94 1d 38 call 0x703a ; 0x703a + flushTcpQueues(); + 3350: 0e 94 4d 36 call 0x6c9a ; 0x6c9a + //flush HTTP long file queue + continue; + 3354: f3 cf rjmp .-26 ; 0x333c + } + + if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + 3356: e0 91 86 0e lds r30, 0x0E86 + 335a: f0 91 87 0e lds r31, 0x0E87 + 335e: e4 84 ldd r14, Z+12 ; 0x0c + 3360: f5 84 ldd r15, Z+13 ; 0x0d + 3362: 80 e0 ldi r24, 0x00 ; 0 + 3364: 98 e0 ldi r25, 0x08 ; 8 + 3366: 0e 94 cb 2a call 0x5596 ; 0x5596 + 336a: e8 16 cp r14, r24 + 336c: f9 06 cpc r15, r25 + 336e: 29 f4 brne .+10 ; 0x337a + { + arpIpIn(); + 3370: 0e 94 ae 30 call 0x615c ; 0x615c + netstackIPv4Process(); + 3374: 0e 94 4f 2d call 0x5a9e ; 0x5a9e + 3378: e1 cf rjmp .-62 ; 0x333c + } + else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + 337a: e0 91 86 0e lds r30, 0x0E86 + 337e: f0 91 87 0e lds r31, 0x0E87 + 3382: e4 84 ldd r14, Z+12 ; 0x0c + 3384: f5 84 ldd r15, Z+13 ; 0x0d + 3386: 86 e0 ldi r24, 0x06 ; 6 + 3388: 98 e0 ldi r25, 0x08 ; 8 + 338a: 0e 94 cb 2a call 0x5596 ; 0x5596 + 338e: e8 16 cp r14, r24 + 3390: f9 06 cpc r15, r25 + 3392: 19 f4 brne .+6 ; 0x339a + { + arpArpIn(); + 3394: 0e 94 5d 32 call 0x64ba ; 0x64ba + 3398: d1 cf rjmp .-94 ; 0x333c + } + else + { + if (netstackDebug != NULL) + 339a: 20 97 sbiw r28, 0x00 ; 0 + 339c: 79 f2 breq .-98 ; 0x333c + { + fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + 339e: 1f 93 push r17 + 33a0: 0f 93 push r16 + 33a2: df 93 push r29 + 33a4: cf 93 push r28 + 33a6: 0e 94 1a 50 call 0xa034 ; 0xa034 + 33aa: 0f 90 pop r0 + 33ac: 0f 90 pop r0 + 33ae: 0f 90 pop r0 + 33b0: 0f 90 pop r0 + 33b2: c4 cf rjmp .-120 ; 0x333c + +000033b4 : +#include "cli_task.h" + +void vTaskVTYusb(void *cliStatePtr) +{ + 33b4: cf 93 push r28 + 33b6: df 93 push r29 + 33b8: 1f 92 push r1 + 33ba: cd b7 in r28, 0x3d ; 61 + 33bc: de b7 in r29, 0x3e ; 62 + 33be: 8c 01 movw r16, r24 + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + 33c0: 8e e8 ldi r24, 0x8E ; 142 + 33c2: 9b e0 ldi r25, 0x0B ; 11 + 33c4: 9f 93 push r25 + 33c6: 8f 93 push r24 + 33c8: f8 01 movw r30, r16 + 33ca: 83 8d ldd r24, Z+27 ; 0x1b + 33cc: 8f 93 push r24 + 33ce: 82 8d ldd r24, Z+26 ; 0x1a + 33d0: 8f 93 push r24 + 33d2: 0e 94 1a 50 call 0xa034 ; 0xa034 + cmdlineInputFunc('\r', state); + 33d6: b8 01 movw r22, r16 + 33d8: 8d e0 ldi r24, 0x0D ; 13 + 33da: 0e 94 5c 20 call 0x40b8 ; 0x40b8 + 33de: 0f 90 pop r0 + 33e0: 0f 90 pop r0 + 33e2: 0f 90 pop r0 + 33e4: 0f 90 pop r0 + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + 33e6: 20 e0 ldi r18, 0x00 ; 0 + 33e8: 4f ef ldi r20, 0xFF ; 255 + 33ea: 5f ef ldi r21, 0xFF ; 255 + 33ec: be 01 movw r22, r28 + 33ee: 6f 5f subi r22, 0xFF ; 255 + 33f0: 7f 4f sbci r23, 0xFF ; 255 + 33f2: 80 91 ac 0e lds r24, 0x0EAC + 33f6: 90 91 ad 0e lds r25, 0x0EAD + 33fa: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 33fe: 88 23 and r24, r24 + 3400: 91 f3 breq .-28 ; 0x33e6 + { + cmdlineInputFunc((char)znak, state); + 3402: b8 01 movw r22, r16 + 3404: 89 81 ldd r24, Y+1 ; 0x01 + 3406: 0e 94 5c 20 call 0x40b8 ; 0x40b8 + cmdlineMainLoop(state); + 340a: c8 01 movw r24, r16 + 340c: 0e 94 60 23 call 0x46c0 ; 0x46c0 + 3410: ea cf rjmp .-44 ; 0x33e6 + +00003412 : + } + } +} + +void vTaskVTYsocket(void *cliStatePtr) +{ + 3412: ec 01 movw r28, r24 + + char znak; + for( ;; ) + { + znak = 0; + znak = fgetc(state->myStdInOut); + 3414: 8a 8d ldd r24, Y+26 ; 0x1a + 3416: 9b 8d ldd r25, Y+27 ; 0x1b + 3418: 0e 94 cc 4f call 0x9f98 ; 0x9f98 + cmdlineInputFunc((char)znak, state); + 341c: be 01 movw r22, r28 + 341e: 0e 94 5c 20 call 0x40b8 ; 0x40b8 + cmdlineMainLoop(state); + 3422: ce 01 movw r24, r28 + 3424: 0e 94 60 23 call 0x46c0 ; 0x46c0 + } + 3428: f5 cf rjmp .-22 ; 0x3414 + +0000342a : +#include "semphr.h" + + +void spiInit(void (*disableAllSpiDevicesFun)(void)) +{ + disableAllSpiDevicesFun(); + 342a: fc 01 movw r30, r24 + 342c: 09 95 icall + portENTER_CRITICAL(); + 342e: 0f b6 in r0, 0x3f ; 63 + 3430: f8 94 cli + 3432: 0f 92 push r0 + vSemaphoreCreateBinary(xSemaphoreSpiSS); + 3434: 60 e0 ldi r22, 0x00 ; 0 + 3436: 81 e0 ldi r24, 0x01 ; 1 + 3438: 0e 94 15 46 call 0x8c2a ; 0x8c2a + 343c: 90 93 bf 0e sts 0x0EBF, r25 + 3440: 80 93 be 0e sts 0x0EBE, r24 + 3444: 00 97 sbiw r24, 0x00 ; 0 + 3446: 39 f0 breq .+14 ; 0x3456 + 3448: 20 e0 ldi r18, 0x00 ; 0 + 344a: 40 e0 ldi r20, 0x00 ; 0 + 344c: 50 e0 ldi r21, 0x00 ; 0 + 344e: 60 e0 ldi r22, 0x00 ; 0 + 3450: 70 e0 ldi r23, 0x00 ; 0 + 3452: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + + SPCR = (1<: + //mode 0,0 +} + +void spiSetCPHA(void) +{ + SPCR |= (1<: +} + +void spiClearCPHA(void) +{ + SPCR &= ~(1<: +} + +void spiSetCPOL(void) +{ + SPCR |= (1<: +} + +void spiClearCPOL(void) +{ + SPCR &= ~(1<: +} + +void spiTake(void) +{ + xSemaphoreTake(xSemaphoreSpiSS, portMAX_DELAY); + 3470: 20 e0 ldi r18, 0x00 ; 0 + 3472: 4f ef ldi r20, 0xFF ; 255 + 3474: 5f ef ldi r21, 0xFF ; 255 + 3476: 60 e0 ldi r22, 0x00 ; 0 + 3478: 70 e0 ldi r23, 0x00 ; 0 + 347a: 80 91 be 0e lds r24, 0x0EBE + 347e: 90 91 bf 0e lds r25, 0x0EBF + 3482: 0c 94 5e 47 jmp 0x8ebc ; 0x8ebc + +00003486 : +} + +void spiGive(void) +{ + xSemaphoreGive(xSemaphoreSpiSS); + 3486: 20 e0 ldi r18, 0x00 ; 0 + 3488: 40 e0 ldi r20, 0x00 ; 0 + 348a: 50 e0 ldi r21, 0x00 ; 0 + 348c: 60 e0 ldi r22, 0x00 ; 0 + 348e: 70 e0 ldi r23, 0x00 ; 0 + 3490: 80 91 be 0e lds r24, 0x0EBE + 3494: 90 91 bf 0e lds r25, 0x0EBF + 3498: 0c 94 a2 46 jmp 0x8d44 ; 0x8d44 + 349c: 80 e0 ldi r24, 0x00 ; 0 + 349e: 08 95 ret + 34a0: 80 e0 ldi r24, 0x00 ; 0 + 34a2: 08 95 ret + +000034a4 : + +#ifdef HEAP_BEGIN +char *heapEnd = (char *)HEAP_BEGIN; + +void *xmalloc(size_t size) +{ + 34a4: cf 93 push r28 + 34a6: df 93 push r29 + 34a8: ec 01 movw r28, r24 + void *result = malloc(size); + 34aa: 0e 94 fe 4c call 0x99fc ; 0x99fc + + heapEnd = (char *)(result); + heapEnd += size; + 34ae: c8 0f add r28, r24 + 34b0: d9 1f adc r29, r25 + 34b2: d0 93 03 01 sts 0x0103, r29 + 34b6: c0 93 02 01 sts 0x0102, r28 + return result; +} + 34ba: df 91 pop r29 + 34bc: cf 91 pop r28 + 34be: 08 95 ret + +000034c0 : + +size_t xmallocAvailable(void) +{ + return __malloc_heap_end - heapEnd + 1; + 34c0: 80 91 05 01 lds r24, 0x0105 + 34c4: 90 91 06 01 lds r25, 0x0106 + 34c8: 20 91 02 01 lds r18, 0x0102 + 34cc: 30 91 03 01 lds r19, 0x0103 + 34d0: 82 1b sub r24, r18 + 34d2: 93 0b sbc r25, r19 +} + 34d4: 01 96 adiw r24, 0x01 ; 1 + 34d6: 08 95 ret + +000034d8 : + + return 1; +} + +static void uaktualnijRozmiarPliku(struct ramPlikFd *fd) +{ + 34d8: fc 01 movw r30, r24 + if (fd->wpis->rozmiarHi == fd->IndHi) + 34da: a4 81 ldd r26, Z+4 ; 0x04 + 34dc: b5 81 ldd r27, Z+5 ; 0x05 + 34de: 12 96 adiw r26, 0x02 ; 2 + 34e0: 9c 91 ld r25, X + 34e2: 12 97 sbiw r26, 0x02 ; 2 + 34e4: 83 81 ldd r24, Z+3 ; 0x03 + 34e6: 98 13 cpse r25, r24 + 34e8: 08 c0 rjmp .+16 ; 0x34fa + { + if (fd->wpis->rozmiarLo < fd->IndLo) + 34ea: 82 81 ldd r24, Z+2 ; 0x02 + 34ec: 11 96 adiw r26, 0x01 ; 1 + 34ee: 9c 91 ld r25, X + 34f0: 11 97 sbiw r26, 0x01 ; 1 + 34f2: 98 17 cp r25, r24 + 34f4: 10 f4 brcc .+4 ; 0x34fa + fd->wpis->rozmiarLo = fd->IndLo; + 34f6: 11 96 adiw r26, 0x01 ; 1 + 34f8: 8c 93 st X, r24 + } + if (fd->wpis->rozmiarHi < fd->IndHi) + 34fa: a4 81 ldd r26, Z+4 ; 0x04 + 34fc: b5 81 ldd r27, Z+5 ; 0x05 + 34fe: 12 96 adiw r26, 0x02 ; 2 + 3500: 9c 91 ld r25, X + 3502: 12 97 sbiw r26, 0x02 ; 2 + 3504: 83 81 ldd r24, Z+3 ; 0x03 + 3506: 98 17 cp r25, r24 + 3508: 40 f4 brcc .+16 ; 0x351a + { + fd->wpis->rozmiarLo = fd->IndLo; + 350a: 82 81 ldd r24, Z+2 ; 0x02 + 350c: 11 96 adiw r26, 0x01 ; 1 + 350e: 8c 93 st X, r24 + fd->wpis->rozmiarHi = fd->IndHi; + 3510: a4 81 ldd r26, Z+4 ; 0x04 + 3512: b5 81 ldd r27, Z+5 ; 0x05 + 3514: 83 81 ldd r24, Z+3 ; 0x03 + 3516: 12 96 adiw r26, 0x02 ; 2 + 3518: 8c 93 st X, r24 + 351a: 08 95 ret + +0000351c : + } + return 0; +} + +static uint8_t nastepnyKlaster(uint8_t nrKlastra) +{ + 351c: 98 2f mov r25, r24 + uint8_t temp = klastry[nrKlastra]; //Temp oznacza na nastÄ™pny klaster. + 351e: e8 2f mov r30, r24 + 3520: f0 e0 ldi r31, 0x00 ; 0 + 3522: e7 53 subi r30, 0x37 ; 55 + 3524: f1 4f sbci r31, 0xF1 ; 241 + 3526: 80 81 ld r24, Z + if (temp == nrKlastra) //JeÅ›li klaster wskazuje na samego siebie, co oznacza, że jest ostatni w pliku + 3528: 89 13 cpse r24, r25 + 352a: 1d c0 rjmp .+58 ; 0x3566 + 352c: aa ec ldi r26, 0xCA ; 202 + 352e: be e0 ldi r27, 0x0E ; 14 + 3530: 81 e0 ldi r24, 0x01 ; 1 + { //Należy znaleźć jakiÅ› wolny klaster i go dodać do Å‚aÅ„cycha klastrów w pliku + for (temp=1; temp <128; temp++) //PrzekglÄ…damy wszystkie klastry za wyjÄ…tkiem klastra 0 (dla temp = 0 nie ma znaczenia instrukcja break) + { //JeÅ›li temp ma wartość 0 to oznacza, że nie ma wolnego klastra + if (klastry[temp] == 0) //JeÅ›li w tablicy klaster wskazuje na 0, to oznacza, że jest on pusty + 3532: 9d 91 ld r25, X+ + 3534: 91 11 cpse r25, r1 + 3536: 13 c0 rjmp .+38 ; 0x355e + break; //Wtedy można przerwać szukanie kolejnych klastrów dla klastra + } //Taka implementacja z zaÅ‚ożenia powoduje defragmentacjÄ™. + + if (temp != 0) //Znaleziono jakiÅ› wolny klaster + { + klastry[nrKlastra] = temp; //Ustawienie Å‚aÅ„cucha z klastrami, dodanie do pliku kolejnego klastra + 3538: 80 83 st Z, r24 + klastry[temp]=temp; //Oznaczenie klastra jako zajÄ™tego (ostatniego w danym pliku) + 353a: 28 2f mov r18, r24 + 353c: 30 e0 ldi r19, 0x00 ; 0 + 353e: f9 01 movw r30, r18 + 3540: e7 53 subi r30, 0x37 ; 55 + 3542: f1 4f sbci r31, 0xF1 ; 241 + 3544: 80 83 st Z, r24 +static void czyscKlaster(uint8_t nrKlastra); + +static void czyscKlaster(uint8_t nrKlastra) +{ + uint8_t *tmpPtr = dataPtr(nrKlastra, 0); + memset (tmpPtr, 0, 256); + 3546: e0 e0 ldi r30, 0x00 ; 0 + 3548: f0 e8 ldi r31, 0x80 ; 128 + 354a: f8 0f add r31, r24 + 354c: 20 e0 ldi r18, 0x00 ; 0 + 354e: 31 e0 ldi r19, 0x01 ; 1 + 3550: df 01 movw r26, r30 + 3552: a9 01 movw r20, r18 + 3554: 1d 92 st X+, r1 + 3556: 41 50 subi r20, 0x01 ; 1 + 3558: 50 40 sbci r21, 0x00 ; 0 + 355a: e1 f7 brne .-8 ; 0x3554 + 355c: 08 95 ret +static uint8_t nastepnyKlaster(uint8_t nrKlastra) +{ + uint8_t temp = klastry[nrKlastra]; //Temp oznacza na nastÄ™pny klaster. + if (temp == nrKlastra) //JeÅ›li klaster wskazuje na samego siebie, co oznacza, że jest ostatni w pliku + { //Należy znaleźć jakiÅ› wolny klaster i go dodać do Å‚aÅ„cycha klastrów w pliku + for (temp=1; temp <128; temp++) //PrzekglÄ…damy wszystkie klastry za wyjÄ…tkiem klastra 0 (dla temp = 0 nie ma znaczenia instrukcja break) + 355e: 8f 5f subi r24, 0xFF ; 255 + 3560: 80 38 cpi r24, 0x80 ; 128 + 3562: 39 f7 brne .-50 ; 0x3532 + 3564: e9 cf rjmp .-46 ; 0x3538 + klastry[temp]=temp; //Oznaczenie klastra jako zajÄ™tego (ostatniego w danym pliku) + czyscKlaster(temp); //Czyszczenie klastra + } + } + return temp; +} + 3566: 08 95 ret + +00003568 : + +static uint8_t znajdzKlasterN(uint8_t nrPierwszegoKlastra, uint8_t lPrzeskokow) +{ + 3568: 1f 93 push r17 + 356a: cf 93 push r28 + 356c: df 93 push r29 + 356e: 1f 92 push r1 + 3570: cd b7 in r28, 0x3d ; 61 + 3572: de b7 in r29, 0x3e ; 62 + uint8_t ind; //PIerwszy klaster ma indeks 0 + uint8_t wynik = nrPierwszegoKlastra; + for (ind=0; ind < lPrzeskokow; ind++) //Należy wykonać klasterN przeskoków na kolejne klastry (IndHi okreÅ›la ile trzeba zrobić przeskoków od pierwszego klastra) + 3574: 10 e0 ldi r17, 0x00 ; 0 + 3576: 16 17 cp r17, r22 + 3578: 41 f0 breq .+16 ; 0x358a + { + wynik = nastepnyKlaster(wynik); //JeÅ›li nie ma kolejnego klastra, to zostanie automatycznie dodany + 357a: 69 83 std Y+1, r22 ; 0x01 + 357c: 0e 94 8e 1a call 0x351c ; 0x351c + if (wynik == 0) //Sprawdzany, czy znalazÅ‚ siÄ™ kolejny klaster + 3580: 69 81 ldd r22, Y+1 ; 0x01 + 3582: 88 23 and r24, r24 + 3584: 11 f0 breq .+4 ; 0x358a + +static uint8_t znajdzKlasterN(uint8_t nrPierwszegoKlastra, uint8_t lPrzeskokow) +{ + uint8_t ind; //PIerwszy klaster ma indeks 0 + uint8_t wynik = nrPierwszegoKlastra; + for (ind=0; ind < lPrzeskokow; ind++) //Należy wykonać klasterN przeskoków na kolejne klastry (IndHi okreÅ›la ile trzeba zrobić przeskoków od pierwszego klastra) + 3586: 1f 5f subi r17, 0xFF ; 255 + 3588: f6 cf rjmp .-20 ; 0x3576 + wynik = nastepnyKlaster(wynik); //JeÅ›li nie ma kolejnego klastra, to zostanie automatycznie dodany + if (wynik == 0) //Sprawdzany, czy znalazÅ‚ siÄ™ kolejny klaster + break; //BÅ‚Ä…d, zwrócony zostanie klaster 0 - zarezerwowany na poczÄ…tek tablicy plików + } + return wynik; +} + 358a: 0f 90 pop r0 + 358c: df 91 pop r29 + 358e: cf 91 pop r28 + 3590: 1f 91 pop r17 + 3592: 08 95 ret + +00003594 : + return 0; +} +#endif + +static struct ramPlik* znajdzPlik(const char *nazwa) +{ + 3594: 8f 92 push r8 + 3596: 9f 92 push r9 + 3598: bf 92 push r11 + 359a: cf 92 push r12 + 359c: df 92 push r13 + 359e: ef 92 push r14 + 35a0: ff 92 push r15 + 35a2: 0f 93 push r16 + 35a4: 1f 93 push r17 + 35a6: cf 93 push r28 + 35a8: df 93 push r29 + 35aa: 7c 01 movw r14, r24 + uint8_t dlNazwy = strlen(nazwa); //Skracanie podanej nazwy do 8 znaków + 35ac: fc 01 movw r30, r24 + 35ae: 01 90 ld r0, Z+ + 35b0: 00 20 and r0, r0 + 35b2: e9 f7 brne .-6 ; 0x35ae + 35b4: 31 97 sbiw r30, 0x01 ; 1 + 35b6: e8 1b sub r30, r24 + 35b8: e9 30 cpi r30, 0x09 ; 9 + 35ba: 08 f0 brcs .+2 ; 0x35be + 35bc: e8 e0 ldi r30, 0x08 ; 8 + if (dlNazwy > 8) + dlNazwy = 8; + + + if (nazwa[dlNazwy-1] == 0) + 35be: d7 01 movw r26, r14 + 35c0: ae 0f add r26, r30 + 35c2: b1 1d adc r27, r1 + 35c4: 11 97 sbiw r26, 0x01 ; 1 + 35c6: 8c 91 ld r24, X + 35c8: 81 11 cpse r24, r1 + 35ca: 01 c0 rjmp .+2 ; 0x35ce + dlNazwy--; //Nie sprawdzamy czy string koÅ„czy siÄ™ /0 + 35cc: e1 50 subi r30, 0x01 ; 1 + 35ce: d7 01 movw r26, r14 + 35d0: 11 96 adiw r26, 0x01 ; 1 + struct ramPlik *plik; + uint8_t temp; + uint8_t tempKlaster=0; + uint8_t tempKlaster2; + + for (temp=1; temp < dlNazwy; temp ++) + 35d2: 81 e0 ldi r24, 0x01 ; 1 + 35d4: 8e 17 cp r24, r30 + 35d6: 28 f4 brcc .+10 ; 0x35e2 + { + if (nazwa[temp] == ' ') //Pozbycie sie spacji + 35d8: 9d 91 ld r25, X+ + 35da: 90 32 cpi r25, 0x20 ; 32 + 35dc: 29 f0 breq .+10 ; 0x35e8 + struct ramPlik *plik; + uint8_t temp; + uint8_t tempKlaster=0; + uint8_t tempKlaster2; + + for (temp=1; temp < dlNazwy; temp ++) + 35de: 8f 5f subi r24, 0xFF ; 255 + 35e0: f9 cf rjmp .-14 ; 0x35d4 + { + dlNazwy = temp; + break; + } + } + if (dlNazwy == 0) + 35e2: e1 11 cpse r30, r1 + 35e4: 02 c0 rjmp .+4 ; 0x35ea + 35e6: 23 c0 rjmp .+70 ; 0x362e + 35e8: e8 2f mov r30, r24 + 35ea: b1 2c mov r11, r1 + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + { + if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + 35ec: ce 2f mov r28, r30 + 35ee: d0 e0 ldi r29, 0x00 ; 0 + if (dlNazwy == 0) + return NULL; + + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + 35f0: cb 2c mov r12, r11 + 35f2: d1 2c mov r13, r1 + 35f4: 86 01 movw r16, r12 + 35f6: 00 58 subi r16, 0x80 ; 128 + 35f8: 1f 4f sbci r17, 0xFF ; 255 + 35fa: 10 2f mov r17, r16 + 35fc: 00 27 eor r16, r16 + 35fe: 48 01 movw r8, r16 + 3600: 93 94 inc r9 + for (temp=0; temp <16; temp++) + { + if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + 3602: ae 01 movw r20, r28 + 3604: b8 01 movw r22, r16 + 3606: 6c 5f subi r22, 0xFC ; 252 + 3608: 7f 4f sbci r23, 0xFF ; 255 + 360a: c7 01 movw r24, r14 + 360c: 0e 94 98 4f call 0x9f30 ; 0x9f30 + 3610: 89 2b or r24, r25 + 3612: 81 f0 breq .+32 ; 0x3634 + return plik; + plik++; //PrzejÅ›cie do kolejnego wpisu (w tym samym klastrze) + 3614: 00 5f subi r16, 0xF0 ; 240 + 3616: 1f 4f sbci r17, 0xFF ; 255 + return NULL; + + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + 3618: 08 15 cp r16, r8 + 361a: 19 05 cpc r17, r9 + 361c: 91 f7 brne .-28 ; 0x3602 + if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + return plik; + plik++; //PrzejÅ›cie do kolejnego wpisu (w tym samym klastrze) + } + tempKlaster2 = tempKlaster; + tempKlaster = klastry[tempKlaster]; + 361e: f6 01 movw r30, r12 + 3620: e7 53 subi r30, 0x37 ; 55 + 3622: f1 4f sbci r31, 0xF1 ; 241 + 3624: 80 81 ld r24, Z + } + while (tempKlaster2 != tempKlaster); + 3626: b8 16 cp r11, r24 + 3628: 11 f0 breq .+4 ; 0x362e + 362a: b8 2e mov r11, r24 + 362c: e1 cf rjmp .-62 ; 0x35f0 + dlNazwy = temp; + break; + } + } + if (dlNazwy == 0) + return NULL; + 362e: 80 e0 ldi r24, 0x00 ; 0 + 3630: 90 e0 ldi r25, 0x00 ; 0 + 3632: 01 c0 rjmp .+2 ; 0x3636 + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + { + if (strncmp(nazwa, plik->nazwa, dlNazwy) == 0) + return plik; + 3634: c8 01 movw r24, r16 + tempKlaster2 = tempKlaster; + tempKlaster = klastry[tempKlaster]; + } + while (tempKlaster2 != tempKlaster); + return NULL; +} + 3636: df 91 pop r29 + 3638: cf 91 pop r28 + 363a: 1f 91 pop r17 + 363c: 0f 91 pop r16 + 363e: ff 90 pop r15 + 3640: ef 90 pop r14 + 3642: df 90 pop r13 + 3644: cf 90 pop r12 + 3646: bf 90 pop r11 + 3648: 9f 90 pop r9 + 364a: 8f 90 pop r8 + 364c: 08 95 ret + +0000364e : +} + +static uint8_t znajdzWolnyKlaster(void) +{ + uint8_t i; + for (i=1; i + 3658: 9c 01 movw r18, r24 + 365a: 2f 5f subi r18, 0xFF ; 255 + 365c: 3f 4f sbci r19, 0xFF ; 255 + 365e: fc 01 movw r30, r24 + 3660: e7 53 subi r30, 0x37 ; 55 + 3662: f1 4f sbci r31, 0xF1 ; 241 + { //Może być rozszerzony na inne klastry. + if (klastry[i] == 0) //Sprawdzanie, czy klaster jest pusty. + 3664: 40 81 ld r20, Z + 3666: 41 11 cpse r20, r1 + 3668: 0d c0 rjmp .+26 ; 0x3684 + { + klastry[i] = i; //Oznaczanie klastra jako ostatniego. + 366a: 80 83 st Z, r24 +static void czyscKlaster(uint8_t nrKlastra); + +static void czyscKlaster(uint8_t nrKlastra) +{ + uint8_t *tmpPtr = dataPtr(nrKlastra, 0); + memset (tmpPtr, 0, 256); + 366c: e0 e0 ldi r30, 0x00 ; 0 + 366e: f0 e8 ldi r31, 0x80 ; 128 + 3670: f8 0f add r31, r24 + 3672: 20 e0 ldi r18, 0x00 ; 0 + 3674: 31 e0 ldi r19, 0x01 ; 1 + 3676: df 01 movw r26, r30 + 3678: a9 01 movw r20, r18 + 367a: 1d 92 st X+, r1 + 367c: 41 50 subi r20, 0x01 ; 1 + 367e: 50 40 sbci r21, 0x00 ; 0 + 3680: e1 f7 brne .-8 ; 0x367a + { //Może być rozszerzony na inne klastry. + if (klastry[i] == 0) //Sprawdzanie, czy klaster jest pusty. + { + klastry[i] = i; //Oznaczanie klastra jako ostatniego. + czyscKlaster(i); //Czyszczenie zawartoÅ›ci klastra. + return i; + 3682: 08 95 ret + 3684: c9 01 movw r24, r18 + 3686: e5 cf rjmp .-54 ; 0x3652 + } + } + return 0; + 3688: 80 e0 ldi r24, 0x00 ; 0 +} + 368a: 08 95 ret + +0000368c : +} + + +void ramDyskInit(void) +{ + memset (klastry, 0, 128); //Czyszczenie tablicy klastrów (wszystkie sÄ… puste) + 368c: 80 e8 ldi r24, 0x80 ; 128 + 368e: e9 ec ldi r30, 0xC9 ; 201 + 3690: fe e0 ldi r31, 0x0E ; 14 + 3692: df 01 movw r26, r30 + 3694: 1d 92 st X+, r1 + 3696: 8a 95 dec r24 + 3698: e9 f7 brne .-6 ; 0x3694 + memset (dataPtr(0,0), 0, 256); //Czyszczenie zerowego klastra z tablicÄ… plików + 369a: 80 e0 ldi r24, 0x00 ; 0 + 369c: 91 e0 ldi r25, 0x01 ; 1 + 369e: e0 e0 ldi r30, 0x00 ; 0 + 36a0: f0 e8 ldi r31, 0x80 ; 128 + 36a2: df 01 movw r26, r30 + 36a4: 9c 01 movw r18, r24 + 36a6: 1d 92 st X+, r1 + 36a8: 21 50 subi r18, 0x01 ; 1 + 36aa: 30 40 sbci r19, 0x00 ; 0 + 36ac: e1 f7 brne .-8 ; 0x36a6 + 36ae: 08 95 ret + +000036b0 : +} +uint8_t ramDyskUtworzPlik(const char *nazwa) +{ //Nowo utworzony plik nie zajmuje żadnego klastra + 36b0: ff 92 push r15 + 36b2: 0f 93 push r16 + 36b4: 1f 93 push r17 + 36b6: cf 93 push r28 + 36b8: df 93 push r29 + 36ba: 8c 01 movw r16, r24 + uint8_t dlNazwy = strlen(nazwa); + 36bc: fc 01 movw r30, r24 + 36be: 01 90 ld r0, Z+ + 36c0: 00 20 and r0, r0 + 36c2: e9 f7 brne .-6 ; 0x36be + 36c4: 31 97 sbiw r30, 0x01 ; 1 + 36c6: fe 2e mov r15, r30 + 36c8: f8 1a sub r15, r24 + 36ca: 88 e0 ldi r24, 0x08 ; 8 + 36cc: 8f 15 cp r24, r15 + 36ce: 10 f4 brcc .+4 ; 0x36d4 + 36d0: 58 e0 ldi r21, 0x08 ; 8 + 36d2: f5 2e mov r15, r21 + 36d4: 90 2f mov r25, r16 + uint8_t i; + if (dlNazwy > 8) + dlNazwy = 8; + + for (i=0; i + { if (nazwa[i] == ' ') + 36e0: 21 91 ld r18, Z+ + 36e2: 20 32 cpi r18, 0x20 ; 32 + 36e4: c9 f7 brne .-14 ; 0x36d8 + 36e6: f8 2e mov r15, r24 + { + dlNazwy = i; + break; + } + } + if (dlNazwy == 0) + 36e8: ff 20 and r15, r15 + 36ea: 09 f4 brne .+2 ; 0x36ee + 36ec: 3f c0 rjmp .+126 ; 0x376c + return 0; + + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) != NULL) + 36ee: c8 01 movw r24, r16 + 36f0: 0e 94 ca 1a call 0x3594 ; 0x3594 + 36f4: 89 2b or r24, r25 + 36f6: d1 f5 brne .+116 ; 0x376c + 36f8: 50 e0 ldi r21, 0x00 ; 0 + uint8_t temp; + uint8_t tempKlaster=0; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + uint8_t tempKlaster2; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + 36fa: 25 2f mov r18, r21 + 36fc: 30 e0 ldi r19, 0x00 ; 0 + 36fe: c9 01 movw r24, r18 + 3700: 80 58 subi r24, 0x80 ; 128 + 3702: 9f 4f sbci r25, 0xFF ; 255 + 3704: 98 2f mov r25, r24 + 3706: 88 27 eor r24, r24 + 3708: fc 01 movw r30, r24 + 370a: 34 96 adiw r30, 0x04 ; 4 + 370c: 8c 5f subi r24, 0xFC ; 252 + 370e: 9e 4f sbci r25, 0xFE ; 254 + 3710: ef 01 movw r28, r30 + 3712: 24 97 sbiw r28, 0x04 ; 4 + for (temp=0; temp <16; temp++) + { + if (plik->nazwa[0] == 0) + 3714: 40 81 ld r20, Z + 3716: 44 23 and r20, r20 + 3718: b9 f0 breq .+46 ; 0x3748 + 371a: 70 96 adiw r30, 0x10 ; 16 + uint8_t tempKlaster=0; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + uint8_t tempKlaster2; //Przeszukiwanie głównego wpisu katalogowego, jest on zapisany w klastrze 0 + do + { + plik = (struct ramPlik *)(dataPtr(tempKlaster, 0)); //Odczyt pierwszego nagłówka pliku w klastrze + for (temp=0; temp <16; temp++) + 371c: e8 17 cp r30, r24 + 371e: f9 07 cpc r31, r25 + 3720: b9 f7 brne .-18 ; 0x3710 + if (plik->nazwa[0] == 0) + return plik; + plik++; //PrzejÅ›cie do kolejnego wpisu (w tym samym klastrze) + } + tempKlaster2 = tempKlaster; + tempKlaster = klastry[tempKlaster]; + 3722: e9 01 movw r28, r18 + 3724: c7 53 subi r28, 0x37 ; 55 + 3726: d1 4f sbci r29, 0xF1 ; 241 + 3728: 88 81 ld r24, Y + } + while (tempKlaster2 != tempKlaster); + 372a: 58 17 cp r21, r24 + 372c: 11 f0 breq .+4 ; 0x3732 + 372e: 58 2f mov r21, r24 + 3730: e4 cf rjmp .-56 ; 0x36fa + + klastry[tempKlaster] = znajdzWolnyKlaster(); + 3732: 0e 94 27 1b call 0x364e ; 0x364e + 3736: 88 83 st Y, r24 + plik = NULL; + if (klastry[tempKlaster] != 0) + 3738: 81 11 cpse r24, r1 + 373a: 02 c0 rjmp .+4 ; 0x3740 + memset(plik, 0, 12); //Czyszczenie wpisu (pola: pierwszyKlaster, rozmiarLo, rozmiarHi, lAktOtw ustawione na wartość 0) + strncpy(plik->nazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + return 0; + } + return 1; + 373c: 81 e0 ldi r24, 0x01 ; 1 + 373e: 17 c0 rjmp .+46 ; 0x376e + while (tempKlaster2 != tempKlaster); + + klastry[tempKlaster] = znajdzWolnyKlaster(); + plik = NULL; + if (klastry[tempKlaster] != 0) + plik = (struct ramPlik*) (dataPtr(klastry[tempKlaster], 0)); + 3740: 90 e0 ldi r25, 0x00 ; 0 + 3742: c9 2f mov r28, r25 + 3744: d0 e8 ldi r29, 0x80 ; 128 + 3746: d8 0f add r29, r24 + if ((plik = znajdzPlik(nazwa)) != NULL) + { + return 0; + } + + if ((plik = znajdzMiejsceNaWpis()) != NULL) //Szukanie pustego wpisu (nagłówka) po skasowanym pliku + 3748: 20 97 sbiw r28, 0x00 ; 0 + 374a: c1 f3 breq .-16 ; 0x373c + { + memset(plik, 0, 12); //Czyszczenie wpisu (pola: pierwszyKlaster, rozmiarLo, rozmiarHi, lAktOtw ustawione na wartość 0) + 374c: 8c e0 ldi r24, 0x0C ; 12 + 374e: fe 01 movw r30, r28 + 3750: 11 92 st Z+, r1 + 3752: 8a 95 dec r24 + 3754: e9 f7 brne .-6 ; 0x3750 + strncpy(plik->nazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + 3756: 4f 2d mov r20, r15 + 3758: 50 e0 ldi r21, 0x00 ; 0 + 375a: b8 01 movw r22, r16 + 375c: ce 01 movw r24, r28 + 375e: 04 96 adiw r24, 0x04 ; 4 + 3760: 0e 94 a6 4f call 0x9f4c ; 0x9f4c + plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + 3764: 1c 86 std Y+12, r1 ; 0x0c + 3766: 1d 86 std Y+13, r1 ; 0x0d + 3768: 1e 86 std Y+14, r1 ; 0x0e + 376a: 1f 86 std Y+15, r1 ; 0x0f + dlNazwy = i; + break; + } + } + if (dlNazwy == 0) + return 0; + 376c: 80 e0 ldi r24, 0x00 ; 0 + strncpy(plik->nazwa, nazwa, dlNazwy); //Ustawianie odpowiedniej nazwy pliku + plik -> dataMod = systemTime(); //Ustawianie czasu modyfikacji + return 0; + } + return 1; +} + 376e: df 91 pop r29 + 3770: cf 91 pop r28 + 3772: 1f 91 pop r17 + 3774: 0f 91 pop r16 + 3776: ff 90 pop r15 + 3778: 08 95 ret + +0000377a : + +uint8_t ramDyskOtworzPlik(const char *nazwa, struct ramPlikFd *fd) +{ + 377a: cf 93 push r28 + 377c: df 93 push r29 + 377e: eb 01 movw r28, r22 + uint8_t wynik = 1; + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) != NULL) + 3780: 0e 94 ca 1a call 0x3594 ; 0x3594 + 3784: 00 97 sbiw r24, 0x00 ; 0 + 3786: 59 f0 breq .+22 ; 0x379e + { + memset(fd, 0, 3); //Zerowanie struktury deskryptora pliku + 3788: 18 82 st Y, r1 + 378a: 19 82 std Y+1, r1 ; 0x01 + 378c: 1a 82 std Y+2, r1 ; 0x02 + fd->wpis = plik; //Ustawianie w deskryptorze wskaźnika na wpis pliku do katalogu głównego + 378e: 9d 83 std Y+5, r25 ; 0x05 + 3790: 8c 83 std Y+4, r24 ; 0x04 + plik->lAktOtw++; //Uaktualnienie licznika otwarć plików + 3792: fc 01 movw r30, r24 + 3794: 23 81 ldd r18, Z+3 ; 0x03 + 3796: 2f 5f subi r18, 0xFF ; 255 + 3798: 23 83 std Z+3, r18 ; 0x03 + wynik = 0; + 379a: 80 e0 ldi r24, 0x00 ; 0 + 379c: 01 c0 rjmp .+2 ; 0x37a0 + return 1; +} + +uint8_t ramDyskOtworzPlik(const char *nazwa, struct ramPlikFd *fd) +{ + uint8_t wynik = 1; + 379e: 81 e0 ldi r24, 0x01 ; 1 + fd->wpis = plik; //Ustawianie w deskryptorze wskaźnika na wpis pliku do katalogu głównego + plik->lAktOtw++; //Uaktualnienie licznika otwarć plików + wynik = 0; + } + return wynik; +} + 37a0: df 91 pop r29 + 37a2: cf 91 pop r28 + 37a4: 08 95 ret + +000037a6 : + +uint8_t ramDyskUsunPlik(const char *nazwa) +{ + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) == NULL) + 37a6: 0e 94 ca 1a call 0x3594 ; 0x3594 + 37aa: fc 01 movw r30, r24 + 37ac: 89 2b or r24, r25 + 37ae: c1 f0 breq .+48 ; 0x37e0 + return 1; //Nie znaleziono pliku + if (plik->lAktOtw != 0) + 37b0: 83 81 ldd r24, Z+3 ; 0x03 + 37b2: 81 11 cpse r24, r1 + 37b4: 17 c0 rjmp .+46 ; 0x37e4 + return 2; //Plik jest otwarty + + uint8_t usuwanyKlaster; + while(plik->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ okazać, że plik nie miaÅ‚ klastrów + 37b6: 80 81 ld r24, Z + 37b8: 88 23 and r24, r24 + 37ba: 61 f0 breq .+24 ; 0x37d4 + { + usuwanyKlaster = plik->pierwszyKlaster; + if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostatniego klastra + 37bc: a8 2f mov r26, r24 + 37be: b0 e0 ldi r27, 0x00 ; 0 + 37c0: a7 53 subi r26, 0x37 ; 55 + 37c2: b1 4f sbci r27, 0xF1 ; 241 + 37c4: 9c 91 ld r25, X + 37c6: 98 13 cpse r25, r24 + 37c8: 02 c0 rjmp .+4 ; 0x37ce + plik->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwanie pliku + 37ca: 10 82 st Z, r1 + 37cc: 01 c0 rjmp .+2 ; 0x37d0 + else + plik->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + 37ce: 90 83 st Z, r25 + klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + 37d0: 1c 92 st X, r1 + 37d2: f1 cf rjmp .-30 ; 0x37b6 + } + + memset (plik, 0, 16); //Wpis katalogowy zostaje. Jest pusty. Inny plik może być tam wpisany + 37d4: 90 e1 ldi r25, 0x10 ; 16 + 37d6: df 01 movw r26, r30 + 37d8: 1d 92 st X+, r1 + 37da: 9a 95 dec r25 + 37dc: e9 f7 brne .-6 ; 0x37d8 +//relokacjaTablicyWpisow() + return 0; + 37de: 08 95 ret + +uint8_t ramDyskUsunPlik(const char *nazwa) +{ + struct ramPlik *plik; + if ((plik = znajdzPlik(nazwa)) == NULL) + return 1; //Nie znaleziono pliku + 37e0: 81 e0 ldi r24, 0x01 ; 1 + 37e2: 08 95 ret + if (plik->lAktOtw != 0) + return 2; //Plik jest otwarty + 37e4: 82 e0 ldi r24, 0x02 ; 2 + } + + memset (plik, 0, 16); //Wpis katalogowy zostaje. Jest pusty. Inny plik może być tam wpisany +//relokacjaTablicyWpisow() + return 0; +} + 37e6: 08 95 ret + +000037e8 : + +void ramDyskZamknijPlik(struct ramPlikFd *fd) +{ + 37e8: fc 01 movw r30, r24 + if (fd -> wpis -> lAktOtw > 0) //Sprawdzanie, czy licznik otwarć jest poprawny + 37ea: a4 81 ldd r26, Z+4 ; 0x04 + 37ec: b5 81 ldd r27, Z+5 ; 0x05 + 37ee: 13 96 adiw r26, 0x03 ; 3 + 37f0: 9c 91 ld r25, X + 37f2: 13 97 sbiw r26, 0x03 ; 3 + 37f4: 99 23 and r25, r25 + 37f6: 41 f0 breq .+16 ; 0x3808 + { + fd->wpis->lAktOtw--; //Zmniejszanie licznika otwarć pliku + 37f8: 91 50 subi r25, 0x01 ; 1 + 37fa: 13 96 adiw r26, 0x03 ; 3 + 37fc: 9c 93 st X, r25 + memset(fd, 0, sizeof(struct ramPlikFd)); //CZyszczenie struktury deskryptora plików + 37fe: 86 e0 ldi r24, 0x06 ; 6 + 3800: df 01 movw r26, r30 + 3802: 1d 92 st X+, r1 + 3804: 8a 95 dec r24 + 3806: e9 f7 brne .-6 ; 0x3802 + 3808: 08 95 ret + +0000380a : + } +} + +uint8_t ramDyskCzyscPlik(struct ramPlikFd *fd) +{ + 380a: cf 93 push r28 + 380c: df 93 push r29 + 380e: fc 01 movw r30, r24 + uint8_t usuwanyKlaster; + while(fd->wpis->pierwszyKlaster != 0) //Już na samym poczÄ…tku może siÄ™ okazać, że plik nie miaÅ‚ klastrów + 3810: a4 81 ldd r26, Z+4 ; 0x04 + 3812: b5 81 ldd r27, Z+5 ; 0x05 + 3814: 8c 91 ld r24, X + 3816: 88 23 and r24, r24 + 3818: 61 f0 breq .+24 ; 0x3832 + { + usuwanyKlaster = fd->wpis->pierwszyKlaster; + if (klastry[usuwanyKlaster] == usuwanyKlaster) //Sprawdzanie, czy nie usuwamy ostatniego klastra + 381a: c8 2f mov r28, r24 + 381c: d0 e0 ldi r29, 0x00 ; 0 + 381e: c7 53 subi r28, 0x37 ; 55 + 3820: d1 4f sbci r29, 0xF1 ; 241 + 3822: 98 81 ld r25, Y + 3824: 98 13 cpse r25, r24 + 3826: 02 c0 rjmp .+4 ; 0x382c + fd->wpis->pierwszyKlaster = 0; //Ok można już zakoÅ„czyć usuwanie pliku + 3828: 1c 92 st X, r1 + 382a: 01 c0 rjmp .+2 ; 0x382e + else + fd->wpis->pierwszyKlaster = klastry[usuwanyKlaster]; //PrzejÅ›cie do nastÄ™pnego klastra + 382c: 9c 93 st X, r25 + klastry[usuwanyKlaster] = 0; //UsuniÄ™cie klastra + 382e: 18 82 st Y, r1 + 3830: ef cf rjmp .-34 ; 0x3810 + } + fd->wpis->rozmiarLo = 0; + 3832: 11 96 adiw r26, 0x01 ; 1 + 3834: 1c 92 st X, r1 + fd->wpis->rozmiarHi = 0; + 3836: a4 81 ldd r26, Z+4 ; 0x04 + 3838: b5 81 ldd r27, Z+5 ; 0x05 + 383a: 12 96 adiw r26, 0x02 ; 2 + 383c: 1c 92 st X, r1 + fd->wpis->dataMod = systemTime(); + 383e: a4 81 ldd r26, Z+4 ; 0x04 + 3840: b5 81 ldd r27, Z+5 ; 0x05 + 3842: 1c 96 adiw r26, 0x0c ; 12 + 3844: 1d 92 st X+, r1 + 3846: 1d 92 st X+, r1 + 3848: 1d 92 st X+, r1 + 384a: 1c 92 st X, r1 + 384c: 1f 97 sbiw r26, 0x0f ; 15 + memset (fd, 0, 4); + 384e: 10 82 st Z, r1 + 3850: 11 82 std Z+1, r1 ; 0x01 + 3852: 12 82 std Z+2, r1 ; 0x02 + 3854: 13 82 std Z+3, r1 ; 0x03 + return 0; +} + 3856: df 91 pop r29 + 3858: cf 91 pop r28 + 385a: 08 95 ret + +0000385c : + +uint8_t ramDyskZapiszBajtDoPliku(struct ramPlikFd *fd, uint8_t znak) +{ + 385c: 1f 93 push r17 + 385e: cf 93 push r28 + 3860: df 93 push r29 + 3862: ec 01 movw r28, r24 + 3864: 16 2f mov r17, r22 + uint8_t tmpKlaster; + if (fd->wpis->pierwszyKlaster == 0) + 3866: ec 81 ldd r30, Y+4 ; 0x04 + 3868: fd 81 ldd r31, Y+5 ; 0x05 + 386a: 80 81 ld r24, Z + 386c: 81 11 cpse r24, r1 + 386e: 07 c0 rjmp .+14 ; 0x387e + { + if ((tmpKlaster = znajdzWolnyKlaster()) == 0) + 3870: 0e 94 27 1b call 0x364e ; 0x364e + 3874: 88 23 and r24, r24 + 3876: 49 f1 breq .+82 ; 0x38ca + return 1; //Nie można byÅ‚o przydzielić pierwszego klastra do pliku + fd->wpis->pierwszyKlaster = tmpKlaster; + 3878: ec 81 ldd r30, Y+4 ; 0x04 + 387a: fd 81 ldd r31, Y+5 ; 0x05 + 387c: 80 83 st Z, r24 + } + if (fd->IndLo == 0) + 387e: 8a 81 ldd r24, Y+2 ; 0x02 + 3880: 81 11 cpse r24, r1 + 3882: 0d c0 rjmp .+26 ; 0x389e + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Wyszukanie lub dodanie nastÄ™pnego klastra. Na podstawie rozmiaru zostanie stwierdzone, czy klaster byÅ‚ dodany + 3884: ec 81 ldd r30, Y+4 ; 0x04 + 3886: fd 81 ldd r31, Y+5 ; 0x05 + 3888: 6b 81 ldd r22, Y+3 ; 0x03 + 388a: 80 81 ld r24, Z + 388c: 0e 94 b4 1a call 0x3568 ; 0x3568 + if (tmpKlaster == 0) + 3890: 88 23 and r24, r24 + 3892: e9 f0 breq .+58 ; 0x38ce + { + return 2; //Nie można byÅ‚o przydzielić kolejnego klastra + } + fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek nowego klastra + 3894: 90 e0 ldi r25, 0x00 ; 0 + 3896: 80 58 subi r24, 0x80 ; 128 + 3898: 9f 4f sbci r25, 0xFF ; 255 + 389a: 18 82 st Y, r1 + 389c: 89 83 std Y+1, r24 ; 0x01 + } + + *(fd->Wsk) = znak; //Zapis bajtu do pliku + 389e: e8 81 ld r30, Y + 38a0: f9 81 ldd r31, Y+1 ; 0x01 + 38a2: 10 83 st Z, r17 + + fd->IndLo++; //ZwiÄ™kszanie indeksu odczytu/zapisu + 38a4: 8a 81 ldd r24, Y+2 ; 0x02 + 38a6: 8f 5f subi r24, 0xFF ; 255 + 38a8: 8a 83 std Y+2, r24 ; 0x02 + if (fd->IndLo == 0) //JeÅ›li ma on wartość 0, to oznacza to, że czÅ‚y klaster jest zapisany + 38aa: 81 11 cpse r24, r1 + 38ac: 04 c0 rjmp .+8 ; 0x38b6 + fd->IndHi++; //Należy zwiÄ™kszyć bardziej znaczÄ…cy bajt indeksu. Nie utworzono nowego klastra, zatem nie uaktualniamy wskaźnika + 38ae: 8b 81 ldd r24, Y+3 ; 0x03 + 38b0: 8f 5f subi r24, 0xFF ; 255 + 38b2: 8b 83 std Y+3, r24 ; 0x03 + 38b4: 05 c0 rjmp .+10 ; 0x38c0 + else //Wziąż dziaÅ‚amy na tym samym klastrze. + fd->Wsk++; //Można uaktualnić wskaźnik + 38b6: 88 81 ld r24, Y + 38b8: 99 81 ldd r25, Y+1 ; 0x01 + 38ba: 01 96 adiw r24, 0x01 ; 1 + 38bc: 99 83 std Y+1, r25 ; 0x01 + 38be: 88 83 st Y, r24 + + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru + 38c0: ce 01 movw r24, r28 + 38c2: 0e 94 6c 1a call 0x34d8 ; 0x34d8 + return 0; + 38c6: 80 e0 ldi r24, 0x00 ; 0 + 38c8: 03 c0 rjmp .+6 ; 0x38d0 +{ + uint8_t tmpKlaster; + if (fd->wpis->pierwszyKlaster == 0) + { + if ((tmpKlaster = znajdzWolnyKlaster()) == 0) + return 1; //Nie można byÅ‚o przydzielić pierwszego klastra do pliku + 38ca: 81 e0 ldi r24, 0x01 ; 1 + 38cc: 01 c0 rjmp .+2 ; 0x38d0 + if (fd->IndLo == 0) + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Wyszukanie lub dodanie nastÄ™pnego klastra. Na podstawie rozmiaru zostanie stwierdzone, czy klaster byÅ‚ dodany + if (tmpKlaster == 0) + { + return 2; //Nie można byÅ‚o przydzielić kolejnego klastra + 38ce: 82 e0 ldi r24, 0x02 ; 2 + else //Wziąż dziaÅ‚amy na tym samym klastrze. + fd->Wsk++; //Można uaktualnić wskaźnik + + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru + return 0; +} + 38d0: df 91 pop r29 + 38d2: cf 91 pop r28 + 38d4: 1f 91 pop r17 + 38d6: 08 95 ret + +000038d8 : + return wynik; + return EOF; +} + +static int putSTD(char c, FILE *stream) +{ + 38d8: fb 01 movw r30, r22 + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + return ramDyskZapiszBajtDoPliku(fd, c); + 38da: 68 2f mov r22, r24 + 38dc: 84 85 ldd r24, Z+12 ; 0x0c + 38de: 95 85 ldd r25, Z+13 ; 0x0d + 38e0: 0e 94 2e 1c call 0x385c ; 0x385c +} + 38e4: 90 e0 ldi r25, 0x00 ; 0 + 38e6: 08 95 ret + +000038e8 : + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru + return 0; +} + +uint8_t ramDyskCzytajBajtZPliku(struct ramPlikFd *fd, uint8_t *bajt) +{ + 38e8: 0f 93 push r16 + 38ea: 1f 93 push r17 + 38ec: cf 93 push r28 + 38ee: df 93 push r29 + 38f0: ec 01 movw r28, r24 + memset (tmpPtr, 0, 256); +} + +static uint8_t wObrebiePliku(struct ramPlikFd *fd) +{ + if (fd->wpis->rozmiarHi > fd->IndHi) + 38f2: ec 81 ldd r30, Y+4 ; 0x04 + 38f4: fd 81 ldd r31, Y+5 ; 0x05 + 38f6: 92 81 ldd r25, Z+2 ; 0x02 + 38f8: 8b 81 ldd r24, Y+3 ; 0x03 + 38fa: 89 17 cp r24, r25 + 38fc: 40 f0 brcs .+16 ; 0x390e + return 0; + + if ((fd->wpis->rozmiarHi == fd->IndHi) && (fd->wpis->rozmiarLo >= fd->IndLo)) + 38fe: 98 13 cpse r25, r24 + 3900: 04 c0 rjmp .+8 ; 0x390a + 3902: 21 81 ldd r18, Z+1 ; 0x01 + 3904: 9a 81 ldd r25, Y+2 ; 0x02 + 3906: 29 17 cp r18, r25 + 3908: 10 f4 brcc .+4 ; 0x390e +} + +uint8_t ramDyskCzytajBajtZPliku(struct ramPlikFd *fd, uint8_t *bajt) +{ + if (wObrebiePliku(fd) != 0) //Sprawdzanie, czy jesteÅ›my w obrÄ™bie pliku + return 1; //1 - eof + 390a: 81 e0 ldi r24, 0x01 ; 1 + 390c: 21 c0 rjmp .+66 ; 0x3950 + 390e: 8b 01 movw r16, r22 + + if (fd->IndLo == 0) //Sprawdzanie, czy dziaÅ‚amy na poczÄ…tku nowego klastra + 3910: 9a 81 ldd r25, Y+2 ; 0x02 + 3912: 91 11 cpse r25, r1 + 3914: 09 c0 rjmp .+18 ; 0x3928 + { + uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + 3916: 68 2f mov r22, r24 + 3918: 80 81 ld r24, Z + 391a: 0e 94 b4 1a call 0x3568 ; 0x3568 + fd->Wsk = dataPtr(nrKlastra, 0); //Ustawianie wskaźnika na poczÄ…tek nowego klastra + 391e: 90 e0 ldi r25, 0x00 ; 0 + 3920: 80 58 subi r24, 0x80 ; 128 + 3922: 9f 4f sbci r25, 0xFF ; 255 + 3924: 18 82 st Y, r1 + 3926: 89 83 std Y+1, r24 ; 0x01 + } + + *bajt = *(fd->Wsk); //Odczyt z pliku + 3928: e8 81 ld r30, Y + 392a: f9 81 ldd r31, Y+1 ; 0x01 + 392c: 80 81 ld r24, Z + 392e: f8 01 movw r30, r16 + 3930: 80 83 st Z, r24 + fd->IndLo++; //ZwiÄ™kszenie indeksu o 1 + 3932: 8a 81 ldd r24, Y+2 ; 0x02 + 3934: 8f 5f subi r24, 0xFF ; 255 + 3936: 8a 83 std Y+2, r24 ; 0x02 + if (fd->IndLo == 0) //Sprawdzamy, czy przeszliÅ›my do nowego klastra + 3938: 81 11 cpse r24, r1 + 393a: 04 c0 rjmp .+8 ; 0x3944 + fd->IndHi++; //Tak: uaktualniamy liczbÄ™ przeskokół wzglÄ™dem pierwszego klastra (bardziej znaczÄ…cy bajt indeksu) + 393c: 9b 81 ldd r25, Y+3 ; 0x03 + 393e: 9f 5f subi r25, 0xFF ; 255 + 3940: 9b 83 std Y+3, r25 ; 0x03 + 3942: 06 c0 rjmp .+12 ; 0x3950 + else //DziaÅ‚amy na tym samym klastrze + fd->Wsk++; //Uaktualniamy wskaźnik do tego klastra + 3944: 88 81 ld r24, Y + 3946: 99 81 ldd r25, Y+1 ; 0x01 + 3948: 01 96 adiw r24, 0x01 ; 1 + 394a: 99 83 std Y+1, r25 ; 0x01 + 394c: 88 83 st Y, r24 + 394e: 80 e0 ldi r24, 0x00 ; 0 + return 0; +} + 3950: df 91 pop r29 + 3952: cf 91 pop r28 + 3954: 1f 91 pop r17 + 3956: 0f 91 pop r16 + 3958: 08 95 ret + +0000395a : + return wynik; +} + + +static int getSTD(FILE *stream) +{ + 395a: cf 93 push r28 + 395c: df 93 push r29 + 395e: 1f 92 push r1 + 3960: cd b7 in r28, 0x3d ; 61 + 3962: de b7 in r29, 0x3e ; 62 + uint8_t wynik; + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + + if (ramDyskCzytajBajtZPliku(fd, &wynik) == 0) + 3964: be 01 movw r22, r28 + 3966: 6f 5f subi r22, 0xFF ; 255 + 3968: 7f 4f sbci r23, 0xFF ; 255 + 396a: fc 01 movw r30, r24 + 396c: 84 85 ldd r24, Z+12 ; 0x0c + 396e: 95 85 ldd r25, Z+13 ; 0x0d + 3970: 0e 94 74 1c call 0x38e8 ; 0x38e8 + 3974: 81 11 cpse r24, r1 + 3976: 03 c0 rjmp .+6 ; 0x397e + return wynik; + 3978: 89 81 ldd r24, Y+1 ; 0x01 + 397a: 90 e0 ldi r25, 0x00 ; 0 + 397c: 02 c0 rjmp .+4 ; 0x3982 + return EOF; + 397e: 8f ef ldi r24, 0xFF ; 255 + 3980: 9f ef ldi r25, 0xFF ; 255 +} + 3982: 0f 90 pop r0 + 3984: df 91 pop r29 + 3986: cf 91 pop r28 + 3988: 08 95 ret + +0000398a : + fd->Wsk++; //Uaktualniamy wskaźnik do tego klastra + return 0; +} + +uint8_t ramDyskZapiszBlokDoPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) +{ + 398a: 8f 92 push r8 + 398c: 9f 92 push r9 + 398e: af 92 push r10 + 3990: bf 92 push r11 + 3992: df 92 push r13 + 3994: ef 92 push r14 + 3996: ff 92 push r15 + 3998: 0f 93 push r16 + 399a: 1f 93 push r17 + 399c: cf 93 push r28 + 399e: df 93 push r29 + 39a0: ec 01 movw r28, r24 + 39a2: 4b 01 movw r8, r22 + 39a4: 5a 01 movw r10, r20 + if (fd->wpis->pierwszyKlaster == 0) + 39a6: 0c 81 ldd r16, Y+4 ; 0x04 + 39a8: 1d 81 ldd r17, Y+5 ; 0x05 + 39aa: f8 01 movw r30, r16 + 39ac: 80 81 ld r24, Z + 39ae: 81 11 cpse r24, r1 + 39b0: 04 c0 rjmp .+8 ; 0x39ba + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 39b2: 0e 94 27 1b call 0x364e ; 0x364e + 39b6: f8 01 movw r30, r16 + 39b8: 80 83 st Z, r24 + + uint16_t dlBloku = 256 - fd->IndLo; //Obliczanie liczby bajtów, jakÄ… da siÄ™ zapisać w aktualnym klastrze + 39ba: 8a 81 ldd r24, Y+2 ; 0x02 + 39bc: 20 e0 ldi r18, 0x00 ; 0 + 39be: 31 e0 ldi r19, 0x01 ; 1 + 39c0: 79 01 movw r14, r18 + 39c2: e8 1a sub r14, r24 + 39c4: f1 08 sbc r15, r1 + uint16_t doZapisu = *dlugosc; + 39c6: f5 01 movw r30, r10 + 39c8: 00 81 ld r16, Z + 39ca: 11 81 ldd r17, Z+1 ; 0x01 + *dlugosc = 0; //Jak do tÄ…d jeszcze nic nie zapisano + 39cc: 11 82 std Z+1, r1 ; 0x01 + 39ce: 10 82 st Z, r1 + uint8_t tmpKlaster = 0; + 39d0: d1 2c mov r13, r1 + while (doZapisu > 0) + 39d2: 01 15 cp r16, r1 + 39d4: 11 05 cpc r17, r1 + 39d6: 09 f4 brne .+2 ; 0x39da + 39d8: 50 c0 rjmp .+160 ; 0x3a7a + { + if (fd->IndLo == 0) //JeÅ›li indeks pokazuje na poczÄ…tek klastra, to należy odczytać jego numer oraz ustawić na niego wskaźnik + 39da: 8a 81 ldd r24, Y+2 ; 0x02 + 39dc: 81 11 cpse r24, r1 + 39de: 15 c0 rjmp .+42 ; 0x3a0a + { + if (tmpKlaster == 0) //Pierwsza operacja zapisu, nie odczytano jeszcze numeru klastra + 39e0: d1 10 cpse r13, r1 + 39e2: 07 c0 rjmp .+14 ; 0x39f2 + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Odczyt numeru klastra na podstawie informacji o liczbie przeskoków od pierwszego + 39e4: ec 81 ldd r30, Y+4 ; 0x04 + 39e6: fd 81 ldd r31, Y+5 ; 0x05 + 39e8: 6b 81 ldd r22, Y+3 ; 0x03 + 39ea: 80 81 ld r24, Z + 39ec: 0e 94 b4 1a call 0x3568 ; 0x3568 + 39f0: 03 c0 rjmp .+6 ; 0x39f8 + else //Znamy poprzedni klaster + tmpKlaster = nastepnyKlaster(tmpKlaster); //Wystarczy przejść do nastÄ™pnego + 39f2: 8d 2d mov r24, r13 + 39f4: 0e 94 8e 1a call 0x351c ; 0x351c + 39f8: d8 2e mov r13, r24 + if (tmpKlaster == 0) //Sprawdzanie, czy udaÅ‚o siÄ™ znaleźć klaster + 39fa: 88 23 and r24, r24 + 39fc: 09 f4 brne .+2 ; 0x3a00 + 39fe: 42 c0 rjmp .+132 ; 0x3a84 + return 1; //1 - Brak wolnego klastra + + fd->Wsk = dataPtr(tmpKlaster, 0); //Ustawianie wskaźnika na poczÄ…tek klastra. Teraz można do niego już pisać + 3a00: 90 e0 ldi r25, 0x00 ; 0 + 3a02: 80 58 subi r24, 0x80 ; 128 + 3a04: 9f 4f sbci r25, 0xFF ; 255 + 3a06: 18 82 st Y, r1 + 3a08: 89 83 std Y+1, r24 ; 0x01 + 3a0a: 88 81 ld r24, Y + 3a0c: 99 81 ldd r25, Y+1 ; 0x01 + } + if (doZapisu > dlBloku) //Sprawdzanie, czy wszystko uda siÄ™ zapisać w bieżącym klastrze + 3a0e: e0 16 cp r14, r16 + 3a10: f1 06 cpc r15, r17 + 3a12: b8 f4 brcc .+46 ; 0x3a42 + { //Nie uda siÄ™, teraz zapiszemy caÅ‚y klastr do koÅ„ca + memcpy(fd->Wsk, znaki, dlBloku); //Zapis do koÅ„ca aktualnego klastra + 3a14: a7 01 movw r20, r14 + 3a16: b4 01 movw r22, r8 + 3a18: 0e 94 76 4f call 0x9eec ; 0x9eec + znaki +=dlBloku; + 3a1c: 8e 0c add r8, r14 + 3a1e: 9f 1c adc r9, r15 + fd->IndLo = 0; //Mniej znaczÄ…cy bajt odczytu wskazuje na poczÄ…tek nowego klastra. Kolejna iteracja go utworzy + 3a20: 1a 82 std Y+2, r1 ; 0x02 + doZapisu -= dlBloku; //Uaktualnianie informacji o liczbie bajtów jaka pozostaÅ‚Ä… do zapisujemy + 3a22: 0e 19 sub r16, r14 + 3a24: 1f 09 sbc r17, r15 + *dlugosc += dlBloku; //Uaktualnianie informacji o liczbie zapisanych danych + 3a26: f5 01 movw r30, r10 + 3a28: 80 81 ld r24, Z + 3a2a: 91 81 ldd r25, Z+1 ; 0x01 + 3a2c: e8 0e add r14, r24 + 3a2e: f9 1e adc r15, r25 + 3a30: f1 82 std Z+1, r15 ; 0x01 + 3a32: e0 82 st Z, r14 + fd->IndHi++; //Ustawienie bardziej znaczÄ…cego bajtu indeksu. Oznacza to przejÅ›cie do kolejnego klastra + 3a34: 8b 81 ldd r24, Y+3 ; 0x03 + 3a36: 8f 5f subi r24, 0xFF ; 255 + 3a38: 8b 83 std Y+3, r24 ; 0x03 + dlBloku = 256; //Do nastÄ™pnego klastra możemy zapisać do 256 bajtów + 3a3a: e1 2c mov r14, r1 + 3a3c: ff 24 eor r15, r15 + 3a3e: f3 94 inc r15 + 3a40: c8 cf rjmp .-112 ; 0x39d2 + } + else //Jest to ostatni zapis. CaÅ‚e dane zostanÄ… skopiowane + { + memcpy(fd->Wsk, znaki, doZapisu); //Ostatnia operacja zapisu do klasrta. + 3a42: a8 01 movw r20, r16 + 3a44: b4 01 movw r22, r8 + 3a46: 0e 94 76 4f call 0x9eec ; 0x9eec + fd->IndLo += doZapisu; //Uaktualnianie indeksu (wystarczy uaktualnić mneij znaczÄ…cy bajt). + 3a4a: 8a 81 ldd r24, Y+2 ; 0x02 + 3a4c: 80 0f add r24, r16 + 3a4e: 8a 83 std Y+2, r24 ; 0x02 + *dlugosc += doZapisu; //Uaktualnianie informacji o liczbie zapisanych danych. + 3a50: f5 01 movw r30, r10 + 3a52: 80 81 ld r24, Z + 3a54: 91 81 ldd r25, Z+1 ; 0x01 + 3a56: 08 0f add r16, r24 + 3a58: 19 1f adc r17, r25 + 3a5a: 11 83 std Z+1, r17 ; 0x01 + 3a5c: 00 83 st Z, r16 + doZapisu = 0; //Równie dobrze można tutaj wstawić break; + fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce klastra. + 3a5e: 8d 2d mov r24, r13 + 3a60: 90 e0 ldi r25, 0x00 ; 0 + 3a62: 80 58 subi r24, 0x80 ; 128 + 3a64: 9f 4f sbci r25, 0xFF ; 255 + 3a66: 98 2f mov r25, r24 + 3a68: 88 27 eor r24, r24 + 3a6a: 2a 81 ldd r18, Y+2 ; 0x02 + 3a6c: 82 0f add r24, r18 + 3a6e: 91 1d adc r25, r1 + 3a70: 99 83 std Y+1, r25 ; 0x01 + 3a72: 88 83 st Y, r24 + else //Jest to ostatni zapis. CaÅ‚e dane zostanÄ… skopiowane + { + memcpy(fd->Wsk, znaki, doZapisu); //Ostatnia operacja zapisu do klasrta. + fd->IndLo += doZapisu; //Uaktualnianie indeksu (wystarczy uaktualnić mneij znaczÄ…cy bajt). + *dlugosc += doZapisu; //Uaktualnianie informacji o liczbie zapisanych danych. + doZapisu = 0; //Równie dobrze można tutaj wstawić break; + 3a74: 00 e0 ldi r16, 0x00 ; 0 + 3a76: 10 e0 ldi r17, 0x00 ; 0 + 3a78: ac cf rjmp .-168 ; 0x39d2 + fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce klastra. + } + } + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + 3a7a: ce 01 movw r24, r28 + 3a7c: 0e 94 6c 1a call 0x34d8 ; 0x34d8 + return 0; + 3a80: 80 e0 ldi r24, 0x00 ; 0 + 3a82: 01 c0 rjmp .+2 ; 0x3a86 + if (tmpKlaster == 0) //Pierwsza operacja zapisu, nie odczytano jeszcze numeru klastra + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); //Odczyt numeru klastra na podstawie informacji o liczbie przeskoków od pierwszego + else //Znamy poprzedni klaster + tmpKlaster = nastepnyKlaster(tmpKlaster); //Wystarczy przejść do nastÄ™pnego + if (tmpKlaster == 0) //Sprawdzanie, czy udaÅ‚o siÄ™ znaleźć klaster + return 1; //1 - Brak wolnego klastra + 3a84: 81 e0 ldi r24, 0x01 ; 1 + fd->Wsk = dataPtr(tmpKlaster, fd->IndLo); //Ustawianie wskaźnika w odpowiednie miejsce klastra. + } + } + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + return 0; +} + 3a86: df 91 pop r29 + 3a88: cf 91 pop r28 + 3a8a: 1f 91 pop r17 + 3a8c: 0f 91 pop r16 + 3a8e: ff 90 pop r15 + 3a90: ef 90 pop r14 + 3a92: df 90 pop r13 + 3a94: bf 90 pop r11 + 3a96: af 90 pop r10 + 3a98: 9f 90 pop r9 + 3a9a: 8f 90 pop r8 + 3a9c: 08 95 ret + +00003a9e : + +uint8_t ramDyskCzytajBlokZPliku(struct ramPlikFd *fd, uint8_t *znaki, uint16_t *dlugosc) +{ + 3a9e: 9f 92 push r9 + 3aa0: af 92 push r10 + 3aa2: bf 92 push r11 + 3aa4: cf 92 push r12 + 3aa6: df 92 push r13 + 3aa8: ef 92 push r14 + 3aaa: ff 92 push r15 + 3aac: 0f 93 push r16 + 3aae: 1f 93 push r17 + 3ab0: cf 93 push r28 + 3ab2: df 93 push r29 + 3ab4: ec 01 movw r28, r24 + 3ab6: 6b 01 movw r12, r22 + 3ab8: 7a 01 movw r14, r20 + if (fd->wpis->pierwszyKlaster == 0) + 3aba: ac 81 ldd r26, Y+4 ; 0x04 + 3abc: bd 81 ldd r27, Y+5 ; 0x05 + 3abe: 8c 91 ld r24, X + 3ac0: 81 11 cpse r24, r1 + 3ac2: 05 c0 rjmp .+10 ; 0x3ace + { + *dlugosc = 0; + 3ac4: fa 01 movw r30, r20 + 3ac6: 11 82 std Z+1, r1 ; 0x01 + 3ac8: 10 82 st Z, r1 + return 1; //1 - Plik jest pusty + 3aca: 81 e0 ldi r24, 0x01 ; 1 + 3acc: 81 c0 rjmp .+258 ; 0x3bd0 + memset (tmpPtr, 0, 256); +} + +static uint8_t wObrebiePliku(struct ramPlikFd *fd) +{ + if (fd->wpis->rozmiarHi > fd->IndHi) + 3ace: 12 96 adiw r26, 0x02 ; 2 + 3ad0: 2c 91 ld r18, X + 3ad2: 12 97 sbiw r26, 0x02 ; 2 + 3ad4: 8b 81 ldd r24, Y+3 ; 0x03 + 3ad6: 82 17 cp r24, r18 + 3ad8: 68 f0 brcs .+26 ; 0x3af4 + return 0; + + if ((fd->wpis->rozmiarHi == fd->IndHi) && (fd->wpis->rozmiarLo >= fd->IndLo)) + 3ada: 28 13 cpse r18, r24 + 3adc: 06 c0 rjmp .+12 ; 0x3aea + 3ade: 11 96 adiw r26, 0x01 ; 1 + 3ae0: 3c 91 ld r19, X + 3ae2: 11 97 sbiw r26, 0x01 ; 1 + 3ae4: 9a 81 ldd r25, Y+2 ; 0x02 + 3ae6: 39 17 cp r19, r25 + 3ae8: 28 f4 brcc .+10 ; 0x3af4 + *dlugosc = 0; + return 1; //1 - Plik jest pusty + } + if (wObrebiePliku(fd) != 0) + { + *dlugosc = 0; + 3aea: f7 01 movw r30, r14 + 3aec: 11 82 std Z+1, r1 ; 0x01 + 3aee: 10 82 st Z, r1 + return 2; //2 - Źle ustawiony indeks odczytu/zapisu (poza obszarem pliku) + 3af0: 82 e0 ldi r24, 0x02 ; 2 + 3af2: 6e c0 rjmp .+220 ; 0x3bd0 + } + + uint16_t lDanych = (fd->wpis->rozmiarHi - fd->IndHi); + 3af4: 30 e0 ldi r19, 0x00 ; 0 + 3af6: f9 01 movw r30, r18 + 3af8: e8 1b sub r30, r24 + 3afa: f1 09 sbc r31, r1 + lDanych +=fd->wpis->rozmiarLo; //Obliczanie liczby bajtów jaka zostaÅ‚Ä… zapisana jeszcze za wskaźnikiem. + 3afc: 11 96 adiw r26, 0x01 ; 1 + 3afe: 2c 91 ld r18, X + 3b00: 30 e0 ldi r19, 0x00 ; 0 + lDanych -=fd->IndLo; //Na podstawie wczeÅ›niej sprawdzonych warunków jest to zawsze liczba dodatnia + 3b02: 8a 81 ldd r24, Y+2 ; 0x02 + 3b04: 28 1b sub r18, r24 + 3b06: 31 09 sbc r19, r1 + 3b08: 2e 0f add r18, r30 + 3b0a: 3f 1f adc r19, r31 + + uint16_t doOdczytania = (lDanych < *dlugosc)? //Sprawdzenie liczby zapisanych bajtół w pliku i okreÅ›lenie ile bajtów zdoÅ‚a siÄ™ odczytać + 3b0c: f7 01 movw r30, r14 + 3b0e: 00 81 ld r16, Z + 3b10: 11 81 ldd r17, Z+1 ; 0x01 + 3b12: 20 17 cp r18, r16 + 3b14: 31 07 cpc r19, r17 + 3b16: 08 f4 brcc .+2 ; 0x3b1a + 3b18: 89 01 movw r16, r18 + lDanych : //W pliku jest mniej bajtów do odczytu niż chcemy odczytać + *dlugosc; //W pliku jest wiÄ™cej bajtów niż chcemy odczytać + *dlugosc = 0; //Jak do tÄ…d odczytano 0 bajtów + 3b1a: f7 01 movw r30, r14 + 3b1c: 11 82 std Z+1, r1 ; 0x01 + 3b1e: 10 82 st Z, r1 + uint16_t dlBloku = 256 - fd->IndLo; //OkreÅ›lanie liczby bajtół jaka zostaÅ‚Ä… do koÅ„ca aktualnego klastra` + 3b20: 8a 81 ldd r24, Y+2 ; 0x02 + 3b22: 20 e0 ldi r18, 0x00 ; 0 + 3b24: 31 e0 ldi r19, 0x01 ; 1 + 3b26: 59 01 movw r10, r18 + 3b28: a8 1a sub r10, r24 + 3b2a: b1 08 sbc r11, r1 + uint8_t tmpKlaster = 0; + 3b2c: 91 2c mov r9, r1 + while (doOdczytania > 0) + 3b2e: 01 15 cp r16, r1 + 3b30: 11 05 cpc r17, r1 + 3b32: 09 f4 brne .+2 ; 0x3b36 + 3b34: 4a c0 rjmp .+148 ; 0x3bca + { + if (fd->IndLo == 0) //Indeks odczytu wskazuje na poczÄ…tek klastra. Oznacza to, że wskaźnik nie jest jeszcze ustawiony + 3b36: 8a 81 ldd r24, Y+2 ; 0x02 + 3b38: 81 11 cpse r24, r1 + 3b3a: 14 c0 rjmp .+40 ; 0x3b64 + { //Bardziej znaczÄ…cy bajt indeksu okreÅ›la o ile klastrów (od poczÄ…tkowego) należy siÄ™ przesunąć do przodu + if (tmpKlaster == 0) + 3b3c: 91 10 cpse r9, r1 + 3b3e: 07 c0 rjmp .+14 ; 0x3b4e + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->IndHi); + 3b40: ec 81 ldd r30, Y+4 ; 0x04 + 3b42: fd 81 ldd r31, Y+5 ; 0x05 + 3b44: 6b 81 ldd r22, Y+3 ; 0x03 + 3b46: 80 81 ld r24, Z + 3b48: 0e 94 b4 1a call 0x3568 ; 0x3568 + 3b4c: 03 c0 rjmp .+6 ; 0x3b54 + else + tmpKlaster = nastepnyKlaster(tmpKlaster); + 3b4e: 89 2d mov r24, r9 + 3b50: 0e 94 8e 1a call 0x351c ; 0x351c + 3b54: 98 2e mov r9, r24 + if (tmpKlaster != 0) //JeÅ›li znaleziono odpowiedni klaster, to + 3b56: 88 23 and r24, r24 + 3b58: d1 f1 breq .+116 ; 0x3bce + fd->Wsk = dataPtr(tmpKlaster, 0); //przestaw wskaźnik na poczÄ…tek tego klastra + 3b5a: 90 e0 ldi r25, 0x00 ; 0 + 3b5c: 80 58 subi r24, 0x80 ; 128 + 3b5e: 9f 4f sbci r25, 0xFF ; 255 + 3b60: 18 82 st Y, r1 + 3b62: 89 83 std Y+1, r24 ; 0x01 + 3b64: 68 81 ld r22, Y + 3b66: 79 81 ldd r23, Y+1 ; 0x01 + else + return 3; //3 - Nie udaÅ‚o siÄ™ znaleźć odpowiedniego klastra + } + + if (doOdczytania > dlBloku) //Odczyt do koÅ„ca zawartoÅ›ci klastra + 3b68: a0 16 cp r10, r16 + 3b6a: b1 06 cpc r11, r17 + 3b6c: b8 f4 brcc .+46 ; 0x3b9c + { //dlBloku okreÅ›la ile zostaÅ‚o jeszcze bajtów do koÅ„ca klasrta + memcpy(znaki, fd->Wsk, dlBloku); //Odczyt zawartoÅ›ci Klastra + 3b6e: a5 01 movw r20, r10 + 3b70: c6 01 movw r24, r12 + 3b72: 0e 94 76 4f call 0x9eec ; 0x9eec + znaki +=dlBloku; //Przestawienie wskaźnika do tablicy, w której zapisujemy odczytane bajty + 3b76: ca 0c add r12, r10 + 3b78: db 1c adc r13, r11 + fd->IndLo = 0; //Indeks wskazuje na poczÄ…tek nowego klastra + 3b7a: 1a 82 std Y+2, r1 ; 0x02 + fd->IndHi++; //Bardziej znaczÄ…cy bajt okreÅ›la zmianÄ™ klastra. Teraz nie ma potrzeby ustawienia wskaźnika odczytu na jego poczÄ…tek + 3b7c: 8b 81 ldd r24, Y+3 ; 0x03 + 3b7e: 8f 5f subi r24, 0xFF ; 255 + 3b80: 8b 83 std Y+3, r24 ; 0x03 + doOdczytania -= dlBloku; //Uaktualnienie liczby bajtół jakÄ… należy odczytać + 3b82: 0a 19 sub r16, r10 + 3b84: 1b 09 sbc r17, r11 + *dlugosc += dlBloku; //Uaktualnienie + 3b86: f7 01 movw r30, r14 + 3b88: 80 81 ld r24, Z + 3b8a: 91 81 ldd r25, Z+1 ; 0x01 + 3b8c: a8 0e add r10, r24 + 3b8e: b9 1e adc r11, r25 + 3b90: b1 82 std Z+1, r11 ; 0x01 + 3b92: a0 82 st Z, r10 + dlBloku = 256; //Kolejny dostÄ™pny blok do odczytania, to dÅ‚ugość caÅ‚ego klastra. + 3b94: a1 2c mov r10, r1 + 3b96: bb 24 eor r11, r11 + 3b98: b3 94 inc r11 + 3b9a: c9 cf rjmp .-110 ; 0x3b2e + } + else //Ostatnia operacja odczytu + { + memcpy(znaki, fd->Wsk, doOdczytania); + 3b9c: a8 01 movw r20, r16 + 3b9e: c6 01 movw r24, r12 + 3ba0: 0e 94 76 4f call 0x9eec ; 0x9eec + fd->Wsk += doOdczytania; //Po zakoÅ„czeniu operacji odczytu nadal dziaÅ‚amy w tym samym klastrze, zatem trzeba teraz uaktualnić wzkaźnik + 3ba4: 88 81 ld r24, Y + 3ba6: 99 81 ldd r25, Y+1 ; 0x01 + 3ba8: 80 0f add r24, r16 + 3baa: 91 1f adc r25, r17 + 3bac: 99 83 std Y+1, r25 ; 0x01 + 3bae: 88 83 st Y, r24 + fd->IndLo += doOdczytania; //Uaktualnianie indeksu. JesteÅ›my w tym samym klastrze, zatem nie trzeba zmieniać IndHi + 3bb0: 8a 81 ldd r24, Y+2 ; 0x02 + 3bb2: 80 0f add r24, r16 + 3bb4: 8a 83 std Y+2, r24 ; 0x02 + *dlugosc += doOdczytania; //Uaktualnianie liczby odczytanych bajtów + 3bb6: f7 01 movw r30, r14 + 3bb8: 80 81 ld r24, Z + 3bba: 91 81 ldd r25, Z+1 ; 0x01 + 3bbc: 08 0f add r16, r24 + 3bbe: 19 1f adc r17, r25 + 3bc0: 11 83 std Z+1, r17 ; 0x01 + 3bc2: 00 83 st Z, r16 + doOdczytania = 0; //Tutaj równie dobrze może być brake + 3bc4: 00 e0 ldi r16, 0x00 ; 0 + 3bc6: 10 e0 ldi r17, 0x00 ; 0 + 3bc8: b2 cf rjmp .-156 ; 0x3b2e + } + } + return 0; + 3bca: 80 e0 ldi r24, 0x00 ; 0 + 3bcc: 01 c0 rjmp .+2 ; 0x3bd0 + else + tmpKlaster = nastepnyKlaster(tmpKlaster); + if (tmpKlaster != 0) //JeÅ›li znaleziono odpowiedni klaster, to + fd->Wsk = dataPtr(tmpKlaster, 0); //przestaw wskaźnik na poczÄ…tek tego klastra + else + return 3; //3 - Nie udaÅ‚o siÄ™ znaleźć odpowiedniego klastra + 3bce: 83 e0 ldi r24, 0x03 ; 3 + *dlugosc += doOdczytania; //Uaktualnianie liczby odczytanych bajtów + doOdczytania = 0; //Tutaj równie dobrze może być brake + } + } + return 0; +} + 3bd0: df 91 pop r29 + 3bd2: cf 91 pop r28 + 3bd4: 1f 91 pop r17 + 3bd6: 0f 91 pop r16 + 3bd8: ff 90 pop r15 + 3bda: ef 90 pop r14 + 3bdc: df 90 pop r13 + 3bde: cf 90 pop r12 + 3be0: bf 90 pop r11 + 3be2: af 90 pop r10 + 3be4: 9f 90 pop r9 + 3be6: 08 95 ret + +00003be8 : + +uint8_t ramDyskUstawWskaznik(struct ramPlikFd *fd, uint16_t indeks) +{ + 3be8: ef 92 push r14 + 3bea: ff 92 push r15 + 3bec: 0f 93 push r16 + 3bee: 1f 93 push r17 + 3bf0: cf 93 push r28 + 3bf2: df 93 push r29 + 3bf4: ec 01 movw r28, r24 + if (indeks == 0) //Sprawdzanie, czy wskaźnik nie pokazuje na poczÄ…tek pliku. + 3bf6: 61 15 cp r22, r1 + 3bf8: 71 05 cpc r23, r1 + 3bfa: 19 f4 brne .+6 ; 0x3c02 + { //JeÅ›li tak, to nie ma potzeby tworzenia klastrów. Plik może nadal nei mieć żadnego klastra. + fd->IndLo = 0; //Ustawianie na 0 indeksów (mniej i bardziej znaczÄ…cego bajtu) + 3bfc: 1a 82 std Y+2, r1 ; 0x02 + fd->IndHi = 0; + 3bfe: 1b 82 std Y+3, r1 ; 0x03 + 3c00: 2f c0 rjmp .+94 ; 0x3c60 + return 0; + } + indeks--; //Zmniejszamy indeks o 1, by odpowiednio ustawić rozmair pliku. + 3c02: 8b 01 movw r16, r22 + 3c04: 01 50 subi r16, 0x01 ; 1 + 3c06: 11 09 sbc r17, r1 + //JeÅ›li indeks jest wiÄ™kszy niż rozmiar pliku, to plik zostanie rozciÄ…gniÄ™ty do zadanej wartoÅ›ci indeksu -1 + + if (fd->wpis->pierwszyKlaster == 0) //Sprawdzanie, czy plik ma już przydzielony pierwszy klaster + 3c08: ec 80 ldd r14, Y+4 ; 0x04 + 3c0a: fd 80 ldd r15, Y+5 ; 0x05 + 3c0c: f7 01 movw r30, r14 + 3c0e: 80 81 ld r24, Z + 3c10: 81 11 cpse r24, r1 + 3c12: 04 c0 rjmp .+8 ; 0x3c1c + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); //Przydzielanie pierwszego klastra dla pliku. Jest to konieczne, ponieważ klaster ma wartość niezerowÄ… + 3c14: 0e 94 27 1b call 0x364e ; 0x364e + 3c18: f7 01 movw r30, r14 + 3c1a: 80 83 st Z, r24 + + uint8_t klasterN = indeks >> 8; //Obliczanie liczby klastrów, jakÄ… należy dodać do pierwszego klastra` + + fd->IndLo = indeks & 0xFF; //Obliczanie na podstawie wartoÅ›ci 16 mniej znaczÄ…cego bajtu indeksu pomniejszonej o 1 + 3c1c: 0a 83 std Y+2, r16 ; 0x02 + fd->IndHi = klasterN; //oraz bardziej znaczÄ…cego bajtu indeksu w deskryptorze. + 3c1e: 1b 83 std Y+3, r17 ; 0x03 + + uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, klasterN); + 3c20: ec 81 ldd r30, Y+4 ; 0x04 + 3c22: fd 81 ldd r31, Y+5 ; 0x05 + 3c24: 61 2f mov r22, r17 + 3c26: 80 81 ld r24, Z + 3c28: 0e 94 b4 1a call 0x3568 ; 0x3568 + 3c2c: 18 2f mov r17, r24 + if (nrKlastra == 0) + 3c2e: 88 23 and r24, r24 + 3c30: c9 f0 breq .+50 ; 0x3c64 + return 1; //Brak klastrów + + uaktualnijRozmiarPliku(fd); //Uaktualnianie rozmiaru pliku + 3c32: ce 01 movw r24, r28 + 3c34: 0e 94 6c 1a call 0x34d8 ; 0x34d8 + + fd->IndLo++; //Powrót do zadanej wartoÅ›ci indeksu + 3c38: 8a 81 ldd r24, Y+2 ; 0x02 + 3c3a: 8f 5f subi r24, 0xFF ; 255 + 3c3c: 8a 83 std Y+2, r24 ; 0x02 + if (fd->IndLo == 0) //JeÅ›li jesteÅ›my na poczÄ…tku klastra, to jeszcze on nie iestnieje + 3c3e: 81 11 cpse r24, r1 + 3c40: 04 c0 rjmp .+8 ; 0x3c4a + fd->IndHi++; //Uaktualniamy tylko bardziej znaczÄ…cy bajt indeksu + 3c42: 9b 81 ldd r25, Y+3 ; 0x03 + 3c44: 9f 5f subi r25, 0xFF ; 255 + 3c46: 9b 83 std Y+3, r25 ; 0x03 + 3c48: 0e c0 rjmp .+28 ; 0x3c66 + else //JesteÅ›my w obszarze utworzonego klastra, można uaktualnić wskaźnik + fd->Wsk=dataPtr(nrKlastra, fd->IndLo); //ustawić wskaźnik na odpowiednie miejsce klastra + 3c4a: 21 2f mov r18, r17 + 3c4c: 30 e0 ldi r19, 0x00 ; 0 + 3c4e: 20 58 subi r18, 0x80 ; 128 + 3c50: 3f 4f sbci r19, 0xFF ; 255 + 3c52: 32 2f mov r19, r18 + 3c54: 22 27 eor r18, r18 + 3c56: a9 01 movw r20, r18 + 3c58: 48 0f add r20, r24 + 3c5a: 51 1d adc r21, r1 + 3c5c: 59 83 std Y+1, r21 ; 0x01 + 3c5e: 48 83 st Y, r20 + + return 0; + 3c60: 80 e0 ldi r24, 0x00 ; 0 + 3c62: 01 c0 rjmp .+2 ; 0x3c66 + fd->IndLo = indeks & 0xFF; //Obliczanie na podstawie wartoÅ›ci 16 mniej znaczÄ…cego bajtu indeksu pomniejszonej o 1 + fd->IndHi = klasterN; //oraz bardziej znaczÄ…cego bajtu indeksu w deskryptorze. + + uint8_t nrKlastra = znajdzKlasterN(fd->wpis->pierwszyKlaster, klasterN); + if (nrKlastra == 0) + return 1; //Brak klastrów + 3c64: 81 e0 ldi r24, 0x01 ; 1 + fd->IndHi++; //Uaktualniamy tylko bardziej znaczÄ…cy bajt indeksu + else //JesteÅ›my w obszarze utworzonego klastra, można uaktualnić wskaźnik + fd->Wsk=dataPtr(nrKlastra, fd->IndLo); //ustawić wskaźnik na odpowiednie miejsce klastra + + return 0; +} + 3c66: df 91 pop r29 + 3c68: cf 91 pop r28 + 3c6a: 1f 91 pop r17 + 3c6c: 0f 91 pop r16 + 3c6e: ff 90 pop r15 + 3c70: ef 90 pop r14 + 3c72: 08 95 ret + +00003c74 : + +uint8_t ramDyskUstawWskaznikNaKoniec(struct ramPlikFd *fd) +{ + 3c74: cf 93 push r28 + 3c76: df 93 push r29 + 3c78: fc 01 movw r30, r24 + if (fd == NULL) + 3c7a: 89 2b or r24, r25 + 3c7c: 01 f1 breq .+64 ; 0x3cbe + return 1; + fd->IndLo = fd->wpis->rozmiarLo; + 3c7e: a4 81 ldd r26, Z+4 ; 0x04 + 3c80: b5 81 ldd r27, Z+5 ; 0x05 + 3c82: 11 96 adiw r26, 0x01 ; 1 + 3c84: 8c 91 ld r24, X + 3c86: 11 97 sbiw r26, 0x01 ; 1 + 3c88: 82 83 std Z+2, r24 ; 0x02 + fd->IndHi = fd->wpis->rozmiarHi; + 3c8a: 12 96 adiw r26, 0x02 ; 2 + 3c8c: 9c 91 ld r25, X + 3c8e: 12 97 sbiw r26, 0x02 ; 2 + 3c90: 93 83 std Z+3, r25 ; 0x03 +// fd->IndLo++; + uint8_t tmpKlaster = 0; + if (fd->IndLo != 0) + 3c92: 88 23 and r24, r24 + 3c94: a9 f0 breq .+42 ; 0x3cc0 + 3c96: ef 01 movw r28, r30 + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->wpis->rozmiarHi); + 3c98: 12 96 adiw r26, 0x02 ; 2 + 3c9a: 6c 91 ld r22, X + 3c9c: 12 97 sbiw r26, 0x02 ; 2 + 3c9e: 8c 91 ld r24, X + 3ca0: 0e 94 b4 1a call 0x3568 ; 0x3568 + fd->Wsk=dataPtr(tmpKlaster, fd->IndLo); + 3ca4: 28 2f mov r18, r24 + 3ca6: 30 e0 ldi r19, 0x00 ; 0 + 3ca8: 20 58 subi r18, 0x80 ; 128 + 3caa: 3f 4f sbci r19, 0xFF ; 255 + 3cac: 32 2f mov r19, r18 + 3cae: 22 27 eor r18, r18 + 3cb0: 8a 81 ldd r24, Y+2 ; 0x02 + 3cb2: 28 0f add r18, r24 + 3cb4: 31 1d adc r19, r1 + 3cb6: 39 83 std Y+1, r19 ; 0x01 + 3cb8: 28 83 st Y, r18 + } + return 0; + 3cba: 80 e0 ldi r24, 0x00 ; 0 + 3cbc: 01 c0 rjmp .+2 ; 0x3cc0 +} + +uint8_t ramDyskUstawWskaznikNaKoniec(struct ramPlikFd *fd) +{ + if (fd == NULL) + return 1; + 3cbe: 81 e0 ldi r24, 0x01 ; 1 + { + tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster, fd->wpis->rozmiarHi); + fd->Wsk=dataPtr(tmpKlaster, fd->IndLo); + } + return 0; +} + 3cc0: df 91 pop r29 + 3cc2: cf 91 pop r28 + 3cc4: 08 95 ret + +00003cc6 : + +uint8_t* ramDyskDodajBlokXmodem(struct ramPlikFd *fd, uint16_t nrBloku) +{ + 3cc6: af 92 push r10 + 3cc8: bf 92 push r11 + 3cca: cf 92 push r12 + 3ccc: df 92 push r13 + 3cce: ef 92 push r14 + 3cd0: ff 92 push r15 + 3cd2: 1f 93 push r17 + 3cd4: cf 93 push r28 + 3cd6: df 93 push r29 + if (nrBloku == 0) + 3cd8: 61 15 cp r22, r1 + 3cda: 71 05 cpc r23, r1 + 3cdc: 19 f4 brne .+6 ; 0x3ce4 + return NULL; + 3cde: 80 e0 ldi r24, 0x00 ; 0 + 3ce0: 90 e0 ldi r25, 0x00 ; 0 + 3ce2: 42 c0 rjmp .+132 ; 0x3d68 + 3ce4: ec 01 movw r28, r24 + nrBloku --; + 3ce6: 6b 01 movw r12, r22 + 3ce8: 81 e0 ldi r24, 0x01 ; 1 + 3cea: c8 1a sub r12, r24 + 3cec: d1 08 sbc r13, r1 + + uint8_t indHi = (uint8_t)(nrBloku / 2); + 3cee: 76 01 movw r14, r12 + 3cf0: f6 94 lsr r15 + 3cf2: e7 94 ror r14 + 3cf4: 1e 2d mov r17, r14 + //uint8_t indLo = 0; + uint8_t *wynik; + + if (fd->wpis->pierwszyKlaster == 0) + 3cf6: ac 80 ldd r10, Y+4 ; 0x04 + 3cf8: bd 80 ldd r11, Y+5 ; 0x05 + 3cfa: f5 01 movw r30, r10 + 3cfc: 80 81 ld r24, Z + 3cfe: 81 11 cpse r24, r1 + 3d00: 04 c0 rjmp .+8 ; 0x3d0a + fd->wpis->pierwszyKlaster = znajdzWolnyKlaster(); + 3d02: 0e 94 27 1b call 0x364e ; 0x364e + 3d06: f5 01 movw r30, r10 + 3d08: 80 83 st Z, r24 + if (fd->wpis->pierwszyKlaster == 0) + 3d0a: ec 81 ldd r30, Y+4 ; 0x04 + 3d0c: fd 81 ldd r31, Y+5 ; 0x05 + 3d0e: 80 81 ld r24, Z + 3d10: 88 23 and r24, r24 + 3d12: 29 f3 breq .-54 ; 0x3cde + return NULL; + + uint8_t tmpKlaster = znajdzKlasterN(fd->wpis->pierwszyKlaster , indHi); + 3d14: 6e 2d mov r22, r14 + 3d16: 0e 94 b4 1a call 0x3568 ; 0x3568 + if (tmpKlaster == 0) + 3d1a: 88 23 and r24, r24 + 3d1c: 01 f3 breq .-64 ; 0x3cde + 3d1e: ec 81 ldd r30, Y+4 ; 0x04 + 3d20: fd 81 ldd r31, Y+5 ; 0x05 + 3d22: 28 2f mov r18, r24 + 3d24: 30 e0 ldi r19, 0x00 ; 0 + return NULL; + if ((nrBloku & 0x0001) == 0x0001) // Druga część klastra + 3d26: c0 fe sbrs r12, 0 + 3d28: 0e c0 rjmp .+28 ; 0x3d46 + { + //indLo = 128; + if (fd->wpis->rozmiarHi <= indHi) + 3d2a: 82 81 ldd r24, Z+2 ; 0x02 + 3d2c: 18 17 cp r17, r24 + 3d2e: 28 f0 brcs .+10 ; 0x3d3a + { + fd->wpis->rozmiarHi = indHi+1; + 3d30: e3 94 inc r14 + 3d32: e2 82 std Z+2, r14 ; 0x02 + fd->wpis->rozmiarLo = 0; + 3d34: ec 81 ldd r30, Y+4 ; 0x04 + 3d36: fd 81 ldd r31, Y+5 ; 0x05 + 3d38: 11 82 std Z+1, r1 ; 0x01 + } + wynik=dataPtr(tmpKlaster, 128); + 3d3a: 32 2f mov r19, r18 + 3d3c: 22 27 eor r18, r18 + 3d3e: 20 58 subi r18, 0x80 ; 128 + 3d40: 3f 47 sbci r19, 0x7F ; 127 + 3d42: c9 01 movw r24, r18 + 3d44: 11 c0 rjmp .+34 ; 0x3d68 + } + else + { + if (fd->wpis->rozmiarHi < indHi) + 3d46: 92 81 ldd r25, Z+2 ; 0x02 + 3d48: 91 17 cp r25, r17 + 3d4a: 20 f4 brcc .+8 ; 0x3d54 + { + fd->wpis->rozmiarHi = indHi; + 3d4c: e2 82 std Z+2, r14 ; 0x02 + fd->wpis->rozmiarLo = 128; + 3d4e: ec 81 ldd r30, Y+4 ; 0x04 + 3d50: fd 81 ldd r31, Y+5 ; 0x05 + 3d52: 05 c0 rjmp .+10 ; 0x3d5e + } + else if ((fd->wpis->rozmiarHi == indHi) && (fd->wpis->rozmiarLo < 128)) + 3d54: 91 13 cpse r25, r17 + 3d56: 05 c0 rjmp .+10 ; 0x3d62 + 3d58: 81 81 ldd r24, Z+1 ; 0x01 + 3d5a: 87 fd sbrc r24, 7 + 3d5c: 02 c0 rjmp .+4 ; 0x3d62 + fd->wpis->rozmiarLo = 128; + 3d5e: 80 e8 ldi r24, 0x80 ; 128 + 3d60: 81 83 std Z+1, r24 ; 0x01 + + wynik=dataPtr(tmpKlaster, 0); + 3d62: 80 e0 ldi r24, 0x00 ; 0 + 3d64: 90 e8 ldi r25, 0x80 ; 128 + 3d66: 92 0f add r25, r18 + } + return wynik; +} + 3d68: df 91 pop r29 + 3d6a: cf 91 pop r28 + 3d6c: 1f 91 pop r17 + 3d6e: ff 90 pop r15 + 3d70: ef 90 pop r14 + 3d72: df 90 pop r13 + 3d74: cf 90 pop r12 + 3d76: bf 90 pop r11 + 3d78: af 90 pop r10 + 3d7a: 08 95 ret + +00003d7c : + +void ramDyskDir(FILE *ostream) +{ + 3d7c: 5f 92 push r5 + 3d7e: 6f 92 push r6 + 3d80: 7f 92 push r7 + 3d82: 8f 92 push r8 + 3d84: 9f 92 push r9 + 3d86: af 92 push r10 + 3d88: bf 92 push r11 + 3d8a: cf 92 push r12 + 3d8c: df 92 push r13 + 3d8e: ef 92 push r14 + 3d90: ff 92 push r15 + 3d92: 0f 93 push r16 + 3d94: 1f 93 push r17 + 3d96: cf 93 push r28 + 3d98: df 93 push r29 + 3d9a: b8 2e mov r11, r24 + 3d9c: a9 2e mov r10, r25 + fprintf(ostream, "nazwa\t\trozmiar\totwarty\r\n"); + 3d9e: 68 2f mov r22, r24 + 3da0: 79 2f mov r23, r25 + 3da2: 8b e0 ldi r24, 0x0B ; 11 + 3da4: 91 e0 ldi r25, 0x01 ; 1 + 3da6: 0e 94 6f 50 call 0xa0de ; 0xa0de + struct ramPlik *plik; + uint8_t tmpKlaster = 0; + 3daa: 71 2c mov r7, r1 + if (tmp3 != 0) + fputc(tmp3 , ostream); + else + fputc(' ' , ostream); + } + fprintf(ostream, "\t%d\t%d\r\n", 256*plik->rozmiarHi+plik->rozmiarLo, plik->lAktOtw); + 3dac: 34 e2 ldi r19, 0x24 ; 36 + 3dae: c3 2e mov r12, r19 + 3db0: 31 e0 ldi r19, 0x01 ; 1 + 3db2: d3 2e mov r13, r19 + uint8_t tmpKlaster = 0; + uint8_t tmpKlaster2; + uint8_t tmp, tmp2, tmp3; + do + { + plik = (struct ramPlik *)(dataPtr(tmpKlaster, 0)); + 3db4: e7 2c mov r14, r7 + 3db6: f1 2c mov r15, r1 + 3db8: 87 01 movw r16, r14 + 3dba: 00 58 subi r16, 0x80 ; 128 + 3dbc: 1f 4f sbci r17, 0xFF ; 255 + 3dbe: 10 2f mov r17, r16 + 3dc0: 00 27 eor r16, r16 + 3dc2: e8 01 movw r28, r16 + 3dc4: 25 96 adiw r28, 0x05 ; 5 + 3dc6: 0b 5f subi r16, 0xFB ; 251 + 3dc8: 1e 4f sbci r17, 0xFE ; 254 + 3dca: fe 01 movw r30, r28 + 3dcc: 31 97 sbiw r30, 0x01 ; 1 + for (tmp=0; tmp<16; tmp++) + { + tmp3=plik->nazwa[0]; + 3dce: 60 80 ld r6, Z + if (tmp3 == 0) + 3dd0: 61 10 cpse r6, r1 + 3dd2: 09 c0 rjmp .+18 ; 0x3de6 + } + fprintf(ostream, "\t%d\t%d\r\n", 256*plik->rozmiarHi+plik->rozmiarLo, plik->lAktOtw); + plik++; + } + tmpKlaster2 = tmpKlaster; + tmpKlaster = klastry[tmpKlaster]; + 3dd4: f7 01 movw r30, r14 + 3dd6: e7 53 subi r30, 0x37 ; 55 + 3dd8: f1 4f sbci r31, 0xF1 ; 241 + 3dda: 80 81 ld r24, Z + } + while (tmpKlaster != tmpKlaster2); + 3ddc: 87 15 cp r24, r7 + 3dde: 09 f4 brne .+2 ; 0x3de2 + 3de0: 47 c0 rjmp .+142 ; 0x3e70 + 3de2: 78 2e mov r7, r24 + 3de4: e7 cf rjmp .-50 ; 0x3db4 + for (tmp=0; tmp<16; tmp++) + { + tmp3=plik->nazwa[0]; + if (tmp3 == 0) + break; //Ten wpis jest pusty. + fputc(tmp3 , ostream); + 3de6: 6b 2d mov r22, r11 + 3de8: 7a 2d mov r23, r10 + 3dea: 86 2d mov r24, r6 + 3dec: 90 e0 ldi r25, 0x00 ; 0 + 3dee: 0e 94 37 50 call 0xa06e ; 0xa06e + 3df2: 4e 01 movw r8, r28 + 3df4: 97 e0 ldi r25, 0x07 ; 7 + 3df6: 59 2e mov r5, r25 + { + if (tmp3 != 0) + tmp3=plik->nazwa[tmp2]; + + if (tmp3 != 0) + fputc(tmp3 , ostream); + 3df8: 6b 2d mov r22, r11 + 3dfa: 7a 2d mov r23, r10 + if (tmp3 == 0) + break; //Ten wpis jest pusty. + fputc(tmp3 , ostream); + for (tmp2=1; tmp2<8; tmp2++) + { + if (tmp3 != 0) + 3dfc: 66 20 and r6, r6 + 3dfe: 49 f0 breq .+18 ; 0x3e12 + tmp3=plik->nazwa[tmp2]; + 3e00: f4 01 movw r30, r8 + 3e02: 60 80 ld r6, Z + + if (tmp3 != 0) + 3e04: 66 20 and r6, r6 + 3e06: 29 f0 breq .+10 ; 0x3e12 + fputc(tmp3 , ostream); + 3e08: 86 2d mov r24, r6 + 3e0a: 90 e0 ldi r25, 0x00 ; 0 + 3e0c: 0e 94 37 50 call 0xa06e ; 0xa06e + 3e10: 05 c0 rjmp .+10 ; 0x3e1c + else + fputc(' ' , ostream); + 3e12: 80 e2 ldi r24, 0x20 ; 32 + 3e14: 90 e0 ldi r25, 0x00 ; 0 + 3e16: 0e 94 37 50 call 0xa06e ; 0xa06e + 3e1a: 61 2c mov r6, r1 + 3e1c: 5a 94 dec r5 + 3e1e: ff ef ldi r31, 0xFF ; 255 + 3e20: 8f 1a sub r8, r31 + 3e22: 9f 0a sbc r9, r31 + { + tmp3=plik->nazwa[0]; + if (tmp3 == 0) + break; //Ten wpis jest pusty. + fputc(tmp3 , ostream); + for (tmp2=1; tmp2<8; tmp2++) + 3e24: 51 10 cpse r5, r1 + 3e26: e8 cf rjmp .-48 ; 0x3df8 + 3e28: fe 01 movw r30, r28 + 3e2a: 32 97 sbiw r30, 0x02 ; 2 + if (tmp3 != 0) + fputc(tmp3 , ostream); + else + fputc(' ' , ostream); + } + fprintf(ostream, "\t%d\t%d\r\n", 256*plik->rozmiarHi+plik->rozmiarLo, plik->lAktOtw); + 3e2c: 80 81 ld r24, Z + 3e2e: 1f 92 push r1 + 3e30: 8f 93 push r24 + 3e32: 31 97 sbiw r30, 0x01 ; 1 + 3e34: 20 81 ld r18, Z + 3e36: 30 e0 ldi r19, 0x00 ; 0 + 3e38: 32 2f mov r19, r18 + 3e3a: 22 27 eor r18, r18 + 3e3c: 31 97 sbiw r30, 0x01 ; 1 + 3e3e: 80 81 ld r24, Z + 3e40: 28 0f add r18, r24 + 3e42: 31 1d adc r19, r1 + 3e44: 3f 93 push r19 + 3e46: 2f 93 push r18 + 3e48: df 92 push r13 + 3e4a: cf 92 push r12 + 3e4c: af 92 push r10 + 3e4e: bf 92 push r11 + 3e50: 0e 94 0a 50 call 0xa014 ; 0xa014 + 3e54: 60 96 adiw r28, 0x10 ; 16 + uint8_t tmpKlaster2; + uint8_t tmp, tmp2, tmp3; + do + { + plik = (struct ramPlik *)(dataPtr(tmpKlaster, 0)); + for (tmp=0; tmp<16; tmp++) + 3e56: 8d b7 in r24, 0x3d ; 61 + 3e58: 9e b7 in r25, 0x3e ; 62 + 3e5a: 08 96 adiw r24, 0x08 ; 8 + 3e5c: 0f b6 in r0, 0x3f ; 63 + 3e5e: f8 94 cli + 3e60: 9e bf out 0x3e, r25 ; 62 + 3e62: 0f be out 0x3f, r0 ; 63 + 3e64: 8d bf out 0x3d, r24 ; 61 + 3e66: c0 17 cp r28, r16 + 3e68: d1 07 cpc r29, r17 + 3e6a: 09 f0 breq .+2 ; 0x3e6e + 3e6c: ae cf rjmp .-164 ; 0x3dca + 3e6e: b2 cf rjmp .-156 ; 0x3dd4 + } + tmpKlaster2 = tmpKlaster; + tmpKlaster = klastry[tmpKlaster]; + } + while (tmpKlaster != tmpKlaster2); +} + 3e70: df 91 pop r29 + 3e72: cf 91 pop r28 + 3e74: 1f 91 pop r17 + 3e76: 0f 91 pop r16 + 3e78: ff 90 pop r15 + 3e7a: ef 90 pop r14 + 3e7c: df 90 pop r13 + 3e7e: cf 90 pop r12 + 3e80: bf 90 pop r11 + 3e82: af 90 pop r10 + 3e84: 9f 90 pop r9 + 3e86: 8f 90 pop r8 + 3e88: 7f 90 pop r7 + 3e8a: 6f 90 pop r6 + 3e8c: 5f 90 pop r5 + 3e8e: 08 95 ret + +00003e90 : + +uint8_t ramDyskLiczbaWolnychKlastrow(void) +{ + 3e90: 29 e4 ldi r18, 0x49 ; 73 + 3e92: 3f e0 ldi r19, 0x0F ; 15 + 3e94: f9 01 movw r30, r18 + uint8_t wynik=0; + 3e96: 80 e0 ldi r24, 0x00 ; 0 + uint8_t temp; + for (temp = L_KLASTROW-1; temp > 0; temp--) + if (klastry[temp] == 0) + 3e98: 92 91 ld r25, -Z + 3e9a: 91 11 cpse r25, r1 + 3e9c: 01 c0 rjmp .+2 ; 0x3ea0 + wynik++; + 3e9e: 8f 5f subi r24, 0xFF ; 255 + 3ea0: 9f e7 ldi r25, 0x7F ; 127 + 3ea2: 9e 0f add r25, r30 + +uint8_t ramDyskLiczbaWolnychKlastrow(void) +{ + uint8_t wynik=0; + uint8_t temp; + for (temp = L_KLASTROW-1; temp > 0; temp--) + 3ea4: 92 13 cpse r25, r18 + 3ea6: f8 cf rjmp .-16 ; 0x3e98 + if (klastry[temp] == 0) + wynik++; + return wynik; +} + 3ea8: 08 95 ret + +00003eaa : + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + return ramDyskZapiszBajtDoPliku(fd, c); +} + +uint8_t ramDyskOtworzPlikStdIo(const char *nazwa, struct ramPlikFd *fd, FILE *stream, uint8_t flags) +{ + 3eaa: ef 92 push r14 + 3eac: ff 92 push r15 + 3eae: 0f 93 push r16 + 3eb0: 1f 93 push r17 + 3eb2: cf 93 push r28 + 3eb4: df 93 push r29 + 3eb6: 1f 92 push r1 + 3eb8: cd b7 in r28, 0x3d ; 61 + 3eba: de b7 in r29, 0x3e ; 62 + 3ebc: 8b 01 movw r16, r22 + 3ebe: 7a 01 movw r14, r20 + uint8_t wynik = ramDyskOtworzPlik(nazwa, fd); + 3ec0: 29 83 std Y+1, r18 ; 0x01 + 3ec2: 0e 94 bd 1b call 0x377a ; 0x377a + if (wynik != 0) + 3ec6: 29 81 ldd r18, Y+1 ; 0x01 + 3ec8: 81 11 cpse r24, r1 + 3eca: 0c c0 rjmp .+24 ; 0x3ee4 + return wynik; + + fdev_setup_stream(stream, putSTD, getSTD, flags); + 3ecc: 4c e6 ldi r20, 0x6C ; 108 + 3ece: 5c e1 ldi r21, 0x1C ; 28 + 3ed0: f7 01 movw r30, r14 + 3ed2: 51 87 std Z+9, r21 ; 0x09 + 3ed4: 40 87 std Z+8, r20 ; 0x08 + 3ed6: 4d ea ldi r20, 0xAD ; 173 + 3ed8: 5c e1 ldi r21, 0x1C ; 28 + 3eda: 53 87 std Z+11, r21 ; 0x0b + 3edc: 42 87 std Z+10, r20 ; 0x0a + 3ede: 23 83 std Z+3, r18 ; 0x03 + fdev_set_udata(stream, fd); + 3ee0: 15 87 std Z+13, r17 ; 0x0d + 3ee2: 04 87 std Z+12, r16 ; 0x0c + return 0; +} + 3ee4: 0f 90 pop r0 + 3ee6: df 91 pop r29 + 3ee8: cf 91 pop r28 + 3eea: 1f 91 pop r17 + 3eec: 0f 91 pop r16 + 3eee: ff 90 pop r15 + 3ef0: ef 90 pop r14 + 3ef2: 08 95 ret + +00003ef4 : + +uint8_t ramDyskZamknijPlikStdIo(FILE *stream) +{ + 3ef4: 0f 93 push r16 + 3ef6: 1f 93 push r17 + 3ef8: cf 93 push r28 + 3efa: df 93 push r29 + 3efc: 8c 01 movw r16, r24 + struct ramPlikFd *fd = (struct ramPlikFd *)(fdev_get_udata(stream)); + 3efe: fc 01 movw r30, r24 + 3f00: c4 85 ldd r28, Z+12 ; 0x0c + 3f02: d5 85 ldd r29, Z+13 ; 0x0d + ramDyskZamknijPlik(fd); + 3f04: ce 01 movw r24, r28 + 3f06: 0e 94 f4 1b call 0x37e8 ; 0x37e8 + fclose(stream); + 3f0a: c8 01 movw r24, r16 + 3f0c: 0e 94 b5 4f call 0x9f6a ; 0x9f6a + return fd->wpis->lAktOtw; + 3f10: ec 81 ldd r30, Y+4 ; 0x04 + 3f12: fd 81 ldd r31, Y+5 ; 0x05 +} + 3f14: 83 81 ldd r24, Z+3 ; 0x03 + 3f16: df 91 pop r29 + 3f18: cf 91 pop r28 + 3f1a: 1f 91 pop r17 + 3f1c: 0f 91 pop r16 + 3f1e: 08 95 ret + +00003f20 : + cmdlinePrintPrompt(state); // output new prompt + } +} + +void cmdlinePrintPrompt(cmdState_t *state) +{ + 3f20: 0f 93 push r16 + 3f22: 1f 93 push r17 + 3f24: cf 93 push r28 + 3f26: df 93 push r29 + 3f28: 8c 01 movw r16, r24 + const char* ptr; + // print a new command prompt + switch (state->cliMode) + 3f2a: fc 01 movw r30, r24 + 3f2c: 80 a1 ldd r24, Z+32 ; 0x20 + 3f2e: 81 30 cpi r24, 0x01 ; 1 + 3f30: 29 f0 breq .+10 ; 0x3f3c + 3f32: 82 30 cpi r24, 0x02 ; 2 + 3f34: 31 f0 breq .+12 ; 0x3f42 + { + case NR_NORMAL: + ptr = CmdlinePromptNormal; + 3f36: c3 e0 ldi r28, 0x03 ; 3 + 3f38: dc e0 ldi r29, 0x0C ; 12 + 3f3a: 05 c0 rjmp .+10 ; 0x3f46 + break; + case NR_ENABLE: + ptr = CmdlinePromptEnable; + 3f3c: cc ef ldi r28, 0xFC ; 252 + 3f3e: db e0 ldi r29, 0x0B ; 11 + 3f40: 02 c0 rjmp .+4 ; 0x3f46 + break; + case NR_CONFIGURE: + ptr = CmdlinePromptConfigure; + 3f42: c5 ef ldi r28, 0xF5 ; 245 + 3f44: db e0 ldi r29, 0x0B ; 11 + break; + default: + ptr = CmdlinePromptNormal; + break; + } + while(pgm_read_byte(ptr)) + 3f46: 9e 01 movw r18, r28 + 3f48: fe 01 movw r30, r28 + 3f4a: 84 91 lpm r24, Z + 3f4c: 88 23 and r24, r24 + 3f4e: 51 f0 breq .+20 ; 0x3f64 + fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 3f50: 21 96 adiw r28, 0x01 ; 1 + 3f52: f9 01 movw r30, r18 + 3f54: 84 91 lpm r24, Z + 3f56: f8 01 movw r30, r16 + 3f58: 62 8d ldd r22, Z+26 ; 0x1a + 3f5a: 73 8d ldd r23, Z+27 ; 0x1b + 3f5c: 90 e0 ldi r25, 0x00 ; 0 + 3f5e: 0e 94 37 50 call 0xa06e ; 0xa06e + 3f62: f1 cf rjmp .-30 ; 0x3f46 +} + 3f64: df 91 pop r29 + 3f66: cf 91 pop r28 + 3f68: 1f 91 pop r17 + 3f6a: 0f 91 pop r16 + 3f6c: 08 95 ret + +00003f6e : + state->CmdlineInputVT100State = 1; + } +} + +void cmdlineRepaint(cmdState_t *state, char *buf) +{ + 3f6e: ef 92 push r14 + 3f70: ff 92 push r15 + 3f72: 0f 93 push r16 + 3f74: 1f 93 push r17 + 3f76: cf 93 push r28 + 3f78: df 93 push r29 + 3f7a: ec 01 movw r28, r24 + 3f7c: f6 2e mov r15, r22 + 3f7e: e7 2e mov r14, r23 + uint8_t i; + + // carriage return + fputc(ASCII_CR , state->myStdInOut); + 3f80: 6a 8d ldd r22, Y+26 ; 0x1a + 3f82: 7b 8d ldd r23, Y+27 ; 0x1b + 3f84: 8d e0 ldi r24, 0x0D ; 13 + 3f86: 90 e0 ldi r25, 0x00 ; 0 + 3f88: 0e 94 37 50 call 0xa06e ; 0xa06e + // print fresh prompt + cmdlinePrintPrompt(state); + 3f8c: ce 01 movw r24, r28 + 3f8e: 0e 94 90 1f call 0x3f20 ; 0x3f20 + // print the new command line buffer + i = state->CmdlineBufferLength; + 3f92: 8d 85 ldd r24, Y+13 ; 0x0d + while(i--) + 3f94: 0f 2d mov r16, r15 + 3f96: 1e 2d mov r17, r14 + 3f98: f8 0e add r15, r24 + 3f9a: f0 16 cp r15, r16 + 3f9c: 59 f0 breq .+22 ; 0x3fb4 + fputc(*buf++ , state->myStdInOut); + 3f9e: f8 01 movw r30, r16 + 3fa0: 81 91 ld r24, Z+ + 3fa2: 8f 01 movw r16, r30 + 3fa4: 6a 8d ldd r22, Y+26 ; 0x1a + 3fa6: 7b 8d ldd r23, Y+27 ; 0x1b + 3fa8: 08 2e mov r0, r24 + 3faa: 00 0c add r0, r0 + 3fac: 99 0b sbc r25, r25 + 3fae: 0e 94 37 50 call 0xa06e ; 0xa06e + 3fb2: f3 cf rjmp .-26 ; 0x3f9a + i = state->bufferMaxSize - state->CmdlineBufferLength; + 3fb4: 1c 85 ldd r17, Y+12 ; 0x0c + 3fb6: 8d 85 ldd r24, Y+13 ; 0x0d + 3fb8: 18 1b sub r17, r24 + while (i--) + 3fba: 11 23 and r17, r17 + 3fbc: 41 f0 breq .+16 ; 0x3fce + fputc(' ', state->myStdInOut); + 3fbe: 6a 8d ldd r22, Y+26 ; 0x1a + 3fc0: 7b 8d ldd r23, Y+27 ; 0x1b + 3fc2: 80 e2 ldi r24, 0x20 ; 32 + 3fc4: 90 e0 ldi r25, 0x00 ; 0 + 3fc6: 0e 94 37 50 call 0xa06e ; 0xa06e + 3fca: 11 50 subi r17, 0x01 ; 1 + 3fcc: f6 cf rjmp .-20 ; 0x3fba + i = state->bufferMaxSize - state->CmdlineBufferLength; + 3fce: 1c 85 ldd r17, Y+12 ; 0x0c + 3fd0: 8d 85 ldd r24, Y+13 ; 0x0d + 3fd2: 18 1b sub r17, r24 + while (i--) + 3fd4: 11 23 and r17, r17 + 3fd6: 41 f0 breq .+16 ; 0x3fe8 + fputc(ASCII_BS, state->myStdInOut); + 3fd8: 6a 8d ldd r22, Y+26 ; 0x1a + 3fda: 7b 8d ldd r23, Y+27 ; 0x1b + 3fdc: 88 e0 ldi r24, 0x08 ; 8 + 3fde: 90 e0 ldi r25, 0x00 ; 0 + 3fe0: 0e 94 37 50 call 0xa06e ; 0xa06e + 3fe4: 11 50 subi r17, 0x01 ; 1 + 3fe6: f6 cf rjmp .-20 ; 0x3fd4 +} + 3fe8: df 91 pop r29 + 3fea: cf 91 pop r28 + 3fec: 1f 91 pop r17 + 3fee: 0f 91 pop r16 + 3ff0: ff 90 pop r15 + 3ff2: ef 90 pop r14 + 3ff4: 08 95 ret + +00003ff6 : + +void cmdHistoryCopy(cmdState_t *state) +{ + 3ff6: 1f 93 push r17 + 3ff8: cf 93 push r28 + 3ffa: df 93 push r29 + 3ffc: ec 01 movw r28, r24 + if (state->historyDepthIdx != 0) + 3ffe: 88 89 ldd r24, Y+16 ; 0x10 + 4000: 88 23 and r24, r24 + 4002: b1 f0 breq .+44 ; 0x4030 + { + uint8_t historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + 4004: 1f 85 ldd r17, Y+15 ; 0x0f + 4006: 18 1b sub r17, r24 + 4008: 13 70 andi r17, 0x03 ; 3 + memset(state->CmdlineBuffer, 0, state->bufferMaxSize); + 400a: 4c 85 ldd r20, Y+12 ; 0x0c + 400c: 50 e0 ldi r21, 0x00 ; 0 + 400e: 60 e0 ldi r22, 0x00 ; 0 + 4010: 70 e0 ldi r23, 0x00 ; 0 + 4012: 88 81 ld r24, Y + 4014: 99 81 ldd r25, Y+1 ; 0x01 + 4016: 0e 94 7f 4f call 0x9efe ; 0x9efe + strcpy(state->CmdlineBuffer, state->CmdlineHistory[historyReadIdx]); + 401a: fe 01 movw r30, r28 + 401c: e1 0f add r30, r17 + 401e: f1 1d adc r31, r1 + 4020: e1 0f add r30, r17 + 4022: f1 1d adc r31, r1 + 4024: 64 81 ldd r22, Z+4 ; 0x04 + 4026: 75 81 ldd r23, Z+5 ; 0x05 + 4028: 88 81 ld r24, Y + 402a: 99 81 ldd r25, Y+1 ; 0x01 + 402c: 0e 94 91 4f call 0x9f22 ; 0x9f22 + } + + state->historyDepthIdx = 0; + 4030: 18 8a std Y+16, r1 ; 0x10 + state->bufferHistoryState = COPIED; + 4032: 81 e0 ldi r24, 0x01 ; 1 + 4034: 89 8b std Y+17, r24 ; 0x11 +} + 4036: df 91 pop r29 + 4038: cf 91 pop r28 + 403a: 1f 91 pop r17 + 403c: 08 95 ret + +0000403e : +static void cmdHistoryCopy (cmdState_t *state); +static void cmdHistoryMove (cmdState_t *state); + + +void cmdStateConfigure(cmdState_t * state, char *buffPtr, uint16_t bufferTotalSize, FILE *stream, const command_t *commands, enum cliModeState mode) +{ + 403e: 8f 92 push r8 + 4040: 9f 92 push r9 + 4042: af 92 push r10 + 4044: bf 92 push r11 + 4046: cf 92 push r12 + 4048: df 92 push r13 + 404a: ef 92 push r14 + 404c: 0f 93 push r16 + 404e: 1f 93 push r17 + 4050: cf 93 push r28 + 4052: df 93 push r29 + 4054: ec 01 movw r28, r24 + 4056: 5b 01 movw r10, r22 + 4058: 6a 01 movw r12, r20 + 405a: 49 01 movw r8, r18 + memset(state, 0, sizeof(cmdState_t)); + 405c: 83 e2 ldi r24, 0x23 ; 35 + 405e: fe 01 movw r30, r28 + 4060: 11 92 st Z+, r1 + 4062: 8a 95 dec r24 + 4064: e9 f7 brne .-6 ; 0x4060 + memset(buffPtr, 0, bufferTotalSize); + 4066: 60 e0 ldi r22, 0x00 ; 0 + 4068: 70 e0 ldi r23, 0x00 ; 0 + 406a: c5 01 movw r24, r10 + 406c: 0e 94 7f 4f call 0x9efe ; 0x9efe + + state->CmdlineBuffer = buffPtr; + 4070: b9 82 std Y+1, r11 ; 0x01 + 4072: a8 82 st Y, r10 + state->bufferMaxSize = (uint8_t)(bufferTotalSize / CMD_STATE_HISTORY); + 4074: d6 94 lsr r13 + 4076: c7 94 ror r12 + 4078: d6 94 lsr r13 + 407a: c7 94 ror r12 + 407c: cc 86 std Y+12, r12 ; 0x0c + + state->cliMode = mode; + 407e: e8 a2 std Y+32, r14 ; 0x20 + state->cmdList = commands; + 4080: 1a a3 std Y+34, r17 ; 0x22 + 4082: 09 a3 std Y+33, r16 ; 0x21 + 4084: fe 01 movw r30, r28 + 4086: 34 96 adiw r30, 0x04 ; 4 + 4088: ce 01 movw r24, r28 + 408a: 0c 96 adiw r24, 0x0c ; 12 + uint8_t i; + char *tmpPtr = buffPtr; + for (i=0; i < CMD_STATE_HISTORY; i++) + { + state->CmdlineHistory[i] = tmpPtr; + tmpPtr += state->bufferMaxSize; + 408c: dd 24 eor r13, r13 + + uint8_t i; + char *tmpPtr = buffPtr; + for (i=0; i < CMD_STATE_HISTORY; i++) + { + state->CmdlineHistory[i] = tmpPtr; + 408e: a1 92 st Z+, r10 + 4090: b1 92 st Z+, r11 + tmpPtr += state->bufferMaxSize; + 4092: ac 0c add r10, r12 + 4094: bd 1c adc r11, r13 + state->cliMode = mode; + state->cmdList = commands; + + uint8_t i; + char *tmpPtr = buffPtr; + for (i=0; i < CMD_STATE_HISTORY; i++) + 4096: e8 17 cp r30, r24 + 4098: f9 07 cpc r31, r25 + 409a: c9 f7 brne .-14 ; 0x408e + { + state->CmdlineHistory[i] = tmpPtr; + tmpPtr += state->bufferMaxSize; + } + state->myStdInOut = stream; + 409c: 9b 8e std Y+27, r9 ; 0x1b + 409e: 8a 8e std Y+26, r8 ; 0x1a +} + 40a0: df 91 pop r29 + 40a2: cf 91 pop r28 + 40a4: 1f 91 pop r17 + 40a6: 0f 91 pop r16 + 40a8: ef 90 pop r14 + 40aa: df 90 pop r13 + 40ac: cf 90 pop r12 + 40ae: bf 90 pop r11 + 40b0: af 90 pop r10 + 40b2: 9f 90 pop r9 + 40b4: 8f 90 pop r8 + 40b6: 08 95 ret + +000040b8 : + // initialize executing function + state->CmdlineExecFunction = 0; +}*/ + +void cmdlineInputFunc(char c, cmdState_t *state) +{ + 40b8: af 92 push r10 + 40ba: bf 92 push r11 + 40bc: cf 92 push r12 + 40be: df 92 push r13 + 40c0: ef 92 push r14 + 40c2: ff 92 push r15 + 40c4: 0f 93 push r16 + 40c6: 1f 93 push r17 + 40c8: cf 93 push r28 + 40ca: df 93 push r29 + 40cc: cd b7 in r28, 0x3d ; 61 + 40ce: de b7 in r29, 0x3e ; 62 + 40d0: 27 97 sbiw r28, 0x07 ; 7 + 40d2: 0f b6 in r0, 0x3f ; 63 + 40d4: f8 94 cli + 40d6: de bf out 0x3e, r29 ; 62 + 40d8: 0f be out 0x3f, r0 ; 63 + 40da: cd bf out 0x3d, r28 ; 61 + 40dc: 28 2f mov r18, r24 + 40de: 8b 01 movw r16, r22 + uint8_t i; + // process the received character + + // VT100 handling + // are we processing a VT100 command? + if(state->CmdlineInputVT100State == 2) + 40e0: db 01 movw r26, r22 + 40e2: 52 96 adiw r26, 0x12 ; 18 + 40e4: 8c 91 ld r24, X + 40e6: 82 30 cpi r24, 0x02 ; 2 + 40e8: 09 f0 breq .+2 ; 0x40ec + 40ea: 92 c0 rjmp .+292 ; 0x4210 + { + // we have already received ESC and [ + // now process the vt100 codeCmdlineExcBuffer + switch(c) + 40ec: 22 34 cpi r18, 0x42 ; 66 + 40ee: 21 f1 breq .+72 ; 0x4138 + 40f0: 1c f4 brge .+6 ; 0x40f8 + 40f2: 21 34 cpi r18, 0x41 ; 65 + 40f4: 41 f0 breq .+16 ; 0x4106 + 40f6: 89 c0 rjmp .+274 ; 0x420a + 40f8: 23 34 cpi r18, 0x43 ; 67 + 40fa: 09 f4 brne .+2 ; 0x40fe + 40fc: 41 c0 rjmp .+130 ; 0x4180 + 40fe: 24 34 cpi r18, 0x44 ; 68 + 4100: 09 f4 brne .+2 ; 0x4104 + 4102: 68 c0 rjmp .+208 ; 0x41d4 + 4104: 82 c0 rjmp .+260 ; 0x420a + + state->CmdlineBuffer = state->CmdlineHistory[state->historyWrIdx]; + } + break; + case CMDLINE_HISTORY_PREV: + if (state->historyDepthIdx == CMD_STATE_HISTORY - 1) + 4106: fb 01 movw r30, r22 + 4108: 90 89 ldd r25, Z+16 ; 0x10 + 410a: 93 30 cpi r25, 0x03 ; 3 + 410c: 09 f4 brne .+2 ; 0x4110 + 410e: 7d c0 rjmp .+250 ; 0x420a + 4110: 87 85 ldd r24, Z+15 ; 0x0f + 4112: 81 50 subi r24, 0x01 ; 1 + break; //We are on the end of the history list + + historyReadIdx = (state->historyWrIdx - state->historyDepthIdx - 1) & CMD_STATE_HISTORY_MASK; + 4114: 89 1b sub r24, r25 + 4116: 83 70 andi r24, 0x03 ; 3 + + if (state->CmdlineHistory[historyReadIdx][0] == 0) + 4118: e8 0f add r30, r24 + 411a: f1 1d adc r31, r1 + 411c: e8 0f add r30, r24 + 411e: f1 1d adc r31, r1 + 4120: 64 81 ldd r22, Z+4 ; 0x04 + 4122: 75 81 ldd r23, Z+5 ; 0x05 + 4124: db 01 movw r26, r22 + 4126: 8c 91 ld r24, X + 4128: 88 23 and r24, r24 + 412a: 09 f4 brne .+2 ; 0x412e + 412c: 6e c0 rjmp .+220 ; 0x420a + break; + + state->historyDepthIdx++; + 412e: 9f 5f subi r25, 0xFF ; 255 + state->historyDepthIdx &= CMD_STATE_HISTORY_MASK; + 4130: 93 70 andi r25, 0x03 ; 3 + 4132: f8 01 movw r30, r16 + 4134: 90 8b std Z+16, r25 ; 0x10 + 4136: 10 c0 rjmp .+32 ; 0x4158 + // "re-paint" line + cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + + break; + case CMDLINE_HISTORY_NEXT: + if (state->historyDepthIdx == 0) + 4138: fb 01 movw r30, r22 + 413a: 90 89 ldd r25, Z+16 ; 0x10 + 413c: 99 23 and r25, r25 + 413e: 09 f4 brne .+2 ; 0x4142 + 4140: 64 c0 rjmp .+200 ; 0x420a + break; //We are on the begining of the history list + + state->historyDepthIdx --; + 4142: 91 50 subi r25, 0x01 ; 1 + 4144: 90 8b std Z+16, r25 ; 0x10 + historyReadIdx = (state->historyWrIdx - state->historyDepthIdx) & CMD_STATE_HISTORY_MASK; + 4146: 87 85 ldd r24, Z+15 ; 0x0f + 4148: 89 1b sub r24, r25 + 414a: 83 70 andi r24, 0x03 ; 3 + + // set the buffer position to the end of the line + state->CmdlineBufferLength = strlen(state->CmdlineHistory[historyReadIdx]); + 414c: e8 0f add r30, r24 + 414e: f1 1d adc r31, r1 + 4150: e8 0f add r30, r24 + 4152: f1 1d adc r31, r1 + 4154: 64 81 ldd r22, Z+4 ; 0x04 + 4156: 75 81 ldd r23, Z+5 ; 0x05 + 4158: fb 01 movw r30, r22 + 415a: 01 90 ld r0, Z+ + 415c: 00 20 and r0, r0 + 415e: e9 f7 brne .-6 ; 0x415a + 4160: 31 97 sbiw r30, 0x01 ; 1 + 4162: e6 1b sub r30, r22 + 4164: f7 0b sbc r31, r23 + 4166: d8 01 movw r26, r16 + 4168: 1d 96 adiw r26, 0x0d ; 13 + 416a: ec 93 st X, r30 + 416c: 1d 97 sbiw r26, 0x0d ; 13 + state->CmdlineBufferEditPos = state->CmdlineBufferLength; + 416e: 1e 96 adiw r26, 0x0e ; 14 + 4170: ec 93 st X, r30 + 4172: 1e 97 sbiw r26, 0x0e ; 14 + + state->bufferHistoryState = NOT_COPIED; + 4174: 51 96 adiw r26, 0x11 ; 17 + 4176: 1c 92 st X, r1 + + // "re-paint" line + cmdlineRepaint(state, state->CmdlineHistory[historyReadIdx]); + 4178: c8 01 movw r24, r16 + 417a: 0e 94 b7 1f call 0x3f6e ; 0x3f6e + 417e: 45 c0 rjmp .+138 ; 0x420a + break; + case VT100_ARROWDOWN: + cmdlineDoHistory(CMDLINE_HISTORY_NEXT, state); + break; + case VT100_ARROWRIGHT: + if (state->bufferHistoryState == NOT_COPIED) + 4180: fb 01 movw r30, r22 + 4182: 81 89 ldd r24, Z+17 ; 0x11 + 4184: 81 11 cpse r24, r1 + 4186: 03 c0 rjmp .+6 ; 0x418e + cmdHistoryCopy(state); + 4188: cb 01 movw r24, r22 + 418a: 0e 94 fb 1f call 0x3ff6 ; 0x3ff6 + // if the edit position less than current string length + if(state->CmdlineBufferEditPos < state->CmdlineBufferLength) + 418e: d8 01 movw r26, r16 + 4190: 1e 96 adiw r26, 0x0e ; 14 + 4192: 8c 91 ld r24, X + 4194: 1e 97 sbiw r26, 0x0e ; 14 + 4196: 1d 96 adiw r26, 0x0d ; 13 + 4198: 9c 91 ld r25, X + 419a: 1d 97 sbiw r26, 0x0d ; 13 + 419c: 5a 96 adiw r26, 0x1a ; 26 + 419e: 6d 91 ld r22, X+ + 41a0: 7c 91 ld r23, X + 41a2: 5b 97 sbiw r26, 0x1b ; 27 + 41a4: 89 17 cp r24, r25 + 41a6: 68 f5 brcc .+90 ; 0x4202 + { + // increment the edit position + state->CmdlineBufferEditPos++; + 41a8: 8f 5f subi r24, 0xFF ; 255 + 41aa: 1e 96 adiw r26, 0x0e ; 14 + 41ac: 8c 93 st X, r24 + // move cursor forward one space (no erase) + fputc(ASCII_ESC , state->myStdInOut); + 41ae: 8b e1 ldi r24, 0x1B ; 27 + 41b0: 90 e0 ldi r25, 0x00 ; 0 + 41b2: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc('[' , state->myStdInOut); + 41b6: f8 01 movw r30, r16 + 41b8: 62 8d ldd r22, Z+26 ; 0x1a + 41ba: 73 8d ldd r23, Z+27 ; 0x1b + 41bc: 8b e5 ldi r24, 0x5B ; 91 + 41be: 90 e0 ldi r25, 0x00 ; 0 + 41c0: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc(VT100_ARROWRIGHT , state->myStdInOut); + 41c4: d8 01 movw r26, r16 + 41c6: 5a 96 adiw r26, 0x1a ; 26 + 41c8: 6d 91 ld r22, X+ + 41ca: 7c 91 ld r23, X + 41cc: 5b 97 sbiw r26, 0x1b ; 27 + 41ce: 83 e4 ldi r24, 0x43 ; 67 + 41d0: 90 e0 ldi r25, 0x00 ; 0 + 41d2: 19 c0 rjmp .+50 ; 0x4206 + fputc(ASCII_BEL , state->myStdInOut); + } + break; + case VT100_ARROWLEFT: + // if the edit position is non-zero + if (state->bufferHistoryState == NOT_COPIED) + 41d4: fb 01 movw r30, r22 + 41d6: 81 89 ldd r24, Z+17 ; 0x11 + 41d8: 81 11 cpse r24, r1 + 41da: 03 c0 rjmp .+6 ; 0x41e2 + cmdHistoryCopy(state); + 41dc: cb 01 movw r24, r22 + 41de: 0e 94 fb 1f call 0x3ff6 ; 0x3ff6 + + if(state->CmdlineBufferEditPos) + 41e2: d8 01 movw r26, r16 + 41e4: 1e 96 adiw r26, 0x0e ; 14 + 41e6: 8c 91 ld r24, X + 41e8: 1e 97 sbiw r26, 0x0e ; 14 + 41ea: 5a 96 adiw r26, 0x1a ; 26 + 41ec: 6d 91 ld r22, X+ + 41ee: 7c 91 ld r23, X + 41f0: 5b 97 sbiw r26, 0x1b ; 27 + 41f2: 88 23 and r24, r24 + 41f4: 31 f0 breq .+12 ; 0x4202 + { + // decrement the edit position + state->CmdlineBufferEditPos--; + 41f6: 81 50 subi r24, 0x01 ; 1 + 41f8: 1e 96 adiw r26, 0x0e ; 14 + 41fa: 8c 93 st X, r24 + // move cursor back one space (no erase) + fputc(ASCII_BS , state->myStdInOut); + 41fc: 88 e0 ldi r24, 0x08 ; 8 + 41fe: 90 e0 ldi r25, 0x00 ; 0 + 4200: 02 c0 rjmp .+4 ; 0x4206 + } + else + { + // else, ring the bell + fputc(ASCII_BEL , state->myStdInOut); + 4202: 87 e0 ldi r24, 0x07 ; 7 + 4204: 90 e0 ldi r25, 0x00 ; 0 + 4206: 0e 94 37 50 call 0xa06e ; 0xa06e + break; + default: + break; + } + // done, reset state + state->CmdlineInputVT100State = 0; + 420a: f8 01 movw r30, r16 + 420c: 12 8a std Z+18, r1 ; 0x12 + return; + 420e: 32 c2 rjmp .+1124 ; 0x4674 + } + else if(state->CmdlineInputVT100State == 1) + 4210: 81 30 cpi r24, 0x01 ; 1 + 4212: 21 f4 brne .+8 ; 0x421c + { + // we last received [ESC] + if(c == '[') + 4214: 2b 35 cpi r18, 0x5B ; 91 + 4216: 11 f4 brne .+4 ; 0x421c + { + state->CmdlineInputVT100State = 2; + 4218: 82 e0 ldi r24, 0x02 ; 2 + 421a: 29 c2 rjmp .+1106 ; 0x466e + return; + } + else + state->CmdlineInputVT100State = 0; + 421c: f8 01 movw r30, r16 + 421e: 12 8a std Z+18, r1 ; 0x12 + state->CmdlineInputVT100State = 0; + } + + // Regular handling + //Protection against buffer Overflow + if (state->CmdlineBufferLength == state->bufferMaxSize) + 4220: 85 85 ldd r24, Z+13 ; 0x0d + 4222: 94 85 ldd r25, Z+12 ; 0x0c + 4224: 89 17 cp r24, r25 + 4226: 29 f0 breq .+10 ; 0x4232 + { + state->CmdlineBuffer[i-1] = state->CmdlineBuffer[i]; + } + } + + if( (c >= 0x20) && (c < 0x7F) ) + 4228: 80 ee ldi r24, 0xE0 ; 224 + 422a: 82 0f add r24, r18 + 422c: 8f 35 cpi r24, 0x5F ; 95 + 422e: 90 f0 brcs .+36 ; 0x4254 + 4230: 75 c0 rjmp .+234 ; 0x431c + + // Regular handling + //Protection against buffer Overflow + if (state->CmdlineBufferLength == state->bufferMaxSize) + { + state->CmdlineBufferLength--; + 4232: 81 50 subi r24, 0x01 ; 1 + 4234: 85 87 std Z+13, r24 ; 0x0d + for (i=1; i < state->bufferMaxSize; i++) + 4236: 81 e0 ldi r24, 0x01 ; 1 + 4238: f8 01 movw r30, r16 + 423a: 94 85 ldd r25, Z+12 ; 0x0c + 423c: 89 17 cp r24, r25 + 423e: a0 f7 brcc .-24 ; 0x4228 + { + state->CmdlineBuffer[i-1] = state->CmdlineBuffer[i]; + 4240: d8 01 movw r26, r16 + 4242: ed 91 ld r30, X+ + 4244: fc 91 ld r31, X + 4246: e8 0f add r30, r24 + 4248: f1 1d adc r31, r1 + 424a: 90 81 ld r25, Z + 424c: 31 97 sbiw r30, 0x01 ; 1 + 424e: 90 83 st Z, r25 + // Regular handling + //Protection against buffer Overflow + if (state->CmdlineBufferLength == state->bufferMaxSize) + { + state->CmdlineBufferLength--; + for (i=1; i < state->bufferMaxSize; i++) + 4250: 8f 5f subi r24, 0xFF ; 255 + 4252: f2 cf rjmp .-28 ; 0x4238 + } + } + + if( (c >= 0x20) && (c < 0x7F) ) + { + if (state->bufferHistoryState == NOT_COPIED) + 4254: d8 01 movw r26, r16 + 4256: 51 96 adiw r26, 0x11 ; 17 + 4258: 8c 91 ld r24, X + 425a: 81 11 cpse r24, r1 + 425c: 05 c0 rjmp .+10 ; 0x4268 + cmdHistoryCopy(state); + 425e: c8 01 movw r24, r16 + 4260: 2f 83 std Y+7, r18 ; 0x07 + 4262: 0e 94 fb 1f call 0x3ff6 ; 0x3ff6 + 4266: 2f 81 ldd r18, Y+7 ; 0x07 + // character is printable + // is this a simple append + if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + 4268: f8 01 movw r30, r16 + 426a: 85 85 ldd r24, Z+13 ; 0x0d + 426c: 96 85 ldd r25, Z+14 ; 0x0e + 426e: 98 13 cpse r25, r24 + 4270: 20 c0 rjmp .+64 ; 0x42b2 + { + // echo character to the output + fputc(c , state->myStdInOut); + 4272: 62 8d ldd r22, Z+26 ; 0x1a + 4274: 73 8d ldd r23, Z+27 ; 0x1b + 4276: 82 2f mov r24, r18 + 4278: 02 2e mov r0, r18 + 427a: 00 0c add r0, r0 + 427c: 99 0b sbc r25, r25 + 427e: 2f 83 std Y+7, r18 ; 0x07 + 4280: 0e 94 37 50 call 0xa06e ; 0xa06e + // add it to the command line buffer + state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + 4284: d8 01 movw r26, r16 + 4286: ed 91 ld r30, X+ + 4288: fc 91 ld r31, X + 428a: 11 97 sbiw r26, 0x01 ; 1 + 428c: 1e 96 adiw r26, 0x0e ; 14 + 428e: 8c 91 ld r24, X + 4290: 1e 97 sbiw r26, 0x0e ; 14 + 4292: 91 e0 ldi r25, 0x01 ; 1 + 4294: 98 0f add r25, r24 + 4296: 1e 96 adiw r26, 0x0e ; 14 + 4298: 9c 93 st X, r25 + 429a: 1e 97 sbiw r26, 0x0e ; 14 + 429c: e8 0f add r30, r24 + 429e: f1 1d adc r31, r1 + 42a0: 2f 81 ldd r18, Y+7 ; 0x07 + 42a2: 20 83 st Z, r18 + // update buffer length + state->CmdlineBufferLength++; + 42a4: 1d 96 adiw r26, 0x0d ; 13 + 42a6: 8c 91 ld r24, X + 42a8: 1d 97 sbiw r26, 0x0d ; 13 + 42aa: 8f 5f subi r24, 0xFF ; 255 + 42ac: 1d 96 adiw r26, 0x0d ; 13 + 42ae: 8c 93 st X, r24 + 42b0: e1 c1 rjmp .+962 ; 0x4674 + else + { + // edit/cursor position != end of buffer + // we're inserting characters at a mid-line edit position + // make room at the insert point + state->CmdlineBufferLength++; + 42b2: 8f 5f subi r24, 0xFF ; 255 + 42b4: f8 01 movw r30, r16 + 42b6: 85 87 std Z+13, r24 ; 0x0d + for(i=state->CmdlineBufferLength; i>state->CmdlineBufferEditPos; i--) + 42b8: d8 01 movw r26, r16 + 42ba: 1e 96 adiw r26, 0x0e ; 14 + 42bc: 9c 91 ld r25, X + 42be: 1e 97 sbiw r26, 0x0e ; 14 + 42c0: 4d 91 ld r20, X+ + 42c2: 5c 91 ld r21, X + 42c4: 11 97 sbiw r26, 0x01 ; 1 + 42c6: 98 17 cp r25, r24 + 42c8: 48 f4 brcc .+18 ; 0x42dc + state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + 42ca: da 01 movw r26, r20 + 42cc: a8 0f add r26, r24 + 42ce: b1 1d adc r27, r1 + 42d0: fd 01 movw r30, r26 + 42d2: 31 97 sbiw r30, 0x01 ; 1 + 42d4: 90 81 ld r25, Z + 42d6: 9c 93 st X, r25 + { + // edit/cursor position != end of buffer + // we're inserting characters at a mid-line edit position + // make room at the insert point + state->CmdlineBufferLength++; + for(i=state->CmdlineBufferLength; i>state->CmdlineBufferEditPos; i--) + 42d8: 81 50 subi r24, 0x01 ; 1 + 42da: ee cf rjmp .-36 ; 0x42b8 + state->CmdlineBuffer[i] = state->CmdlineBuffer[i-1]; + // insert character + state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + 42dc: 81 e0 ldi r24, 0x01 ; 1 + 42de: 89 0f add r24, r25 + 42e0: 1e 96 adiw r26, 0x0e ; 14 + 42e2: 8c 93 st X, r24 + 42e4: 1e 97 sbiw r26, 0x0e ; 14 + 42e6: fa 01 movw r30, r20 + 42e8: e9 0f add r30, r25 + 42ea: f1 1d adc r31, r1 + 42ec: 20 83 st Z, r18 + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + 42ee: 6d 91 ld r22, X+ + 42f0: 7c 91 ld r23, X + 42f2: c8 01 movw r24, r16 + 42f4: 0e 94 b7 1f call 0x3f6e ; 0x3f6e + // reposition cursor + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 42f8: f8 01 movw r30, r16 + 42fa: f6 84 ldd r15, Z+14 ; 0x0e + 42fc: f8 01 movw r30, r16 + 42fe: 85 85 ldd r24, Z+13 ; 0x0d + 4300: f8 16 cp r15, r24 + 4302: 08 f0 brcs .+2 ; 0x4306 + 4304: b7 c1 rjmp .+878 ; 0x4674 + fputc(ASCII_BS , state->myStdInOut); + 4306: d8 01 movw r26, r16 + 4308: 5a 96 adiw r26, 0x1a ; 26 + 430a: 6d 91 ld r22, X+ + 430c: 7c 91 ld r23, X + 430e: 5b 97 sbiw r26, 0x1b ; 27 + 4310: 88 e0 ldi r24, 0x08 ; 8 + 4312: 90 e0 ldi r25, 0x00 ; 0 + 4314: 0e 94 37 50 call 0xa06e ; 0xa06e + // insert character + state->CmdlineBuffer[state->CmdlineBufferEditPos++] = c; + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + // reposition cursor + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 4318: f3 94 inc r15 + 431a: f0 cf rjmp .-32 ; 0x42fc + fputc(ASCII_BS , state->myStdInOut); + } + } + // handle special characters + else if(c == ASCII_CR) + 431c: 2d 30 cpi r18, 0x0D ; 13 + 431e: 09 f0 breq .+2 ; 0x4322 + 4320: 38 c1 rjmp .+624 ; 0x4592 + { + if (state->bufferHistoryState == NOT_COPIED) + 4322: d8 01 movw r26, r16 + 4324: 51 96 adiw r26, 0x11 ; 17 + 4326: 8c 91 ld r24, X + 4328: 51 97 sbiw r26, 0x11 ; 17 + 432a: 81 11 cpse r24, r1 + 432c: 46 c0 rjmp .+140 ; 0x43ba + state->bufferHistoryState = COPIED; +} + +void cmdHistoryMove(cmdState_t *state) +{ + uint8_t i=state->historyDepthIdx; + 432e: 50 96 adiw r26, 0x10 ; 16 + 4330: 4c 91 ld r20, X + 4332: 50 97 sbiw r26, 0x10 ; 16 + 4334: 1f 96 adiw r26, 0x0f ; 15 + 4336: 5c 91 ld r21, X + + if (state->historyDepthIdx != 0) + 4338: 41 11 cpse r20, r1 + 433a: 12 c0 rjmp .+36 ; 0x4360 + for ( ; iCmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK] = state->CmdlineHistory[(state->historyWrIdx-i-1) & CMD_STATE_HISTORY_MASK]; + } + } + state->CmdlineHistory[state->historyWrIdx] = state->CmdlineBuffer; + 433c: f8 01 movw r30, r16 + 433e: e5 0f add r30, r21 + 4340: f1 1d adc r31, r1 + 4342: e5 0f add r30, r21 + 4344: f1 1d adc r31, r1 + 4346: d8 01 movw r26, r16 + 4348: 8d 91 ld r24, X+ + 434a: 9c 91 ld r25, X + 434c: 11 97 sbiw r26, 0x01 ; 1 + 434e: 95 83 std Z+5, r25 ; 0x05 + 4350: 84 83 std Z+4, r24 ; 0x04 + + state->historyDepthIdx = 0; + 4352: 50 96 adiw r26, 0x10 ; 16 + 4354: 1c 92 st X, r1 + 4356: 50 97 sbiw r26, 0x10 ; 16 + state->bufferHistoryState = COPIED; + 4358: 81 e0 ldi r24, 0x01 ; 1 + 435a: 51 96 adiw r26, 0x11 ; 17 + 435c: 8c 93 st X, r24 + 435e: 2d c0 rjmp .+90 ; 0x43ba +{ + uint8_t i=state->historyDepthIdx; + + if (state->historyDepthIdx != 0) + { + state->CmdlineBuffer = state->CmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK]; + 4360: 25 2f mov r18, r21 + 4362: 30 e0 ldi r19, 0x00 ; 0 + 4364: f9 01 movw r30, r18 + 4366: e4 1b sub r30, r20 + 4368: f1 09 sbc r31, r1 + 436a: e3 70 andi r30, 0x03 ; 3 + 436c: ff 27 eor r31, r31 + 436e: 32 96 adiw r30, 0x02 ; 2 + 4370: ee 0f add r30, r30 + 4372: ff 1f adc r31, r31 + 4374: e0 0f add r30, r16 + 4376: f1 1f adc r31, r17 + 4378: 80 81 ld r24, Z + 437a: 91 81 ldd r25, Z+1 ; 0x01 + 437c: f8 01 movw r30, r16 + 437e: 91 83 std Z+1, r25 ; 0x01 + 4380: 80 83 st Z, r24 + for ( ; i + { + state->CmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK] = state->CmdlineHistory[(state->historyWrIdx-i-1) & CMD_STATE_HISTORY_MASK]; + 4386: c9 01 movw r24, r18 + 4388: 84 1b sub r24, r20 + 438a: 91 09 sbc r25, r1 + 438c: fc 01 movw r30, r24 + 438e: 31 97 sbiw r30, 0x01 ; 1 + 4390: e3 70 andi r30, 0x03 ; 3 + 4392: ff 27 eor r31, r31 + 4394: 32 96 adiw r30, 0x02 ; 2 + 4396: ee 0f add r30, r30 + 4398: ff 1f adc r31, r31 + 439a: e0 0f add r30, r16 + 439c: f1 1f adc r31, r17 + 439e: 60 81 ld r22, Z + 43a0: 71 81 ldd r23, Z+1 ; 0x01 + 43a2: fc 01 movw r30, r24 + 43a4: e3 70 andi r30, 0x03 ; 3 + 43a6: ff 27 eor r31, r31 + 43a8: 32 96 adiw r30, 0x02 ; 2 + 43aa: ee 0f add r30, r30 + 43ac: ff 1f adc r31, r31 + 43ae: e0 0f add r30, r16 + 43b0: f1 1f adc r31, r17 + 43b2: 71 83 std Z+1, r23 ; 0x01 + 43b4: 60 83 st Z, r22 + uint8_t i=state->historyDepthIdx; + + if (state->historyDepthIdx != 0) + { + state->CmdlineBuffer = state->CmdlineHistory[(state->historyWrIdx-i) & CMD_STATE_HISTORY_MASK]; + for ( ; i + if (state->bufferHistoryState == NOT_COPIED) + cmdHistoryMove(state); + + // user pressed [ENTER] + // echo CR and LF to terminal + fputc(ASCII_CR , state->myStdInOut); + 43ba: d8 01 movw r26, r16 + 43bc: 5a 96 adiw r26, 0x1a ; 26 + 43be: 6d 91 ld r22, X+ + 43c0: 7c 91 ld r23, X + 43c2: 5b 97 sbiw r26, 0x1b ; 27 + 43c4: 8d e0 ldi r24, 0x0D ; 13 + 43c6: 90 e0 ldi r25, 0x00 ; 0 + 43c8: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc(ASCII_LF , state->myStdInOut); + 43cc: f8 01 movw r30, r16 + 43ce: 62 8d ldd r22, Z+26 ; 0x1a + 43d0: 73 8d ldd r23, Z+27 ; 0x1b + 43d2: 8a e0 ldi r24, 0x0A ; 10 + 43d4: 90 e0 ldi r25, 0x00 ; 0 + 43d6: 0e 94 37 50 call 0xa06e ; 0xa06e + // add null termination to command + state->CmdlineBuffer[state->CmdlineBufferLength++] = 0; + 43da: d8 01 movw r26, r16 + 43dc: ed 91 ld r30, X+ + 43de: fc 91 ld r31, X + 43e0: 11 97 sbiw r26, 0x01 ; 1 + 43e2: 1d 96 adiw r26, 0x0d ; 13 + 43e4: 8c 91 ld r24, X + 43e6: 1d 97 sbiw r26, 0x0d ; 13 + 43e8: 91 e0 ldi r25, 0x01 ; 1 + 43ea: 98 0f add r25, r24 + 43ec: 1d 96 adiw r26, 0x0d ; 13 + 43ee: 9c 93 st X, r25 + 43f0: 1d 97 sbiw r26, 0x0d ; 13 + 43f2: e8 0f add r30, r24 + 43f4: f1 1d adc r31, r1 + 43f6: 10 82 st Z, r1 + state->CmdlineBufferEditPos++; + 43f8: 1e 96 adiw r26, 0x0e ; 14 + 43fa: 8c 91 ld r24, X + 43fc: 1e 97 sbiw r26, 0x0e ; 14 + 43fe: 8f 5f subi r24, 0xFF ; 255 + 4400: 1e 96 adiw r26, 0x0e ; 14 + 4402: 8c 93 st X, r24 + 4404: 1e 97 sbiw r26, 0x0e ; 14 +} + +void cmdlineProcessInputString(cmdState_t *state) +{ + uint8_t i=0; + state->CmdlineExcBuffer = state->CmdlineBuffer; // We will use exec buffer later to read the arguments + 4406: 2d 91 ld r18, X+ + 4408: 3c 91 ld r19, X + 440a: 11 97 sbiw r26, 0x01 ; 1 + 440c: 13 96 adiw r26, 0x03 ; 3 + 440e: 3c 93 st X, r19 + 4410: 2e 93 st -X, r18 + 4412: 12 97 sbiw r26, 0x02 ; 2 + } +} + +void cmdlineProcessInputString(cmdState_t *state) +{ + uint8_t i=0; + 4414: 80 e0 ldi r24, 0x00 ; 0 + state->CmdlineExcBuffer = state->CmdlineBuffer; // We will use exec buffer later to read the arguments + + while( !((state->CmdlineExcBuffer[i] == ' ') // find the end of the command (excluding arguments) + 4416: c8 2e mov r12, r24 + 4418: d1 2c mov r13, r1 + 441a: f9 01 movw r30, r18 + 441c: ec 0d add r30, r12 + 441e: fd 1d adc r31, r13 + 4420: 90 81 ld r25, Z + 4422: 9f 7d andi r25, 0xDF ; 223 + 4424: 11 f0 breq .+4 ; 0x442a + || (state->CmdlineExcBuffer[i] == 0)) ) // find first whitespace character in CmdlineBuffer + i++; // i determines the cammand length + 4426: 8f 5f subi r24, 0xFF ; 255 + 4428: f6 cf rjmp .-20 ; 0x4416 + + if(!i) // command was null or empty + 442a: 88 23 and r24, r24 + 442c: 09 f4 brne .+2 ; 0x4430 + 442e: a7 c0 rjmp .+334 ; 0x457e + { + cmdlinePrintPrompt(state); // output a new prompt + return; + } + + const command_t *tmpPtr = state->cmdList; // Set list of commands. The list depends of the cli mode + 4430: f8 01 movw r30, r16 + 4432: e1 a0 ldd r14, Z+33 ; 0x21 + 4434: f2 a0 ldd r15, Z+34 ; 0x22 + command_t tmp; // We need to create this object. We can't directly + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // read from flash. We need to copy it before. + 4436: 46 e0 ldi r20, 0x06 ; 6 + 4438: 50 e0 ldi r21, 0x00 ; 0 + 443a: b7 01 movw r22, r14 + 443c: ce 01 movw r24, r28 + 443e: 01 96 adiw r24, 0x01 ; 1 + 4440: 0e 94 5f 4f call 0x9ebe ; 0x9ebe + + do // search command list for match with entered command + { + if( !strncmp_P(state->CmdlineExcBuffer, tmp.commandStr, i) ) // user-entered command matched a command in the list + 4444: a9 80 ldd r10, Y+1 ; 0x01 + 4446: ba 80 ldd r11, Y+2 ; 0x02 + 4448: a6 01 movw r20, r12 + 444a: b5 01 movw r22, r10 + 444c: d8 01 movw r26, r16 + 444e: 12 96 adiw r26, 0x02 ; 2 + 4450: 8d 91 ld r24, X+ + 4452: 9c 91 ld r25, X + 4454: 13 97 sbiw r26, 0x03 ; 3 + 4456: 0e 94 68 4f call 0x9ed0 ; 0x9ed0 + 445a: 89 2b or r24, r25 + 445c: 41 f5 brne .+80 ; 0x44ae + { // + state->CmdlineExecFunction = tmp.commandFun; // set function pointer + 445e: 8d 81 ldd r24, Y+5 ; 0x05 + 4460: 9e 81 ldd r25, Y+6 ; 0x06 + 4462: f8 01 movw r30, r16 + 4464: 90 8f std Z+24, r25 ; 0x18 + 4466: 87 8b std Z+23, r24 ; 0x17 + state->command_str = tmp.commandStr; + 4468: b4 8a std Z+20, r11 ; 0x14 + 446a: a3 8a std Z+19, r10 ; 0x13 + state->command_help_str = tmp.commandHelpStr; + 446c: 8b 81 ldd r24, Y+3 ; 0x03 + 446e: 9c 81 ldd r25, Y+4 ; 0x04 + 4470: 96 8b std Z+22, r25 ; 0x16 + 4472: 85 8b std Z+21, r24 ; 0x15 + uint8_t historyReadIdx; + switch(action) + { + case CMDLINE_HISTORY_SAVE: + // copy CmdlineBuffer to history if not null string + state->CmdlineBufferLength = 0; + 4474: 15 86 std Z+13, r1 ; 0x0d + state->CmdlineBufferEditPos = 0; + 4476: 16 86 std Z+14, r1 ; 0x0e + state->bufferHistoryState = NOT_COPIED; + 4478: 11 8a std Z+17, r1 ; 0x11 + + if( strlen(state->CmdlineBuffer) ) + 447a: 01 90 ld r0, Z+ + 447c: f0 81 ld r31, Z + 447e: e0 2d mov r30, r0 + 4480: 80 81 ld r24, Z + 4482: 88 23 and r24, r24 + 4484: 09 f4 brne .+2 ; 0x4488 + 4486: 7e c0 rjmp .+252 ; 0x4584 + { + state->historyWrIdx++; + 4488: d8 01 movw r26, r16 + 448a: 1f 96 adiw r26, 0x0f ; 15 + 448c: 8c 91 ld r24, X + 448e: 1f 97 sbiw r26, 0x0f ; 15 + 4490: 8f 5f subi r24, 0xFF ; 255 + state->historyWrIdx &= CMD_STATE_HISTORY_MASK; + 4492: 83 70 andi r24, 0x03 ; 3 + 4494: 1f 96 adiw r26, 0x0f ; 15 + 4496: 8c 93 st X, r24 + + state->CmdlineBuffer = state->CmdlineHistory[state->historyWrIdx]; + 4498: f8 01 movw r30, r16 + 449a: e8 0f add r30, r24 + 449c: f1 1d adc r31, r1 + 449e: e8 0f add r30, r24 + 44a0: f1 1d adc r31, r1 + 44a2: 84 81 ldd r24, Z+4 ; 0x04 + 44a4: 95 81 ldd r25, Z+5 ; 0x05 + 44a6: f8 01 movw r30, r16 + 44a8: 91 83 std Z+1, r25 ; 0x01 + 44aa: 80 83 st Z, r24 + 44ac: 6b c0 rjmp .+214 ; 0x4584 + state->command_str = tmp.commandStr; + state->command_help_str = tmp.commandHelpStr; + cmdlineDoHistory(CMDLINE_HISTORY_SAVE, state); // save command in history + return; + } + tmpPtr++; // Next command + 44ae: f6 e0 ldi r31, 0x06 ; 6 + 44b0: ef 0e add r14, r31 + 44b2: f1 1c adc r15, r1 + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); // Copy this command from flash to ram + 44b4: 46 e0 ldi r20, 0x06 ; 6 + 44b6: 50 e0 ldi r21, 0x00 ; 0 + 44b8: b7 01 movw r22, r14 + 44ba: ce 01 movw r24, r28 + 44bc: 01 96 adiw r24, 0x01 ; 1 + 44be: 0e 94 5f 4f call 0x9ebe ; 0x9ebe + } + while (tmp.commandStr != NULL); // Last command on the list is NULL. It is required !!! + 44c2: 89 81 ldd r24, Y+1 ; 0x01 + 44c4: 9a 81 ldd r25, Y+2 ; 0x02 + 44c6: 89 2b or r24, r25 + 44c8: 09 f0 breq .+2 ; 0x44cc + 44ca: bc cf rjmp .-136 ; 0x4444 + 44cc: 9b ee ldi r25, 0xEB ; 235 + 44ce: e9 2e mov r14, r25 + 44d0: 9b e0 ldi r25, 0x0B ; 11 + 44d2: f9 2e mov r15, r25 + char * ptr; + + // print a notice header + // (uint8_t*) cast used to avoid compiler warning + ptr = (char*)CmdlineNotice; + while(pgm_read_byte(ptr)) + 44d4: c7 01 movw r24, r14 + 44d6: f7 01 movw r30, r14 + 44d8: 24 91 lpm r18, Z + 44da: 22 23 and r18, r18 + 44dc: 71 f0 breq .+28 ; 0x44fa + fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 44de: 2f ef ldi r18, 0xFF ; 255 + 44e0: e2 1a sub r14, r18 + 44e2: f2 0a sbc r15, r18 + 44e4: fc 01 movw r30, r24 + 44e6: 84 91 lpm r24, Z + 44e8: d8 01 movw r26, r16 + 44ea: 5a 96 adiw r26, 0x1a ; 26 + 44ec: 6d 91 ld r22, X+ + 44ee: 7c 91 ld r23, X + 44f0: 5b 97 sbiw r26, 0x1b ; 27 + 44f2: 90 e0 ldi r25, 0x00 ; 0 + 44f4: 0e 94 37 50 call 0xa06e ; 0xa06e + 44f8: ed cf rjmp .-38 ; 0x44d4 + 44fa: d8 01 movw r26, r16 + 44fc: ed 90 ld r14, X+ + 44fe: fc 90 ld r15, X + + // print the offending command + ptr = state->CmdlineBuffer; + while((*ptr) && (*ptr != ' ')) + 4500: f7 01 movw r30, r14 + 4502: 81 91 ld r24, Z+ + 4504: 7f 01 movw r14, r30 + 4506: 98 2f mov r25, r24 + 4508: 9f 7d andi r25, 0xDF ; 223 + 450a: d8 01 movw r26, r16 + 450c: 5a 96 adiw r26, 0x1a ; 26 + 450e: 6d 91 ld r22, X+ + 4510: 7c 91 ld r23, X + 4512: 5b 97 sbiw r26, 0x1b ; 27 + 4514: 99 23 and r25, r25 + 4516: 31 f0 breq .+12 ; 0x4524 + fputc(*ptr++ , state->myStdInOut); + 4518: 08 2e mov r0, r24 + 451a: 00 0c add r0, r0 + 451c: 99 0b sbc r25, r25 + 451e: 0e 94 37 50 call 0xa06e ; 0xa06e + 4522: ee cf rjmp .-36 ; 0x4500 + + fputc(':' , state->myStdInOut); + 4524: 8a e3 ldi r24, 0x3A ; 58 + 4526: 90 e0 ldi r25, 0x00 ; 0 + 4528: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc(' ' , state->myStdInOut); + 452c: f8 01 movw r30, r16 + 452e: 62 8d ldd r22, Z+26 ; 0x1a + 4530: 73 8d ldd r23, Z+27 ; 0x1b + 4532: 80 e2 ldi r24, 0x20 ; 32 + 4534: 90 e0 ldi r25, 0x00 ; 0 + 4536: 0e 94 37 50 call 0xa06e ; 0xa06e + + // print the not-found message + // (uint8_t*) cast used to avoid compiler warning + ptr = (char*)CmdlineCmdNotFound; + 453a: 86 ee ldi r24, 0xE6 ; 230 + 453c: e8 2e mov r14, r24 + 453e: 8b e0 ldi r24, 0x0B ; 11 + 4540: f8 2e mov r15, r24 + while(pgm_read_byte(ptr)) + 4542: 97 01 movw r18, r14 + 4544: f7 01 movw r30, r14 + 4546: 94 91 lpm r25, Z + 4548: d8 01 movw r26, r16 + 454a: 5a 96 adiw r26, 0x1a ; 26 + 454c: 6d 91 ld r22, X+ + 454e: 7c 91 ld r23, X + 4550: 5b 97 sbiw r26, 0x1b ; 27 + 4552: 99 23 and r25, r25 + 4554: 49 f0 breq .+18 ; 0x4568 + fputc(pgm_read_byte(ptr++) , state->myStdInOut); + 4556: ff ef ldi r31, 0xFF ; 255 + 4558: ef 1a sub r14, r31 + 455a: ff 0a sbc r15, r31 + 455c: f9 01 movw r30, r18 + 455e: 84 91 lpm r24, Z + 4560: 90 e0 ldi r25, 0x00 ; 0 + 4562: 0e 94 37 50 call 0xa06e ; 0xa06e + 4566: ed cf rjmp .-38 ; 0x4542 + + fputc('\r' , state->myStdInOut); + 4568: 8d e0 ldi r24, 0x0D ; 13 + 456a: 90 e0 ldi r25, 0x00 ; 0 + 456c: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc('\n' , state->myStdInOut); + 4570: f8 01 movw r30, r16 + 4572: 62 8d ldd r22, Z+26 ; 0x1a + 4574: 73 8d ldd r23, Z+27 ; 0x1b + 4576: 8a e0 ldi r24, 0x0A ; 10 + 4578: 90 e0 ldi r25, 0x00 ; 0 + 457a: 0e 94 37 50 call 0xa06e ; 0xa06e + } + while (tmp.commandStr != NULL); // Last command on the list is NULL. It is required !!! + + // if we did not get a match + cmdlinePrintError(state); // output an error message + cmdlinePrintPrompt(state); // output a new prompt + 457e: c8 01 movw r24, r16 + 4580: 0e 94 90 1f call 0x3f20 ; 0x3f20 + state->CmdlineBuffer[state->CmdlineBufferLength++] = 0; + state->CmdlineBufferEditPos++; + // command is complete, process it + cmdlineProcessInputString(state); + // reset buffer + state->CmdlineBufferLength = 0; + 4584: d8 01 movw r26, r16 + 4586: 1d 96 adiw r26, 0x0d ; 13 + 4588: 1c 92 st X, r1 + 458a: 1d 97 sbiw r26, 0x0d ; 13 + state->CmdlineBufferEditPos = 0; + 458c: 1e 96 adiw r26, 0x0e ; 14 + 458e: 1c 92 st X, r1 + 4590: 71 c0 rjmp .+226 ; 0x4674 + } + else if(c == ASCII_BS) + 4592: 28 30 cpi r18, 0x08 ; 8 + 4594: 09 f0 breq .+2 ; 0x4598 + 4596: 68 c0 rjmp .+208 ; 0x4668 + { + if(state->CmdlineBufferEditPos) + 4598: f8 01 movw r30, r16 + 459a: 86 85 ldd r24, Z+14 ; 0x0e + 459c: 88 23 and r24, r24 + 459e: 09 f4 brne .+2 ; 0x45a2 + 45a0: 5b c0 rjmp .+182 ; 0x4658 + { + // is this a simple delete (off the end of the line) + if(state->CmdlineBufferEditPos == state->CmdlineBufferLength) + 45a2: 95 85 ldd r25, Z+13 ; 0x0d + 45a4: 89 13 cpse r24, r25 + 45a6: 25 c0 rjmp .+74 ; 0x45f2 + { + // destructive backspace + // echo backspace-space-backspace + fputc(ASCII_BS , state->myStdInOut); + 45a8: 62 8d ldd r22, Z+26 ; 0x1a + 45aa: 73 8d ldd r23, Z+27 ; 0x1b + 45ac: 88 e0 ldi r24, 0x08 ; 8 + 45ae: 90 e0 ldi r25, 0x00 ; 0 + 45b0: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc(' ' , state->myStdInOut); + 45b4: d8 01 movw r26, r16 + 45b6: 5a 96 adiw r26, 0x1a ; 26 + 45b8: 6d 91 ld r22, X+ + 45ba: 7c 91 ld r23, X + 45bc: 5b 97 sbiw r26, 0x1b ; 27 + 45be: 80 e2 ldi r24, 0x20 ; 32 + 45c0: 90 e0 ldi r25, 0x00 ; 0 + 45c2: 0e 94 37 50 call 0xa06e ; 0xa06e + fputc(ASCII_BS , state->myStdInOut); + 45c6: f8 01 movw r30, r16 + 45c8: 62 8d ldd r22, Z+26 ; 0x1a + 45ca: 73 8d ldd r23, Z+27 ; 0x1b + 45cc: 88 e0 ldi r24, 0x08 ; 8 + 45ce: 90 e0 ldi r25, 0x00 ; 0 + 45d0: 0e 94 37 50 call 0xa06e ; 0xa06e + // decrement our buffer length and edit position + state->CmdlineBufferLength--; + 45d4: d8 01 movw r26, r16 + 45d6: 1d 96 adiw r26, 0x0d ; 13 + 45d8: 8c 91 ld r24, X + 45da: 1d 97 sbiw r26, 0x0d ; 13 + 45dc: 81 50 subi r24, 0x01 ; 1 + 45de: 1d 96 adiw r26, 0x0d ; 13 + 45e0: 8c 93 st X, r24 + 45e2: 1d 97 sbiw r26, 0x0d ; 13 + state->CmdlineBufferEditPos--; + 45e4: 1e 96 adiw r26, 0x0e ; 14 + 45e6: 8c 91 ld r24, X + 45e8: 1e 97 sbiw r26, 0x0e ; 14 + 45ea: 81 50 subi r24, 0x01 ; 1 + 45ec: 1e 96 adiw r26, 0x0e ; 14 + 45ee: 8c 93 st X, r24 + 45f0: 41 c0 rjmp .+130 ; 0x4674 + else + { + // edit/cursor position != end of buffer + // we're deleting characters at a mid-line edit position + // shift characters down, effectively deleting + state->CmdlineBufferLength--; + 45f2: 91 50 subi r25, 0x01 ; 1 + 45f4: f8 01 movw r30, r16 + 45f6: 95 87 std Z+13, r25 ; 0x0d + state->CmdlineBufferEditPos--; + 45f8: 81 50 subi r24, 0x01 ; 1 + 45fa: 86 87 std Z+14, r24 ; 0x0e + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 45fc: d8 01 movw r26, r16 + 45fe: 1d 96 adiw r26, 0x0d ; 13 + 4600: 9c 91 ld r25, X + 4602: 1d 97 sbiw r26, 0x0d ; 13 + 4604: 6d 91 ld r22, X+ + 4606: 7c 91 ld r23, X + 4608: 89 17 cp r24, r25 + 460a: 38 f4 brcc .+14 ; 0x461a + state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + 460c: fb 01 movw r30, r22 + 460e: e8 0f add r30, r24 + 4610: f1 1d adc r31, r1 + 4612: 91 81 ldd r25, Z+1 ; 0x01 + 4614: 90 83 st Z, r25 + // edit/cursor position != end of buffer + // we're deleting characters at a mid-line edit position + // shift characters down, effectively deleting + state->CmdlineBufferLength--; + state->CmdlineBufferEditPos--; + for(i=state->CmdlineBufferEditPos; iCmdlineBufferLength; i++) + 4616: 8f 5f subi r24, 0xFF ; 255 + 4618: f1 cf rjmp .-30 ; 0x45fc + state->CmdlineBuffer[i] = state->CmdlineBuffer[i+1]; + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + 461a: c8 01 movw r24, r16 + 461c: 0e 94 b7 1f call 0x3f6e ; 0x3f6e + // add space to clear leftover characters + fputc(' ' , state->myStdInOut); + 4620: f8 01 movw r30, r16 + 4622: 62 8d ldd r22, Z+26 ; 0x1a + 4624: 73 8d ldd r23, Z+27 ; 0x1b + 4626: 80 e2 ldi r24, 0x20 ; 32 + 4628: 90 e0 ldi r25, 0x00 ; 0 + 462a: 0e 94 37 50 call 0xa06e ; 0xa06e + // reposition cursor + for(i=state->CmdlineBufferEditPos; i<(state->CmdlineBufferLength+1); i++) + 462e: d8 01 movw r26, r16 + 4630: 1e 96 adiw r26, 0x0e ; 14 + 4632: fc 90 ld r15, X + 4634: d8 01 movw r26, r16 + 4636: 1d 96 adiw r26, 0x0d ; 13 + 4638: 8c 91 ld r24, X + 463a: 90 e0 ldi r25, 0x00 ; 0 + 463c: 2f 2d mov r18, r15 + 463e: 30 e0 ldi r19, 0x00 ; 0 + 4640: 82 17 cp r24, r18 + 4642: 93 07 cpc r25, r19 + 4644: bc f0 brlt .+46 ; 0x4674 + fputc(ASCII_BS , state->myStdInOut); + 4646: f8 01 movw r30, r16 + 4648: 62 8d ldd r22, Z+26 ; 0x1a + 464a: 73 8d ldd r23, Z+27 ; 0x1b + 464c: 88 e0 ldi r24, 0x08 ; 8 + 464e: 90 e0 ldi r25, 0x00 ; 0 + 4650: 0e 94 37 50 call 0xa06e ; 0xa06e + // repaint + cmdlineRepaint(state, state->CmdlineBuffer); + // add space to clear leftover characters + fputc(' ' , state->myStdInOut); + // reposition cursor + for(i=state->CmdlineBufferEditPos; i<(state->CmdlineBufferLength+1); i++) + 4654: f3 94 inc r15 + 4656: ee cf rjmp .-36 ; 0x4634 + } + } + else + { + // else, ring the bell + fputc(ASCII_BEL , state->myStdInOut); + 4658: f8 01 movw r30, r16 + 465a: 62 8d ldd r22, Z+26 ; 0x1a + 465c: 73 8d ldd r23, Z+27 ; 0x1b + 465e: 87 e0 ldi r24, 0x07 ; 7 + 4660: 90 e0 ldi r25, 0x00 ; 0 + 4662: 0e 94 37 50 call 0xa06e ; 0xa06e + 4666: 06 c0 rjmp .+12 ; 0x4674 + } + else if(c == ASCII_DEL) + { + // not yet handled + } + else if(c == ASCII_ESC) + 4668: 2b 31 cpi r18, 0x1B ; 27 + 466a: 21 f4 brne .+8 ; 0x4674 + { + state->CmdlineInputVT100State = 1; + 466c: 81 e0 ldi r24, 0x01 ; 1 + 466e: d8 01 movw r26, r16 + 4670: 52 96 adiw r26, 0x12 ; 18 + 4672: 8c 93 st X, r24 + } +} + 4674: 27 96 adiw r28, 0x07 ; 7 + 4676: 0f b6 in r0, 0x3f ; 63 + 4678: f8 94 cli + 467a: de bf out 0x3e, r29 ; 62 + 467c: 0f be out 0x3f, r0 ; 63 + 467e: cd bf out 0x3d, r28 ; 61 + 4680: df 91 pop r29 + 4682: cf 91 pop r28 + 4684: 1f 91 pop r17 + 4686: 0f 91 pop r16 + 4688: ff 90 pop r15 + 468a: ef 90 pop r14 + 468c: df 90 pop r13 + 468e: cf 90 pop r12 + 4690: bf 90 pop r11 + 4692: af 90 pop r10 + 4694: 08 95 ret + +00004696 : + fputc('\n' , state->myStdInOut); +} + + +uint8_t cmdLineGetLastArgIdx(cmdState_t *state) +{ + 4696: dc 01 movw r26, r24 + 4698: 12 96 adiw r26, 0x02 ; 2 + 469a: ed 91 ld r30, X+ + 469c: fc 91 ld r31, X + 469e: 13 97 sbiw r26, 0x03 ; 3 + uint8_t result = 0; + uint8_t lastWhite = 1; + 46a0: 91 e0 ldi r25, 0x01 ; 1 +} + + +uint8_t cmdLineGetLastArgIdx(cmdState_t *state) +{ + uint8_t result = 0; + 46a2: 80 e0 ldi r24, 0x00 ; 0 + uint8_t lastWhite = 1; + char *str = state->CmdlineExcBuffer; + while(*str != 0) + 46a4: 21 91 ld r18, Z+ + 46a6: 22 23 and r18, r18 + 46a8: 51 f0 breq .+20 ; 0x46be + { + if (*str == ' ') + 46aa: 20 32 cpi r18, 0x20 ; 32 + 46ac: 21 f4 brne .+8 ; 0x46b6 + { + if (lastWhite == 0) + 46ae: 91 11 cpse r25, r1 + 46b0: 04 c0 rjmp .+8 ; 0x46ba + result++; + 46b2: 8f 5f subi r24, 0xFF ; 255 + 46b4: 02 c0 rjmp .+4 ; 0x46ba + lastWhite = 1; + } + else + lastWhite = 0; + 46b6: 90 e0 ldi r25, 0x00 ; 0 + 46b8: f5 cf rjmp .-22 ; 0x46a4 + { + if (*str == ' ') + { + if (lastWhite == 0) + result++; + lastWhite = 1; + 46ba: 91 e0 ldi r25, 0x01 ; 1 + 46bc: f3 cf rjmp .-26 ; 0x46a4 + else + lastWhite = 0; + str++; + } + return result; +} + 46be: 08 95 ret + +000046c0 : + cmdlinePrintError(state); // output an error message + cmdlinePrintPrompt(state); // output a new prompt +} + +void cmdlineMainLoop(cmdState_t *state) +{ + 46c0: 0f 93 push r16 + 46c2: 1f 93 push r17 + 46c4: cf 93 push r28 + 46c6: df 93 push r29 + cliExRes_t result; + if(state->CmdlineExecFunction) // do we have a command/function to be executed + 46c8: fc 01 movw r30, r24 + 46ca: 07 89 ldd r16, Z+23 ; 0x17 + 46cc: 10 8d ldd r17, Z+24 ; 0x18 + 46ce: 01 15 cp r16, r1 + 46d0: 11 05 cpc r17, r1 + 46d2: 09 f4 brne .+2 ; 0x46d6 + 46d4: 71 c0 rjmp .+226 ; 0x47b8 + 46d6: ec 01 movw r28, r24 + { + state->argc = cmdLineGetLastArgIdx(state); // get number of arguments + 46d8: 0e 94 4b 23 call 0x4696 ; 0x4696 + 46dc: 89 8f std Y+25, r24 ; 0x19 + result = state->CmdlineExecFunction(state); // run it + 46de: ce 01 movw r24, r28 + 46e0: f8 01 movw r30, r16 + 46e2: 09 95 icall + + switch(result) + 46e4: 82 30 cpi r24, 0x02 ; 2 + 46e6: 91 05 cpc r25, r1 + 46e8: 89 f0 breq .+34 ; 0x470c + 46ea: 30 f4 brcc .+12 ; 0x46f8 + 46ec: 01 97 sbiw r24, 0x01 ; 1 + 46ee: 09 f0 breq .+2 ; 0x46f2 + 46f0: 56 c0 rjmp .+172 ; 0x479e + { + case OK_INFORM: + fprintf_P(state->myStdInOut, PSTR("OK\r\n")); + 46f2: 81 ee ldi r24, 0xE1 ; 225 + 46f4: 9b e0 ldi r25, 0x0B ; 11 + 46f6: 47 c0 rjmp .+142 ; 0x4786 + if(state->CmdlineExecFunction) // do we have a command/function to be executed + { + state->argc = cmdLineGetLastArgIdx(state); // get number of arguments + result = state->CmdlineExecFunction(state); // run it + + switch(result) + 46f8: 84 30 cpi r24, 0x04 ; 4 + 46fa: 91 05 cpc r25, r1 + 46fc: 09 f4 brne .+2 ; 0x4700 + 46fe: 41 c0 rjmp .+130 ; 0x4782 + 4700: 05 97 sbiw r24, 0x05 ; 5 + 4702: 09 f0 breq .+2 ; 0x4706 + 4704: 4c c0 rjmp .+152 ; 0x479e + break; + case ERROR_INFORM: + fprintf_P(state->myStdInOut, PSTR("Operation failed\r\n")); + break; + case ERROR_OPERATION_NOT_ALLOWED: + fprintf_P(state->myStdInOut, PSTR("Operation not allowed\r\n")); + 4706: 8d e9 ldi r24, 0x9D ; 157 + 4708: 9b e0 ldi r25, 0x0B ; 11 + 470a: 3d c0 rjmp .+122 ; 0x4786 + { + case OK_INFORM: + fprintf_P(state->myStdInOut, PSTR("OK\r\n")); + break; + case SYNTAX_ERROR: + fprintf_P(state->myStdInOut, PSTR("Syntax Error. Use: ")); + 470c: 8d ec ldi r24, 0xCD ; 205 + 470e: 9b e0 ldi r25, 0x0B ; 11 + 4710: 9f 93 push r25 + 4712: 8f 93 push r24 + 4714: 8b 8d ldd r24, Y+27 ; 0x1b + 4716: 8f 93 push r24 + 4718: 8a 8d ldd r24, Y+26 ; 0x1a + 471a: 8f 93 push r24 + 471c: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, state->command_str); + 4720: 8c 89 ldd r24, Y+20 ; 0x14 + 4722: 8f 93 push r24 + 4724: 8b 89 ldd r24, Y+19 ; 0x13 + 4726: 8f 93 push r24 + 4728: 8b 8d ldd r24, Y+27 ; 0x1b + 472a: 8f 93 push r24 + 472c: 8a 8d ldd r24, Y+26 ; 0x1a + 472e: 8f 93 push r24 + 4730: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, PSTR(" ")); + 4734: 8b ec ldi r24, 0xCB ; 203 + 4736: 9b e0 ldi r25, 0x0B ; 11 + 4738: 9f 93 push r25 + 473a: 8f 93 push r24 + 473c: 8b 8d ldd r24, Y+27 ; 0x1b + 473e: 8f 93 push r24 + 4740: 8a 8d ldd r24, Y+26 ; 0x1a + 4742: 8f 93 push r24 + 4744: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, state->command_help_str); + 4748: 8e 89 ldd r24, Y+22 ; 0x16 + 474a: 8f 93 push r24 + 474c: 8d 89 ldd r24, Y+21 ; 0x15 + 474e: 8f 93 push r24 + 4750: 8b 8d ldd r24, Y+27 ; 0x1b + 4752: 8f 93 push r24 + 4754: 8a 8d ldd r24, Y+26 ; 0x1a + 4756: 8f 93 push r24 + 4758: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, PSTR("\r\n")); + 475c: 88 ec ldi r24, 0xC8 ; 200 + 475e: 9b e0 ldi r25, 0x0B ; 11 + 4760: 9f 93 push r25 + 4762: 8f 93 push r24 + 4764: 8b 8d ldd r24, Y+27 ; 0x1b + 4766: 8f 93 push r24 + 4768: 8a 8d ldd r24, Y+26 ; 0x1a + 476a: 8f 93 push r24 + 476c: 0e 94 1a 50 call 0xa034 ; 0xa034 + break; + 4770: 8d b7 in r24, 0x3d ; 61 + 4772: 9e b7 in r25, 0x3e ; 62 + 4774: 44 96 adiw r24, 0x14 ; 20 + 4776: 0f b6 in r0, 0x3f ; 63 + 4778: f8 94 cli + 477a: 9e bf out 0x3e, r25 ; 62 + 477c: 0f be out 0x3f, r0 ; 63 + 477e: 8d bf out 0x3d, r24 ; 61 + 4780: 0e c0 rjmp .+28 ; 0x479e + case ERROR_INFORM: + fprintf_P(state->myStdInOut, PSTR("Operation failed\r\n")); + 4782: 85 eb ldi r24, 0xB5 ; 181 + 4784: 9b e0 ldi r25, 0x0B ; 11 + break; + case ERROR_OPERATION_NOT_ALLOWED: + fprintf_P(state->myStdInOut, PSTR("Operation not allowed\r\n")); + 4786: 9f 93 push r25 + 4788: 8f 93 push r24 + 478a: 8b 8d ldd r24, Y+27 ; 0x1b + 478c: 8f 93 push r24 + 478e: 8a 8d ldd r24, Y+26 ; 0x1a + 4790: 8f 93 push r24 + 4792: 0e 94 1a 50 call 0xa034 ; 0xa034 + break; + 4796: 0f 90 pop r0 + 4798: 0f 90 pop r0 + 479a: 0f 90 pop r0 + 479c: 0f 90 pop r0 + default: + break; + } + state->CmdlineExecFunction = NULL; // reset + 479e: 18 8e std Y+24, r1 ; 0x18 + 47a0: 1f 8a std Y+23, r1 ; 0x17 + state->command_str = NULL; + 47a2: 1c 8a std Y+20, r1 ; 0x14 + 47a4: 1b 8a std Y+19, r1 ; 0x13 + state->command_help_str = NULL; + 47a6: 1e 8a std Y+22, r1 ; 0x16 + 47a8: 1d 8a std Y+21, r1 ; 0x15 + cmdlinePrintPrompt(state); // output new prompt + 47aa: ce 01 movw r24, r28 + } +} + 47ac: df 91 pop r29 + 47ae: cf 91 pop r28 + 47b0: 1f 91 pop r17 + 47b2: 0f 91 pop r16 + break; + } + state->CmdlineExecFunction = NULL; // reset + state->command_str = NULL; + state->command_help_str = NULL; + cmdlinePrintPrompt(state); // output new prompt + 47b4: 0c 94 90 1f jmp 0x3f20 ; 0x3f20 + } +} + 47b8: df 91 pop r29 + 47ba: cf 91 pop r28 + 47bc: 1f 91 pop r17 + 47be: 0f 91 pop r16 + 47c0: 08 95 ret + +000047c2 : + // find the offset of argument number [argnum] + uint8_t idx=0; + uint8_t arg; + + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + 47c2: fb 01 movw r30, r22 + 47c4: 22 81 ldd r18, Z+2 ; 0x02 + 47c6: 33 81 ldd r19, Z+3 ; 0x03 +} + +char* cmdlineGetArgStr(uint8_t argnum, cmdState_t *state) +{ + // find the offset of argument number [argnum] + uint8_t idx=0; + 47c8: 90 e0 ldi r25, 0x00 ; 0 + uint8_t arg; + + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + 47ca: f9 01 movw r30, r18 + 47cc: e9 0f add r30, r25 + 47ce: f1 1d adc r31, r1 + 47d0: 40 81 ld r20, Z + 47d2: 40 32 cpi r20, 0x20 ; 32 + 47d4: 11 f4 brne .+4 ; 0x47da + 47d6: 9f 5f subi r25, 0xFF ; 255 + 47d8: f8 cf rjmp .-16 ; 0x47ca + 47da: 40 e0 ldi r20, 0x00 ; 0 + + // we are at the first argument + for(arg=0; arg + { + // find the next whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] != ' ')) idx++; + 47e0: f9 01 movw r30, r18 + 47e2: e9 0f add r30, r25 + 47e4: f1 1d adc r31, r1 + 47e6: 50 81 ld r21, Z + 47e8: 5f 7d andi r21, 0xDF ; 223 + 47ea: 11 f0 breq .+4 ; 0x47f0 + 47ec: 9f 5f subi r25, 0xFF ; 255 + 47ee: f8 cf rjmp .-16 ; 0x47e0 + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + 47f0: f9 01 movw r30, r18 + 47f2: e9 0f add r30, r25 + 47f4: f1 1d adc r31, r1 + 47f6: 50 81 ld r21, Z + 47f8: 50 32 cpi r21, 0x20 ; 32 + 47fa: 11 f4 brne .+4 ; 0x4800 + 47fc: 9f 5f subi r25, 0xFF ; 255 + 47fe: f8 cf rjmp .-16 ; 0x47f0 + + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + + // we are at the first argument + for(arg=0; arg + // find the first non-whitespace character + while( (state->CmdlineExcBuffer[idx] != 0) && (state->CmdlineExcBuffer[idx] == ' ')) idx++; + } + // we are at the requested argument or the end of the buffer + return &state->CmdlineExcBuffer[idx]; +} + 4804: a9 01 movw r20, r18 + 4806: 49 0f add r20, r25 + 4808: 51 1d adc r21, r1 + 480a: ca 01 movw r24, r20 + 480c: 08 95 ret + +0000480e : + +// return argument [argnum] interpreted as a decimal integer +long cmdlineGetArgInt(uint8_t argnum, cmdState_t *state) +{ + 480e: cf 93 push r28 + 4810: df 93 push r29 + 4812: 00 d0 rcall .+0 ; 0x4814 + 4814: cd b7 in r28, 0x3d ; 61 + 4816: de b7 in r29, 0x3e ; 62 + char* endptr; + return strtol(cmdlineGetArgStr(argnum, state), &endptr, 10); + 4818: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 481c: 4a e0 ldi r20, 0x0A ; 10 + 481e: 50 e0 ldi r21, 0x00 ; 0 + 4820: be 01 movw r22, r28 + 4822: 6f 5f subi r22, 0xFF ; 255 + 4824: 7f 4f sbci r23, 0xFF ; 255 + 4826: 0e 94 2b 4e call 0x9c56 ; 0x9c56 +} + 482a: 0f 90 pop r0 + 482c: 0f 90 pop r0 + 482e: df 91 pop r29 + 4830: cf 91 pop r28 + 4832: 08 95 ret + +00004834 : + +// return argument [argnum] interpreted as a hex integer +long cmdlineGetArgHex(uint8_t argnum, cmdState_t *state) +{ + 4834: cf 93 push r28 + 4836: df 93 push r29 + 4838: 00 d0 rcall .+0 ; 0x483a + 483a: cd b7 in r28, 0x3d ; 61 + 483c: de b7 in r29, 0x3e ; 62 + char* endptr; + return strtol(cmdlineGetArgStr(argnum, state), &endptr, 16); + 483e: 0e 94 e1 23 call 0x47c2 ; 0x47c2 + 4842: 40 e1 ldi r20, 0x10 ; 16 + 4844: 50 e0 ldi r21, 0x00 ; 0 + 4846: be 01 movw r22, r28 + 4848: 6f 5f subi r22, 0xFF ; 255 + 484a: 7f 4f sbci r23, 0xFF ; 255 + 484c: 0e 94 2b 4e call 0x9c56 ; 0x9c56 +} + 4850: 0f 90 pop r0 + 4852: 0f 90 pop r0 + 4854: df 91 pop r29 + 4856: cf 91 pop r28 + 4858: 08 95 ret + +0000485a : + +void cmdPrintHelp(cmdState_t *state) +{ + 485a: af 92 push r10 + 485c: bf 92 push r11 + 485e: cf 92 push r12 + 4860: df 92 push r13 + 4862: ef 92 push r14 + 4864: ff 92 push r15 + 4866: 0f 93 push r16 + 4868: 1f 93 push r17 + 486a: cf 93 push r28 + 486c: df 93 push r29 + 486e: 00 d0 rcall .+0 ; 0x4870 + 4870: 00 d0 rcall .+0 ; 0x4872 + 4872: 00 d0 rcall .+0 ; 0x4874 + 4874: cd b7 in r28, 0x3d ; 61 + 4876: de b7 in r29, 0x3e ; 62 + 4878: 8c 01 movw r16, r24 + command_t tmp; + const command_t *tmpPtr = state->cmdList; + 487a: fc 01 movw r30, r24 + 487c: e1 a0 ldd r14, Z+33 ; 0x21 + 487e: f2 a0 ldd r15, Z+34 ; 0x22 + + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + 4880: 46 e0 ldi r20, 0x06 ; 6 + 4882: 50 e0 ldi r21, 0x00 ; 0 + 4884: b7 01 movw r22, r14 + 4886: ce 01 movw r24, r28 + 4888: 01 96 adiw r24, 0x01 ; 1 + 488a: 0e 94 5f 4f call 0x9ebe ; 0x9ebe + do + { + fprintf_P(state->myStdInOut, tmp.commandStr); + fprintf_P(state->myStdInOut, PSTR("\t")); + 488e: 8b e9 ldi r24, 0x9B ; 155 + 4890: a8 2e mov r10, r24 + 4892: 8b e0 ldi r24, 0x0B ; 11 + 4894: b8 2e mov r11, r24 + fprintf_P(state->myStdInOut, tmp.commandHelpStr); + fprintf_P(state->myStdInOut, PSTR("\r\n")); + 4896: 98 e9 ldi r25, 0x98 ; 152 + 4898: c9 2e mov r12, r25 + 489a: 9b e0 ldi r25, 0x0B ; 11 + 489c: d9 2e mov r13, r25 + const command_t *tmpPtr = state->cmdList; + + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + do + { + fprintf_P(state->myStdInOut, tmp.commandStr); + 489e: 8a 81 ldd r24, Y+2 ; 0x02 + 48a0: 8f 93 push r24 + 48a2: 89 81 ldd r24, Y+1 ; 0x01 + 48a4: 8f 93 push r24 + 48a6: f8 01 movw r30, r16 + 48a8: 83 8d ldd r24, Z+27 ; 0x1b + 48aa: 8f 93 push r24 + 48ac: 82 8d ldd r24, Z+26 ; 0x1a + 48ae: 8f 93 push r24 + 48b0: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, PSTR("\t")); + 48b4: bf 92 push r11 + 48b6: af 92 push r10 + 48b8: f8 01 movw r30, r16 + 48ba: 83 8d ldd r24, Z+27 ; 0x1b + 48bc: 8f 93 push r24 + 48be: 82 8d ldd r24, Z+26 ; 0x1a + 48c0: 8f 93 push r24 + 48c2: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, tmp.commandHelpStr); + 48c6: 8c 81 ldd r24, Y+4 ; 0x04 + 48c8: 8f 93 push r24 + 48ca: 8b 81 ldd r24, Y+3 ; 0x03 + 48cc: 8f 93 push r24 + 48ce: f8 01 movw r30, r16 + 48d0: 83 8d ldd r24, Z+27 ; 0x1b + 48d2: 8f 93 push r24 + 48d4: 82 8d ldd r24, Z+26 ; 0x1a + 48d6: 8f 93 push r24 + 48d8: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(state->myStdInOut, PSTR("\r\n")); + 48dc: df 92 push r13 + 48de: cf 92 push r12 + 48e0: f8 01 movw r30, r16 + 48e2: 83 8d ldd r24, Z+27 ; 0x1b + 48e4: 8f 93 push r24 + 48e6: 82 8d ldd r24, Z+26 ; 0x1a + 48e8: 8f 93 push r24 + 48ea: 0e 94 1a 50 call 0xa034 ; 0xa034 + + tmpPtr++; + 48ee: f6 e0 ldi r31, 0x06 ; 6 + 48f0: ef 0e add r14, r31 + 48f2: f1 1c adc r15, r1 + memcpy_P(&tmp, tmpPtr, sizeof(command_t)); + 48f4: 46 e0 ldi r20, 0x06 ; 6 + 48f6: 50 e0 ldi r21, 0x00 ; 0 + 48f8: b7 01 movw r22, r14 + 48fa: ce 01 movw r24, r28 + 48fc: 01 96 adiw r24, 0x01 ; 1 + 48fe: 0e 94 5f 4f call 0x9ebe ; 0x9ebe + } + while (tmp.commandFun != NULL); + 4902: 0f b6 in r0, 0x3f ; 63 + 4904: f8 94 cli + 4906: de bf out 0x3e, r29 ; 62 + 4908: 0f be out 0x3f, r0 ; 63 + 490a: cd bf out 0x3d, r28 ; 61 + 490c: 8d 81 ldd r24, Y+5 ; 0x05 + 490e: 9e 81 ldd r25, Y+6 ; 0x06 + 4910: 89 2b or r24, r25 + 4912: 29 f6 brne .-118 ; 0x489e +} + 4914: 26 96 adiw r28, 0x06 ; 6 + 4916: 0f b6 in r0, 0x3f ; 63 + 4918: f8 94 cli + 491a: de bf out 0x3e, r29 ; 62 + 491c: 0f be out 0x3f, r0 ; 63 + 491e: cd bf out 0x3d, r28 ; 61 + 4920: df 91 pop r29 + 4922: cf 91 pop r28 + 4924: 1f 91 pop r17 + 4926: 0f 91 pop r16 + 4928: ff 90 pop r15 + 492a: ef 90 pop r14 + 492c: df 90 pop r13 + 492e: cf 90 pop r12 + 4930: bf 90 pop r11 + 4932: af 90 pop r10 + 4934: 08 95 ret + +00004936 : +void vt100Init(cmdState_t *state) +{ + // initializes terminal to "power-on" settings + // ESC c + + fprintf_P(state->myStdInOut, "\x1B\x63"); + 4936: 2d e2 ldi r18, 0x2D ; 45 + 4938: 31 e0 ldi r19, 0x01 ; 1 + 493a: 3f 93 push r19 + 493c: 2f 93 push r18 + 493e: fc 01 movw r30, r24 + 4940: 23 8d ldd r18, Z+27 ; 0x1b + 4942: 2f 93 push r18 + 4944: 82 8d ldd r24, Z+26 ; 0x1a + 4946: 8f 93 push r24 + 4948: 0e 94 1a 50 call 0xa034 ; 0xa034 + 494c: 0f 90 pop r0 + 494e: 0f 90 pop r0 + 4950: 0f 90 pop r0 + 4952: 0f 90 pop r0 + 4954: 08 95 ret + +00004956 : +} + +void vt100ClearScreen(cmdState_t *state) +{ + // ESC [ 2 J + fprintf_P(state->myStdInOut, "\x1B[2J"); + 4956: 20 e3 ldi r18, 0x30 ; 48 + 4958: 31 e0 ldi r19, 0x01 ; 1 + 495a: 3f 93 push r19 + 495c: 2f 93 push r18 + 495e: fc 01 movw r30, r24 + 4960: 23 8d ldd r18, Z+27 ; 0x1b + 4962: 2f 93 push r18 + 4964: 82 8d ldd r24, Z+26 ; 0x1a + 4966: 8f 93 push r24 + 4968: 0e 94 1a 50 call 0xa034 ; 0xa034 + 496c: 0f 90 pop r0 + 496e: 0f 90 pop r0 + 4970: 0f 90 pop r0 + 4972: 0f 90 pop r0 + 4974: 08 95 ret + +00004976 : +} + +void vt100SetAttr(uint8_t attr, cmdState_t *state) +{ + // ESC [ Ps m + fprintf_P(state->myStdInOut, "\x1B[%dm",attr); + 4976: 1f 92 push r1 + 4978: 8f 93 push r24 + 497a: 85 e3 ldi r24, 0x35 ; 53 + 497c: 91 e0 ldi r25, 0x01 ; 1 + 497e: 9f 93 push r25 + 4980: 8f 93 push r24 + 4982: fb 01 movw r30, r22 + 4984: 83 8d ldd r24, Z+27 ; 0x1b + 4986: 8f 93 push r24 + 4988: 82 8d ldd r24, Z+26 ; 0x1a + 498a: 8f 93 push r24 + 498c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 4990: 0f 90 pop r0 + 4992: 0f 90 pop r0 + 4994: 0f 90 pop r0 + 4996: 0f 90 pop r0 + 4998: 0f 90 pop r0 + 499a: 0f 90 pop r0 + 499c: 08 95 ret + +0000499e : +} + +void vt100SetCursorMode(uint8_t visible, cmdState_t *state) +{ + 499e: fb 01 movw r30, r22 + 49a0: 23 8d ldd r18, Z+27 ; 0x1b + 49a2: 92 8d ldd r25, Z+26 ; 0x1a + if(visible) + 49a4: 88 23 and r24, r24 + 49a6: 19 f0 breq .+6 ; 0x49ae + // ESC [ ? 25 h + fprintf_P(state->myStdInOut, "\x1B[?25h"); + 49a8: 4b e3 ldi r20, 0x3B ; 59 + 49aa: 51 e0 ldi r21, 0x01 ; 1 + 49ac: 02 c0 rjmp .+4 ; 0x49b2 + else + // ESC [ ? 25 l + fprintf_P(state->myStdInOut, "\x1B[?25l"); + 49ae: 42 e4 ldi r20, 0x42 ; 66 + 49b0: 51 e0 ldi r21, 0x01 ; 1 + 49b2: 5f 93 push r21 + 49b4: 4f 93 push r20 + 49b6: 2f 93 push r18 + 49b8: 9f 93 push r25 + 49ba: 0e 94 1a 50 call 0xa034 ; 0xa034 + 49be: 0f 90 pop r0 + 49c0: 0f 90 pop r0 + 49c2: 0f 90 pop r0 + 49c4: 0f 90 pop r0 + 49c6: 08 95 ret + +000049c8 : +} + +void vt100SetCursorPos(uint8_t line, uint8_t col, cmdState_t *state) +{ + // ESC [ Pl ; Pc H + fprintf_P(state->myStdInOut, "\x1B[%d;%dH",line,col); + 49c8: 1f 92 push r1 + 49ca: 6f 93 push r22 + 49cc: 1f 92 push r1 + 49ce: 8f 93 push r24 + 49d0: 89 e4 ldi r24, 0x49 ; 73 + 49d2: 91 e0 ldi r25, 0x01 ; 1 + 49d4: 9f 93 push r25 + 49d6: 8f 93 push r24 + 49d8: fa 01 movw r30, r20 + 49da: 83 8d ldd r24, Z+27 ; 0x1b + 49dc: 8f 93 push r24 + 49de: 82 8d ldd r24, Z+26 ; 0x1a + 49e0: 8f 93 push r24 + 49e2: 0e 94 1a 50 call 0xa034 ; 0xa034 + 49e6: 8d b7 in r24, 0x3d ; 61 + 49e8: 9e b7 in r25, 0x3e ; 62 + 49ea: 08 96 adiw r24, 0x08 ; 8 + 49ec: 0f b6 in r0, 0x3f ; 63 + 49ee: f8 94 cli + 49f0: 9e bf out 0x3e, r25 ; 62 + 49f2: 0f be out 0x3f, r0 ; 63 + 49f4: 8d bf out 0x3d, r24 ; 61 + 49f6: 08 95 ret + 49f8: 08 95 ret + 49fa: 08 95 ret + +000049fc : +void spiEnableDS1305(void) {}; +void spiDisableDS1305(void) {}; + + +void readTimeBCD(timeBCD_t *time) +{ + 49fc: 0f 93 push r16 + 49fe: 1f 93 push r17 + 4a00: cf 93 push r28 + 4a02: 8c 01 movw r16, r24 + spiTake(); + 4a04: 0e 94 38 1a call 0x3470 ; 0x3470 + spiEnableDS1305(); + 4a08: 0e 94 53 0f call 0x1ea6 ; 0x1ea6 + + uint8_t *ptr = (uint8_t *)(time); + uint8_t i; + + spiSend(0x00); + 4a0c: 80 e0 ldi r24, 0x00 ; 0 + 4a0e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + for (i=0; i + 4a1a: f8 01 movw r30, r16 + 4a1c: 81 93 st Z+, r24 + 4a1e: 8f 01 movw r16, r30 + uint8_t *ptr = (uint8_t *)(time); + uint8_t i; + + spiSend(0x00); + + for (i=0; i + { + *ptr = spiSend(i); + ptr++; + } + spiDisableDS1305(); + 4a26: 0e 94 58 0f call 0x1eb0 ; 0x1eb0 + spiGive(); +} + 4a2a: cf 91 pop r28 + 4a2c: 1f 91 pop r17 + 4a2e: 0f 91 pop r16 + { + *ptr = spiSend(i); + ptr++; + } + spiDisableDS1305(); + spiGive(); + 4a30: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004a34 : +} + +#if USE_DECODED_TIME_STRUCT +void readTimeDecoded(timeDecoded_t *time) +{ + readTimeBCD((timeBCD_t *)(time)); + 4a34: 0c 94 fe 24 jmp 0x49fc ; 0x49fc + +00004a38 : +} +void readTime (time_t *time) +{ + readTimeBCD((timeBCD_t *)(time)); + 4a38: 0c 94 fe 24 jmp 0x49fc ; 0x49fc + +00004a3c : +} +#endif /* USE_DECODED_TIME_STRUCT */ + + +void setTimeBCD(timeBCD_t *time) +{ + 4a3c: 0f 93 push r16 + 4a3e: 1f 93 push r17 + 4a40: cf 93 push r28 + 4a42: df 93 push r29 + 4a44: ec 01 movw r28, r24 + spiTake(); + 4a46: 0e 94 38 1a call 0x3470 ; 0x3470 + spiEnableDS1305(); + 4a4a: 0e 94 53 0f call 0x1ea6 ; 0x1ea6 + + uint8_t *ptr = (uint8_t *)(time); + uint8_t i; + spiSend(0x80); + 4a4e: 80 e8 ldi r24, 0x80 ; 128 + 4a50: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4a54: 8e 01 movw r16, r28 + 4a56: 09 5f subi r16, 0xF9 ; 249 + 4a58: 1f 4f sbci r17, 0xFF ; 255 + for (i=0; i + spiEnableDS1305(); + + uint8_t *ptr = (uint8_t *)(time); + uint8_t i; + spiSend(0x80); + for (i=0; i + { + spiSend(*ptr); + ptr++; + } + + spiDisableDS1305(); + 4a66: 0e 94 58 0f call 0x1eb0 ; 0x1eb0 + spiGive(); +} + 4a6a: df 91 pop r29 + 4a6c: cf 91 pop r28 + 4a6e: 1f 91 pop r17 + 4a70: 0f 91 pop r16 + spiSend(*ptr); + ptr++; + } + + spiDisableDS1305(); + spiGive(); + 4a72: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004a76 : +} + +#if USE_DECODED_TIME_STRUCT +void setTimeDecoded(timeDecoded_t *time) +{ + setTimeBCD((timeBCD_t *)(time)); + 4a76: 0c 94 1e 25 jmp 0x4a3c ; 0x4a3c + +00004a7a : +} +void setTime(time_t *time) +{ + setTimeBCD((timeBCD_t *)(time)); + 4a7a: 0c 94 1e 25 jmp 0x4a3c ; 0x4a3c + +00004a7e : +} +#endif /* USE_DECODED_TIME_STRUCT */ + +void ds1305start(void) +{ + spiTake(); + 4a7e: 0e 94 38 1a call 0x3470 ; 0x3470 + spiEnableDS1305(); + 4a82: 0e 94 53 0f call 0x1ea6 ; 0x1ea6 + + spiSend(0x8F); + 4a86: 8f e8 ldi r24, 0x8F ; 143 + 4a88: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(0x00); + 4a8c: 80 e0 ldi r24, 0x00 ; 0 + 4a8e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + spiDisableDS1305(); + 4a92: 0e 94 58 0f call 0x1eb0 ; 0x1eb0 + spiGive(); + 4a96: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004a9a : + return; +} + + +uint8_t ds1305writeMem (uint8_t addr, uint8_t length, uint8_t *data) +{ + 4a9a: ff 92 push r15 + 4a9c: 0f 93 push r16 + 4a9e: 1f 93 push r17 + 4aa0: cf 93 push r28 + 4aa2: df 93 push r29 + 4aa4: 1f 92 push r1 + 4aa6: cd b7 in r28, 0x3d ; 61 + 4aa8: de b7 in r29, 0x3e ; 62 + 4aaa: f6 2e mov r15, r22 + 4aac: 8a 01 movw r16, r20 + if (addr > 95) + 4aae: 80 36 cpi r24, 0x60 ; 96 + 4ab0: f8 f4 brcc .+62 ; 0x4af0 + return 1; + if (addr + length > 95) + 4ab2: 26 2f mov r18, r22 + 4ab4: 30 e0 ldi r19, 0x00 ; 0 + 4ab6: 28 0f add r18, r24 + 4ab8: 31 1d adc r19, r1 + 4aba: 20 36 cpi r18, 0x60 ; 96 + 4abc: 31 05 cpc r19, r1 + 4abe: d4 f4 brge .+52 ; 0x4af4 + return 2; + + addr += 0xA0; + + spiTake(); + 4ac0: 89 83 std Y+1, r24 ; 0x01 + 4ac2: 0e 94 38 1a call 0x3470 ; 0x3470 + spiEnableDS1305(); + 4ac6: 0e 94 53 0f call 0x1ea6 ; 0x1ea6 + + spiSend(addr); + 4aca: 89 81 ldd r24, Y+1 ; 0x01 + 4acc: 80 56 subi r24, 0x60 ; 96 + 4ace: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + while (length > 0) + 4ad2: ff 20 and r15, r15 + 4ad4: 39 f0 breq .+14 ; 0x4ae4 + { + spiSend(*data); + 4ad6: f8 01 movw r30, r16 + 4ad8: 81 91 ld r24, Z+ + 4ada: 8f 01 movw r16, r30 + 4adc: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + data++; + length--; + 4ae0: fa 94 dec r15 + 4ae2: f7 cf rjmp .-18 ; 0x4ad2 + } + + spiDisableDS1305(); + 4ae4: 0e 94 58 0f call 0x1eb0 ; 0x1eb0 + spiGive(); + 4ae8: 0e 94 43 1a call 0x3486 ; 0x3486 + return 0; + 4aec: 80 e0 ldi r24, 0x00 ; 0 + 4aee: 03 c0 rjmp .+6 ; 0x4af6 + + +uint8_t ds1305writeMem (uint8_t addr, uint8_t length, uint8_t *data) +{ + if (addr > 95) + return 1; + 4af0: 81 e0 ldi r24, 0x01 ; 1 + 4af2: 01 c0 rjmp .+2 ; 0x4af6 + if (addr + length > 95) + return 2; + 4af4: 82 e0 ldi r24, 0x02 ; 2 + } + + spiDisableDS1305(); + spiGive(); + return 0; +} + 4af6: 0f 90 pop r0 + 4af8: df 91 pop r29 + 4afa: cf 91 pop r28 + 4afc: 1f 91 pop r17 + 4afe: 0f 91 pop r16 + 4b00: ff 90 pop r15 + 4b02: 08 95 ret + +00004b04 : +uint8_t ds1305readMem (uint8_t addr, uint8_t length, uint8_t *data) +{ + 4b04: ff 92 push r15 + 4b06: 0f 93 push r16 + 4b08: 1f 93 push r17 + 4b0a: cf 93 push r28 + 4b0c: df 93 push r29 + 4b0e: 1f 92 push r1 + 4b10: cd b7 in r28, 0x3d ; 61 + 4b12: de b7 in r29, 0x3e ; 62 + 4b14: f6 2e mov r15, r22 + 4b16: 8a 01 movw r16, r20 + if (addr >95) + 4b18: 80 36 cpi r24, 0x60 ; 96 + 4b1a: 00 f5 brcc .+64 ; 0x4b5c + return 1; + if (addr + length > 95) + 4b1c: 26 2f mov r18, r22 + 4b1e: 30 e0 ldi r19, 0x00 ; 0 + 4b20: 28 0f add r18, r24 + 4b22: 31 1d adc r19, r1 + 4b24: 20 36 cpi r18, 0x60 ; 96 + 4b26: 31 05 cpc r19, r1 + 4b28: dc f4 brge .+54 ; 0x4b60 + return 2; + + addr += 0x20; + + spiTake(); + 4b2a: 89 83 std Y+1, r24 ; 0x01 + 4b2c: 0e 94 38 1a call 0x3470 ; 0x3470 + spiEnableDS1305(); + 4b30: 0e 94 53 0f call 0x1ea6 ; 0x1ea6 + + spiSend(addr); + 4b34: 89 81 ldd r24, Y+1 ; 0x01 + 4b36: 80 5e subi r24, 0xE0 ; 224 + 4b38: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + while (length > 0) + 4b3c: ff 20 and r15, r15 + 4b3e: 41 f0 breq .+16 ; 0x4b50 + { + *data = spiSend(0); + 4b40: 80 e0 ldi r24, 0x00 ; 0 + 4b42: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4b46: f8 01 movw r30, r16 + 4b48: 81 93 st Z+, r24 + 4b4a: 8f 01 movw r16, r30 + data++; + length--; + 4b4c: fa 94 dec r15 + 4b4e: f6 cf rjmp .-20 ; 0x4b3c + } + + spiDisableDS1305(); + 4b50: 0e 94 58 0f call 0x1eb0 ; 0x1eb0 + spiGive(); + 4b54: 0e 94 43 1a call 0x3486 ; 0x3486 + return 0; + 4b58: 80 e0 ldi r24, 0x00 ; 0 + 4b5a: 03 c0 rjmp .+6 ; 0x4b62 + return 0; +} +uint8_t ds1305readMem (uint8_t addr, uint8_t length, uint8_t *data) +{ + if (addr >95) + return 1; + 4b5c: 81 e0 ldi r24, 0x01 ; 1 + 4b5e: 01 c0 rjmp .+2 ; 0x4b62 + if (addr + length > 95) + return 2; + 4b60: 82 e0 ldi r24, 0x02 ; 2 + } + + spiDisableDS1305(); + spiGive(); + return 0; +} + 4b62: 0f 90 pop r0 + 4b64: df 91 pop r29 + 4b66: cf 91 pop r28 + 4b68: 1f 91 pop r17 + 4b6a: 0f 91 pop r16 + 4b6c: ff 90 pop r15 + 4b6e: 08 95 ret + 4b70: 08 95 ret + 4b72: 08 95 ret + +00004b74 : +void enableSpiMPC23S17(void) {} +void disableSpiMPC23S17(void) {} + + +void MPC23s17SetDirA(uint8_t portAdir, uint8_t addr) +{ + 4b74: cf 93 push r28 + 4b76: df 93 push r29 + 4b78: d8 2f mov r29, r24 + addr = addr<<1; + 4b7a: c6 2f mov r28, r22 + 4b7c: cc 0f add r28, r28 + addr &= 0x0E; + 4b7e: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + 4b80: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4b84: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4b88: 8c 2f mov r24, r28 + 4b8a: 80 64 ori r24, 0x40 ; 64 + 4b8c: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_IODIRA); + 4b90: 80 e0 ldi r24, 0x00 ; 0 + 4b92: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portAdir); + 4b96: 8d 2f mov r24, r29 + 4b98: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4b9c: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4ba0: df 91 pop r29 + 4ba2: cf 91 pop r28 + spiSend(addr); + spiSend(B0_IODIRA); + spiSend(portAdir); + + disableSpiMPC23S17(); + spiGive(); + 4ba4: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004ba8 : +} + +void MPC23s17SetDirB(uint8_t portBdir, uint8_t addr) +{ + 4ba8: cf 93 push r28 + 4baa: df 93 push r29 + 4bac: d8 2f mov r29, r24 + addr = addr<<1; + 4bae: c6 2f mov r28, r22 + 4bb0: cc 0f add r28, r28 + addr &= 0x0E; + 4bb2: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + 4bb4: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4bb8: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + + spiSend(addr); + 4bbc: 8c 2f mov r24, r28 + 4bbe: 80 64 ori r24, 0x40 ; 64 + 4bc0: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_IODIRB); + 4bc4: 81 e0 ldi r24, 0x01 ; 1 + 4bc6: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portBdir); + 4bca: 8d 2f mov r24, r29 + 4bcc: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4bd0: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4bd4: df 91 pop r29 + 4bd6: cf 91 pop r28 + spiSend(addr); + spiSend(B0_IODIRB); + spiSend(portBdir); + + disableSpiMPC23S17(); + spiGive(); + 4bd8: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004bdc : +} + +void MPC23s17SetPortA(uint8_t portAout, uint8_t addr) +{ + 4bdc: 1f 93 push r17 + 4bde: cf 93 push r28 + 4be0: df 93 push r29 + 4be2: 1f 92 push r1 + 4be4: cd b7 in r28, 0x3d ; 61 + 4be6: de b7 in r29, 0x3e ; 62 + addr = addr<<1; + 4be8: 66 0f add r22, r22 + addr &= 0x0E; + 4bea: 16 2f mov r17, r22 + 4bec: 1e 70 andi r17, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + spiTake(); + 4bee: 89 83 std Y+1, r24 ; 0x01 + 4bf0: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4bf4: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + portA = portAout; + 4bf8: 89 81 ldd r24, Y+1 ; 0x01 + 4bfa: 80 93 c2 0e sts 0x0EC2, r24 + spiSend(addr); + 4bfe: 81 2f mov r24, r17 + 4c00: 80 64 ori r24, 0x40 ; 64 + 4c02: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATA); + 4c06: 84 e1 ldi r24, 0x14 ; 20 + 4c08: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portA); + 4c0c: 80 91 c2 0e lds r24, 0x0EC2 + 4c10: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4c14: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4c18: 0f 90 pop r0 + 4c1a: df 91 pop r29 + 4c1c: cf 91 pop r28 + 4c1e: 1f 91 pop r17 + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + + disableSpiMPC23S17(); + spiGive(); + 4c20: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004c24 : +} + +void MPC23s17SetBitsOnPortA(uint8_t portAout, uint8_t addr) +{ + 4c24: cf 93 push r28 + addr = addr<<1; + 4c26: c6 2f mov r28, r22 + 4c28: cc 0f add r28, r28 + addr &= 0x0E; + 4c2a: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portA |= portAout; + 4c2c: 90 91 c2 0e lds r25, 0x0EC2 + 4c30: 89 2b or r24, r25 + 4c32: 80 93 c2 0e sts 0x0EC2, r24 + + spiTake(); + 4c36: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4c3a: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4c3e: 8c 2f mov r24, r28 + 4c40: 80 64 ori r24, 0x40 ; 64 + 4c42: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATA); + 4c46: 84 e1 ldi r24, 0x14 ; 20 + 4c48: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portA); + 4c4c: 80 91 c2 0e lds r24, 0x0EC2 + 4c50: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + disableSpiMPC23S17(); + 4c54: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4c58: cf 91 pop r28 + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + disableSpiMPC23S17(); + spiGive(); + 4c5a: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004c5e : +} + +void MPC23s17ClearBitsOnPortA(uint8_t portAout, uint8_t addr) +{ + 4c5e: cf 93 push r28 + addr = addr<<1; + 4c60: c6 2f mov r28, r22 + 4c62: cc 0f add r28, r28 + addr &= 0x0E; + 4c64: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portA &= (~portAout); + 4c66: 90 91 c2 0e lds r25, 0x0EC2 + 4c6a: 80 95 com r24 + 4c6c: 98 23 and r25, r24 + 4c6e: 90 93 c2 0e sts 0x0EC2, r25 + + spiTake(); + 4c72: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4c76: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4c7a: 8c 2f mov r24, r28 + 4c7c: 80 64 ori r24, 0x40 ; 64 + 4c7e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATA); + 4c82: 84 e1 ldi r24, 0x14 ; 20 + 4c84: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portA); + 4c88: 80 91 c2 0e lds r24, 0x0EC2 + 4c8c: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + disableSpiMPC23S17(); + 4c90: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4c94: cf 91 pop r28 + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATA); + spiSend(portA); + disableSpiMPC23S17(); + spiGive(); + 4c96: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004c9a : +} + +void MPC23s17SetPortB(uint8_t portBout, uint8_t addr) +{ + 4c9a: cf 93 push r28 + addr = addr<<1; + 4c9c: c6 2f mov r28, r22 + 4c9e: cc 0f add r28, r28 + addr &= 0x0E; + 4ca0: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB = portBout; + 4ca2: 80 93 79 0e sts 0x0E79, r24 + + spiTake(); + 4ca6: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4caa: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4cae: 8c 2f mov r24, r28 + 4cb0: 80 64 ori r24, 0x40 ; 64 + 4cb2: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATB); + 4cb6: 85 e1 ldi r24, 0x15 ; 21 + 4cb8: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portB); + 4cbc: 80 91 79 0e lds r24, 0x0E79 + 4cc0: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + disableSpiMPC23S17(); + 4cc4: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4cc8: cf 91 pop r28 + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + disableSpiMPC23S17(); + spiGive(); + 4cca: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004cce : +} + +void MPC23s17SetBitsOnPortB(uint8_t portBout, uint8_t addr) +{ + 4cce: cf 93 push r28 + addr = addr<<1; + 4cd0: c6 2f mov r28, r22 + 4cd2: cc 0f add r28, r28 + addr &= 0x0E; + 4cd4: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB |= portBout; + 4cd6: 90 91 79 0e lds r25, 0x0E79 + 4cda: 89 2b or r24, r25 + 4cdc: 80 93 79 0e sts 0x0E79, r24 + + spiTake(); + 4ce0: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4ce4: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4ce8: 8c 2f mov r24, r28 + 4cea: 80 64 ori r24, 0x40 ; 64 + 4cec: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATB); + 4cf0: 85 e1 ldi r24, 0x15 ; 21 + 4cf2: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portB); + 4cf6: 80 91 79 0e lds r24, 0x0E79 + 4cfa: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + disableSpiMPC23S17(); + 4cfe: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4d02: cf 91 pop r28 + enableSpiMPC23S17(); + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + disableSpiMPC23S17(); + spiGive(); + 4d04: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004d08 : +} + +void MPC23s17ClearBitsOnPortB(uint8_t portBout, uint8_t addr) +{ + 4d08: cf 93 push r28 + addr = addr<<1; + 4d0a: c6 2f mov r28, r22 + 4d0c: cc 0f add r28, r28 + addr &= 0x0E; + 4d0e: ce 70 andi r28, 0x0E ; 14 + addr |= 0x40; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + + portB &= (~portBout); + 4d10: 90 91 79 0e lds r25, 0x0E79 + 4d14: 80 95 com r24 + 4d16: 98 23 and r25, r24 + 4d18: 90 93 79 0e sts 0x0E79, r25 + + spiTake(); + 4d1c: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4d20: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + spiSend(addr); + 4d24: 8c 2f mov r24, r28 + 4d26: 80 64 ori r24, 0x40 ; 64 + 4d28: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_OLATB); + 4d2c: 85 e1 ldi r24, 0x15 ; 21 + 4d2e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(portB); + 4d32: 80 91 79 0e lds r24, 0x0E79 + 4d36: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4d3a: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); +} + 4d3e: cf 91 pop r28 + spiSend(addr); + spiSend(B0_OLATB); + spiSend(portB); + + disableSpiMPC23S17(); + spiGive(); + 4d40: 0c 94 43 1a jmp 0x3486 ; 0x3486 + +00004d44 : +} + +uint8_t MPC23s17ReadPortA(uint8_t addr) +{ + 4d44: 1f 93 push r17 + 4d46: cf 93 push r28 + 4d48: df 93 push r29 + 4d4a: 1f 92 push r1 + 4d4c: cd b7 in r28, 0x3d ; 61 + 4d4e: de b7 in r29, 0x3e ; 62 + addr = addr<<1; + 4d50: 88 0f add r24, r24 + addr &= 0x0E; + 4d52: 8e 70 andi r24, 0x0E ; 14 + addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 4d54: 18 2f mov r17, r24 + 4d56: 11 64 ori r17, 0x41 ; 65 + + spiTake(); + 4d58: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4d5c: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + + spiSend(addr); + 4d60: 81 2f mov r24, r17 + 4d62: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_GPIOA); + 4d66: 82 e1 ldi r24, 0x12 ; 18 + 4d68: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + uint8_t result = spiSend(addr); + 4d6c: 81 2f mov r24, r17 + 4d6e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4d72: 89 83 std Y+1, r24 ; 0x01 + 4d74: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); + 4d78: 0e 94 43 1a call 0x3486 ; 0x3486 + + return result; +} + 4d7c: 89 81 ldd r24, Y+1 ; 0x01 + 4d7e: 0f 90 pop r0 + 4d80: df 91 pop r29 + 4d82: cf 91 pop r28 + 4d84: 1f 91 pop r17 + 4d86: 08 95 ret + +00004d88 : + +uint8_t MPC23s17ReadPortB(uint8_t addr) +{ + 4d88: 1f 93 push r17 + 4d8a: cf 93 push r28 + 4d8c: df 93 push r29 + 4d8e: 1f 92 push r1 + 4d90: cd b7 in r28, 0x3d ; 61 + 4d92: de b7 in r29, 0x3e ; 62 + addr = addr<<1; + 4d94: 88 0f add r24, r24 + addr &= 0x0E; + 4d96: 8e 70 andi r24, 0x0E ; 14 + addr |= 0x41; //OPCODE 0100 AAA 0 bit0: 0 - zapis, 1 - odczyt + 4d98: 18 2f mov r17, r24 + 4d9a: 11 64 ori r17, 0x41 ; 65 + + spiTake(); + 4d9c: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMPC23S17(); + 4da0: 0e 94 3b 0f call 0x1e76 ; 0x1e76 + + spiSend(addr); + 4da4: 81 2f mov r24, r17 + 4da6: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(B0_GPIOB); + 4daa: 83 e1 ldi r24, 0x13 ; 19 + 4dac: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + uint8_t result = spiSend(addr); + 4db0: 81 2f mov r24, r17 + 4db2: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMPC23S17(); + 4db6: 89 83 std Y+1, r24 ; 0x01 + 4db8: 0e 94 3d 0f call 0x1e7a ; 0x1e7a + spiGive(); + 4dbc: 0e 94 43 1a call 0x3486 ; 0x3486 + + return result; +} + 4dc0: 89 81 ldd r24, Y+1 ; 0x01 + 4dc2: 0f 90 pop r0 + 4dc4: df 91 pop r29 + 4dc6: cf 91 pop r28 + 4dc8: 1f 91 pop r17 + 4dca: 08 95 ret + 4dcc: 08 95 ret + 4dce: 08 95 ret + +00004dd0 : +void enableSpiMCP3008(void) {}; +void disableSpiMCP3008(void) {}; + + +uint16_t MCP3008_getSampleDiff(uint8_t inputNo) +{ + 4dd0: cf 93 push r28 + 4dd2: df 93 push r29 + uint8_t resultLo; + uint8_t resultHi; + inputNo = inputNo << 4; + 4dd4: c8 2f mov r28, r24 + 4dd6: c2 95 swap r28 + 4dd8: c0 7f andi r28, 0xF0 ; 240 + inputNo &= 0x70; + + spiTake(); + 4dda: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMCP3008(); + 4dde: 0e 94 3f 0f call 0x1e7e ; 0x1e7e + + spiSend(0x01); //Start + 4de2: 81 e0 ldi r24, 0x01 ; 1 + 4de4: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + 4de8: 8c 2f mov r24, r28 + 4dea: 80 77 andi r24, 0x70 ; 112 + 4dec: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4df0: d8 2f mov r29, r24 + resultLo = spiSend(0); //X X X X X X X X + 4df2: 80 e0 ldi r24, 0x00 ; 0 + 4df4: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4df8: c8 2f mov r28, r24 + + disableSpiMCP3008(); + 4dfa: 0e 94 44 0f call 0x1e88 ; 0x1e88 + spiGive(); + 4dfe: 0e 94 43 1a call 0x3486 ; 0x3486 + + resultHi &= 0x03; + 4e02: d3 70 andi r29, 0x03 ; 3 + return resultHi << 8 | resultLo; + 4e04: 8c 2f mov r24, r28 + 4e06: 90 e0 ldi r25, 0x00 ; 0 +} + 4e08: 9d 2b or r25, r29 + 4e0a: df 91 pop r29 + 4e0c: cf 91 pop r28 + 4e0e: 08 95 ret + +00004e10 : + +uint16_t MCP3008_getSampleSingle(uint8_t inputNo) +{ + 4e10: cf 93 push r28 + 4e12: df 93 push r29 + uint8_t resultLo; + uint8_t resultHi; + inputNo = inputNo << 4; + 4e14: 82 95 swap r24 + 4e16: 80 7f andi r24, 0xF0 ; 240 + inputNo &= 0x70; + 4e18: c8 2f mov r28, r24 + 4e1a: c0 77 andi r28, 0x70 ; 112 + inputNo |= 0x80; + + spiTake(); + 4e1c: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMCP3008(); + 4e20: 0e 94 3f 0f call 0x1e7e ; 0x1e7e + + spiSend(0x01); //Start + 4e24: 81 e0 ldi r24, 0x01 ; 1 + 4e26: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + resultHi = spiSend(inputNo); //DIFF/!SGL A2 A1 A0 X X X X + 4e2a: 8c 2f mov r24, r28 + 4e2c: 80 68 ori r24, 0x80 ; 128 + 4e2e: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4e32: d8 2f mov r29, r24 + resultLo = spiSend(0); //X X X X X X X X + 4e34: 80 e0 ldi r24, 0x00 ; 0 + 4e36: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + 4e3a: c8 2f mov r28, r24 + + disableSpiMCP3008(); + 4e3c: 0e 94 44 0f call 0x1e88 ; 0x1e88 + spiGive(); + 4e40: 0e 94 43 1a call 0x3486 ; 0x3486 + + resultHi &= 0x03; + 4e44: d3 70 andi r29, 0x03 ; 3 + return resultHi << 8 | resultLo; + 4e46: 8c 2f mov r24, r28 + 4e48: 90 e0 ldi r25, 0x00 ; 0 +} + 4e4a: 9d 2b or r25, r29 + 4e4c: df 91 pop r29 + 4e4e: cf 91 pop r28 + 4e50: 08 95 ret + 4e52: 08 95 ret + 4e54: 08 95 ret + +00004e56 : +/** + * Ustawia wartość rezystancji + * @param inputNo - WARTOŚĆ OD 0 DO 255. + */ +void MCP4150_setValue(uint8_t value) +{ + 4e56: cf 93 push r28 + 4e58: c8 2f mov r28, r24 + spiTake(); + 4e5a: 0e 94 38 1a call 0x3470 ; 0x3470 + enableSpiMCP4150(); + 4e5e: 0e 94 49 0f call 0x1e92 ; 0x1e92 + + spiSend(0x11); + 4e62: 81 e1 ldi r24, 0x11 ; 17 + 4e64: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + spiSend(value); + 4e68: 8c 2f mov r24, r28 + 4e6a: 0e 94 e2 0e call 0x1dc4 ; 0x1dc4 + + disableSpiMCP4150(); + 4e6e: 0e 94 4e 0f call 0x1e9c ; 0x1e9c + spiGive(); +} + 4e72: cf 91 pop r28 + + spiSend(0x11); + spiSend(value); + + disableSpiMCP4150(); + spiGive(); + 4e74: 0c 94 43 1a jmp 0x3486 ; 0x3486 + 4e78: 08 95 ret + 4e7a: 08 95 ret + +00004e7c : + // spiGive(); + return result; +} + +void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data) +{ + 4e7c: cf 93 push r28 + 4e7e: df 93 push r29 + 4e80: 00 d0 rcall .+0 ; 0x4e82 + 4e82: 1f 92 push r1 + 4e84: cd b7 in r28, 0x3d ; 61 + 4e86: de b7 in r29, 0x3e ; 62 + // spiTake(); + spiEnableEnc28j60(); + 4e88: 4b 83 std Y+3, r20 ; 0x03 + 4e8a: 6a 83 std Y+2, r22 ; 0x02 + 4e8c: 89 83 std Y+1, r24 ; 0x01 + 4e8e: 0e 94 2b 0f call 0x1e56 ; 0x1e56 + // issue write command + //spiSend(op | (address & ADDR_MASK)); + spiSendENC(op | (address & ADDR_MASK)); + 4e92: 6a 81 ldd r22, Y+2 ; 0x02 + 4e94: 6f 71 andi r22, 0x1F ; 31 + 4e96: 89 81 ldd r24, Y+1 ; 0x01 + 4e98: 86 2b or r24, r22 + 4e9a: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + spiSendENC(data); + 4e9e: 4b 81 ldd r20, Y+3 ; 0x03 + 4ea0: 84 2f mov r24, r20 + 4ea2: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + spiDisableEnc28j60(); + // spiGive(); +} + 4ea6: 0f 90 pop r0 + 4ea8: 0f 90 pop r0 + 4eaa: 0f 90 pop r0 + 4eac: df 91 pop r29 + 4eae: cf 91 pop r28 + spiEnableEnc28j60(); + // issue write command + //spiSend(op | (address & ADDR_MASK)); + spiSendENC(op | (address & ADDR_MASK)); + spiSendENC(data); + spiDisableEnc28j60(); + 4eb0: 0c 94 2d 0f jmp 0x1e5a ; 0x1e5a + +00004eb4 : +// spiGive(); +// } + + +void enc28j60SetBank(uint8_t address) +{ + 4eb4: 1f 93 push r17 + 4eb6: cf 93 push r28 + 4eb8: df 93 push r29 + // set the bank (if needed) + if((address & BANK_MASK) != Enc28j60Bank) + 4eba: 18 2f mov r17, r24 + 4ebc: 10 76 andi r17, 0x60 ; 96 + 4ebe: c1 2f mov r28, r17 + 4ec0: d0 e0 ldi r29, 0x00 ; 0 + 4ec2: 20 91 92 01 lds r18, 0x0192 + 4ec6: 30 e0 ldi r19, 0x00 ; 0 + 4ec8: c2 17 cp r28, r18 + 4eca: d3 07 cpc r29, r19 + 4ecc: 89 f0 breq .+34 ; 0x4ef0 + { + // set the bank + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); + 4ece: 43 e0 ldi r20, 0x03 ; 3 + 4ed0: 6f e1 ldi r22, 0x1F ; 31 + 4ed2: 80 ea ldi r24, 0xA0 ; 160 + 4ed4: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); + 4ed8: ae 01 movw r20, r28 + 4eda: 85 e0 ldi r24, 0x05 ; 5 + 4edc: 55 95 asr r21 + 4ede: 47 95 ror r20 + 4ee0: 8a 95 dec r24 + 4ee2: e1 f7 brne .-8 ; 0x4edc + 4ee4: 6f e1 ldi r22, 0x1F ; 31 + 4ee6: 80 e8 ldi r24, 0x80 ; 128 + 4ee8: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + Enc28j60Bank = (address & BANK_MASK); + 4eec: 10 93 92 01 sts 0x0192, r17 + } +} + 4ef0: df 91 pop r29 + 4ef2: cf 91 pop r28 + 4ef4: 1f 91 pop r17 + 4ef6: 08 95 ret + +00004ef8 : + + return (enc28j60Read(MIRDH)); +} + +void enc28j60Write(uint8_t address, uint8_t data) +{ + 4ef8: 1f 93 push r17 + 4efa: cf 93 push r28 + 4efc: df 93 push r29 + 4efe: 1f 92 push r1 + 4f00: cd b7 in r28, 0x3d ; 61 + 4f02: de b7 in r29, 0x3e ; 62 + 4f04: 18 2f mov r17, r24 + // set the bank + enc28j60SetBank(address); + 4f06: 69 83 std Y+1, r22 ; 0x01 + 4f08: 0e 94 5a 27 call 0x4eb4 ; 0x4eb4 + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); + 4f0c: 49 81 ldd r20, Y+1 ; 0x01 + 4f0e: 61 2f mov r22, r17 + 4f10: 80 e4 ldi r24, 0x40 ; 64 +} + 4f12: 0f 90 pop r0 + 4f14: df 91 pop r29 + 4f16: cf 91 pop r28 + 4f18: 1f 91 pop r17 +void enc28j60Write(uint8_t address, uint8_t data) +{ + // set the bank + enc28j60SetBank(address); + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); + 4f1a: 0c 94 3e 27 jmp 0x4e7c ; 0x4e7c + +00004f1e : + enc28j60PhyWrite (PHLCON, 0x476); + vTaskDelay (2); +} + +uint8_t enc28j60ReadOp(uint8_t op, uint8_t address) +{ + 4f1e: 1f 93 push r17 + 4f20: cf 93 push r28 + 4f22: df 93 push r29 + 4f24: 1f 92 push r1 + 4f26: cd b7 in r28, 0x3d ; 61 + 4f28: de b7 in r29, 0x3e ; 62 + 4f2a: 16 2f mov r17, r22 + uint8_t result; + //spiTake(); + spiEnableEnc28j60(); + 4f2c: 89 83 std Y+1, r24 ; 0x01 + 4f2e: 0e 94 2b 0f call 0x1e56 ; 0x1e56 + + // issue read command + spiSendENC(op | (address & ADDR_MASK)); + 4f32: 91 2f mov r25, r17 + 4f34: 9f 71 andi r25, 0x1F ; 31 + 4f36: 89 81 ldd r24, Y+1 ; 0x01 + 4f38: 89 2b or r24, r25 + 4f3a: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + + // read data + result = spiSendENC(0x00); + 4f3e: 80 e0 ldi r24, 0x00 ; 0 + 4f40: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + + // do dummy read if needed (for mac and mii, see datasheet page 29) + if(address & 0x80) + 4f44: 17 ff sbrs r17, 7 + 4f46: 03 c0 rjmp .+6 ; 0x4f4e + { + result = spiSendENC(0x00); + 4f48: 80 e0 ldi r24, 0x00 ; 0 + 4f4a: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + } + + spiDisableEnc28j60(); + 4f4e: 89 83 std Y+1, r24 ; 0x01 + 4f50: 0e 94 2d 0f call 0x1e5a ; 0x1e5a + // spiGive(); + return result; +} + 4f54: 89 81 ldd r24, Y+1 ; 0x01 + 4f56: 0f 90 pop r0 + 4f58: df 91 pop r29 + 4f5a: cf 91 pop r28 + 4f5c: 1f 91 pop r17 + 4f5e: 08 95 ret + +00004f60 : + Enc28j60Bank = (address & BANK_MASK); + } +} + +uint8_t enc28j60Read(uint8_t address) +{ + 4f60: cf 93 push r28 + 4f62: df 93 push r29 + 4f64: 1f 92 push r1 + 4f66: cd b7 in r28, 0x3d ; 61 + 4f68: de b7 in r29, 0x3e ; 62 + 4f6a: 68 2f mov r22, r24 + // set the bank + enc28j60SetBank(address); + 4f6c: 69 83 std Y+1, r22 ; 0x01 + 4f6e: 0e 94 5a 27 call 0x4eb4 ; 0x4eb4 + // do the read + uint8_t result = enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); + 4f72: 69 81 ldd r22, Y+1 ; 0x01 + 4f74: 80 e0 ldi r24, 0x00 ; 0 + return result; +} + 4f76: 0f 90 pop r0 + 4f78: df 91 pop r29 + 4f7a: cf 91 pop r28 +uint8_t enc28j60Read(uint8_t address) +{ + // set the bank + enc28j60SetBank(address); + // do the read + uint8_t result = enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); + 4f7c: 0c 94 8f 27 jmp 0x4f1e ; 0x4f1e + +00004f80 : + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +} + +void enc28j60PhyWrite(uint8_t address, uint16_t data) +{ + 4f80: 1f 93 push r17 + 4f82: cf 93 push r28 + 4f84: df 93 push r29 + 4f86: 1f 92 push r1 + 4f88: cd b7 in r28, 0x3d ; 61 + 4f8a: de b7 in r29, 0x3e ; 62 + 4f8c: 16 2f mov r17, r22 + // set the PHY register address + enc28j60Write(MIREGADR, address); + 4f8e: 68 2f mov r22, r24 + 4f90: 84 ed ldi r24, 0xD4 ; 212 + 4f92: 79 83 std Y+1, r23 ; 0x01 + 4f94: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // write the PHY data + enc28j60Write(MIWRL, data); + 4f98: 61 2f mov r22, r17 + 4f9a: 86 ed ldi r24, 0xD6 ; 214 + 4f9c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MIWRH, data>>8); + 4fa0: 79 81 ldd r23, Y+1 ; 0x01 + 4fa2: 67 2f mov r22, r23 + 4fa4: 87 ed ldi r24, 0xD7 ; 215 + 4fa6: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // wait until the PHY write completes + + while(enc28j60Read(MISTAT) & MISTAT_BUSY) + 4faa: 8a ee ldi r24, 0xEA ; 234 + 4fac: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 4fb0: 80 ff sbrs r24, 0 + 4fb2: 05 c0 rjmp .+10 ; 0x4fbe + { + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + 4fb4: 80 e0 ldi r24, 0x00 ; 0 + 4fb6: 90 e0 ldi r25, 0x00 ; 0 + 4fb8: 0e 94 81 43 call 0x8702 ; 0x8702 + 4fbc: f6 cf rjmp .-20 ; 0x4faa + } +} + 4fbe: 0f 90 pop r0 + 4fc0: df 91 pop r29 + 4fc2: cf 91 pop r28 + 4fc4: 1f 91 pop r17 + 4fc6: 08 95 ret + +00004fc8 : +} + +// read the revision of the chip: +uint8_t enc28j60getrev(void) +{ + return(enc28j60Read(EREVID)); + 4fc8: 82 e7 ldi r24, 0x72 ; 114 + 4fca: 0c 94 b0 27 jmp 0x4f60 ; 0x4f60 + +00004fce : +} + +// just probe if there might be a packet +uint8_t enc28j60hasRxPkt(void) +{ + if( enc28j60Read(EPKTCNT) ==0 ) + 4fce: 89 e3 ldi r24, 0x39 ; 57 + 4fd0: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 4fd4: 91 e0 ldi r25, 0x01 ; 1 + 4fd6: 81 11 cpse r24, r1 + 4fd8: 01 c0 rjmp .+2 ; 0x4fdc + 4fda: 90 e0 ldi r25, 0x00 ; 0 + { + return(0); + } + return(1); +} + 4fdc: 89 2f mov r24, r25 + 4fde: 08 95 ret + +00004fe0 : + +// read upper 8 bits +uint16_t enc28j60PhyReadH(uint8_t address) +{ + // Set the right address and start the register read operation + enc28j60Write(MIREGADR, address); + 4fe0: 61 e1 ldi r22, 0x11 ; 17 + 4fe2: 84 ed ldi r24, 0xD4 ; 212 + 4fe4: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MICMD, MICMD_MIIRD); + 4fe8: 61 e0 ldi r22, 0x01 ; 1 + 4fea: 82 ed ldi r24, 0xD2 ; 210 + 4fec: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + + vTaskDelay(0); + + // wait until the PHY read completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY) + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zawieszenie + 4ff0: 80 e0 ldi r24, 0x00 ; 0 + 4ff2: 90 e0 ldi r25, 0x00 ; 0 + 4ff4: 0e 94 81 43 call 0x8702 ; 0x8702 + enc28j60Write(MICMD, MICMD_MIIRD); + + vTaskDelay(0); + + // wait until the PHY read completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY) + 4ff8: 8a ee ldi r24, 0xEA ; 234 + 4ffa: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 4ffe: 80 fd sbrc r24, 0 + 5000: f7 cf rjmp .-18 ; 0x4ff0 + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zawieszenie + + // reset reading bit + enc28j60Write(MICMD, 0x00); + 5002: 60 e0 ldi r22, 0x00 ; 0 + 5004: 82 ed ldi r24, 0xD2 ; 210 + 5006: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + + return (enc28j60Read(MIRDH)); + 500a: 89 ed ldi r24, 0xD9 ; 217 + 500c: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + +// link status +uint8_t enc28j60linkup(void) +{ + // bit 10 (= bit 3 in upper reg) + return(enc28j60PhyReadH(PHSTAT2) && 4); + 5010: 91 e0 ldi r25, 0x01 ; 1 + 5012: 81 11 cpse r24, r1 + 5014: 01 c0 rjmp .+2 ; 0x5018 + 5016: 90 e0 ldi r25, 0x00 ; 0 +} + 5018: 89 2f mov r24, r25 + 501a: 08 95 ret + +0000501c : + +void nicSend(uint16_t len) +{ + 501c: 0f 93 push r16 + 501e: 1f 93 push r17 + 5020: cf 93 push r28 + 5022: df 93 push r29 + 5024: ec 01 movw r28, r24 + // Check no transmit in progress + while (enc28j60ReadOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS) + 5026: 6f e1 ldi r22, 0x1F ; 31 + 5028: 80 e0 ldi r24, 0x00 ; 0 + 502a: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 502e: 83 ff sbrs r24, 3 + 5030: 14 c0 rjmp .+40 ; 0x505a + { + // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. + if( (enc28j60Read(EIR) & EIR_TXERIF) ) + 5032: 8c e1 ldi r24, 0x1C ; 28 + 5034: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 5038: 81 ff sbrs r24, 1 + 503a: 0a c0 rjmp .+20 ; 0x5050 + { + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); + 503c: 40 e8 ldi r20, 0x80 ; 128 + 503e: 6f e1 ldi r22, 0x1F ; 31 + 5040: 80 e8 ldi r24, 0x80 ; 128 + 5042: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); + 5046: 40 e8 ldi r20, 0x80 ; 128 + 5048: 6f e1 ldi r22, 0x1F ; 31 + 504a: 80 ea ldi r24, 0xA0 ; 160 + 504c: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + } + vTaskDelay ( 0 ); //FIXME być może tutaj nastÄ™puje zakleszczenie + 5050: 80 e0 ldi r24, 0x00 ; 0 + 5052: 90 e0 ldi r25, 0x00 ; 0 + 5054: 0e 94 81 43 call 0x8702 ; 0x8702 + 5058: e6 cf rjmp .-52 ; 0x5026 + } + // Set the write pointer to start of transmit buffer area + enc28j60Write(EWRPTL, TXSTART_INIT&0xFF); + 505a: 6f ef ldi r22, 0xFF ; 255 + 505c: 82 e0 ldi r24, 0x02 ; 2 + 505e: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(EWRPTH, TXSTART_INIT>>8); + 5062: 69 e1 ldi r22, 0x19 ; 25 + 5064: 83 e0 ldi r24, 0x03 ; 3 + 5066: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // Set the TXND pointer to correspond to the packet size given + enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF); + 506a: 6c 2f mov r22, r28 + 506c: 61 50 subi r22, 0x01 ; 1 + 506e: 86 e0 ldi r24, 0x06 ; 6 + 5070: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + 5074: ce 01 movw r24, r28 + 5076: 81 50 subi r24, 0x01 ; 1 + 5078: 96 4e sbci r25, 0xE6 ; 230 + 507a: 69 2f mov r22, r25 + 507c: 87 e0 ldi r24, 0x07 ; 7 + 507e: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // write per-packet control byte (0x00 means use macon3 settings) + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + 5082: 40 e0 ldi r20, 0x00 ; 0 + 5084: 60 e0 ldi r22, 0x00 ; 0 + 5086: 8a e7 ldi r24, 0x7A ; 122 + 5088: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, nicState.layer2.buf); + 508c: 00 91 86 0e lds r16, 0x0E86 + 5090: 10 91 87 0e lds r17, 0x0E87 +} + +void enc28j60WriteBuffer(uint16_t len, uint8_t* data) +{ + //spiTake(); + spiEnableEnc28j60(); + 5094: 0e 94 2b 0f call 0x1e56 ; 0x1e56 + // issue write command + //spiSend(ENC28J60_WRITE_BUF_MEM); // + spiSendENC(ENC28J60_WRITE_BUF_MEM); + 5098: 8a e7 ldi r24, 0x7A ; 122 + 509a: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + 509e: c0 0f add r28, r16 + 50a0: d1 1f adc r29, r17 + while(len) + 50a2: 0c 17 cp r16, r28 + 50a4: 1d 07 cpc r17, r29 + 50a6: 31 f0 breq .+12 ; 0x50b4 + { + len--; + spiSendENC(*data); // write data + 50a8: f8 01 movw r30, r16 + 50aa: 81 91 ld r24, Z+ + 50ac: 8f 01 movw r16, r30 + 50ae: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + 50b2: f7 cf rjmp .-18 ; 0x50a2 + data++; + } + spiDisableEnc28j60(); + 50b4: 0e 94 2d 0f call 0x1e5a ; 0x1e5a + // write per-packet control byte (0x00 means use macon3 settings) + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, nicState.layer2.buf); + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); + 50b8: 48 e0 ldi r20, 0x08 ; 8 + 50ba: 6f e1 ldi r22, 0x1F ; 31 + 50bc: 80 e8 ldi r24, 0x80 ; 128 +} + 50be: df 91 pop r29 + 50c0: cf 91 pop r28 + 50c2: 1f 91 pop r17 + 50c4: 0f 91 pop r16 + // write per-packet control byte (0x00 means use macon3 settings) + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, nicState.layer2.buf); + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); + 50c6: 0c 94 3e 27 jmp 0x4e7c ; 0x4e7c + +000050ca : + } + return(1); +} + +uint16_t nicPoll(void) +{ + 50ca: ef 92 push r14 + 50cc: ff 92 push r15 + 50ce: 0f 93 push r16 + 50d0: 1f 93 push r17 + 50d2: cf 93 push r28 + 50d4: df 93 push r29 + uint16_t rxstat; + uint16_t len; + // check if a packet has been received and buffered + //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ + // The above does not work. See Rev. B4 Silicon Errata point 6. + if( enc28j60Read(EPKTCNT) == 0 ) + 50d6: 89 e3 ldi r24, 0x39 ; 57 + 50d8: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 50dc: 88 23 and r24, r24 + 50de: 09 f4 brne .+2 ; 0x50e2 + 50e0: 7f c0 rjmp .+254 ; 0x51e0 + { + return(0); + } + + // Set the read pointer to the start of the received packet + enc28j60Write(ERDPTL, (gNextPacketPtr &0xFF)); + 50e2: 60 91 90 01 lds r22, 0x0190 + 50e6: 80 e0 ldi r24, 0x00 ; 0 + 50e8: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERDPTH, (gNextPacketPtr)>>8); + 50ec: 60 91 91 01 lds r22, 0x0191 + 50f0: 81 e0 ldi r24, 0x01 ; 1 + 50f2: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // read the next packet pointer + gNextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 50f6: 60 e0 ldi r22, 0x00 ; 0 + 50f8: 8a e3 ldi r24, 0x3A ; 58 + 50fa: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 50fe: 90 e0 ldi r25, 0x00 ; 0 + 5100: 90 93 91 01 sts 0x0191, r25 + 5104: 80 93 90 01 sts 0x0190, r24 + gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 5108: 60 e0 ldi r22, 0x00 ; 0 + 510a: 8a e3 ldi r24, 0x3A ; 58 + 510c: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 5110: 20 91 90 01 lds r18, 0x0190 + 5114: 30 91 91 01 lds r19, 0x0191 + 5118: 38 2b or r19, r24 + 511a: 30 93 91 01 sts 0x0191, r19 + 511e: 20 93 90 01 sts 0x0190, r18 + // read the packet length (see datasheet page 43) + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 5122: 60 e0 ldi r22, 0x00 ; 0 + 5124: 8a e3 ldi r24, 0x3A ; 58 + 5126: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 512a: c8 2f mov r28, r24 + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 512c: 60 e0 ldi r22, 0x00 ; 0 + 512e: 8a e3 ldi r24, 0x3A ; 58 + 5130: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 5134: f8 2e mov r15, r24 + len-=4; //remove the CRC count + // read the receive status (see datasheet page 43) + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + 5136: 60 e0 ldi r22, 0x00 ; 0 + 5138: 8a e3 ldi r24, 0x3A ; 58 + 513a: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + 513e: 08 2f mov r16, r24 + rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8; + 5140: 60 e0 ldi r22, 0x00 ; 0 + 5142: 8a e3 ldi r24, 0x3A ; 58 + 5144: 0e 94 8f 27 call 0x4f1e ; 0x4f1e + // limit retrieve length + if (len> nicState.bufferSize -1) + 5148: 20 91 7e 0e lds r18, 0x0E7E + 514c: 30 91 7f 0e lds r19, 0x0E7F + } + // check CRC and symbol errors (see datasheet page 44, table 7-3): + // The ERXFCON.CRCEN is set by default. Normally we should not + // need to check this. + + if ((rxstat & 0x80)==0) + 5150: 07 ff sbrs r16, 7 + 5152: 24 c0 rjmp .+72 ; 0x519c + len-=4; //remove the CRC count + // read the receive status (see datasheet page 43) + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8; + // limit retrieve length + if (len> nicState.bufferSize -1) + 5154: 21 50 subi r18, 0x01 ; 1 + 5156: 31 09 sbc r19, r1 + // read the next packet pointer + gNextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the packet length (see datasheet page 43) + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + 5158: d0 e0 ldi r29, 0x00 ; 0 + 515a: df 29 or r29, r15 + 515c: 24 97 sbiw r28, 0x04 ; 4 + 515e: 2c 17 cp r18, r28 + 5160: 3d 07 cpc r19, r29 + 5162: 08 f4 brcc .+2 ; 0x5166 + 5164: e9 01 movw r28, r18 + len=0; + } + else + { + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, nicState.layer2.buf); + 5166: 00 91 86 0e lds r16, 0x0E86 + 516a: 10 91 87 0e lds r17, 0x0E87 +} + +void enc28j60ReadBuffer(uint16_t len, uint8_t* data) +{ + // spiTake(); + spiEnableEnc28j60(); + 516e: 0e 94 2b 0f call 0x1e56 ; 0x1e56 + spiSendENC(ENC28J60_READ_BUF_MEM); + 5172: 8a e3 ldi r24, 0x3A ; 58 + 5174: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + 5178: 78 01 movw r14, r16 + 517a: ec 0e add r14, r28 + 517c: fd 1e adc r15, r29 + while(len) + 517e: 0e 15 cp r16, r14 + 5180: 1f 05 cpc r17, r15 + 5182: 39 f0 breq .+14 ; 0x5192 + { + len--; + *data = spiSendENC(0x00); + 5184: 80 e0 ldi r24, 0x00 ; 0 + 5186: 0e 94 f9 0e call 0x1df2 ; 0x1df2 + 518a: f8 01 movw r30, r16 + 518c: 81 93 st Z+, r24 + 518e: 8f 01 movw r16, r30 + 5190: f6 cf rjmp .-20 ; 0x517e + data++; + } + *data='\0'; + 5192: f8 01 movw r30, r16 + 5194: 10 82 st Z, r1 + spiDisableEnc28j60(); + 5196: 0e 94 2d 0f call 0x1e5a ; 0x1e5a + 519a: 02 c0 rjmp .+4 ; 0x51a0 + // need to check this. + + if ((rxstat & 0x80)==0) + { + // invalid + len=0; + 519c: c0 e0 ldi r28, 0x00 ; 0 + 519e: d0 e0 ldi r29, 0x00 ; 0 + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, nicState.layer2.buf); + } + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out + enc28j60Write(ERXRDPTL, (gNextPacketPtr &0xFF)); + 51a0: 60 91 90 01 lds r22, 0x0190 + 51a4: 8c e0 ldi r24, 0x0C ; 12 + 51a6: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXRDPTH, (gNextPacketPtr)>>8); + 51aa: 60 91 91 01 lds r22, 0x0191 + 51ae: 8d e0 ldi r24, 0x0D ; 13 + 51b0: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXRDPTH, (RXSTOP_INIT)>>8); + } + else + { +#endif + enc28j60Write(ERXRDPTL, (gNextPacketPtr-1)&0xFF); + 51b4: 60 91 90 01 lds r22, 0x0190 + 51b8: 61 50 subi r22, 0x01 ; 1 + 51ba: 8c e0 ldi r24, 0x0C ; 12 + 51bc: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8); + 51c0: 80 91 90 01 lds r24, 0x0190 + 51c4: 90 91 91 01 lds r25, 0x0191 + 51c8: 01 97 sbiw r24, 0x01 ; 1 + 51ca: 69 2f mov r22, r25 + 51cc: 8d e0 ldi r24, 0x0D ; 13 + 51ce: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 +#if RXSTART_INIT > 0 + } +#endif + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + 51d2: 40 e4 ldi r20, 0x40 ; 64 + 51d4: 6e e1 ldi r22, 0x1E ; 30 + 51d6: 80 e8 ldi r24, 0x80 ; 128 + 51d8: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + return(len); + 51dc: ce 01 movw r24, r28 + 51de: 02 c0 rjmp .+4 ; 0x51e4 + // check if a packet has been received and buffered + //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ + // The above does not work. See Rev. B4 Silicon Errata point 6. + if( enc28j60Read(EPKTCNT) == 0 ) + { + return(0); + 51e0: 80 e0 ldi r24, 0x00 ; 0 + 51e2: 90 e0 ldi r25, 0x00 ; 0 + } +#endif + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + return(len); +} + 51e4: df 91 pop r29 + 51e6: cf 91 pop r28 + 51e8: 1f 91 pop r17 + 51ea: 0f 91 pop r16 + 51ec: ff 90 pop r15 + 51ee: ef 90 pop r14 + 51f0: 08 95 ret + +000051f2 : + +void spiEnableEnc28j60(void) {}; +void spiDisableEnc28j60(void) {}; + +void nicSetMacAddress(uint8_t* macaddr) +{ + 51f2: cf 93 push r28 + 51f4: df 93 push r29 + 51f6: ec 01 movw r28, r24 +//NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, macaddr[0]); + 51f8: 68 81 ld r22, Y + 51fa: 84 ee ldi r24, 0xE4 ; 228 + 51fc: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAADR4, macaddr[1]); + 5200: 69 81 ldd r22, Y+1 ; 0x01 + 5202: 85 ee ldi r24, 0xE5 ; 229 + 5204: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAADR3, macaddr[2]); + 5208: 6a 81 ldd r22, Y+2 ; 0x02 + 520a: 82 ee ldi r24, 0xE2 ; 226 + 520c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAADR2, macaddr[3]); + 5210: 6b 81 ldd r22, Y+3 ; 0x03 + 5212: 83 ee ldi r24, 0xE3 ; 227 + 5214: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAADR1, macaddr[4]); + 5218: 6c 81 ldd r22, Y+4 ; 0x04 + 521a: 80 ee ldi r24, 0xE0 ; 224 + 521c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAADR0, macaddr[5]); + 5220: 6d 81 ldd r22, Y+5 ; 0x05 + 5222: 81 ee ldi r24, 0xE1 ; 225 + //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); +} + 5224: df 91 pop r29 + 5226: cf 91 pop r28 + enc28j60Write(MAADR5, macaddr[0]); + enc28j60Write(MAADR4, macaddr[1]); + enc28j60Write(MAADR3, macaddr[2]); + enc28j60Write(MAADR2, macaddr[3]); + enc28j60Write(MAADR1, macaddr[4]); + enc28j60Write(MAADR0, macaddr[5]); + 5228: 0c 94 7c 27 jmp 0x4ef8 ; 0x4ef8 + +0000522c : +uint8_t enc28j60getrev(void); +uint8_t enc28j60linkup(void); + +void nicMacInit(void) +{ + vTaskDelay (5); + 522c: 85 e0 ldi r24, 0x05 ; 5 + 522e: 90 e0 ldi r25, 0x00 ; 0 + 5230: 0e 94 81 43 call 0x8702 ; 0x8702 +void enc28j60Init(uint8_t* macaddr) +{ + // perform system reset + + //ENC28j60 reset is on PE2 TODO add in hardware.c macros for that. + ENC_RST_ON; // PORTE &= ~0x04; + 5234: 1a 98 cbi 0x03, 2 ; 3 + vTaskDelay(5); // 50ms + 5236: 85 e0 ldi r24, 0x05 ; 5 + 5238: 90 e0 ldi r25, 0x00 ; 0 + 523a: 0e 94 81 43 call 0x8702 ; 0x8702 + ENC_RST_OFF; //PORTE |= 0x04; + 523e: 1a 9a sbi 0x03, 2 ; 3 + vTaskDelay(5); // 50ms + 5240: 85 e0 ldi r24, 0x05 ; 5 + 5242: 90 e0 ldi r25, 0x00 ; 0 + 5244: 0e 94 81 43 call 0x8702 ; 0x8702 + //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)); + // do bank 0 stuff + // initialize receive buffer + // 16-bit transfers, must write low byte first + // set receive buffer start address + gNextPacketPtr = RXSTART_INIT; + 5248: 10 92 91 01 sts 0x0191, r1 + 524c: 10 92 90 01 sts 0x0190, r1 + // Rx start + enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); + 5250: 60 e0 ldi r22, 0x00 ; 0 + 5252: 88 e0 ldi r24, 0x08 ; 8 + 5254: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXSTH, RXSTART_INIT>>8); + 5258: 60 e0 ldi r22, 0x00 ; 0 + 525a: 89 e0 ldi r24, 0x09 ; 9 + 525c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // set receive pointer address + enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + 5260: 60 e0 ldi r22, 0x00 ; 0 + 5262: 8c e0 ldi r24, 0x0C ; 12 + 5264: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + 5268: 60 e0 ldi r22, 0x00 ; 0 + 526a: 8d e0 ldi r24, 0x0D ; 13 + 526c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // RX end + enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + 5270: 6e ef ldi r22, 0xFE ; 254 + 5272: 8a e0 ldi r24, 0x0A ; 10 + 5274: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + 5278: 69 e1 ldi r22, 0x19 ; 25 + 527a: 8b e0 ldi r24, 0x0B ; 11 + 527c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // TX start + enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + 5280: 6f ef ldi r22, 0xFF ; 255 + 5282: 84 e0 ldi r24, 0x04 ; 4 + 5284: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ETXSTH, TXSTART_INIT>>8); + 5288: 69 e1 ldi r22, 0x19 ; 25 + 528a: 85 e0 ldi r24, 0x05 ; 5 + 528c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // TX end + enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF); + 5290: 6f ef ldi r22, 0xFF ; 255 + 5292: 86 e0 ldi r24, 0x06 ; 6 + 5294: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(ETXNDH, TXSTOP_INIT>>8); + 5298: 6f e1 ldi r22, 0x1F ; 31 + 529a: 87 e0 ldi r24, 0x07 ; 7 + 529c: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // ARP BROADCAST + // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 + // in binary these poitions are:11 0000 0011 1111 + // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 + //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); //Bez wejsca dla broadcastu (jak opis powyzej, wpusci tylko arp - na zasadzie checksumy zgodnej z pakietem) + enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_MCEN); //Z wejsciem dla calego broadcastu + 52a0: 62 eb ldi r22, 0xB2 ; 178 + 52a2: 88 e3 ldi r24, 0x38 ; 56 + 52a4: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(EPMM0, 0x3f); + 52a8: 6f e3 ldi r22, 0x3F ; 63 + 52aa: 88 e2 ldi r24, 0x28 ; 40 + 52ac: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(EPMM1, 0x30); + 52b0: 60 e3 ldi r22, 0x30 ; 48 + 52b2: 89 e2 ldi r24, 0x29 ; 41 + 52b4: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(EPMCSL, 0xf9); + 52b8: 69 ef ldi r22, 0xF9 ; 249 + 52ba: 80 e3 ldi r24, 0x30 ; 48 + 52bc: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(EPMCSH, 0xf7); + 52c0: 67 ef ldi r22, 0xF7 ; 247 + 52c2: 81 e3 ldi r24, 0x31 ; 49 + 52c4: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // + // + // do bank 2 stuff + // enable MAC receive + enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + 52c8: 6d e0 ldi r22, 0x0D ; 13 + 52ca: 80 ec ldi r24, 0xC0 ; 192 + 52cc: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // bring MAC out of reset + enc28j60Write(MACON2, 0x00); + 52d0: 60 e0 ldi r22, 0x00 ; 0 + 52d2: 81 ec ldi r24, 0xC1 ; 193 + 52d4: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // enable automatic padding to 60bytes and CRC operations + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + 52d8: 42 e3 ldi r20, 0x32 ; 50 + 52da: 62 ec ldi r22, 0xC2 ; 194 + 52dc: 80 e8 ldi r24, 0x80 ; 128 + 52de: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + // set inter-frame gap (non-back-to-back) + enc28j60Write(MAIPGL, 0x12); + 52e2: 62 e1 ldi r22, 0x12 ; 18 + 52e4: 86 ec ldi r24, 0xC6 ; 198 + 52e6: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAIPGH, 0x0C); + 52ea: 6c e0 ldi r22, 0x0C ; 12 + 52ec: 87 ec ldi r24, 0xC7 ; 199 + 52ee: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // set inter-frame gap (back-to-back) + enc28j60Write(MABBIPG, 0x12); + 52f2: 62 e1 ldi r22, 0x12 ; 18 + 52f4: 84 ec ldi r24, 0xC4 ; 196 + 52f6: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + // Set the maximum packet size which the controller will accept + // Do not send packets longer than MAX_FRAMELEN: + enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + 52fa: 6c ed ldi r22, 0xDC ; 220 + 52fc: 8a ec ldi r24, 0xCA ; 202 + 52fe: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + 5302: 65 e0 ldi r22, 0x05 ; 5 + 5304: 8b ec ldi r24, 0xCB ; 203 + 5306: 0e 94 7c 27 call 0x4ef8 ; 0x4ef8 + + // do bank 3 stuff + // write MAC address + + nicSetMacAddress(macaddr); + 530a: 80 e8 ldi r24, 0x80 ; 128 + 530c: 9e e0 ldi r25, 0x0E ; 14 + 530e: 0e 94 f9 28 call 0x51f2 ; 0x51f2 + + // no loopback of transmitted frames + enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + 5312: 60 e0 ldi r22, 0x00 ; 0 + 5314: 71 e0 ldi r23, 0x01 ; 1 + 5316: 80 e1 ldi r24, 0x10 ; 16 + 5318: 0e 94 c0 27 call 0x4f80 ; 0x4f80 + + enc28j60SetBank(ECON1); // switch to bank 0 + 531c: 8f e1 ldi r24, 0x1F ; 31 + 531e: 0e 94 5a 27 call 0x4eb4 ; 0x4eb4 + // enable interrutps + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + 5322: 40 ec ldi r20, 0xC0 ; 192 + 5324: 6b e1 ldi r22, 0x1B ; 27 + 5326: 80 e8 ldi r24, 0x80 ; 128 + 5328: 0e 94 3e 27 call 0x4e7c ; 0x4e7c + // enable packet reception + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); + 532c: 44 e0 ldi r20, 0x04 ; 4 + 532e: 6f e1 ldi r22, 0x1F ; 31 + 5330: 80 e8 ldi r24, 0x80 ; 128 + 5332: 0e 94 3e 27 call 0x4e7c ; 0x4e7c +void nicMacInit(void) +{ + vTaskDelay (5); + enc28j60Init (nicState.mac.addr); +// enc28j60clkout (2); // change clkout from 6.25MHz to 12.5MHz + vTaskDelay (5); + 5336: 85 e0 ldi r24, 0x05 ; 5 + 5338: 90 e0 ldi r25, 0x00 ; 0 + 533a: 0e 94 81 43 call 0x8702 ; 0x8702 + enc28j60PhyWrite (PHLCON, 0x476); + 533e: 66 e7 ldi r22, 0x76 ; 118 + 5340: 74 e0 ldi r23, 0x04 ; 4 + 5342: 84 e1 ldi r24, 0x14 ; 20 + 5344: 0e 94 c0 27 call 0x4f80 ; 0x4f80 + vTaskDelay (2); + 5348: 82 e0 ldi r24, 0x02 ; 2 + 534a: 90 e0 ldi r25, 0x00 ; 0 + 534c: 0c 94 81 43 jmp 0x8702 ; 0x8702 + +00005350 : + enc28j60Write(MAADR0, macaddr[5]); + //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); +} + +void nicGetMacAddress(uint8_t* macaddr) +{ + 5350: cf 93 push r28 + 5352: df 93 push r29 + 5354: ec 01 movw r28, r24 + macaddr[5] = enc28j60Read(MAADR0); + 5356: 81 ee ldi r24, 0xE1 ; 225 + 5358: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 535c: 8d 83 std Y+5, r24 ; 0x05 + macaddr[4] = enc28j60Read(MAADR1); + 535e: 80 ee ldi r24, 0xE0 ; 224 + 5360: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 5364: 8c 83 std Y+4, r24 ; 0x04 + macaddr[3] = enc28j60Read(MAADR2); + 5366: 83 ee ldi r24, 0xE3 ; 227 + 5368: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 536c: 8b 83 std Y+3, r24 ; 0x03 + macaddr[2] = enc28j60Read(MAADR3); + 536e: 82 ee ldi r24, 0xE2 ; 226 + 5370: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 5374: 8a 83 std Y+2, r24 ; 0x02 + macaddr[1] = enc28j60Read(MAADR4); + 5376: 85 ee ldi r24, 0xE5 ; 229 + 5378: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 537c: 89 83 std Y+1, r24 ; 0x01 + macaddr[0] = enc28j60Read(MAADR5); + 537e: 84 ee ldi r24, 0xE4 ; 228 + 5380: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 5384: 88 83 st Y, r24 + //strncpy((void *)(nicState.mac.addr), (void *)(macaddr), 6); +} + 5386: df 91 pop r29 + 5388: cf 91 pop r28 + 538a: 08 95 ret + +0000538c : + +void nicRegDump(FILE *stream) +{ + 538c: cf 93 push r28 + 538e: df 93 push r29 + 5390: ec 01 movw r28, r24 + uint8_t temp; + fprintf_P(stream, PSTR("ENC28j60 stan rejestrow:\r\n")); + 5392: 84 e6 ldi r24, 0x64 ; 100 + 5394: 9c e0 ldi r25, 0x0C ; 12 + 5396: 9f 93 push r25 + 5398: 8f 93 push r24 + 539a: df 93 push r29 + 539c: cf 93 push r28 + 539e: 0e 94 1a 50 call 0xa034 ; 0xa034 + + temp = enc28j60Read(MAADR0); fprintf_P(stream, PSTR("\tMAADR0 0x%x\r\n"), temp); + 53a2: 81 ee ldi r24, 0xE1 ; 225 + 53a4: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 53a8: 1f 92 push r1 + 53aa: 8f 93 push r24 + 53ac: 85 e5 ldi r24, 0x55 ; 85 + 53ae: 9c e0 ldi r25, 0x0C ; 12 + 53b0: 9f 93 push r25 + 53b2: 8f 93 push r24 + 53b4: df 93 push r29 + 53b6: cf 93 push r28 + 53b8: 0e 94 1a 50 call 0xa034 ; 0xa034 + temp = enc28j60Read(MAADR1); fprintf_P(stream, PSTR("\tMAADR1 0x%x\r\n"), temp); + 53bc: 80 ee ldi r24, 0xE0 ; 224 + 53be: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 53c2: 1f 92 push r1 + 53c4: 8f 93 push r24 + 53c6: 86 e4 ldi r24, 0x46 ; 70 + 53c8: 9c e0 ldi r25, 0x0C ; 12 + 53ca: 9f 93 push r25 + 53cc: 8f 93 push r24 + 53ce: df 93 push r29 + 53d0: cf 93 push r28 + 53d2: 0e 94 1a 50 call 0xa034 ; 0xa034 + temp = enc28j60Read(MAADR2); fprintf_P(stream, PSTR("\tMAADR2 0x%x\r\n"), temp); + 53d6: 83 ee ldi r24, 0xE3 ; 227 + 53d8: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 53dc: 1f 92 push r1 + 53de: 8f 93 push r24 + 53e0: 87 e3 ldi r24, 0x37 ; 55 + 53e2: 9c e0 ldi r25, 0x0C ; 12 + 53e4: 9f 93 push r25 + 53e6: 8f 93 push r24 + 53e8: df 93 push r29 + 53ea: cf 93 push r28 + 53ec: 0e 94 1a 50 call 0xa034 ; 0xa034 + temp = enc28j60Read(MAADR3); fprintf_P(stream, PSTR("\tMAADR3 0x%x\r\n"), temp); + 53f0: 82 ee ldi r24, 0xE2 ; 226 + 53f2: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 53f6: 1f 92 push r1 + 53f8: 8f 93 push r24 + 53fa: 88 e2 ldi r24, 0x28 ; 40 + 53fc: 9c e0 ldi r25, 0x0C ; 12 + 53fe: 9f 93 push r25 + 5400: 8f 93 push r24 + 5402: df 93 push r29 + 5404: cf 93 push r28 + 5406: 0e 94 1a 50 call 0xa034 ; 0xa034 + temp = enc28j60Read(MAADR4); fprintf_P(stream, PSTR("\tMAADR4 0x%x\r\n"), temp); + 540a: 85 ee ldi r24, 0xE5 ; 229 + 540c: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 5410: 1f 92 push r1 + 5412: 8f 93 push r24 + 5414: 89 e1 ldi r24, 0x19 ; 25 + 5416: 9c e0 ldi r25, 0x0C ; 12 + 5418: 9f 93 push r25 + 541a: 8f 93 push r24 + 541c: df 93 push r29 + 541e: cf 93 push r28 + 5420: 0e 94 1a 50 call 0xa034 ; 0xa034 + temp = enc28j60Read(MAADR5); fprintf_P(stream, PSTR("\tMAADR5 0x%x\r\n"), temp); + 5424: 8d b7 in r24, 0x3d ; 61 + 5426: 9e b7 in r25, 0x3e ; 62 + 5428: 82 96 adiw r24, 0x22 ; 34 + 542a: 0f b6 in r0, 0x3f ; 63 + 542c: f8 94 cli + 542e: 9e bf out 0x3e, r25 ; 62 + 5430: 0f be out 0x3f, r0 ; 63 + 5432: 8d bf out 0x3d, r24 ; 61 + 5434: 84 ee ldi r24, 0xE4 ; 228 + 5436: 0e 94 b0 27 call 0x4f60 ; 0x4f60 + 543a: 1f 92 push r1 + 543c: 8f 93 push r24 + 543e: 8a e0 ldi r24, 0x0A ; 10 + 5440: 9c e0 ldi r25, 0x0C ; 12 + 5442: 9f 93 push r25 + 5444: 8f 93 push r24 + 5446: df 93 push r29 + 5448: cf 93 push r28 + 544a: 0e 94 1a 50 call 0xa034 ; 0xa034 + 544e: 0f 90 pop r0 + 5450: 0f 90 pop r0 + 5452: 0f 90 pop r0 + 5454: 0f 90 pop r0 + 5456: 0f 90 pop r0 + 5458: 0f 90 pop r0 +} + 545a: df 91 pop r29 + 545c: cf 91 pop r28 + 545e: 08 95 ret + +00005460 : + xQueueSend( strBuf->Tx, &c, portMAX_DELAY); + return 0; +} + +static int streamQueueInputFun(FILE *istream) +{ + 5460: cf 93 push r28 + 5462: df 93 push r29 + 5464: 1f 92 push r1 + 5466: cd b7 in r28, 0x3d ; 61 + 5468: de b7 in r29, 0x3e ; 62 + char c; + streamBuffers_t *strBuf = (streamBuffers_t *) istream->udata; + xQueueReceive(strBuf->Rx, &c, portMAX_DELAY); + 546a: dc 01 movw r26, r24 + 546c: 1c 96 adiw r26, 0x0c ; 12 + 546e: ed 91 ld r30, X+ + 5470: fc 91 ld r31, X + 5472: 1d 97 sbiw r26, 0x0d ; 13 + 5474: 20 e0 ldi r18, 0x00 ; 0 + 5476: 4f ef ldi r20, 0xFF ; 255 + 5478: 5f ef ldi r21, 0xFF ; 255 + 547a: be 01 movw r22, r28 + 547c: 6f 5f subi r22, 0xFF ; 255 + 547e: 7f 4f sbci r23, 0xFF ; 255 + 5480: 80 81 ld r24, Z + 5482: 91 81 ldd r25, Z+1 ; 0x01 + 5484: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + return c; + 5488: 89 81 ldd r24, Y+1 ; 0x01 +} + 548a: 08 2e mov r0, r24 + 548c: 00 0c add r0, r0 + 548e: 99 0b sbc r25, r25 + 5490: 0f 90 pop r0 + 5492: df 91 pop r29 + 5494: cf 91 pop r28 + 5496: 08 95 ret + +00005498 : + buffer->Tx = Tx; + return; +} + +static int streamQueueOutputFun(char c, FILE *ostream) +{ + 5498: cf 93 push r28 + 549a: df 93 push r29 + 549c: 1f 92 push r1 + 549e: cd b7 in r28, 0x3d ; 61 + 54a0: de b7 in r29, 0x3e ; 62 + 54a2: 89 83 std Y+1, r24 ; 0x01 +/* if (xQueueSend( strBuf->Tx, &c, strBuf->tx_timeout)) + { + return EOF; + } + else*/ + xQueueSend( strBuf->Tx, &c, portMAX_DELAY); + 54a4: db 01 movw r26, r22 + 54a6: 1c 96 adiw r26, 0x0c ; 12 + 54a8: ed 91 ld r30, X+ + 54aa: fc 91 ld r31, X + 54ac: 1d 97 sbiw r26, 0x0d ; 13 + 54ae: 20 e0 ldi r18, 0x00 ; 0 + 54b0: 4f ef ldi r20, 0xFF ; 255 + 54b2: 5f ef ldi r21, 0xFF ; 255 + 54b4: be 01 movw r22, r28 + 54b6: 6f 5f subi r22, 0xFF ; 255 + 54b8: 7f 4f sbci r23, 0xFF ; 255 + 54ba: 82 81 ldd r24, Z+2 ; 0x02 + 54bc: 93 81 ldd r25, Z+3 ; 0x03 + 54be: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + return 0; +} + 54c2: 80 e0 ldi r24, 0x00 ; 0 + 54c4: 90 e0 ldi r25, 0x00 ; 0 + 54c6: 0f 90 pop r0 + 54c8: df 91 pop r29 + 54ca: cf 91 pop r28 + 54cc: 08 95 ret + +000054ce : + +static int streamQueueOutputFun(char c, FILE *ostream); +static int streamQueueInputFun(FILE *istream); + +void initQueueStream(FILE *stream, streamBuffers_t *buffer, xQueueHandle Rx, xQueueHandle Tx) +{ + 54ce: fc 01 movw r30, r24 + fdev_setup_stream(stream, streamQueueOutputFun, streamQueueInputFun, _FDEV_SETUP_RW); + 54d0: 8c e4 ldi r24, 0x4C ; 76 + 54d2: 9a e2 ldi r25, 0x2A ; 42 + 54d4: 91 87 std Z+9, r25 ; 0x09 + 54d6: 80 87 std Z+8, r24 ; 0x08 + 54d8: 80 e3 ldi r24, 0x30 ; 48 + 54da: 9a e2 ldi r25, 0x2A ; 42 + 54dc: 93 87 std Z+11, r25 ; 0x0b + 54de: 82 87 std Z+10, r24 ; 0x0a + 54e0: 83 e0 ldi r24, 0x03 ; 3 + 54e2: 83 83 std Z+3, r24 ; 0x03 + fdev_set_udata(stream, (void *)buffer); + 54e4: 75 87 std Z+13, r23 ; 0x0d + 54e6: 64 87 std Z+12, r22 ; 0x0c + buffer->Rx = Rx; + 54e8: fb 01 movw r30, r22 + 54ea: 51 83 std Z+1, r21 ; 0x01 + 54ec: 40 83 st Z, r20 + buffer->Tx = Tx; + 54ee: 33 83 std Z+3, r19 ; 0x03 + 54f0: 22 83 std Z+2, r18 ; 0x02 + 54f2: 08 95 ret + 54f4: 08 95 ret + 54f6: 08 95 ret + 54f8: 80 e0 ldi r24, 0x00 ; 0 + 54fa: 90 e0 ldi r25, 0x00 ; 0 + 54fc: 08 95 ret + +000054fe : + nicLoadConfig(); +} + +void nicLoadConfig(void) +{ + eeprom_read_block(&nicState.mac.addr, mymac_eep, 6); + 54fe: 46 e0 ldi r20, 0x06 ; 6 + 5500: 50 e0 ldi r21, 0x00 ; 0 + 5502: 60 e2 ldi r22, 0x20 ; 32 + 5504: 70 e0 ldi r23, 0x00 ; 0 + 5506: 80 e8 ldi r24, 0x80 ; 128 + 5508: 9e e0 ldi r25, 0x0E ; 14 + 550a: 0c 94 3d 53 jmp 0xa67a ; 0xa67a + +0000550e : +} + +void nicSaveConfig(void) +{ + eeprom_update_block(&nicState.mac.addr, mymac_eep, 6); + 550e: 46 e0 ldi r20, 0x06 ; 6 + 5510: 50 e0 ldi r21, 0x00 ; 0 + 5512: 60 e2 ldi r22, 0x20 ; 32 + 5514: 70 e0 ldi r23, 0x00 ; 0 + 5516: 80 e8 ldi r24, 0x80 ; 128 + 5518: 9e e0 ldi r25, 0x0E ; 14 + 551a: 0c 94 59 53 jmp 0xa6b2 ; 0xa6b2 + +0000551e : + + + +static void nicBufferInit(void) +{ + nicState.bufferSize = NETWORK_STACK_BUF_SIZE; + 551e: ee e7 ldi r30, 0x7E ; 126 + 5520: fe e0 ldi r31, 0x0E ; 14 + 5522: 80 e0 ldi r24, 0x00 ; 0 + 5524: 96 e0 ldi r25, 0x06 ; 6 + 5526: 91 83 std Z+1, r25 ; 0x01 + 5528: 80 83 st Z, r24 + nicState.layer2.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR); + 552a: a0 e0 ldi r26, 0x00 ; 0 + 552c: ba e7 ldi r27, 0x7A ; 122 + 552e: b1 87 std Z+9, r27 ; 0x09 + 5530: a0 87 std Z+8, r26 ; 0x08 + nicState.layer3.ip = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te wartosci beda ustawiane w czasie analizy pakietu + 5532: 2e e0 ldi r18, 0x0E ; 14 + 5534: 3a e7 ldi r19, 0x7A ; 122 + 5536: 33 87 std Z+11, r19 ; 0x0b + 5538: 22 87 std Z+10, r18 ; 0x0a + nicState.layer4.icmp = (struct netIcmpHeader *)(NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN + IP_HEADER_LEN); + 553a: 22 e2 ldi r18, 0x22 ; 34 + 553c: 3a e7 ldi r19, 0x7A ; 122 + 553e: 35 87 std Z+13, r19 ; 0x0d + 5540: 24 87 std Z+12, r18 ; 0x0c + #if IPV6_SUPPORT + nicState.layer3.ipv6 = (struct netIpHeader *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + nicState.layer3.buf = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); + //nicState.layer4.icmpv6 = (uint8_t *) (NETWORK_STACK_BUF_ADDR + ETH_HEADER_LEN); //Te wartosci beda ustawiane w czasie analizy pakietu + #endif /*IPV6_SUPPORT*/ + memset(nicState.layer2.buf, 0, nicState.bufferSize); + 5542: fd 01 movw r30, r26 + 5544: 9c 01 movw r18, r24 + 5546: 11 92 st Z+, r1 + 5548: 21 50 subi r18, 0x01 ; 1 + 554a: 30 40 sbci r19, 0x00 ; 0 + 554c: e1 f7 brne .-8 ; 0x5546 + nicLoadConfig(); + 554e: 0e 94 7f 2a call 0x54fe ; 0x54fe +} + +void nicInit() +{ + nicBufferInit(); + nicMacInit(); + 5552: 0c 94 16 29 jmp 0x522c ; 0x522c + 5556: 46 e0 ldi r20, 0x06 ; 6 + 5558: 50 e0 ldi r21, 0x00 ; 0 + 555a: 60 e8 ldi r22, 0x80 ; 128 + 555c: 7e e0 ldi r23, 0x0E ; 14 + 555e: 0c 94 a6 4f jmp 0x9f4c ; 0x9f4c + 5562: 46 e0 ldi r20, 0x06 ; 6 + 5564: 50 e0 ldi r21, 0x00 ; 0 + 5566: bc 01 movw r22, r24 + 5568: 80 e8 ldi r24, 0x80 ; 128 + 556a: 9e e0 ldi r25, 0x0E ; 14 + 556c: 0e 94 a6 4f call 0x9f4c ; 0x9f4c + 5570: 0c 94 16 29 jmp 0x522c ; 0x522c + 5574: 2f e7 ldi r18, 0x7F ; 127 + 5576: 3c e0 ldi r19, 0x0C ; 12 + 5578: 3f 93 push r19 + 557a: 2f 93 push r18 + 557c: 9f 93 push r25 + 557e: 8f 93 push r24 + 5580: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5584: 0f 90 pop r0 + 5586: 0f 90 pop r0 + 5588: 0f 90 pop r0 + 558a: 0f 90 pop r0 + 558c: 08 95 ret + +0000558e : + + +uint16_t ntohs(uint16_t val) +{ + return (val<<8) | (val>>8); +} + 558e: 98 27 eor r25, r24 + 5590: 89 27 eor r24, r25 + 5592: 98 27 eor r25, r24 + 5594: 08 95 ret + +00005596 : + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); +} + 5596: 98 27 eor r25, r24 + 5598: 89 27 eor r24, r25 + 559a: 98 27 eor r25, r24 + 559c: 08 95 ret + +0000559e : + +uint32_t htonl(uint32_t val) +{ + 559e: 0e 94 f7 4c call 0x99ee ; 0x99ee <__bswapsi2> + return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); +} + 55a2: 08 95 ret + +000055a4 : + +uint32_t ntohl(uint32_t val) +{ + 55a4: 0e 94 f7 4c call 0x99ee ; 0x99ee <__bswapsi2> + return (ntohs(val>>16) | (uint32_t)ntohs(val&0x0000FFFF)<<16); +} + 55a8: 08 95 ret + +000055aa : + + +uint16_t netChecksum(uint8_t *data, uint16_t len) +{ + 55aa: cf 93 push r28 + 55ac: df 93 push r29 + 55ae: db 01 movw r26, r22 + 55b0: 9b 01 movw r18, r22 + 55b2: fc 01 movw r30, r24 + register uint32_t sum = 0; + 55b4: 40 e0 ldi r20, 0x00 ; 0 + 55b6: 50 e0 ldi r21, 0x00 ; 0 + 55b8: ba 01 movw r22, r20 + + for (;;) + { + if (len < 2) + 55ba: 22 30 cpi r18, 0x02 ; 2 + 55bc: 31 05 cpc r19, r1 + 55be: 48 f0 brcs .+18 ; 0x55d2 + break; +//sum += *((uint16_t *)data)++; + sum += *((uint16_t *)data); + 55c0: c1 91 ld r28, Z+ + 55c2: d1 91 ld r29, Z+ + 55c4: 4c 0f add r20, r28 + 55c6: 5d 1f adc r21, r29 + 55c8: 61 1d adc r22, r1 + 55ca: 71 1d adc r23, r1 + data+=2; + len -= 2; + 55cc: 22 50 subi r18, 0x02 ; 2 + 55ce: 31 09 sbc r19, r1 + } + 55d0: f4 cf rjmp .-24 ; 0x55ba + 55d2: 9d 01 movw r18, r26 + 55d4: 2e 7f andi r18, 0xFE ; 254 + 55d6: fc 01 movw r30, r24 + 55d8: e2 0f add r30, r18 + 55da: f3 1f adc r31, r19 + if (len) + 55dc: a0 ff sbrs r26, 0 + 55de: 05 c0 rjmp .+10 ; 0x55ea + sum += *(uint8_t *) data; + 55e0: 80 81 ld r24, Z + 55e2: 48 0f add r20, r24 + 55e4: 51 1d adc r21, r1 + 55e6: 61 1d adc r22, r1 + 55e8: 71 1d adc r23, r1 + + while ((len = (uint16_t) (sum >> 16)) != 0) + 55ea: cb 01 movw r24, r22 + 55ec: aa 27 eor r26, r26 + 55ee: bb 27 eor r27, r27 + 55f0: 00 97 sbiw r24, 0x00 ; 0 + 55f2: 29 f0 breq .+10 ; 0x55fe + sum = (uint16_t) sum + len; + 55f4: 48 0f add r20, r24 + 55f6: 59 1f adc r21, r25 + 55f8: 60 e0 ldi r22, 0x00 ; 0 + 55fa: 70 e0 ldi r23, 0x00 ; 0 + 55fc: f6 cf rjmp .-20 ; 0x55ea + + return (uint16_t) sum ^ 0xFFFF; + 55fe: ca 01 movw r24, r20 + 5600: 80 95 com r24 + 5602: 90 95 com r25 +} + 5604: df 91 pop r29 + 5606: cf 91 pop r28 + 5608: 08 95 ret + +0000560a : + +void netPrintEthAddr(FILE *stream, struct netEthAddr* ethaddr) +{ + 560a: fb 01 movw r30, r22 + fprintf_P(stream, PSTR("%02x:%02x:%02x:%02x:%02x:%02x"), ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]); + 560c: 25 81 ldd r18, Z+5 ; 0x05 + 560e: 1f 92 push r1 + 5610: 2f 93 push r18 + 5612: 24 81 ldd r18, Z+4 ; 0x04 + 5614: 1f 92 push r1 + 5616: 2f 93 push r18 + 5618: 23 81 ldd r18, Z+3 ; 0x03 + 561a: 1f 92 push r1 + 561c: 2f 93 push r18 + 561e: 22 81 ldd r18, Z+2 ; 0x02 + 5620: 1f 92 push r1 + 5622: 2f 93 push r18 + 5624: 21 81 ldd r18, Z+1 ; 0x01 + 5626: 1f 92 push r1 + 5628: 2f 93 push r18 + 562a: 20 81 ld r18, Z + 562c: 1f 92 push r1 + 562e: 2f 93 push r18 + 5630: 2a ec ldi r18, 0xCA ; 202 + 5632: 3d e0 ldi r19, 0x0D ; 13 + 5634: 3f 93 push r19 + 5636: 2f 93 push r18 + 5638: 9f 93 push r25 + 563a: 8f 93 push r24 + 563c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5640: 8d b7 in r24, 0x3d ; 61 + 5642: 9e b7 in r25, 0x3e ; 62 + 5644: 40 96 adiw r24, 0x10 ; 16 + 5646: 0f b6 in r0, 0x3f ; 63 + 5648: f8 94 cli + 564a: 9e bf out 0x3e, r25 ; 62 + 564c: 0f be out 0x3f, r0 ; 63 + 564e: 8d bf out 0x3d, r24 ; 61 + 5650: 08 95 ret + +00005652 : +} + +void netPrintIPAddr(FILE *stream, uint32_t ipaddr) +{ + 5652: cf 93 push r28 + 5654: df 93 push r29 + 5656: 00 d0 rcall .+0 ; 0x5658 + 5658: 00 d0 rcall .+0 ; 0x565a + 565a: cd b7 in r28, 0x3d ; 61 + 565c: de b7 in r29, 0x3e ; 62 + 565e: 49 83 std Y+1, r20 ; 0x01 + 5660: 5a 83 std Y+2, r21 ; 0x02 + 5662: 6b 83 std Y+3, r22 ; 0x03 + 5664: 7c 83 std Y+4, r23 ; 0x04 + fprintf_P(stream, PSTR("%d.%d.%d.%d"), ((unsigned char*)&ipaddr)[0], ((unsigned char*)&ipaddr)[1], ((unsigned char*)&ipaddr)[2], ((unsigned char*)&ipaddr)[3]); + 5666: 2c 81 ldd r18, Y+4 ; 0x04 + 5668: 1f 92 push r1 + 566a: 2f 93 push r18 + 566c: 2b 81 ldd r18, Y+3 ; 0x03 + 566e: 1f 92 push r1 + 5670: 2f 93 push r18 + 5672: 2a 81 ldd r18, Y+2 ; 0x02 + 5674: 1f 92 push r1 + 5676: 2f 93 push r18 + 5678: 29 81 ldd r18, Y+1 ; 0x01 + 567a: 1f 92 push r1 + 567c: 2f 93 push r18 + 567e: 2e eb ldi r18, 0xBE ; 190 + 5680: 3d e0 ldi r19, 0x0D ; 13 + 5682: 3f 93 push r19 + 5684: 2f 93 push r18 + 5686: 9f 93 push r25 + 5688: 8f 93 push r24 + 568a: 0e 94 1a 50 call 0xa034 ; 0xa034 + 568e: 0f b6 in r0, 0x3f ; 63 + 5690: f8 94 cli + 5692: de bf out 0x3e, r29 ; 62 + 5694: 0f be out 0x3f, r0 ; 63 + 5696: cd bf out 0x3d, r28 ; 61 +} + 5698: 0f 90 pop r0 + 569a: 0f 90 pop r0 + 569c: 0f 90 pop r0 + 569e: 0f 90 pop r0 + 56a0: df 91 pop r29 + 56a2: cf 91 pop r28 + 56a4: 08 95 ret + +000056a6 : + +void netPrintEthHeader(FILE *stream, struct netEthHeader* eth_hdr) +{ + 56a6: 0f 93 push r16 + 56a8: 1f 93 push r17 + 56aa: cf 93 push r28 + 56ac: df 93 push r29 + 56ae: d8 2f mov r29, r24 + 56b0: c9 2f mov r28, r25 + 56b2: 8b 01 movw r16, r22 + fprintf_P(stream, PSTR("Eth Packet Type: 0x%x"), eth_hdr->type); + 56b4: fb 01 movw r30, r22 + 56b6: 85 85 ldd r24, Z+13 ; 0x0d + 56b8: 8f 93 push r24 + 56ba: 84 85 ldd r24, Z+12 ; 0x0c + 56bc: 8f 93 push r24 + 56be: 88 ea ldi r24, 0xA8 ; 168 + 56c0: 9d e0 ldi r25, 0x0D ; 13 + 56c2: 9f 93 push r25 + 56c4: 8f 93 push r24 + 56c6: cf 93 push r28 + 56c8: df 93 push r29 + 56ca: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR(" SRC:")); + 56ce: 82 ea ldi r24, 0xA2 ; 162 + 56d0: 9d e0 ldi r25, 0x0D ; 13 + 56d2: 9f 93 push r25 + 56d4: 8f 93 push r24 + 56d6: cf 93 push r28 + 56d8: df 93 push r29 + 56da: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintEthAddr(stream, ð_hdr->src); + 56de: b8 01 movw r22, r16 + 56e0: 6a 5f subi r22, 0xFA ; 250 + 56e2: 7f 4f sbci r23, 0xFF ; 255 + 56e4: 8d 2f mov r24, r29 + 56e6: 9c 2f mov r25, r28 + 56e8: 0e 94 05 2b call 0x560a ; 0x560a + fprintf_P(stream, PSTR("->DST:")); + 56ec: 8b e9 ldi r24, 0x9B ; 155 + 56ee: 9d e0 ldi r25, 0x0D ; 13 + 56f0: 9f 93 push r25 + 56f2: 8f 93 push r24 + 56f4: cf 93 push r28 + 56f6: df 93 push r29 + 56f8: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintEthAddr(stream, ð_hdr->dest); + 56fc: 8d b7 in r24, 0x3d ; 61 + 56fe: 9e b7 in r25, 0x3e ; 62 + 5700: 0e 96 adiw r24, 0x0e ; 14 + 5702: 0f b6 in r0, 0x3f ; 63 + 5704: f8 94 cli + 5706: 9e bf out 0x3e, r25 ; 62 + 5708: 0f be out 0x3f, r0 ; 63 + 570a: 8d bf out 0x3d, r24 ; 61 + 570c: b8 01 movw r22, r16 + 570e: 8d 2f mov r24, r29 + 5710: 9c 2f mov r25, r28 +} + 5712: df 91 pop r29 + 5714: cf 91 pop r28 + 5716: 1f 91 pop r17 + 5718: 0f 91 pop r16 +{ + fprintf_P(stream, PSTR("Eth Packet Type: 0x%x"), eth_hdr->type); + fprintf_P(stream, PSTR(" SRC:")); + netPrintEthAddr(stream, ð_hdr->src); + fprintf_P(stream, PSTR("->DST:")); + netPrintEthAddr(stream, ð_hdr->dest); + 571a: 0c 94 05 2b jmp 0x560a ; 0x560a + +0000571e : +} + +void netPrintIpHeader(FILE *stream, struct netIpHeader* ipheader) +{ + 571e: 0f 93 push r16 + 5720: 1f 93 push r17 + 5722: cf 93 push r28 + 5724: df 93 push r29 + 5726: ec 01 movw r28, r24 + 5728: 8b 01 movw r16, r22 + fprintf_P(stream, PSTR("IP Header\r\n")); + 572a: 8f e8 ldi r24, 0x8F ; 143 + 572c: 9d e0 ldi r25, 0x0D ; 13 + 572e: 9f 93 push r25 + 5730: 8f 93 push r24 + 5732: df 93 push r29 + 5734: cf 93 push r28 + 5736: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Ver : %d\r\n"), (ipheader->vhl)>>4); + 573a: f8 01 movw r30, r16 + 573c: 80 81 ld r24, Z + 573e: 82 95 swap r24 + 5740: 8f 70 andi r24, 0x0F ; 15 + 5742: 1f 92 push r1 + 5744: 8f 93 push r24 + 5746: 80 e8 ldi r24, 0x80 ; 128 + 5748: 9d e0 ldi r25, 0x0D ; 13 + 574a: 9f 93 push r25 + 574c: 8f 93 push r24 + 574e: df 93 push r29 + 5750: cf 93 push r28 + 5752: 0e 94 1a 50 call 0xa034 ; 0xa034 + return (val<<8) | (val>>8); +} + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); + 5756: f8 01 movw r30, r16 + 5758: 82 81 ldd r24, Z+2 ; 0x02 + 575a: 93 81 ldd r25, Z+3 ; 0x03 + 575c: 98 27 eor r25, r24 + 575e: 89 27 eor r24, r25 + 5760: 98 27 eor r25, r24 + +void netPrintIpHeader(FILE *stream, struct netIpHeader* ipheader) +{ + fprintf_P(stream, PSTR("IP Header\r\n")); + fprintf_P(stream, PSTR("Ver : %d\r\n"), (ipheader->vhl)>>4); + fprintf_P(stream, PSTR("Length : %d\r\n"), htons(ipheader->len)); + 5762: 9f 93 push r25 + 5764: 8f 93 push r24 + 5766: 81 e7 ldi r24, 0x71 ; 113 + 5768: 9d e0 ldi r25, 0x0D ; 13 + 576a: 9f 93 push r25 + 576c: 8f 93 push r24 + 576e: df 93 push r29 + 5770: cf 93 push r28 + 5772: 0e 94 1a 50 call 0xa034 ; 0xa034 + if(ipheader->proto == IP_PROTO_ICMP) + 5776: f8 01 movw r30, r16 + 5778: 81 85 ldd r24, Z+9 ; 0x09 + 577a: 2d b7 in r18, 0x3d ; 61 + 577c: 3e b7 in r19, 0x3e ; 62 + 577e: 20 5f subi r18, 0xF0 ; 240 + 5780: 3f 4f sbci r19, 0xFF ; 255 + 5782: 0f b6 in r0, 0x3f ; 63 + 5784: f8 94 cli + 5786: 3e bf out 0x3e, r19 ; 62 + 5788: 0f be out 0x3f, r0 ; 63 + 578a: 2d bf out 0x3d, r18 ; 61 + 578c: 81 30 cpi r24, 0x01 ; 1 + 578e: 19 f4 brne .+6 ; 0x5796 + fprintf_P(stream, PSTR("Protocol: ICMP\r\n")); + 5790: 80 e6 ldi r24, 0x60 ; 96 + 5792: 9d e0 ldi r25, 0x0D ; 13 + 5794: 04 c0 rjmp .+8 ; 0x579e + else if(ipheader->proto == IP_PROTO_TCP) + 5796: 86 30 cpi r24, 0x06 ; 6 + 5798: 69 f4 brne .+26 ; 0x57b4 + fprintf_P(stream, PSTR("Protocol: TCP\r\n")); + 579a: 80 e5 ldi r24, 0x50 ; 80 + 579c: 9d e0 ldi r25, 0x0D ; 13 + 579e: 9f 93 push r25 + 57a0: 8f 93 push r24 + 57a2: df 93 push r29 + 57a4: cf 93 push r28 + 57a6: 0e 94 1a 50 call 0xa034 ; 0xa034 + 57aa: 0f 90 pop r0 + 57ac: 0f 90 pop r0 + 57ae: 0f 90 pop r0 + 57b0: 0f 90 pop r0 + 57b2: 15 c0 rjmp .+42 ; 0x57de + else if(ipheader->proto == IP_PROTO_UDP) + 57b4: 81 31 cpi r24, 0x11 ; 17 + 57b6: 19 f4 brne .+6 ; 0x57be + fprintf_P(stream, PSTR("Protocol: UDP\r\n")); + 57b8: 80 e4 ldi r24, 0x40 ; 64 + 57ba: 9d e0 ldi r25, 0x0D ; 13 + 57bc: f0 cf rjmp .-32 ; 0x579e + else + fprintf_P(stream, PSTR("Protocol: %d\r\n"), ipheader->proto); + 57be: 1f 92 push r1 + 57c0: 8f 93 push r24 + 57c2: 81 e3 ldi r24, 0x31 ; 49 + 57c4: 9d e0 ldi r25, 0x0D ; 13 + 57c6: 9f 93 push r25 + 57c8: 8f 93 push r24 + 57ca: df 93 push r29 + 57cc: cf 93 push r28 + 57ce: 0e 94 1a 50 call 0xa034 ; 0xa034 + 57d2: 0f 90 pop r0 + 57d4: 0f 90 pop r0 + 57d6: 0f 90 pop r0 + 57d8: 0f 90 pop r0 + 57da: 0f 90 pop r0 + 57dc: 0f 90 pop r0 + + fprintf_P(stream, PSTR("SourceIP: ")); netPrintIPAddr(stream, htonl(ipheader->srcipaddr)); fprintf_P(stream, PSTR("\r\n")); + 57de: 86 e2 ldi r24, 0x26 ; 38 + 57e0: 9d e0 ldi r25, 0x0D ; 13 + 57e2: 9f 93 push r25 + 57e4: 8f 93 push r24 + 57e6: df 93 push r29 + 57e8: cf 93 push r28 + 57ea: 0e 94 1a 50 call 0xa034 ; 0xa034 + 57ee: f8 01 movw r30, r16 + 57f0: 64 85 ldd r22, Z+12 ; 0x0c + 57f2: 75 85 ldd r23, Z+13 ; 0x0d + 57f4: 86 85 ldd r24, Z+14 ; 0x0e + 57f6: 97 85 ldd r25, Z+15 ; 0x0f + 57f8: 0e 94 cf 2a call 0x559e ; 0x559e + 57fc: ab 01 movw r20, r22 + 57fe: bc 01 movw r22, r24 + 5800: ce 01 movw r24, r28 + 5802: 0e 94 29 2b call 0x5652 ; 0x5652 + 5806: 83 e2 ldi r24, 0x23 ; 35 + 5808: 9d e0 ldi r25, 0x0D ; 13 + 580a: 9f 93 push r25 + 580c: 8f 93 push r24 + 580e: df 93 push r29 + 5810: cf 93 push r28 + 5812: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Dest IP: ")); netPrintIPAddr(stream, htonl(ipheader->destipaddr)); fprintf_P(stream, PSTR("\r\n")); + 5816: 88 e1 ldi r24, 0x18 ; 24 + 5818: 9d e0 ldi r25, 0x0D ; 13 + 581a: 9f 93 push r25 + 581c: 8f 93 push r24 + 581e: df 93 push r29 + 5820: cf 93 push r28 + 5822: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5826: f8 01 movw r30, r16 + 5828: 60 89 ldd r22, Z+16 ; 0x10 + 582a: 71 89 ldd r23, Z+17 ; 0x11 + 582c: 82 89 ldd r24, Z+18 ; 0x12 + 582e: 93 89 ldd r25, Z+19 ; 0x13 + 5830: 0e 94 cf 2a call 0x559e ; 0x559e + 5834: ab 01 movw r20, r22 + 5836: bc 01 movw r22, r24 + 5838: ce 01 movw r24, r28 + 583a: 0e 94 29 2b call 0x5652 ; 0x5652 + 583e: 85 e1 ldi r24, 0x15 ; 21 + 5840: 9d e0 ldi r25, 0x0D ; 13 + 5842: 9f 93 push r25 + 5844: 8f 93 push r24 + 5846: df 93 push r29 + 5848: cf 93 push r28 + 584a: 0e 94 1a 50 call 0xa034 ; 0xa034 + 584e: 2d b7 in r18, 0x3d ; 61 + 5850: 3e b7 in r19, 0x3e ; 62 + 5852: 20 5f subi r18, 0xF0 ; 240 + 5854: 3f 4f sbci r19, 0xFF ; 255 + 5856: 0f b6 in r0, 0x3f ; 63 + 5858: f8 94 cli + 585a: 3e bf out 0x3e, r19 ; 62 + 585c: 0f be out 0x3f, r0 ; 63 + 585e: 2d bf out 0x3d, r18 ; 61 +} + 5860: df 91 pop r29 + 5862: cf 91 pop r28 + 5864: 1f 91 pop r17 + 5866: 0f 91 pop r16 + 5868: 08 95 ret + +0000586a : + +void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader) +{ + 586a: 0f 93 push r16 + 586c: 1f 93 push r17 + 586e: cf 93 push r28 + 5870: df 93 push r29 + 5872: ec 01 movw r28, r24 + 5874: 8b 01 movw r16, r22 + fprintf_P(stream, PSTR("TCP Header\r\n")); + 5876: 88 e0 ldi r24, 0x08 ; 8 + 5878: 9d e0 ldi r25, 0x0D ; 13 + 587a: 9f 93 push r25 + 587c: 8f 93 push r24 + 587e: df 93 push r29 + 5880: cf 93 push r28 + 5882: 0e 94 1a 50 call 0xa034 ; 0xa034 + return (val<<8) | (val>>8); +} + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); + 5886: f8 01 movw r30, r16 + 5888: 80 81 ld r24, Z + 588a: 91 81 ldd r25, Z+1 ; 0x01 + 588c: 98 27 eor r25, r24 + 588e: 89 27 eor r24, r25 + 5890: 98 27 eor r25, r24 +} + +void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader) +{ + fprintf_P(stream, PSTR("TCP Header\r\n")); + fprintf_P(stream, PSTR("Src Port: %d\r\n"), htons(tcpheader->srcport)); + 5892: 9f 93 push r25 + 5894: 8f 93 push r24 + 5896: 89 ef ldi r24, 0xF9 ; 249 + 5898: 9c e0 ldi r25, 0x0C ; 12 + 589a: 9f 93 push r25 + 589c: 8f 93 push r24 + 589e: df 93 push r29 + 58a0: cf 93 push r28 + 58a2: 0e 94 1a 50 call 0xa034 ; 0xa034 + return (val<<8) | (val>>8); +} + +uint16_t htons(uint16_t val) +{ + return (val<<8) | (val>>8); + 58a6: f8 01 movw r30, r16 + 58a8: 82 81 ldd r24, Z+2 ; 0x02 + 58aa: 93 81 ldd r25, Z+3 ; 0x03 + 58ac: 98 27 eor r25, r24 + 58ae: 89 27 eor r24, r25 + 58b0: 98 27 eor r25, r24 + +void netPrintTcpHeader(FILE *stream, struct netTcpHeader* tcpheader) +{ + fprintf_P(stream, PSTR("TCP Header\r\n")); + fprintf_P(stream, PSTR("Src Port: %d\r\n"), htons(tcpheader->srcport)); + fprintf_P(stream, PSTR("Dst Port: %d\r\n"), htons(tcpheader->destport)); + 58b2: 9f 93 push r25 + 58b4: 8f 93 push r24 + 58b6: 8a ee ldi r24, 0xEA ; 234 + 58b8: 9c e0 ldi r25, 0x0C ; 12 + 58ba: 9f 93 push r25 + 58bc: 8f 93 push r24 + 58be: df 93 push r29 + 58c0: cf 93 push r28 + 58c2: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Seq Num : 0x%x"), htonl(tcpheader->seqno)); + 58c6: f8 01 movw r30, r16 + 58c8: 64 81 ldd r22, Z+4 ; 0x04 + 58ca: 75 81 ldd r23, Z+5 ; 0x05 + 58cc: 86 81 ldd r24, Z+6 ; 0x06 + 58ce: 97 81 ldd r25, Z+7 ; 0x07 + 58d0: 0e 94 cf 2a call 0x559e ; 0x559e + 58d4: 9f 93 push r25 + 58d6: 8f 93 push r24 + 58d8: 7f 93 push r23 + 58da: 6f 93 push r22 + 58dc: 8b ed ldi r24, 0xDB ; 219 + 58de: 9c e0 ldi r25, 0x0C ; 12 + 58e0: 9f 93 push r25 + 58e2: 8f 93 push r24 + 58e4: df 93 push r29 + 58e6: cf 93 push r28 + 58e8: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Ack Num : 0x%x\r\n"), htonl(tcpheader->ackno)); + 58ec: f8 01 movw r30, r16 + 58ee: 60 85 ldd r22, Z+8 ; 0x08 + 58f0: 71 85 ldd r23, Z+9 ; 0x09 + 58f2: 82 85 ldd r24, Z+10 ; 0x0a + 58f4: 93 85 ldd r25, Z+11 ; 0x0b + 58f6: 0e 94 cf 2a call 0x559e ; 0x559e + 58fa: 9f 93 push r25 + 58fc: 8f 93 push r24 + 58fe: 7f 93 push r23 + 5900: 6f 93 push r22 + 5902: 8a ec ldi r24, 0xCA ; 202 + 5904: 9c e0 ldi r25, 0x0C ; 12 + 5906: 9f 93 push r25 + 5908: 8f 93 push r24 + 590a: df 93 push r29 + 590c: cf 93 push r28 + 590e: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Flags : ")); + 5912: 8d b7 in r24, 0x3d ; 61 + 5914: 9e b7 in r25, 0x3e ; 62 + 5916: 80 96 adiw r24, 0x20 ; 32 + 5918: 0f b6 in r0, 0x3f ; 63 + 591a: f8 94 cli + 591c: 9e bf out 0x3e, r25 ; 62 + 591e: 0f be out 0x3f, r0 ; 63 + 5920: 8d bf out 0x3d, r24 ; 61 + 5922: 8f eb ldi r24, 0xBF ; 191 + 5924: 9c e0 ldi r25, 0x0C ; 12 + 5926: 9f 93 push r25 + 5928: 8f 93 push r24 + 592a: df 93 push r29 + 592c: cf 93 push r28 + 592e: 0e 94 1a 50 call 0xa034 ; 0xa034 + if(tcpheader->flags & TCP_FLAGS_FIN) + 5932: f8 01 movw r30, r16 + 5934: 85 85 ldd r24, Z+13 ; 0x0d + 5936: 0f 90 pop r0 + 5938: 0f 90 pop r0 + 593a: 0f 90 pop r0 + 593c: 0f 90 pop r0 + 593e: 80 ff sbrs r24, 0 + 5940: 0c c0 rjmp .+24 ; 0x595a + fprintf_P(stream, PSTR("FIN ")); + 5942: 8a eb ldi r24, 0xBA ; 186 + 5944: 9c e0 ldi r25, 0x0C ; 12 + 5946: 9f 93 push r25 + 5948: 8f 93 push r24 + 594a: df 93 push r29 + 594c: cf 93 push r28 + 594e: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5952: 0f 90 pop r0 + 5954: 0f 90 pop r0 + 5956: 0f 90 pop r0 + 5958: 0f 90 pop r0 + if(tcpheader->flags & TCP_FLAGS_SYN) + 595a: f8 01 movw r30, r16 + 595c: 85 85 ldd r24, Z+13 ; 0x0d + 595e: 81 ff sbrs r24, 1 + 5960: 0c c0 rjmp .+24 ; 0x597a + fprintf_P(stream, PSTR("SYN ")); + 5962: 85 eb ldi r24, 0xB5 ; 181 + 5964: 9c e0 ldi r25, 0x0C ; 12 + 5966: 9f 93 push r25 + 5968: 8f 93 push r24 + 596a: df 93 push r29 + 596c: cf 93 push r28 + 596e: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5972: 0f 90 pop r0 + 5974: 0f 90 pop r0 + 5976: 0f 90 pop r0 + 5978: 0f 90 pop r0 + if(tcpheader->flags & TCP_FLAGS_RST) + 597a: f8 01 movw r30, r16 + 597c: 85 85 ldd r24, Z+13 ; 0x0d + 597e: 82 ff sbrs r24, 2 + 5980: 0c c0 rjmp .+24 ; 0x599a + fprintf_P(stream, PSTR("RST ")); + 5982: 80 eb ldi r24, 0xB0 ; 176 + 5984: 9c e0 ldi r25, 0x0C ; 12 + 5986: 9f 93 push r25 + 5988: 8f 93 push r24 + 598a: df 93 push r29 + 598c: cf 93 push r28 + 598e: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5992: 0f 90 pop r0 + 5994: 0f 90 pop r0 + 5996: 0f 90 pop r0 + 5998: 0f 90 pop r0 + if(tcpheader->flags & TCP_FLAGS_PSH) + 599a: f8 01 movw r30, r16 + 599c: 85 85 ldd r24, Z+13 ; 0x0d + 599e: 83 ff sbrs r24, 3 + 59a0: 0c c0 rjmp .+24 ; 0x59ba + fprintf_P(stream, PSTR("PSH ")); + 59a2: 8b ea ldi r24, 0xAB ; 171 + 59a4: 9c e0 ldi r25, 0x0C ; 12 + 59a6: 9f 93 push r25 + 59a8: 8f 93 push r24 + 59aa: df 93 push r29 + 59ac: cf 93 push r28 + 59ae: 0e 94 1a 50 call 0xa034 ; 0xa034 + 59b2: 0f 90 pop r0 + 59b4: 0f 90 pop r0 + 59b6: 0f 90 pop r0 + 59b8: 0f 90 pop r0 + if(tcpheader->flags & TCP_FLAGS_ACK) + 59ba: f8 01 movw r30, r16 + 59bc: 85 85 ldd r24, Z+13 ; 0x0d + 59be: 84 ff sbrs r24, 4 + 59c0: 0c c0 rjmp .+24 ; 0x59da + fprintf_P(stream, PSTR("ACK ")); + 59c2: 86 ea ldi r24, 0xA6 ; 166 + 59c4: 9c e0 ldi r25, 0x0C ; 12 + 59c6: 9f 93 push r25 + 59c8: 8f 93 push r24 + 59ca: df 93 push r29 + 59cc: cf 93 push r28 + 59ce: 0e 94 1a 50 call 0xa034 ; 0xa034 + 59d2: 0f 90 pop r0 + 59d4: 0f 90 pop r0 + 59d6: 0f 90 pop r0 + 59d8: 0f 90 pop r0 + if(tcpheader->flags & TCP_FLAGS_URG) + 59da: f8 01 movw r30, r16 + 59dc: 85 85 ldd r24, Z+13 ; 0x0d + 59de: 85 ff sbrs r24, 5 + 59e0: 0c c0 rjmp .+24 ; 0x59fa + fprintf_P(stream, PSTR("URG ")); + 59e2: 81 ea ldi r24, 0xA1 ; 161 + 59e4: 9c e0 ldi r25, 0x0C ; 12 + 59e6: 9f 93 push r25 + 59e8: 8f 93 push r24 + 59ea: df 93 push r29 + 59ec: cf 93 push r28 + 59ee: 0e 94 1a 50 call 0xa034 ; 0xa034 + 59f2: 0f 90 pop r0 + 59f4: 0f 90 pop r0 + 59f6: 0f 90 pop r0 + 59f8: 0f 90 pop r0 + fprintf_P(stream, PSTR("\r\n")); + 59fa: 8e e9 ldi r24, 0x9E ; 158 + 59fc: 9c e0 ldi r25, 0x0C ; 12 + 59fe: 9f 93 push r25 + 5a00: 8f 93 push r24 + 5a02: df 93 push r29 + 5a04: cf 93 push r28 + 5a06: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5a0a: 0f 90 pop r0 + 5a0c: 0f 90 pop r0 + 5a0e: 0f 90 pop r0 + 5a10: 0f 90 pop r0 +} + 5a12: df 91 pop r29 + 5a14: cf 91 pop r28 + 5a16: 1f 91 pop r17 + 5a18: 0f 91 pop r16 + 5a1a: 08 95 ret + +00005a1c : +static uint32_t myip_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_IP4 << 24) + ((uint32_t)MY_IP3 <<16) + ((uint32_t)MY_IP2 <<8) + MY_IP1; +static uint32_t mask_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_MASK4 << 24) + ((uint32_t)MY_MASK3 <<16) + ((uint32_t)MY_MASK2 <<8) + MY_MASK1; +static uint32_t defGw_eep __attribute__((section (".eeprom"))) = ((uint32_t)MY_GW4 << 24) + ((uint32_t)MY_GW3 <<16) + ((uint32_t)MY_GW2 <<8) + MY_GW1; + +void ipInit() +{ + 5a1c: 08 95 ret + +00005a1e : + +} + +void ipLoadConfig(void) +{ + 5a1e: cf 93 push r28 + 5a20: df 93 push r29 + IpMyConfig.ip = eeprom_read_dword(&myip_eep); + 5a22: 8e e2 ldi r24, 0x2E ; 46 + 5a24: 90 e0 ldi r25, 0x00 ; 0 + 5a26: 0e 94 4d 53 call 0xa69a ; 0xa69a + 5a2a: ce e4 ldi r28, 0x4E ; 78 + 5a2c: df e0 ldi r29, 0x0F ; 15 + 5a2e: 68 83 st Y, r22 + 5a30: 79 83 std Y+1, r23 ; 0x01 + 5a32: 8a 83 std Y+2, r24 ; 0x02 + 5a34: 9b 83 std Y+3, r25 ; 0x03 + IpMyConfig.netmask = eeprom_read_dword(&mask_eep); + 5a36: 8a e2 ldi r24, 0x2A ; 42 + 5a38: 90 e0 ldi r25, 0x00 ; 0 + 5a3a: 0e 94 4d 53 call 0xa69a ; 0xa69a + 5a3e: 6c 83 std Y+4, r22 ; 0x04 + 5a40: 7d 83 std Y+5, r23 ; 0x05 + 5a42: 8e 83 std Y+6, r24 ; 0x06 + 5a44: 9f 83 std Y+7, r25 ; 0x07 + IpMyConfig.gateway = eeprom_read_dword(&defGw_eep); + 5a46: 86 e2 ldi r24, 0x26 ; 38 + 5a48: 90 e0 ldi r25, 0x00 ; 0 + 5a4a: 0e 94 4d 53 call 0xa69a ; 0xa69a + 5a4e: 68 87 std Y+8, r22 ; 0x08 + 5a50: 79 87 std Y+9, r23 ; 0x09 + 5a52: 8a 87 std Y+10, r24 ; 0x0a + 5a54: 9b 87 std Y+11, r25 ; 0x0b +#if IP_DEBUG + IpMyConfig.dbgLevel = 0; + 5a56: 1e 86 std Y+14, r1 ; 0x0e + IpMyConfig.dbgStream = NULL; + 5a58: 1d 86 std Y+13, r1 ; 0x0d + 5a5a: 1c 86 std Y+12, r1 ; 0x0c +#endif +} + 5a5c: df 91 pop r29 + 5a5e: cf 91 pop r28 + 5a60: 08 95 ret + +00005a62 : + +void ipSaveConfig(void) +{ + 5a62: cf 93 push r28 + 5a64: df 93 push r29 + eeprom_update_dword(&myip_eep, IpMyConfig.ip); + 5a66: ce e4 ldi r28, 0x4E ; 78 + 5a68: df e0 ldi r29, 0x0F ; 15 + 5a6a: 48 81 ld r20, Y + 5a6c: 59 81 ldd r21, Y+1 ; 0x01 + 5a6e: 6a 81 ldd r22, Y+2 ; 0x02 + 5a70: 7b 81 ldd r23, Y+3 ; 0x03 + 5a72: 8e e2 ldi r24, 0x2E ; 46 + 5a74: 90 e0 ldi r25, 0x00 ; 0 + 5a76: 0e 94 7a 53 call 0xa6f4 ; 0xa6f4 + eeprom_update_dword(&mask_eep, IpMyConfig.netmask); + 5a7a: 4c 81 ldd r20, Y+4 ; 0x04 + 5a7c: 5d 81 ldd r21, Y+5 ; 0x05 + 5a7e: 6e 81 ldd r22, Y+6 ; 0x06 + 5a80: 7f 81 ldd r23, Y+7 ; 0x07 + 5a82: 8a e2 ldi r24, 0x2A ; 42 + 5a84: 90 e0 ldi r25, 0x00 ; 0 + 5a86: 0e 94 7a 53 call 0xa6f4 ; 0xa6f4 + eeprom_update_dword(&defGw_eep, IpMyConfig.gateway); + 5a8a: 48 85 ldd r20, Y+8 ; 0x08 + 5a8c: 59 85 ldd r21, Y+9 ; 0x09 + 5a8e: 6a 85 ldd r22, Y+10 ; 0x0a + 5a90: 7b 85 ldd r23, Y+11 ; 0x0b + 5a92: 86 e2 ldi r24, 0x26 ; 38 + 5a94: 90 e0 ldi r25, 0x00 ; 0 +} + 5a96: df 91 pop r29 + 5a98: cf 91 pop r28 + +void ipSaveConfig(void) +{ + eeprom_update_dword(&myip_eep, IpMyConfig.ip); + eeprom_update_dword(&mask_eep, IpMyConfig.netmask); + eeprom_update_dword(&defGw_eep, IpMyConfig.gateway); + 5a9a: 0c 94 7a 53 jmp 0xa6f4 ; 0xa6f4 + +00005a9e : +} + +inline void netstackIPv4Process(void) +{ + 5a9e: 0f 93 push r16 + 5aa0: 1f 93 push r17 +// check IP addressing, stop processing if not for me and not a broadcast + if( (nicState.layer3.ip->destipaddr != ipGetConfig()->ip) && //Różne adresy IP + 5aa2: e0 91 88 0e lds r30, 0x0E88 + 5aa6: f0 91 89 0e lds r31, 0x0E89 + 5aaa: 40 89 ldd r20, Z+16 ; 0x10 + 5aac: 51 89 ldd r21, Z+17 ; 0x11 + 5aae: 62 89 ldd r22, Z+18 ; 0x12 + 5ab0: 73 89 ldd r23, Z+19 ; 0x13 + 5ab2: 80 91 4e 0f lds r24, 0x0F4E + 5ab6: 90 91 4f 0f lds r25, 0x0F4F + 5aba: a0 91 50 0f lds r26, 0x0F50 + 5abe: b0 91 51 0f lds r27, 0x0F51 + 5ac2: 48 17 cp r20, r24 + 5ac4: 59 07 cpc r21, r25 + 5ac6: 6a 07 cpc r22, r26 + 5ac8: 7b 07 cpc r23, r27 + 5aca: d9 f0 breq .+54 ; 0x5b02 + (nicState.layer3.ip->destipaddr != (ipGetConfig()->ip | (~ipGetConfig()->netmask))) && //Nie jest to adres rozgÅ‚oszeniowy sieci + 5acc: 00 91 52 0f lds r16, 0x0F52 + 5ad0: 10 91 53 0f lds r17, 0x0F53 + 5ad4: 20 91 54 0f lds r18, 0x0F54 + 5ad8: 30 91 55 0f lds r19, 0x0F55 + 5adc: 00 95 com r16 + 5ade: 10 95 com r17 + 5ae0: 20 95 com r18 + 5ae2: 30 95 com r19 + 5ae4: 80 2b or r24, r16 + 5ae6: 91 2b or r25, r17 + 5ae8: a2 2b or r26, r18 + 5aea: b3 2b or r27, r19 +} + +inline void netstackIPv4Process(void) +{ +// check IP addressing, stop processing if not for me and not a broadcast + if( (nicState.layer3.ip->destipaddr != ipGetConfig()->ip) && //Różne adresy IP + 5aec: 48 17 cp r20, r24 + 5aee: 59 07 cpc r21, r25 + 5af0: 6a 07 cpc r22, r26 + 5af2: 7b 07 cpc r23, r27 + 5af4: 31 f0 breq .+12 ; 0x5b02 + (nicState.layer3.ip->destipaddr != (ipGetConfig()->ip | (~ipGetConfig()->netmask))) && //Nie jest to adres rozgÅ‚oszeniowy sieci + 5af6: 4f 3f cpi r20, 0xFF ; 255 + 5af8: 5f 4f sbci r21, 0xFF ; 255 + 5afa: 6f 4f sbci r22, 0xFF ; 255 + 5afc: 7f 4f sbci r23, 0xFF ; 255 + 5afe: 09 f0 breq .+2 ; 0x5b02 + 5b00: 59 c0 rjmp .+178 ; 0x5bb4 + (nicState.layer3.ip->destipaddr != 0xFFFFFFFF)) //Nie jest to brodcast + return; + +// handle ICMP packet + if(nicState.layer3.ip->proto == IP_PROTO_ICMP) + 5b02: 21 85 ldd r18, Z+9 ; 0x09 + 5b04: 80 91 5a 0f lds r24, 0x0F5A + 5b08: 90 91 5b 0f lds r25, 0x0F5B + 5b0c: 21 30 cpi r18, 0x01 ; 1 + 5b0e: 41 f5 brne .+80 ; 0x5b60 + { +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5b10: 00 97 sbiw r24, 0x00 ; 0 + 5b12: 11 f1 breq .+68 ; 0x5b58 + { + if (IpMyConfig.dbgLevel > 0) + 5b14: 20 91 5c 0f lds r18, 0x0F5C + 5b18: 22 23 and r18, r18 + 5b1a: 61 f0 breq .+24 ; 0x5b34 + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: ICMP/IP packet\r\n")); + 5b1c: 23 ef ldi r18, 0xF3 ; 243 + 5b1e: 3e e0 ldi r19, 0x0E ; 14 + 5b20: 3f 93 push r19 + 5b22: 2f 93 push r18 + 5b24: 9f 93 push r25 + 5b26: 8f 93 push r24 + 5b28: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5b2c: 0f 90 pop r0 + 5b2e: 0f 90 pop r0 + 5b30: 0f 90 pop r0 + 5b32: 0f 90 pop r0 + if (IpMyConfig.dbgLevel > 2) + 5b34: 80 91 5c 0f lds r24, 0x0F5C + 5b38: 83 30 cpi r24, 0x03 ; 3 + 5b3a: 70 f0 brcs .+28 ; 0x5b58 + icmpPrintHeader(IpMyConfig.dbgStream, nicState.layer3.ip, nicState.layer4.icmp); + 5b3c: 40 91 8a 0e lds r20, 0x0E8A + 5b40: 50 91 8b 0e lds r21, 0x0E8B + 5b44: 60 91 88 0e lds r22, 0x0E88 + 5b48: 70 91 89 0e lds r23, 0x0E89 + 5b4c: 80 91 5a 0f lds r24, 0x0F5A + 5b50: 90 91 5b 0f lds r25, 0x0F5B + 5b54: 0e 94 5f 2f call 0x5ebe ; 0x5ebe + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + } +#endif /*IP_DEBUG*/ +} + 5b58: 1f 91 pop r17 + 5b5a: 0f 91 pop r16 + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: ICMP/IP packet\r\n")); + if (IpMyConfig.dbgLevel > 2) + icmpPrintHeader(IpMyConfig.dbgStream, nicState.layer3.ip, nicState.layer4.icmp); + } +#endif /*IP_DEBUG*/ + icmpIpIn(); + 5b5c: 0c 94 4b 30 jmp 0x6096 ; 0x6096 + return; + } + if( nicState.layer3.ip->proto == IP_PROTO_UDP ) + 5b60: 21 31 cpi r18, 0x11 ; 17 + 5b62: b1 f4 brne .+44 ; 0x5b90 + { +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5b64: 00 97 sbiw r24, 0x00 ; 0 + 5b66: 81 f0 breq .+32 ; 0x5b88 + { + if (IpMyConfig.dbgLevel > 0) + 5b68: 20 91 5c 0f lds r18, 0x0F5C + 5b6c: 22 23 and r18, r18 + 5b6e: 61 f0 breq .+24 ; 0x5b88 + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: UDP/IP packet\r\n")); + 5b70: 2b ed ldi r18, 0xDB ; 219 + 5b72: 3e e0 ldi r19, 0x0E ; 14 + 5b74: 3f 93 push r19 + 5b76: 2f 93 push r18 + 5b78: 9f 93 push r25 + 5b7a: 8f 93 push r24 + 5b7c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5b80: 0f 90 pop r0 + 5b82: 0f 90 pop r0 + 5b84: 0f 90 pop r0 + 5b86: 0f 90 pop r0 + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + } +#endif /*IP_DEBUG*/ +} + 5b88: 1f 91 pop r17 + 5b8a: 0f 91 pop r16 + { + if (IpMyConfig.dbgLevel > 0) + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: UDP/IP packet\r\n")); + } +#endif /*IP_DEBUG*/ + netstackUDPIPProcess(); + 5b8c: 0c 94 13 37 jmp 0x6e26 ; 0x6e26 + netstackTCPIPProcess(); + return; + } +#endif +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5b90: 00 97 sbiw r24, 0x00 ; 0 + 5b92: 81 f0 breq .+32 ; 0x5bb4 + { + if (IpMyConfig.dbgLevel > 0) + 5b94: 20 91 5c 0f lds r18, 0x0F5C + 5b98: 22 23 and r18, r18 + 5b9a: 61 f0 breq .+24 ; 0x5bb4 + fprintf_P(IpMyConfig.dbgStream, PSTR("NET Rx: Unknown IP packet\r\n")); + 5b9c: 2f eb ldi r18, 0xBF ; 191 + 5b9e: 3e e0 ldi r19, 0x0E ; 14 + 5ba0: 3f 93 push r19 + 5ba2: 2f 93 push r18 + 5ba4: 9f 93 push r25 + 5ba6: 8f 93 push r24 + 5ba8: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5bac: 0f 90 pop r0 + 5bae: 0f 90 pop r0 + 5bb0: 0f 90 pop r0 + 5bb2: 0f 90 pop r0 + } +#endif /*IP_DEBUG*/ +} + 5bb4: 1f 91 pop r17 + 5bb6: 0f 91 pop r16 + 5bb8: 08 95 ret + +00005bba : + +#if IP_DEBUG +void setIpDebug(FILE *stream, uint8_t level) +{ + IpMyConfig.dbgStream = stream; + 5bba: 90 93 5b 0f sts 0x0F5B, r25 + 5bbe: 80 93 5a 0f sts 0x0F5A, r24 + IpMyConfig.dbgLevel = level; + 5bc2: 60 93 5c 0f sts 0x0F5C, r22 + if (level == 0) + 5bc6: 61 11 cpse r22, r1 + 5bc8: 04 c0 rjmp .+8 ; 0x5bd2 + IpMyConfig.dbgStream = NULL; + 5bca: 10 92 5b 0f sts 0x0F5B, r1 + 5bce: 10 92 5a 0f sts 0x0F5A, r1 + 5bd2: 08 95 ret + +00005bd4 : +} +#endif + +void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp) +{ + 5bd4: ef 92 push r14 + 5bd6: ff 92 push r15 + 5bd8: 0f 93 push r16 + 5bda: 1f 93 push r17 + // set local addressing + IpMyConfig.ip = myIp; + 5bdc: ee e4 ldi r30, 0x4E ; 78 + 5bde: ff e0 ldi r31, 0x0F ; 15 + 5be0: 60 83 st Z, r22 + 5be2: 71 83 std Z+1, r23 ; 0x01 + 5be4: 82 83 std Z+2, r24 ; 0x02 + 5be6: 93 83 std Z+3, r25 ; 0x03 + IpMyConfig.netmask = netmask; + 5be8: 24 83 std Z+4, r18 ; 0x04 + 5bea: 35 83 std Z+5, r19 ; 0x05 + 5bec: 46 83 std Z+6, r20 ; 0x06 + 5bee: 57 83 std Z+7, r21 ; 0x07 + IpMyConfig.gateway = gatewayIp; + 5bf0: e0 86 std Z+8, r14 ; 0x08 + 5bf2: f1 86 std Z+9, r15 ; 0x09 + 5bf4: 02 87 std Z+10, r16 ; 0x0a + 5bf6: 13 87 std Z+11, r17 ; 0x0b +} + 5bf8: 1f 91 pop r17 + 5bfa: 0f 91 pop r16 + 5bfc: ff 90 pop r15 + 5bfe: ef 90 pop r14 + 5c00: 08 95 ret + +00005c02 : + +void ipSetConfigIp(uint32_t myIp) +{ + // set local addressing + IpMyConfig.ip = myIp; + 5c02: 60 93 4e 0f sts 0x0F4E, r22 + 5c06: 70 93 4f 0f sts 0x0F4F, r23 + 5c0a: 80 93 50 0f sts 0x0F50, r24 + 5c0e: 90 93 51 0f sts 0x0F51, r25 + 5c12: 08 95 ret + +00005c14 : +} + +void ipSetConfigMask(uint32_t netmask) +{ + IpMyConfig.netmask = netmask; + 5c14: 60 93 52 0f sts 0x0F52, r22 + 5c18: 70 93 53 0f sts 0x0F53, r23 + 5c1c: 80 93 54 0f sts 0x0F54, r24 + 5c20: 90 93 55 0f sts 0x0F55, r25 + 5c24: 08 95 ret + +00005c26 : +} + +void ipSetConfigGw(uint32_t gatewayIp) +{ + IpMyConfig.gateway = gatewayIp; + 5c26: 60 93 56 0f sts 0x0F56, r22 + 5c2a: 70 93 57 0f sts 0x0F57, r23 + 5c2e: 80 93 58 0f sts 0x0F58, r24 + 5c32: 90 93 59 0f sts 0x0F59, r25 + 5c36: 08 95 ret + +00005c38 : + + +struct ipConfig* ipGetConfig(void) +{ + return &IpMyConfig; +} + 5c38: 8e e4 ldi r24, 0x4E ; 78 + 5c3a: 9f e0 ldi r25, 0x0F ; 15 + 5c3c: 08 95 ret + +00005c3e : + +void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len) +{ + 5c3e: af 92 push r10 + 5c40: bf 92 push r11 + 5c42: cf 92 push r12 + 5c44: df 92 push r13 + 5c46: ef 92 push r14 + 5c48: ff 92 push r15 + 5c4a: 0f 93 push r16 + 5c4c: 1f 93 push r17 + 5c4e: cf 93 push r28 + 5c50: df 93 push r29 + 5c52: 1f 92 push r1 + 5c54: cd b7 in r28, 0x3d ; 61 + 5c56: de b7 in r29, 0x3e ; 62 + 5c58: 6b 01 movw r12, r22 + 5c5a: 7c 01 movw r14, r24 + 5c5c: 89 01 movw r16, r18 +// make pointer to ethernet/IP header +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5c5e: 20 91 5a 0f lds r18, 0x0F5A + 5c62: 30 91 5b 0f lds r19, 0x0F5B + 5c66: 21 15 cp r18, r1 + 5c68: 31 05 cpc r19, r1 + 5c6a: 91 f0 breq .+36 ; 0x5c90 + { + if (IpMyConfig.dbgLevel > 2) + 5c6c: 80 91 5c 0f lds r24, 0x0F5C + 5c70: 83 30 cpi r24, 0x03 ; 3 + 5c72: 70 f0 brcs .+28 ; 0x5c90 + fprintf_P(IpMyConfig.dbgStream, "Sending Ip packet\r\n"); + 5c74: 82 e5 ldi r24, 0x52 ; 82 + 5c76: 91 e0 ldi r25, 0x01 ; 1 + 5c78: 9f 93 push r25 + 5c7a: 8f 93 push r24 + 5c7c: 3f 93 push r19 + 5c7e: 2f 93 push r18 + 5c80: 49 83 std Y+1, r20 ; 0x01 + 5c82: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5c86: 0f 90 pop r0 + 5c88: 0f 90 pop r0 + 5c8a: 0f 90 pop r0 + 5c8c: 0f 90 pop r0 + 5c8e: 49 81 ldd r20, Y+1 ; 0x01 + +// adjust length to add IP header + len += IP_HEADER_LEN; + +// fill IP header + nicState.layer3.ip->destipaddr = dstIp; + 5c90: a0 90 88 0e lds r10, 0x0E88 + 5c94: b0 90 89 0e lds r11, 0x0E89 + 5c98: f5 01 movw r30, r10 + 5c9a: c0 8a std Z+16, r12 ; 0x10 + 5c9c: d1 8a std Z+17, r13 ; 0x11 + 5c9e: e2 8a std Z+18, r14 ; 0x12 + 5ca0: f3 8a std Z+19, r15 ; 0x13 + nicState.layer3.ip->srcipaddr = IpMyConfig.ip; + 5ca2: 80 91 4e 0f lds r24, 0x0F4E + 5ca6: 90 91 4f 0f lds r25, 0x0F4F + 5caa: a0 91 50 0f lds r26, 0x0F50 + 5cae: b0 91 51 0f lds r27, 0x0F51 + 5cb2: 84 87 std Z+12, r24 ; 0x0c + 5cb4: 95 87 std Z+13, r25 ; 0x0d + 5cb6: a6 87 std Z+14, r26 ; 0x0e + 5cb8: b7 87 std Z+15, r27 ; 0x0f + nicState.layer3.ip->proto = protocol; + 5cba: 41 87 std Z+9, r20 ; 0x09 + nicState.layer3.ip->len = htons(len); + 5cbc: c8 01 movw r24, r16 + 5cbe: 44 96 adiw r24, 0x14 ; 20 + 5cc0: 0e 94 cb 2a call 0x5596 ; 0x5596 + 5cc4: f5 01 movw r30, r10 + 5cc6: 93 83 std Z+3, r25 ; 0x03 + 5cc8: 82 83 std Z+2, r24 ; 0x02 + nicState.layer3.ip->vhl = 0x45; + 5cca: a0 90 88 0e lds r10, 0x0E88 + 5cce: b0 90 89 0e lds r11, 0x0E89 + 5cd2: 85 e4 ldi r24, 0x45 ; 69 + 5cd4: f5 01 movw r30, r10 + 5cd6: 80 83 st Z, r24 + nicState.layer3.ip->tos = 0; + 5cd8: 11 82 std Z+1, r1 ; 0x01 + nicState.layer3.ip->ipid = 0; + 5cda: 15 82 std Z+5, r1 ; 0x05 + 5cdc: 14 82 std Z+4, r1 ; 0x04 + nicState.layer3.ip->ipoffset = 0; + 5cde: 17 82 std Z+7, r1 ; 0x07 + 5ce0: 16 82 std Z+6, r1 ; 0x06 + nicState.layer3.ip->ttl = IP_TIME_TO_LIVE; + 5ce2: 80 e8 ldi r24, 0x80 ; 128 + 5ce4: 80 87 std Z+8, r24 ; 0x08 + nicState.layer3.ip->ipchksum = 0; + 5ce6: 13 86 std Z+11, r1 ; 0x0b + 5ce8: 12 86 std Z+10, r1 ; 0x0a + +// calculate and apply IP checksum +// DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER + nicState.layer3.ip->ipchksum = netChecksum((uint8_t *)(nicState.layer3.ip), IP_HEADER_LEN); + 5cea: 64 e1 ldi r22, 0x14 ; 20 + 5cec: 70 e0 ldi r23, 0x00 ; 0 + 5cee: c5 01 movw r24, r10 + 5cf0: 0e 94 d5 2a call 0x55aa ; 0x55aa + 5cf4: f5 01 movw r30, r10 + 5cf6: 93 87 std Z+11, r25 ; 0x0b + 5cf8: 82 87 std Z+10, r24 ; 0x0a + +// add ethernet routing +// check if we need to send to gateway + if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) + 5cfa: 80 91 4e 0f lds r24, 0x0F4E + 5cfe: 90 91 4f 0f lds r25, 0x0F4F + 5d02: a0 91 50 0f lds r26, 0x0F50 + 5d06: b0 91 51 0f lds r27, 0x0F51 + 5d0a: 8c 25 eor r24, r12 + 5d0c: 9d 25 eor r25, r13 + 5d0e: ae 25 eor r26, r14 + 5d10: bf 25 eor r27, r15 + 5d12: 40 91 52 0f lds r20, 0x0F52 + 5d16: 50 91 53 0f lds r21, 0x0F53 + 5d1a: 60 91 54 0f lds r22, 0x0F54 + 5d1e: 70 91 55 0f lds r23, 0x0F55 + 5d22: 84 23 and r24, r20 + 5d24: 95 23 and r25, r21 + 5d26: a6 23 and r26, r22 + 5d28: b7 23 and r27, r23 + 5d2a: 89 2b or r24, r25 + 5d2c: 8a 2b or r24, r26 + 5d2e: 8b 2b or r24, r27 + 5d30: 71 f4 brne .+28 ; 0x5d4e + { + arpIpOut(0); // local send + 5d32: 60 e0 ldi r22, 0x00 ; 0 + 5d34: 70 e0 ldi r23, 0x00 ; 0 + 5d36: cb 01 movw r24, r22 + 5d38: 0e 94 52 31 call 0x62a4 ; 0x62a4 +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5d3c: 80 91 5a 0f lds r24, 0x0F5A + 5d40: 90 91 5b 0f lds r25, 0x0F5B + 5d44: 00 97 sbiw r24, 0x00 ; 0 + 5d46: f9 f0 breq .+62 ; 0x5d86 + fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet on local net\r\n")); + 5d48: 2e e9 ldi r18, 0x9E ; 158 + 5d4a: 3e e0 ldi r19, 0x0E ; 14 + 5d4c: 12 c0 rjmp .+36 ; 0x5d72 +#endif + } + else + { + arpIpOut(IpMyConfig.gateway); // gateway send + 5d4e: 60 91 56 0f lds r22, 0x0F56 + 5d52: 70 91 57 0f lds r23, 0x0F57 + 5d56: 80 91 58 0f lds r24, 0x0F58 + 5d5a: 90 91 59 0f lds r25, 0x0F59 + 5d5e: 0e 94 52 31 call 0x62a4 ; 0x62a4 +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5d62: 80 91 5a 0f lds r24, 0x0F5A + 5d66: 90 91 5b 0f lds r25, 0x0F5B + 5d6a: 00 97 sbiw r24, 0x00 ; 0 + 5d6c: 61 f0 breq .+24 ; 0x5d86 + fprintf_P(IpMyConfig.dbgStream, PSTR("Sending IP packet to gateway\r\n")); + 5d6e: 2f e7 ldi r18, 0x7F ; 127 + 5d70: 3e e0 ldi r19, 0x0E ; 14 + 5d72: 3f 93 push r19 + 5d74: 2f 93 push r18 + 5d76: 9f 93 push r25 + 5d78: 8f 93 push r24 + 5d7a: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5d7e: 0f 90 pop r0 + 5d80: 0f 90 pop r0 + 5d82: 0f 90 pop r0 + 5d84: 0f 90 pop r0 +#endif + } + +// adjust length to add ethernet header + len += ETH_HEADER_LEN; + 5d86: 0e 5d subi r16, 0xDE ; 222 + 5d88: 1f 4f sbci r17, 0xFF ; 255 + +#if IP_DEBUG + if (IpMyConfig.dbgStream != NULL) + 5d8a: 80 91 5a 0f lds r24, 0x0F5A + 5d8e: 90 91 5b 0f lds r25, 0x0F5B + 5d92: 00 97 sbiw r24, 0x00 ; 0 + 5d94: e9 f0 breq .+58 ; 0x5dd0 + { + if (IpMyConfig.dbgLevel > 3) + 5d96: 20 91 5c 0f lds r18, 0x0F5C + 5d9a: 24 30 cpi r18, 0x04 ; 4 + 5d9c: c8 f0 brcs .+50 ; 0x5dd0 + { + fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(ETH_HEADER_LEN, &data[0]);")); + 5d9e: 21 e5 ldi r18, 0x51 ; 81 + 5da0: 3e e0 ldi r19, 0x0E ; 14 + 5da2: 3f 93 push r19 + 5da4: 2f 93 push r18 + 5da6: 9f 93 push r25 + 5da8: 8f 93 push r24 + 5daa: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]);")); + 5dae: 82 e1 ldi r24, 0x12 ; 18 + 5db0: 9e e0 ldi r25, 0x0E ; 14 + 5db2: 9f 93 push r25 + 5db4: 8f 93 push r24 + 5db6: 80 91 5b 0f lds r24, 0x0F5B + 5dba: 8f 93 push r24 + 5dbc: 80 91 5a 0f lds r24, 0x0F5A + 5dc0: 8f 93 push r24 + 5dc2: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5dc6: 0f b6 in r0, 0x3f ; 63 + 5dc8: f8 94 cli + 5dca: de bf out 0x3e, r29 ; 62 + 5dcc: 0f be out 0x3f, r0 ; 63 + 5dce: cd bf out 0x3d, r28 ; 61 + } + } +#endif +// send it + nicSend(len); + 5dd0: c8 01 movw r24, r16 +} + 5dd2: 0f 90 pop r0 + 5dd4: df 91 pop r29 + 5dd6: cf 91 pop r28 + 5dd8: 1f 91 pop r17 + 5dda: 0f 91 pop r16 + 5ddc: ff 90 pop r15 + 5dde: ef 90 pop r14 + 5de0: df 90 pop r13 + 5de2: cf 90 pop r12 + 5de4: bf 90 pop r11 + 5de6: af 90 pop r10 + fprintf_P(IpMyConfig.dbgStream, PSTR("debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]);")); + } + } +#endif +// send it + nicSend(len); + 5de8: 0c 94 0e 28 jmp 0x501c ; 0x501c + +00005dec : +} + +void ipPrintConfig(FILE *stream, struct ipConfig* config) +{ + 5dec: 0f 93 push r16 + 5dee: 1f 93 push r17 + 5df0: cf 93 push r28 + 5df2: df 93 push r29 + 5df4: ec 01 movw r28, r24 + 5df6: 8b 01 movw r16, r22 + fprintf_P(stream, PSTR("IP Addr : ")); netPrintIPAddr(stream, config->ip); fprintf_P(stream, PSTR("\r\n")); + 5df8: 87 e0 ldi r24, 0x07 ; 7 + 5dfa: 9e e0 ldi r25, 0x0E ; 14 + 5dfc: 9f 93 push r25 + 5dfe: 8f 93 push r24 + 5e00: df 93 push r29 + 5e02: cf 93 push r28 + 5e04: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5e08: f8 01 movw r30, r16 + 5e0a: 40 81 ld r20, Z + 5e0c: 51 81 ldd r21, Z+1 ; 0x01 + 5e0e: 62 81 ldd r22, Z+2 ; 0x02 + 5e10: 73 81 ldd r23, Z+3 ; 0x03 + 5e12: ce 01 movw r24, r28 + 5e14: 0e 94 29 2b call 0x5652 ; 0x5652 + 5e18: 84 e0 ldi r24, 0x04 ; 4 + 5e1a: 9e e0 ldi r25, 0x0E ; 14 + 5e1c: 9f 93 push r25 + 5e1e: 8f 93 push r24 + 5e20: df 93 push r29 + 5e22: cf 93 push r28 + 5e24: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Netmask : ")); netPrintIPAddr(stream, config->netmask); fprintf_P(stream, PSTR("\r\n")); + 5e28: 89 ef ldi r24, 0xF9 ; 249 + 5e2a: 9d e0 ldi r25, 0x0D ; 13 + 5e2c: 9f 93 push r25 + 5e2e: 8f 93 push r24 + 5e30: df 93 push r29 + 5e32: cf 93 push r28 + 5e34: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5e38: f8 01 movw r30, r16 + 5e3a: 44 81 ldd r20, Z+4 ; 0x04 + 5e3c: 55 81 ldd r21, Z+5 ; 0x05 + 5e3e: 66 81 ldd r22, Z+6 ; 0x06 + 5e40: 77 81 ldd r23, Z+7 ; 0x07 + 5e42: ce 01 movw r24, r28 + 5e44: 0e 94 29 2b call 0x5652 ; 0x5652 + 5e48: 86 ef ldi r24, 0xF6 ; 246 + 5e4a: 9d e0 ldi r25, 0x0D ; 13 + 5e4c: 9f 93 push r25 + 5e4e: 8f 93 push r24 + 5e50: df 93 push r29 + 5e52: cf 93 push r28 + 5e54: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("Gateway : ")); netPrintIPAddr(stream, config->gateway); fprintf_P(stream, PSTR("\r\n")); + 5e58: 8b ee ldi r24, 0xEB ; 235 + 5e5a: 9d e0 ldi r25, 0x0D ; 13 + 5e5c: 9f 93 push r25 + 5e5e: 8f 93 push r24 + 5e60: df 93 push r29 + 5e62: cf 93 push r28 + 5e64: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5e68: f8 01 movw r30, r16 + 5e6a: 40 85 ldd r20, Z+8 ; 0x08 + 5e6c: 51 85 ldd r21, Z+9 ; 0x09 + 5e6e: 62 85 ldd r22, Z+10 ; 0x0a + 5e70: 73 85 ldd r23, Z+11 ; 0x0b + 5e72: ce 01 movw r24, r28 + 5e74: 0e 94 29 2b call 0x5652 ; 0x5652 + 5e78: 88 ee ldi r24, 0xE8 ; 232 + 5e7a: 9d e0 ldi r25, 0x0D ; 13 + 5e7c: 9f 93 push r25 + 5e7e: 8f 93 push r24 + 5e80: df 93 push r29 + 5e82: cf 93 push r28 + 5e84: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5e88: 8d b7 in r24, 0x3d ; 61 + 5e8a: 9e b7 in r25, 0x3e ; 62 + 5e8c: 48 96 adiw r24, 0x18 ; 24 + 5e8e: 0f b6 in r0, 0x3f ; 63 + 5e90: f8 94 cli + 5e92: 9e bf out 0x3e, r25 ; 62 + 5e94: 0f be out 0x3f, r0 ; 63 + 5e96: 8d bf out 0x3d, r24 ; 61 +} + 5e98: df 91 pop r29 + 5e9a: cf 91 pop r28 + 5e9c: 1f 91 pop r17 + 5e9e: 0f 91 pop r16 + 5ea0: 08 95 ret + +00005ea2 : + + +// functions +void icmpInit(void) +{ + icmpDebug = NULL; + 5ea2: 10 92 ab 0e sts 0x0EAB, r1 + 5ea6: 10 92 aa 0e sts 0x0EAA, r1 + icmpDebugLevel = 0; + 5eaa: 10 92 4b 0f sts 0x0F4B, r1 + 5eae: 08 95 ret + +00005eb0 : +} + +#if ICMP_DEBUG +void setIcmpDebug(FILE *stream, uint8_t level) +{ + icmpDebug = stream; + 5eb0: 90 93 ab 0e sts 0x0EAB, r25 + 5eb4: 80 93 aa 0e sts 0x0EAA, r24 + icmpDebugLevel = level; + 5eb8: 60 93 4b 0f sts 0x0F4B, r22 + 5ebc: 08 95 ret + +00005ebe : +} +#endif + +void icmpPrintHeader(FILE *stream, struct netIpHeader *ipPacket, struct netIcmpHeader *icmpPacket) +{ + 5ebe: ef 92 push r14 + 5ec0: ff 92 push r15 + 5ec2: 0f 93 push r16 + 5ec4: 1f 93 push r17 + 5ec6: cf 93 push r28 + 5ec8: df 93 push r29 + 5eca: ec 01 movw r28, r24 + 5ecc: 7b 01 movw r14, r22 + 5ece: 8a 01 movw r16, r20 + fprintf_P(stream, PSTR("ICMP Packet:\r\n")); + 5ed0: 89 e4 ldi r24, 0x49 ; 73 + 5ed2: 9f e0 ldi r25, 0x0F ; 15 + 5ed4: 9f 93 push r25 + 5ed6: 8f 93 push r24 + 5ed8: df 93 push r29 + 5eda: cf 93 push r28 + 5edc: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print source IP address + fprintf_P(stream, PSTR("SrcIpAddr: ")); netPrintIPAddr(stream, ipPacket->srcipaddr); fprintf_P(stream, PSTR("\r\n")); + 5ee0: 8d e3 ldi r24, 0x3D ; 61 + 5ee2: 9f e0 ldi r25, 0x0F ; 15 + 5ee4: 9f 93 push r25 + 5ee6: 8f 93 push r24 + 5ee8: df 93 push r29 + 5eea: cf 93 push r28 + 5eec: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5ef0: f7 01 movw r30, r14 + 5ef2: 44 85 ldd r20, Z+12 ; 0x0c + 5ef4: 55 85 ldd r21, Z+13 ; 0x0d + 5ef6: 66 85 ldd r22, Z+14 ; 0x0e + 5ef8: 77 85 ldd r23, Z+15 ; 0x0f + 5efa: ce 01 movw r24, r28 + 5efc: 0e 94 29 2b call 0x5652 ; 0x5652 + 5f00: 8a e3 ldi r24, 0x3A ; 58 + 5f02: 9f e0 ldi r25, 0x0F ; 15 + 5f04: 9f 93 push r25 + 5f06: 8f 93 push r24 + 5f08: df 93 push r29 + 5f0a: cf 93 push r28 + 5f0c: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print dest IP address + fprintf_P(stream, PSTR("DstIpAddr: ")); netPrintIPAddr(stream, ipPacket->destipaddr); fprintf_P(stream, PSTR("\r\n")); + 5f10: 8e e2 ldi r24, 0x2E ; 46 + 5f12: 9f e0 ldi r25, 0x0F ; 15 + 5f14: 9f 93 push r25 + 5f16: 8f 93 push r24 + 5f18: df 93 push r29 + 5f1a: cf 93 push r28 + 5f1c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5f20: f7 01 movw r30, r14 + 5f22: 40 89 ldd r20, Z+16 ; 0x10 + 5f24: 51 89 ldd r21, Z+17 ; 0x11 + 5f26: 62 89 ldd r22, Z+18 ; 0x12 + 5f28: 73 89 ldd r23, Z+19 ; 0x13 + 5f2a: ce 01 movw r24, r28 + 5f2c: 0e 94 29 2b call 0x5652 ; 0x5652 + 5f30: 8b e2 ldi r24, 0x2B ; 43 + 5f32: 9f e0 ldi r25, 0x0F ; 15 + 5f34: 9f 93 push r25 + 5f36: 8f 93 push r24 + 5f38: df 93 push r29 + 5f3a: cf 93 push r28 + 5f3c: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print type + fprintf_P(stream, PSTR("Type: 0x%x "), icmpPacket->type); + 5f40: f8 01 movw r30, r16 + 5f42: 80 81 ld r24, Z + 5f44: 1f 92 push r1 + 5f46: 8f 93 push r24 + 5f48: 8c e1 ldi r24, 0x1C ; 28 + 5f4a: 9f e0 ldi r25, 0x0F ; 15 + 5f4c: 9f 93 push r25 + 5f4e: 8f 93 push r24 + 5f50: df 93 push r29 + 5f52: cf 93 push r28 + 5f54: 0e 94 1a 50 call 0xa034 ; 0xa034 +// fprintf_P(stream, ("???")); +// break; +//} +// fprintf_P(stream, PSTR("\r\n")); +// print code + fprintf_P(stream, PSTR("Code : 0x%x\r\n"), icmpPacket->icode); + 5f58: f8 01 movw r30, r16 + 5f5a: 81 81 ldd r24, Z+1 ; 0x01 + 5f5c: 1f 92 push r1 + 5f5e: 8f 93 push r24 + 5f60: 8c e0 ldi r24, 0x0C ; 12 + 5f62: 9f e0 ldi r25, 0x0F ; 15 + 5f64: 9f 93 push r25 + 5f66: 8f 93 push r24 + 5f68: df 93 push r29 + 5f6a: cf 93 push r28 + 5f6c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5f70: 8d b7 in r24, 0x3d ; 61 + 5f72: 9e b7 in r25, 0x3e ; 62 + 5f74: 80 96 adiw r24, 0x20 ; 32 + 5f76: 0f b6 in r0, 0x3f ; 63 + 5f78: f8 94 cli + 5f7a: 9e bf out 0x3e, r25 ; 62 + 5f7c: 0f be out 0x3f, r0 ; 63 + 5f7e: 8d bf out 0x3d, r24 ; 61 +} + 5f80: df 91 pop r29 + 5f82: cf 91 pop r28 + 5f84: 1f 91 pop r17 + 5f86: 0f 91 pop r16 + 5f88: ff 90 pop r15 + 5f8a: ef 90 pop r14 + 5f8c: 08 95 ret + +00005f8e : + break; + } +} + +void icmpEchoRequest(void) +{ + 5f8e: cf 93 push r28 + 5f90: df 93 push r29 +#if ICMP_DEBUG + if (icmpDebug != NULL) + 5f92: 80 91 aa 0e lds r24, 0x0EAA + 5f96: 90 91 ab 0e lds r25, 0x0EAB + 5f9a: 00 97 sbiw r24, 0x00 ; 0 + 5f9c: 81 f0 breq .+32 ; 0x5fbe + { + if (icmpDebugLevel > 1) + 5f9e: 20 91 4b 0f lds r18, 0x0F4B + 5fa2: 22 30 cpi r18, 0x02 ; 2 + 5fa4: 60 f0 brcs .+24 ; 0x5fbe + fprintf_P(icmpDebug, PSTR("Received ICMP request: ")); + 5fa6: 2c e6 ldi r18, 0x6C ; 108 + 5fa8: 3f e0 ldi r19, 0x0F ; 15 + 5faa: 3f 93 push r19 + 5fac: 2f 93 push r18 + 5fae: 9f 93 push r25 + 5fb0: 8f 93 push r24 + 5fb2: 0e 94 1a 50 call 0xa034 ; 0xa034 + 5fb6: 0f 90 pop r0 + 5fb8: 0f 90 pop r0 + 5fba: 0f 90 pop r0 + 5fbc: 0f 90 pop r0 + } +#endif + uint32_t tempIp; + + // change type to reply + nicState.layer4.icmp->type = ICMP_TYPE_ECHOREPLY; + 5fbe: e0 91 8a 0e lds r30, 0x0E8A + 5fc2: f0 91 8b 0e lds r31, 0x0E8B + 5fc6: 10 82 st Z, r1 + // recalculate checksum + nicState.layer4.icmp->icmpchksum = 0; + 5fc8: e0 91 8a 0e lds r30, 0x0E8A + 5fcc: f0 91 8b 0e lds r31, 0x0E8B + 5fd0: 13 82 std Z+3, r1 ; 0x03 + 5fd2: 12 82 std Z+2, r1 ; 0x02 + nicState.layer4.icmp->icmpchksum = netChecksum((uint8_t*)(nicState.layer4.icmp), htons(nicState.layer3.ip->len)-IP_HEADER_LEN); + 5fd4: e0 91 88 0e lds r30, 0x0E88 + 5fd8: f0 91 89 0e lds r31, 0x0E89 + 5fdc: 82 81 ldd r24, Z+2 ; 0x02 + 5fde: 93 81 ldd r25, Z+3 ; 0x03 + 5fe0: 0e 94 cb 2a call 0x5596 ; 0x5596 + 5fe4: c0 91 8a 0e lds r28, 0x0E8A + 5fe8: d0 91 8b 0e lds r29, 0x0E8B + 5fec: bc 01 movw r22, r24 + 5fee: 64 51 subi r22, 0x14 ; 20 + 5ff0: 71 09 sbc r23, r1 + 5ff2: ce 01 movw r24, r28 + 5ff4: 0e 94 d5 2a call 0x55aa ; 0x55aa + 5ff8: 9b 83 std Y+3, r25 ; 0x03 + 5ffa: 8a 83 std Y+2, r24 ; 0x02 + // return to sender + tempIp = nicState.layer3.ip->destipaddr; + 5ffc: e0 91 88 0e lds r30, 0x0E88 + 6000: f0 91 89 0e lds r31, 0x0E89 + 6004: 80 89 ldd r24, Z+16 ; 0x10 + 6006: 91 89 ldd r25, Z+17 ; 0x11 + 6008: a2 89 ldd r26, Z+18 ; 0x12 + 600a: b3 89 ldd r27, Z+19 ; 0x13 + nicState.layer3.ip->destipaddr = nicState.layer3.ip->srcipaddr; + 600c: 44 85 ldd r20, Z+12 ; 0x0c + 600e: 55 85 ldd r21, Z+13 ; 0x0d + 6010: 66 85 ldd r22, Z+14 ; 0x0e + 6012: 77 85 ldd r23, Z+15 ; 0x0f + 6014: 40 8b std Z+16, r20 ; 0x10 + 6016: 51 8b std Z+17, r21 ; 0x11 + 6018: 62 8b std Z+18, r22 ; 0x12 + 601a: 73 8b std Z+19, r23 ; 0x13 + nicState.layer3.ip->srcipaddr = tempIp; + 601c: 84 87 std Z+12, r24 ; 0x0c + 601e: 95 87 std Z+13, r25 ; 0x0d + 6020: a6 87 std Z+14, r26 ; 0x0e + 6022: b7 87 std Z+15, r27 ; 0x0f + // add ethernet routing + arpIpOut(0); + 6024: 60 e0 ldi r22, 0x00 ; 0 + 6026: 70 e0 ldi r23, 0x00 ; 0 + 6028: cb 01 movw r24, r22 + 602a: 0e 94 52 31 call 0x62a4 ; 0x62a4 + + // debugging + if (icmpDebug != NULL) + 602e: 80 91 aa 0e lds r24, 0x0EAA + 6032: 90 91 ab 0e lds r25, 0x0EAB + 6036: 00 97 sbiw r24, 0x00 ; 0 + 6038: 51 f0 breq .+20 ; 0x604e + icmpPrintHeader(icmpDebug, nicState.layer3.ip, nicState.layer4.icmp); + 603a: 40 91 8a 0e lds r20, 0x0E8A + 603e: 50 91 8b 0e lds r21, 0x0E8B + 6042: 60 91 88 0e lds r22, 0x0E88 + 6046: 70 91 89 0e lds r23, 0x0E89 + 604a: 0e 94 5f 2f call 0x5ebe ; 0x5ebe + //debugPrintHexTable(htons(packet->ip.len), (uint8_t*)packet); + + // send it (packet->ip.len+ETH_HEADER_LEN + nicSend(htons(nicState.layer3.ip->len) + ETH_HEADER_LEN); + 604e: e0 91 88 0e lds r30, 0x0E88 + 6052: f0 91 89 0e lds r31, 0x0E89 + 6056: 82 81 ldd r24, Z+2 ; 0x02 + 6058: 93 81 ldd r25, Z+3 ; 0x03 + 605a: 0e 94 cb 2a call 0x5596 ; 0x5596 + 605e: 0e 96 adiw r24, 0x0e ; 14 + 6060: 0e 94 0e 28 call 0x501c ; 0x501c +#if ICMP_DEBUG + if (icmpDebug != NULL) + 6064: 80 91 aa 0e lds r24, 0x0EAA + 6068: 90 91 ab 0e lds r25, 0x0EAB + 606c: 00 97 sbiw r24, 0x00 ; 0 + 606e: 81 f0 breq .+32 ; 0x6090 + { + if (icmpDebugLevel > 1) + 6070: 20 91 4b 0f lds r18, 0x0F4B + 6074: 22 30 cpi r18, 0x02 ; 2 + 6076: 60 f0 brcs .+24 ; 0x6090 + fprintf_P(icmpDebug, PSTR("Sending ICMP PONG\r\n")); + 6078: 28 e5 ldi r18, 0x58 ; 88 + 607a: 3f e0 ldi r19, 0x0F ; 15 + 607c: 3f 93 push r19 + 607e: 2f 93 push r18 + 6080: 9f 93 push r25 + 6082: 8f 93 push r24 + 6084: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6088: 0f 90 pop r0 + 608a: 0f 90 pop r0 + 608c: 0f 90 pop r0 + 608e: 0f 90 pop r0 + } +#endif +} + 6090: df 91 pop r29 + 6092: cf 91 pop r28 + 6094: 08 95 ret + +00006096 : +} + +void icmpIpIn(void) +{ + // check ICMP type + switch(nicState.layer4.icmp->type) + 6096: e0 91 8a 0e lds r30, 0x0E8A + 609a: f0 91 8b 0e lds r31, 0x0E8B + 609e: 80 81 ld r24, Z + 60a0: 88 30 cpi r24, 0x08 ; 8 + 60a2: 11 f4 brne .+4 ; 0x60a8 + { + case ICMP_TYPE_ECHOREQUEST: + icmpEchoRequest(); // echo request + 60a4: 0c 94 c7 2f jmp 0x5f8e ; 0x5f8e + break; + default: +#if ICMP_DEBUG + if (icmpDebug != NULL) + 60a8: 80 91 aa 0e lds r24, 0x0EAA + 60ac: 90 91 ab 0e lds r25, 0x0EAB + 60b0: 00 97 sbiw r24, 0x00 ; 0 + 60b2: 81 f0 breq .+32 ; 0x60d4 + { + if (icmpDebugLevel > 0) + 60b4: 20 91 4b 0f lds r18, 0x0F4B + 60b8: 22 23 and r18, r18 + 60ba: 61 f0 breq .+24 ; 0x60d4 + fprintf_P(icmpDebug, PSTR("Unknown ICMP typeReceived ICMP request: ")); + 60bc: 24 e8 ldi r18, 0x84 ; 132 + 60be: 3f e0 ldi r19, 0x0F ; 15 + 60c0: 3f 93 push r19 + 60c2: 2f 93 push r18 + 60c4: 9f 93 push r25 + 60c6: 8f 93 push r24 + 60c8: 0e 94 1a 50 call 0xa034 ; 0xa034 + 60cc: 0f 90 pop r0 + 60ce: 0f 90 pop r0 + 60d0: 0f 90 pop r0 + 60d2: 0f 90 pop r0 + 60d4: 08 95 ret + +000060d6 : + +#ifdef ARP_DEBUG + +void setArpDebug(FILE *stream, uint8_t level) +{ + arpDebug = stream; + 60d6: 90 93 8d 0e sts 0x0E8D, r25 + 60da: 80 93 8c 0e sts 0x0E8C, r24 + arpDebugLevel = level; + 60de: 60 93 5d 0f sts 0x0F5D, r22 + if (level == 0) + 60e2: 61 11 cpse r22, r1 + 60e4: 04 c0 rjmp .+8 ; 0x60ee + arpDebug = NULL; + 60e6: 10 92 8d 0e sts 0x0E8D, r1 + 60ea: 10 92 8c 0e sts 0x0E8C, r1 + 60ee: 08 95 ret + +000060f0 : +#endif /*ARP_DEBUG*/ + +void arpInit() +{ + + memset(ArpTable, 0, sizeof(ArpTable)); + 60f0: 8e e6 ldi r24, 0x6E ; 110 + 60f2: e8 e6 ldi r30, 0x68 ; 104 + 60f4: ff e0 ldi r31, 0x0F ; 15 + 60f6: df 01 movw r26, r30 + 60f8: 1d 92 st X+, r1 + 60fa: 8a 95 dec r24 + 60fc: e9 f7 brne .-6 ; 0x60f8 + arpDebug = NULL; + 60fe: 10 92 8d 0e sts 0x0E8D, r1 + 6102: 10 92 8c 0e sts 0x0E8C, r1 + 6106: 08 95 ret + +00006108 : + nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + } +} + +void arpTimer(void) +{ + 6108: e2 e7 ldi r30, 0x72 ; 114 + 610a: ff e0 ldi r31, 0x0F ; 15 +// this function meant to be called on a regular time interval + +// decrement time-to-live for all entries + for(index=0; index + ArpTable[index].time--; + 6112: 81 50 subi r24, 0x01 ; 1 + 6114: 80 83 st Z, r24 + 6116: 3b 96 adiw r30, 0x0b ; 11 +{ + int index; +// this function meant to be called on a regular time interval + +// decrement time-to-live for all entries + for(index=0; index + { + if(ArpTable[index].time) + ArpTable[index].time--; + } +} + 6120: 08 95 ret + +00006122 : + +int arpMatchIp(uint32_t ipaddr) +{ + 6122: 0f 93 push r16 + 6124: 1f 93 push r17 + 6126: e8 e6 ldi r30, 0x68 ; 104 + 6128: ff e0 ldi r31, 0x0F ; 15 + 612a: 20 e0 ldi r18, 0x00 ; 0 + 612c: 30 e0 ldi r19, 0x00 ; 0 + uint8_t i; + + // check if IP address is present in arp table + for(i=0; i + 6142: 9a 01 movw r18, r20 + 6144: 2f 5f subi r18, 0xFF ; 255 + 6146: 3f 4f sbci r19, 0xFF ; 255 + 6148: 3b 96 adiw r30, 0x0b ; 11 +int arpMatchIp(uint32_t ipaddr) +{ + uint8_t i; + + // check if IP address is present in arp table + for(i=0; i + return i; + } + } + +// no match + return -1; + 6150: 4f ef ldi r20, 0xFF ; 255 + 6152: 5f ef ldi r21, 0xFF ; 255 +} + 6154: ca 01 movw r24, r20 + 6156: 1f 91 pop r17 + 6158: 0f 91 pop r16 + 615a: 08 95 ret + +0000615c : + nicSend(sizeof(struct netArpHeader) + ETH_HEADER_LEN); + } +} + +void arpIpIn(void) +{ + 615c: cf 93 push r28 + 615e: df 93 push r29 +#ifdef ARP_DEBUG + if (arpDebug != NULL) + 6160: 80 91 8c 0e lds r24, 0x0E8C + 6164: 90 91 8d 0e lds r25, 0x0E8D + 6168: 00 97 sbiw r24, 0x00 ; 0 + 616a: 09 f4 brne .+2 ; 0x616e + 616c: 47 c0 rjmp .+142 ; 0x61fc + { + if (arpDebugLevel > 0) + 616e: 20 91 5d 0f lds r18, 0x0F5D + 6172: 22 23 and r18, r18 + 6174: 09 f4 brne .+2 ; 0x6178 + 6176: 42 c0 rjmp .+132 ; 0x61fc + { + fprintf_P(arpDebug, PSTR("ARP IP in MAC: ")); + 6178: 27 e9 ldi r18, 0x97 ; 151 + 617a: 30 e1 ldi r19, 0x10 ; 16 + 617c: 3f 93 push r19 + 617e: 2f 93 push r18 + 6180: 9f 93 push r25 + 6182: 8f 93 push r24 + 6184: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintEthAddr(arpDebug, &nicState.layer2.ethHeader->src); + 6188: 60 91 86 0e lds r22, 0x0E86 + 618c: 70 91 87 0e lds r23, 0x0E87 + 6190: 6a 5f subi r22, 0xFA ; 250 + 6192: 7f 4f sbci r23, 0xFF ; 255 + 6194: 80 91 8c 0e lds r24, 0x0E8C + 6198: 90 91 8d 0e lds r25, 0x0E8D + 619c: 0e 94 05 2b call 0x560a ; 0x560a + fprintf_P(arpDebug, PSTR(" IP: ")); + 61a0: 81 e9 ldi r24, 0x91 ; 145 + 61a2: 90 e1 ldi r25, 0x10 ; 16 + 61a4: 9f 93 push r25 + 61a6: 8f 93 push r24 + 61a8: 80 91 8d 0e lds r24, 0x0E8D + 61ac: 8f 93 push r24 + 61ae: 80 91 8c 0e lds r24, 0x0E8C + 61b2: 8f 93 push r24 + 61b4: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(arpDebug, nicState.layer3.ip->srcipaddr); + 61b8: e0 91 88 0e lds r30, 0x0E88 + 61bc: f0 91 89 0e lds r31, 0x0E89 + 61c0: 44 85 ldd r20, Z+12 ; 0x0c + 61c2: 55 85 ldd r21, Z+13 ; 0x0d + 61c4: 66 85 ldd r22, Z+14 ; 0x0e + 61c6: 77 85 ldd r23, Z+15 ; 0x0f + 61c8: 80 91 8c 0e lds r24, 0x0E8C + 61cc: 90 91 8d 0e lds r25, 0x0E8D + 61d0: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(arpDebug, PSTR("\r\n")); + 61d4: 8e e8 ldi r24, 0x8E ; 142 + 61d6: 90 e1 ldi r25, 0x10 ; 16 + 61d8: 9f 93 push r25 + 61da: 8f 93 push r24 + 61dc: 80 91 8d 0e lds r24, 0x0E8D + 61e0: 8f 93 push r24 + 61e2: 80 91 8c 0e lds r24, 0x0E8C + 61e6: 8f 93 push r24 + 61e8: 0e 94 1a 50 call 0xa034 ; 0xa034 + 61ec: 8d b7 in r24, 0x3d ; 61 + 61ee: 9e b7 in r25, 0x3e ; 62 + 61f0: 0c 96 adiw r24, 0x0c ; 12 + 61f2: 0f b6 in r0, 0x3f ; 63 + 61f4: f8 94 cli + 61f6: 9e bf out 0x3e, r25 ; 62 + 61f8: 0f be out 0x3f, r0 ; 63 + 61fa: 8d bf out 0x3d, r24 ; 61 + } +#endif + int8_t index; + +// check if sender is already present in arp table + index = arpMatchIp(nicState.layer3.ip->srcipaddr); + 61fc: c0 91 88 0e lds r28, 0x0E88 + 6200: d0 91 89 0e lds r29, 0x0E89 + 6204: 6c 85 ldd r22, Y+12 ; 0x0c + 6206: 7d 85 ldd r23, Y+13 ; 0x0d + 6208: 8e 85 ldd r24, Y+14 ; 0x0e + 620a: 9f 85 ldd r25, Y+15 ; 0x0f + 620c: 0e 94 91 30 call 0x6122 ; 0x6122 + if(index != -1) + 6210: 8f 3f cpi r24, 0xFF ; 255 + 6212: b9 f0 breq .+46 ; 0x6242 + { +// sender's IP address found, update ARP entry + ArpTable[index].ethaddr = nicState.layer2.ethHeader->src; + 6214: 2b e0 ldi r18, 0x0B ; 11 + 6216: 82 02 muls r24, r18 + 6218: c0 01 movw r24, r0 + 621a: 11 24 eor r1, r1 + 621c: dc 01 movw r26, r24 + 621e: a4 59 subi r26, 0x94 ; 148 + 6220: b0 4f sbci r27, 0xF0 ; 240 + 6222: e0 91 86 0e lds r30, 0x0E86 + 6226: f0 91 87 0e lds r31, 0x0E87 + 622a: 26 e0 ldi r18, 0x06 ; 6 + 622c: 36 96 adiw r30, 0x06 ; 6 + 622e: 01 90 ld r0, Z+ + 6230: 0d 92 st X+, r0 + 6232: 2a 95 dec r18 + 6234: e1 f7 brne .-8 ; 0x622e + ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 6236: fc 01 movw r30, r24 + 6238: e8 59 subi r30, 0x98 ; 152 + 623a: f0 4f sbci r31, 0xF0 ; 240 + 623c: 20 e8 ldi r18, 0x80 ; 128 + 623e: 22 87 std Z+10, r18 ; 0x0a +// and we're done + return; + 6240: 2e c0 rjmp .+92 ; 0x629e + 6242: e2 e7 ldi r30, 0x72 ; 114 + 6244: ff e0 ldi r31, 0x0F ; 15 +#endif + int8_t index; + +// check if sender is already present in arp table + index = arpMatchIp(nicState.layer3.ip->srcipaddr); + if(index != -1) + 6246: 20 e0 ldi r18, 0x00 ; 0 + 6248: 30 e0 ldi r19, 0x00 ; 0 + +// sender was not present in table, +// must add in empty/expired slot + for(index=0; index + { +// write entry + ArpTable[index].ethaddr = nicState.layer2.ethHeader->src; + 6250: 4b e0 ldi r20, 0x0B ; 11 + 6252: 42 9f mul r20, r18 + 6254: c0 01 movw r24, r0 + 6256: 43 9f mul r20, r19 + 6258: 90 0d add r25, r0 + 625a: 11 24 eor r1, r1 + 625c: dc 01 movw r26, r24 + 625e: a4 59 subi r26, 0x94 ; 148 + 6260: b0 4f sbci r27, 0xF0 ; 240 + 6262: e0 91 86 0e lds r30, 0x0E86 + 6266: f0 91 87 0e lds r31, 0x0E87 + 626a: 26 e0 ldi r18, 0x06 ; 6 + 626c: 36 96 adiw r30, 0x06 ; 6 + 626e: 01 90 ld r0, Z+ + 6270: 0d 92 st X+, r0 + 6272: 2a 95 dec r18 + 6274: e1 f7 brne .-8 ; 0x626e + ArpTable[index].ipaddr = nicState.layer3.ip->srcipaddr; + 6276: fc 01 movw r30, r24 + 6278: e8 59 subi r30, 0x98 ; 152 + 627a: f0 4f sbci r31, 0xF0 ; 240 + 627c: 8c 85 ldd r24, Y+12 ; 0x0c + 627e: 9d 85 ldd r25, Y+13 ; 0x0d + 6280: ae 85 ldd r26, Y+14 ; 0x0e + 6282: bf 85 ldd r27, Y+15 ; 0x0f + 6284: 80 83 st Z, r24 + 6286: 91 83 std Z+1, r25 ; 0x01 + 6288: a2 83 std Z+2, r26 ; 0x02 + 628a: b3 83 std Z+3, r27 ; 0x03 + ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE; + 628c: 80 e8 ldi r24, 0x80 ; 128 + 628e: 82 87 std Z+10, r24 ; 0x0a +// and we're done + return; + 6290: 06 c0 rjmp .+12 ; 0x629e + 6292: 2f 5f subi r18, 0xFF ; 255 + 6294: 3f 4f sbci r19, 0xFF ; 255 + 6296: 3b 96 adiw r30, 0x0b ; 11 + return; + } + +// sender was not present in table, +// must add in empty/expired slot + for(index=0; index +// and we're done + return; + } + } +// no space in table, we give up +} + 629e: df 91 pop r29 + 62a0: cf 91 pop r28 + 62a2: 08 95 ret + +000062a4 : +void arpIpOut(uint32_t phyDstIp) +{ + int index; +// check if destination is already present in arp table +// use the physical dstIp if it's provided, otherwise the dstIp in packet + if(phyDstIp) + 62a4: 61 15 cp r22, r1 + 62a6: 71 05 cpc r23, r1 + 62a8: 81 05 cpc r24, r1 + 62aa: 91 05 cpc r25, r1 + 62ac: 41 f4 brne .+16 ; 0x62be + index = arpMatchIp(phyDstIp); + else + index = arpMatchIp(nicState.layer3.ip->destipaddr); + 62ae: e0 91 88 0e lds r30, 0x0E88 + 62b2: f0 91 89 0e lds r31, 0x0E89 + 62b6: 60 89 ldd r22, Z+16 ; 0x10 + 62b8: 71 89 ldd r23, Z+17 ; 0x11 + 62ba: 82 89 ldd r24, Z+18 ; 0x12 + 62bc: 93 89 ldd r25, Z+19 ; 0x13 + 62be: 0e 94 91 30 call 0x6122 ; 0x6122 + 62c2: a0 91 86 0e lds r26, 0x0E86 + 62c6: b0 91 87 0e lds r27, 0x0E87 +// fill in ethernet info + if(index != -1) + 62ca: 8f 3f cpi r24, 0xFF ; 255 + 62cc: 2f ef ldi r18, 0xFF ; 255 + 62ce: 92 07 cpc r25, r18 + 62d0: d1 f0 breq .+52 ; 0x6306 + { +// ARP entry present, fill eth address(es) + nicState.layer2.ethHeader->src = nicState.mac; + 62d2: 26 e0 ldi r18, 0x06 ; 6 + 62d4: e0 e8 ldi r30, 0x80 ; 128 + 62d6: fe e0 ldi r31, 0x0E ; 14 + 62d8: 16 96 adiw r26, 0x06 ; 6 + 62da: 01 90 ld r0, Z+ + 62dc: 0d 92 st X+, r0 + 62de: 2a 95 dec r18 + 62e0: e1 f7 brne .-8 ; 0x62da + nicState.layer2.ethHeader->dest = ArpTable[index].ethaddr; + 62e2: a0 91 86 0e lds r26, 0x0E86 + 62e6: b0 91 87 0e lds r27, 0x0E87 + 62ea: 2b e0 ldi r18, 0x0B ; 11 + 62ec: 28 9f mul r18, r24 + 62ee: f0 01 movw r30, r0 + 62f0: 29 9f mul r18, r25 + 62f2: f0 0d add r31, r0 + 62f4: 11 24 eor r1, r1 + 62f6: e4 59 subi r30, 0x94 ; 148 + 62f8: f0 4f sbci r31, 0xF0 ; 240 + 62fa: 86 e0 ldi r24, 0x06 ; 6 + 62fc: 01 90 ld r0, Z+ + 62fe: 0d 92 st X+, r0 + 6300: 8a 95 dec r24 + 6302: e1 f7 brne .-8 ; 0x62fc + 6304: 12 c0 rjmp .+36 ; 0x632a + nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + } + else + { +// not in table, must send ARP request + nicState.layer2.ethHeader->src = nicState.mac; + 6306: 86 e0 ldi r24, 0x06 ; 6 + 6308: e0 e8 ldi r30, 0x80 ; 128 + 630a: fe e0 ldi r31, 0x0E ; 14 + 630c: 16 96 adiw r26, 0x06 ; 6 + 630e: 01 90 ld r0, Z+ + 6310: 0d 92 st X+, r0 + 6312: 8a 95 dec r24 + 6314: e1 f7 brne .-8 ; 0x630e +// TODO MUST CHANGE, but for now, send this one broadcast +// before sending frame, must copy buffer + memset(nicState.layer2.ethHeader->dest.addr, 0xFF, 6); + 6316: 46 e0 ldi r20, 0x06 ; 6 + 6318: 50 e0 ldi r21, 0x00 ; 0 + 631a: 6f ef ldi r22, 0xFF ; 255 + 631c: 70 e0 ldi r23, 0x00 ; 0 + 631e: 80 91 86 0e lds r24, 0x0E86 + 6322: 90 91 87 0e lds r25, 0x0E87 + 6326: 0e 94 7f 4f call 0x9efe ; 0x9efe + nicState.layer2.ethHeader->type = HTONS(ETHTYPE_IP); + 632a: e0 91 86 0e lds r30, 0x0E86 + 632e: f0 91 87 0e lds r31, 0x0E87 + 6332: 88 e0 ldi r24, 0x08 ; 8 + 6334: 90 e0 ldi r25, 0x00 ; 0 + 6336: 95 87 std Z+13, r25 ; 0x0d + 6338: 84 87 std Z+12, r24 ; 0x0c + 633a: 08 95 ret + +0000633c : + return -1; +} + +#if ARP_DEBUG +void arpPrintHeader(FILE *stream, struct netArpHeader* packet) +{ + 633c: ef 92 push r14 + 633e: ff 92 push r15 + 6340: 0f 93 push r16 + 6342: 1f 93 push r17 + 6344: cf 93 push r28 + 6346: df 93 push r29 + 6348: ec 01 movw r28, r24 + 634a: 8b 01 movw r16, r22 + fprintf_P(stream, PSTR("ARP Packet:\r\n")); + 634c: 80 e8 ldi r24, 0x80 ; 128 + 634e: 90 e1 ldi r25, 0x10 ; 16 + 6350: 9f 93 push r25 + 6352: 8f 93 push r24 + 6354: df 93 push r29 + 6356: cf 93 push r28 + 6358: 0e 94 1a 50 call 0xa034 ; 0xa034 + //debugPrintHexTable(60, (unsigned char*)&packet); + // print operation type + fprintf_P(stream, PSTR("Operation : ")); + 635c: 81 e7 ldi r24, 0x71 ; 113 + 635e: 90 e1 ldi r25, 0x10 ; 16 + 6360: 9f 93 push r25 + 6362: 8f 93 push r24 + 6364: df 93 push r29 + 6366: cf 93 push r28 + 6368: 0e 94 1a 50 call 0xa034 ; 0xa034 + if(packet->opcode == htons(ARP_OPCODE_REQUEST)) + 636c: f8 01 movw r30, r16 + 636e: e6 80 ldd r14, Z+6 ; 0x06 + 6370: f7 80 ldd r15, Z+7 ; 0x07 + 6372: 81 e0 ldi r24, 0x01 ; 1 + 6374: 90 e0 ldi r25, 0x00 ; 0 + 6376: 0e 94 cb 2a call 0x5596 ; 0x5596 + 637a: 2d b7 in r18, 0x3d ; 61 + 637c: 3e b7 in r19, 0x3e ; 62 + 637e: 28 5f subi r18, 0xF8 ; 248 + 6380: 3f 4f sbci r19, 0xFF ; 255 + 6382: 0f b6 in r0, 0x3f ; 63 + 6384: f8 94 cli + 6386: 3e bf out 0x3e, r19 ; 62 + 6388: 0f be out 0x3f, r0 ; 63 + 638a: 2d bf out 0x3d, r18 ; 61 + 638c: e8 16 cp r14, r24 + 638e: f9 06 cpc r15, r25 + 6390: 19 f4 brne .+6 ; 0x6398 + fprintf_P(stream, PSTR("REQUEST")); + 6392: 89 e6 ldi r24, 0x69 ; 105 + 6394: 90 e1 ldi r25, 0x10 ; 16 + 6396: 0f c0 rjmp .+30 ; 0x63b6 + else if(packet->opcode == htons(ARP_OPCODE_REPLY)) + 6398: f8 01 movw r30, r16 + 639a: e6 80 ldd r14, Z+6 ; 0x06 + 639c: f7 80 ldd r15, Z+7 ; 0x07 + 639e: 82 e0 ldi r24, 0x02 ; 2 + 63a0: 90 e0 ldi r25, 0x00 ; 0 + 63a2: 0e 94 cb 2a call 0x5596 ; 0x5596 + 63a6: e8 16 cp r14, r24 + 63a8: f9 06 cpc r15, r25 + 63aa: 19 f4 brne .+6 ; 0x63b2 + fprintf_P(stream, PSTR("REPLY")); + 63ac: 83 e6 ldi r24, 0x63 ; 99 + 63ae: 90 e1 ldi r25, 0x10 ; 16 + 63b0: 02 c0 rjmp .+4 ; 0x63b6 + else + fprintf_P(stream, PSTR("UNKNOWN")); + 63b2: 8b e5 ldi r24, 0x5B ; 91 + 63b4: 90 e1 ldi r25, 0x10 ; 16 + 63b6: 9f 93 push r25 + 63b8: 8f 93 push r24 + 63ba: df 93 push r29 + 63bc: cf 93 push r28 + 63be: 0e 94 1a 50 call 0xa034 ; 0xa034 + 63c2: 0f 90 pop r0 + 63c4: 0f 90 pop r0 + 63c6: 0f 90 pop r0 + 63c8: 0f 90 pop r0 + fprintf_P(stream, PSTR("\r\n")); + 63ca: 88 e5 ldi r24, 0x58 ; 88 + 63cc: 90 e1 ldi r25, 0x10 ; 16 + 63ce: 9f 93 push r25 + 63d0: 8f 93 push r24 + 63d2: df 93 push r29 + 63d4: cf 93 push r28 + 63d6: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print source hardware address + fprintf_P(stream, PSTR("SrcHwAddr : ")); netPrintEthAddr(stream, &packet->shwaddr); fprintf_P(stream, PSTR("\r\n")); + 63da: 89 e4 ldi r24, 0x49 ; 73 + 63dc: 90 e1 ldi r25, 0x10 ; 16 + 63de: 9f 93 push r25 + 63e0: 8f 93 push r24 + 63e2: df 93 push r29 + 63e4: cf 93 push r28 + 63e6: 0e 94 1a 50 call 0xa034 ; 0xa034 + 63ea: b8 01 movw r22, r16 + 63ec: 68 5f subi r22, 0xF8 ; 248 + 63ee: 7f 4f sbci r23, 0xFF ; 255 + 63f0: ce 01 movw r24, r28 + 63f2: 0e 94 05 2b call 0x560a ; 0x560a + 63f6: 86 e4 ldi r24, 0x46 ; 70 + 63f8: 90 e1 ldi r25, 0x10 ; 16 + 63fa: 9f 93 push r25 + 63fc: 8f 93 push r24 + 63fe: df 93 push r29 + 6400: cf 93 push r28 + 6402: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print source protocol address + fprintf_P(stream, PSTR("SrcProtoAddr: ")); netPrintIPAddr(stream, packet->sipaddr); fprintf_P(stream, PSTR("\r\n")); + 6406: 87 e3 ldi r24, 0x37 ; 55 + 6408: 90 e1 ldi r25, 0x10 ; 16 + 640a: 9f 93 push r25 + 640c: 8f 93 push r24 + 640e: df 93 push r29 + 6410: cf 93 push r28 + 6412: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6416: f8 01 movw r30, r16 + 6418: 46 85 ldd r20, Z+14 ; 0x0e + 641a: 57 85 ldd r21, Z+15 ; 0x0f + 641c: 60 89 ldd r22, Z+16 ; 0x10 + 641e: 71 89 ldd r23, Z+17 ; 0x11 + 6420: ce 01 movw r24, r28 + 6422: 0e 94 29 2b call 0x5652 ; 0x5652 + 6426: 84 e3 ldi r24, 0x34 ; 52 + 6428: 90 e1 ldi r25, 0x10 ; 16 + 642a: 9f 93 push r25 + 642c: 8f 93 push r24 + 642e: df 93 push r29 + 6430: cf 93 push r28 + 6432: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print target hardware address + fprintf_P(stream, PSTR("DstHwAddr : ")); netPrintEthAddr(stream, &packet->dhwaddr); fprintf_P(stream, PSTR("\r\n")); + 6436: 85 e2 ldi r24, 0x25 ; 37 + 6438: 90 e1 ldi r25, 0x10 ; 16 + 643a: 9f 93 push r25 + 643c: 8f 93 push r24 + 643e: df 93 push r29 + 6440: cf 93 push r28 + 6442: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6446: b8 01 movw r22, r16 + 6448: 6e 5e subi r22, 0xEE ; 238 + 644a: 7f 4f sbci r23, 0xFF ; 255 + 644c: ce 01 movw r24, r28 + 644e: 0e 94 05 2b call 0x560a ; 0x560a + 6452: 82 e2 ldi r24, 0x22 ; 34 + 6454: 90 e1 ldi r25, 0x10 ; 16 + 6456: 9f 93 push r25 + 6458: 8f 93 push r24 + 645a: df 93 push r29 + 645c: cf 93 push r28 + 645e: 0e 94 1a 50 call 0xa034 ; 0xa034 +// print target protocol address + fprintf_P(stream, PSTR("DstProtoAddr: ")); netPrintIPAddr(stream, packet->dipaddr); fprintf_P(stream, PSTR("\r\n")); + 6462: 83 e1 ldi r24, 0x13 ; 19 + 6464: 90 e1 ldi r25, 0x10 ; 16 + 6466: 9f 93 push r25 + 6468: 8f 93 push r24 + 646a: df 93 push r29 + 646c: cf 93 push r28 + 646e: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6472: 2d b7 in r18, 0x3d ; 61 + 6474: 3e b7 in r19, 0x3e ; 62 + 6476: 20 5e subi r18, 0xE0 ; 224 + 6478: 3f 4f sbci r19, 0xFF ; 255 + 647a: 0f b6 in r0, 0x3f ; 63 + 647c: f8 94 cli + 647e: 3e bf out 0x3e, r19 ; 62 + 6480: 0f be out 0x3f, r0 ; 63 + 6482: 2d bf out 0x3d, r18 ; 61 + 6484: f8 01 movw r30, r16 + 6486: 40 8d ldd r20, Z+24 ; 0x18 + 6488: 51 8d ldd r21, Z+25 ; 0x19 + 648a: 62 8d ldd r22, Z+26 ; 0x1a + 648c: 73 8d ldd r23, Z+27 ; 0x1b + 648e: ce 01 movw r24, r28 + 6490: 0e 94 29 2b call 0x5652 ; 0x5652 + 6494: 80 e1 ldi r24, 0x10 ; 16 + 6496: 90 e1 ldi r25, 0x10 ; 16 + 6498: 9f 93 push r25 + 649a: 8f 93 push r24 + 649c: df 93 push r29 + 649e: cf 93 push r28 + 64a0: 0e 94 1a 50 call 0xa034 ; 0xa034 + 64a4: 0f 90 pop r0 + 64a6: 0f 90 pop r0 + 64a8: 0f 90 pop r0 + 64aa: 0f 90 pop r0 +} + 64ac: df 91 pop r29 + 64ae: cf 91 pop r28 + 64b0: 1f 91 pop r17 + 64b2: 0f 91 pop r16 + 64b4: ff 90 pop r15 + 64b6: ef 90 pop r14 + 64b8: 08 95 ret + +000064ba : + memset(ArpTable, 0, sizeof(ArpTable)); + arpDebug = NULL; +} + +void arpArpIn(void) +{ + 64ba: cf 93 push r28 + 64bc: df 93 push r29 +#ifdef ARP_DEBUG + if (arpDebug != NULL) + 64be: 80 91 8c 0e lds r24, 0x0E8C + 64c2: 90 91 8d 0e lds r25, 0x0E8D + 64c6: 00 97 sbiw r24, 0x00 ; 0 + 64c8: f1 f0 breq .+60 ; 0x6506 + { + if (arpDebugLevel > 1) + 64ca: 20 91 5d 0f lds r18, 0x0F5D + 64ce: 22 30 cpi r18, 0x02 ; 2 + 64d0: 60 f0 brcs .+24 ; 0x64ea + fprintf_P(arpDebug, PSTR("Received ARP Request\r\n")); + 64d2: 2b eb ldi r18, 0xBB ; 187 + 64d4: 30 e1 ldi r19, 0x10 ; 16 + 64d6: 3f 93 push r19 + 64d8: 2f 93 push r18 + 64da: 9f 93 push r25 + 64dc: 8f 93 push r24 + 64de: 0e 94 1a 50 call 0xa034 ; 0xa034 + 64e2: 0f 90 pop r0 + 64e4: 0f 90 pop r0 + 64e6: 0f 90 pop r0 + 64e8: 0f 90 pop r0 + if (arpDebugLevel > 2) + 64ea: 80 91 5d 0f lds r24, 0x0F5D + 64ee: 83 30 cpi r24, 0x03 ; 3 + 64f0: 50 f0 brcs .+20 ; 0x6506 + arpPrintHeader(arpDebug, nicState.layer3.arp); + 64f2: 60 91 88 0e lds r22, 0x0E88 + 64f6: 70 91 89 0e lds r23, 0x0E89 + 64fa: 80 91 8c 0e lds r24, 0x0E8C + 64fe: 90 91 8d 0e lds r25, 0x0E8D + 6502: 0e 94 9e 31 call 0x633c ; 0x633c + } +#endif + +// for now, we just reply to requests +// need to add ARP cache + if((nicState.layer3.arp->dipaddr == IpMyConfig.ip) && (nicState.layer3.arp->opcode == htons(ARP_OPCODE_REQUEST)) ) + 6506: e0 91 88 0e lds r30, 0x0E88 + 650a: f0 91 89 0e lds r31, 0x0E89 + 650e: 40 8d ldd r20, Z+24 ; 0x18 + 6510: 51 8d ldd r21, Z+25 ; 0x19 + 6512: 62 8d ldd r22, Z+26 ; 0x1a + 6514: 73 8d ldd r23, Z+27 ; 0x1b + 6516: 80 91 4e 0f lds r24, 0x0F4E + 651a: 90 91 4f 0f lds r25, 0x0F4F + 651e: a0 91 50 0f lds r26, 0x0F50 + 6522: b0 91 51 0f lds r27, 0x0F51 + 6526: 48 17 cp r20, r24 + 6528: 59 07 cpc r21, r25 + 652a: 6a 07 cpc r22, r26 + 652c: 7b 07 cpc r23, r27 + 652e: 09 f0 breq .+2 ; 0x6532 + 6530: 7b c0 rjmp .+246 ; 0x6628 + 6532: c6 81 ldd r28, Z+6 ; 0x06 + 6534: d7 81 ldd r29, Z+7 ; 0x07 + 6536: 81 e0 ldi r24, 0x01 ; 1 + 6538: 90 e0 ldi r25, 0x00 ; 0 + 653a: 0e 94 cb 2a call 0x5596 ; 0x5596 + 653e: c8 17 cp r28, r24 + 6540: d9 07 cpc r29, r25 + 6542: 09 f0 breq .+2 ; 0x6546 + 6544: 71 c0 rjmp .+226 ; 0x6628 + { +// in ARP header +// copy sender's address info to dest. fields + nicState.layer3.arp->dhwaddr = nicState.layer3.arp->shwaddr; + 6546: c0 91 88 0e lds r28, 0x0E88 + 654a: d0 91 89 0e lds r29, 0x0E89 + 654e: 86 e0 ldi r24, 0x06 ; 6 + 6550: fe 01 movw r30, r28 + 6552: 38 96 adiw r30, 0x08 ; 8 + 6554: de 01 movw r26, r28 + 6556: 52 96 adiw r26, 0x12 ; 18 + 6558: 01 90 ld r0, Z+ + 655a: 0d 92 st X+, r0 + 655c: 8a 95 dec r24 + 655e: e1 f7 brne .-8 ; 0x6558 + nicState.layer3.arp->dipaddr = nicState.layer3.arp->sipaddr; + 6560: 8e 85 ldd r24, Y+14 ; 0x0e + 6562: 9f 85 ldd r25, Y+15 ; 0x0f + 6564: a8 89 ldd r26, Y+16 ; 0x10 + 6566: b9 89 ldd r27, Y+17 ; 0x11 + 6568: 88 8f std Y+24, r24 ; 0x18 + 656a: 99 8f std Y+25, r25 ; 0x19 + 656c: aa 8f std Y+26, r26 ; 0x1a + 656e: bb 8f std Y+27, r27 ; 0x1b +// fill in our information + nicState.layer3.arp->shwaddr = nicState.mac; + 6570: 86 e0 ldi r24, 0x06 ; 6 + 6572: e0 e8 ldi r30, 0x80 ; 128 + 6574: fe e0 ldi r31, 0x0E ; 14 + 6576: de 01 movw r26, r28 + 6578: 18 96 adiw r26, 0x08 ; 8 + 657a: 01 90 ld r0, Z+ + 657c: 0d 92 st X+, r0 + 657e: 8a 95 dec r24 + 6580: e1 f7 brne .-8 ; 0x657a + nicState.layer3.arp->sipaddr = IpMyConfig.ip; + 6582: 80 91 4e 0f lds r24, 0x0F4E + 6586: 90 91 4f 0f lds r25, 0x0F4F + 658a: a0 91 50 0f lds r26, 0x0F50 + 658e: b0 91 51 0f lds r27, 0x0F51 + 6592: 8e 87 std Y+14, r24 ; 0x0e + 6594: 9f 87 std Y+15, r25 ; 0x0f + 6596: a8 8b std Y+16, r26 ; 0x10 + 6598: b9 8b std Y+17, r27 ; 0x11 +// change op to reply + nicState.layer3.arp->opcode = htons(ARP_OPCODE_REPLY); + 659a: 82 e0 ldi r24, 0x02 ; 2 + 659c: 90 e0 ldi r25, 0x00 ; 0 + 659e: 0e 94 cb 2a call 0x5596 ; 0x5596 + 65a2: 9f 83 std Y+7, r25 ; 0x07 + 65a4: 8e 83 std Y+6, r24 ; 0x06 + +// in ethernet header + nicState.layer2.ethHeader->dest = nicState.layer2.ethHeader->src; + 65a6: a0 91 86 0e lds r26, 0x0E86 + 65aa: b0 91 87 0e lds r27, 0x0E87 + 65ae: 86 e0 ldi r24, 0x06 ; 6 + 65b0: fd 01 movw r30, r26 + 65b2: 36 96 adiw r30, 0x06 ; 6 + 65b4: 01 90 ld r0, Z+ + 65b6: 0d 92 st X+, r0 + 65b8: 8a 95 dec r24 + 65ba: e1 f7 brne .-8 ; 0x65b4 + nicState.layer2.ethHeader->src = nicState.mac; + 65bc: a0 91 86 0e lds r26, 0x0E86 + 65c0: b0 91 87 0e lds r27, 0x0E87 + 65c4: 86 e0 ldi r24, 0x06 ; 6 + 65c6: e0 e8 ldi r30, 0x80 ; 128 + 65c8: fe e0 ldi r31, 0x0E ; 14 + 65ca: 16 96 adiw r26, 0x06 ; 6 + 65cc: 01 90 ld r0, Z+ + 65ce: 0d 92 st X+, r0 + 65d0: 8a 95 dec r24 + 65d2: e1 f7 brne .-8 ; 0x65cc + +#ifdef ARP_DEBUG + if (arpDebug != NULL) + 65d4: 80 91 8c 0e lds r24, 0x0E8C + 65d8: 90 91 8d 0e lds r25, 0x0E8D + 65dc: 00 97 sbiw r24, 0x00 ; 0 + 65de: f1 f0 breq .+60 ; 0x661c + { + if (arpDebugLevel > 0) + 65e0: 20 91 5d 0f lds r18, 0x0F5D + 65e4: 22 23 and r18, r18 + 65e6: 61 f0 breq .+24 ; 0x6600 + fprintf_P(arpDebug, PSTR("Sending ARP Reply\r\n")); + 65e8: 27 ea ldi r18, 0xA7 ; 167 + 65ea: 30 e1 ldi r19, 0x10 ; 16 + 65ec: 3f 93 push r19 + 65ee: 2f 93 push r18 + 65f0: 9f 93 push r25 + 65f2: 8f 93 push r24 + 65f4: 0e 94 1a 50 call 0xa034 ; 0xa034 + 65f8: 0f 90 pop r0 + 65fa: 0f 90 pop r0 + 65fc: 0f 90 pop r0 + 65fe: 0f 90 pop r0 + if (arpDebugLevel > 2) + 6600: 80 91 5d 0f lds r24, 0x0F5D + 6604: 83 30 cpi r24, 0x03 ; 3 + 6606: 50 f0 brcs .+20 ; 0x661c + arpPrintHeader(arpDebug, nicState.layer3.arp); + 6608: 60 91 88 0e lds r22, 0x0E88 + 660c: 70 91 89 0e lds r23, 0x0E89 + 6610: 80 91 8c 0e lds r24, 0x0E8C + 6614: 90 91 8d 0e lds r25, 0x0E8D + 6618: 0e 94 9e 31 call 0x633c ; 0x633c + } +#endif +// send reply! + nicSend(sizeof(struct netArpHeader) + ETH_HEADER_LEN); + 661c: 8a e2 ldi r24, 0x2A ; 42 + 661e: 90 e0 ldi r25, 0x00 ; 0 + } +} + 6620: df 91 pop r29 + 6622: cf 91 pop r28 + if (arpDebugLevel > 2) + arpPrintHeader(arpDebug, nicState.layer3.arp); + } +#endif +// send reply! + nicSend(sizeof(struct netArpHeader) + ETH_HEADER_LEN); + 6624: 0c 94 0e 28 jmp 0x501c ; 0x501c + } +} + 6628: df 91 pop r29 + 662a: cf 91 pop r28 + 662c: 08 95 ret + +0000662e : + fprintf_P(stream, PSTR("DstProtoAddr: ")); netPrintIPAddr(stream, packet->dipaddr); fprintf_P(stream, PSTR("\r\n")); +} +#endif /*ARP_DEBUG*/ + +void arpPrintTable(FILE *stream) +{ + 662e: af 92 push r10 + 6630: bf 92 push r11 + 6632: cf 92 push r12 + 6634: df 92 push r13 + 6636: ef 92 push r14 + 6638: ff 92 push r15 + 663a: 0f 93 push r16 + 663c: 1f 93 push r17 + 663e: cf 93 push r28 + 6640: df 93 push r29 + 6642: ec 01 movw r28, r24 + uint8_t i; + + // print ARP table + fprintf_P(stream, PSTR("Time Eth Address IP Address\r\n")); + 6644: 8b ee ldi r24, 0xEB ; 235 + 6646: 9f e0 ldi r25, 0x0F ; 15 + 6648: 9f 93 push r25 + 664a: 8f 93 push r24 + 664c: df 93 push r29 + 664e: cf 93 push r28 + 6650: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("-----------------------------------\r\n")); + 6654: 85 ec ldi r24, 0xC5 ; 197 + 6656: 9f e0 ldi r25, 0x0F ; 15 + 6658: 9f 93 push r25 + 665a: 8f 93 push r24 + 665c: df 93 push r29 + 665e: cf 93 push r28 + 6660: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR(" MY ")); + 6664: 8f eb ldi r24, 0xBF ; 191 + 6666: 9f e0 ldi r25, 0x0F ; 15 + 6668: 9f 93 push r25 + 666a: 8f 93 push r24 + 666c: df 93 push r29 + 666e: cf 93 push r28 + 6670: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintEthAddr(stream, &nicState.mac); + 6674: 60 e8 ldi r22, 0x80 ; 128 + 6676: 7e e0 ldi r23, 0x0E ; 14 + 6678: ce 01 movw r24, r28 + 667a: 0e 94 05 2b call 0x560a ; 0x560a + fprintf_P(stream, PSTR(" ")); + 667e: 8c eb ldi r24, 0xBC ; 188 + 6680: 9f e0 ldi r25, 0x0F ; 15 + 6682: 9f 93 push r25 + 6684: 8f 93 push r24 + 6686: df 93 push r29 + 6688: cf 93 push r28 + 668a: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(stream, IpMyConfig.ip); + 668e: 40 91 4e 0f lds r20, 0x0F4E + 6692: 50 91 4f 0f lds r21, 0x0F4F + 6696: 60 91 50 0f lds r22, 0x0F50 + 669a: 70 91 51 0f lds r23, 0x0F51 + 669e: ce 01 movw r24, r28 + 66a0: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n")); + 66a4: 89 eb ldi r24, 0xB9 ; 185 + 66a6: 9f e0 ldi r25, 0x0F ; 15 + 66a8: 9f 93 push r25 + 66aa: 8f 93 push r24 + 66ac: df 93 push r29 + 66ae: cf 93 push r28 + 66b0: 0e 94 1a 50 call 0xa034 ; 0xa034 + 66b4: 08 e6 ldi r16, 0x68 ; 104 + 66b6: 1f e0 ldi r17, 0x0F ; 15 + 66b8: 8d b7 in r24, 0x3d ; 61 + 66ba: 9e b7 in r25, 0x3e ; 62 + 66bc: 44 96 adiw r24, 0x14 ; 20 + 66be: 0f b6 in r0, 0x3f ; 63 + 66c0: f8 94 cli + 66c2: 9e bf out 0x3e, r25 ; 62 + 66c4: 0f be out 0x3f, r0 ; 63 + 66c6: 8d bf out 0x3d, r24 ; 61 + + for(i=0; i + continue; + fprintf_P(stream, PSTR("%3d "), ArpTable[i].time); + 66f2: 82 85 ldd r24, Z+10 ; 0x0a + 66f4: 1f 92 push r1 + 66f6: 8f 93 push r24 + 66f8: ff 92 push r15 + 66fa: ef 92 push r14 + 66fc: df 93 push r29 + 66fe: cf 93 push r28 + 6700: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6704: b8 01 movw r22, r16 + 6706: 6c 5f subi r22, 0xFC ; 252 + 6708: 7f 4f sbci r23, 0xFF ; 255 + netPrintEthAddr(stream, &ArpTable[i].ethaddr); + 670a: ce 01 movw r24, r28 + 670c: 0e 94 05 2b call 0x560a ; 0x560a + fprintf_P(stream, PSTR(" ")); + 6710: df 92 push r13 + 6712: cf 92 push r12 + 6714: df 93 push r29 + 6716: cf 93 push r28 + 6718: 0e 94 1a 50 call 0xa034 ; 0xa034 + netPrintIPAddr(stream, ArpTable[i].ipaddr); + 671c: f8 01 movw r30, r16 + 671e: 40 81 ld r20, Z + 6720: 51 81 ldd r21, Z+1 ; 0x01 + 6722: 62 81 ldd r22, Z+2 ; 0x02 + 6724: 73 81 ldd r23, Z+3 ; 0x03 + 6726: ce 01 movw r24, r28 + 6728: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n")); + 672c: bf 92 push r11 + 672e: af 92 push r10 + 6730: df 93 push r29 + 6732: cf 93 push r28 + 6734: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6738: 8d b7 in r24, 0x3d ; 61 + 673a: 9e b7 in r25, 0x3e ; 62 + 673c: 0e 96 adiw r24, 0x0e ; 14 + 673e: 0f b6 in r0, 0x3f ; 63 + 6740: f8 94 cli + 6742: 9e bf out 0x3e, r25 ; 62 + 6744: 0f be out 0x3f, r0 ; 63 + 6746: 8d bf out 0x3d, r24 ; 61 + 6748: 05 5f subi r16, 0xF5 ; 245 + 674a: 1f 4f sbci r17, 0xFF ; 255 + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR(" ")); + netPrintIPAddr(stream, IpMyConfig.ip); + fprintf_P(stream, PSTR("\r\n")); + + for(i=0; i + netPrintEthAddr(stream, &ArpTable[i].ethaddr); + fprintf_P(stream, PSTR(" ")); + netPrintIPAddr(stream, ArpTable[i].ipaddr); + fprintf_P(stream, PSTR("\r\n")); + } +} + 6754: df 91 pop r29 + 6756: cf 91 pop r28 + 6758: 1f 91 pop r17 + 675a: 0f 91 pop r16 + 675c: ff 90 pop r15 + 675e: ef 90 pop r14 + 6760: df 90 pop r13 + 6762: cf 90 pop r12 + 6764: bf 90 pop r11 + 6766: af 90 pop r10 + 6768: 08 95 ret + +0000676a : + * @param *sck socket + */ +static inline void tcpAcceptConn(struct TcpIpSocket *sck); + +inline void socketInit(void) +{ + 676a: 8f 92 push r8 + 676c: 9f 92 push r9 + 676e: af 92 push r10 + 6770: bf 92 push r11 + 6772: ff 92 push r15 + 6774: 0f 93 push r16 + 6776: 1f 93 push r17 + 6778: cf 93 push r28 + 677a: df 93 push r29 + sockets = xmalloc(NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + 677c: 80 e3 ldi r24, 0x30 ; 48 + 677e: 92 e0 ldi r25, 0x02 ; 2 + 6780: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 6784: 90 93 bd 0e sts 0x0EBD, r25 + 6788: 80 93 bc 0e sts 0x0EBC, r24 + memset(sockets, 0, NUMBER_OF_SOCKETS * sizeof(struct TcpIpSocket)); + 678c: 20 e3 ldi r18, 0x30 ; 48 + 678e: 32 e0 ldi r19, 0x02 ; 2 + 6790: fc 01 movw r30, r24 + 6792: a9 01 movw r20, r18 + 6794: 11 92 st Z+, r1 + 6796: 41 50 subi r20, 0x01 ; 1 + 6798: 50 40 sbci r21, 0x00 ; 0 + 679a: e1 f7 brne .-8 ; 0x6794 + + uint8_t i; + uint8_t *ptr = (uint8_t *)RTOS_TCP_BUF_BASE_ADDR; + + struct TcpIpSocket *sck = sockets; + 679c: 00 91 bc 0e lds r16, 0x0EBC + 67a0: 10 91 bd 0e lds r17, 0x0EBD + 67a4: c8 ea ldi r28, 0xA8 ; 168 + 67a6: d1 e6 ldi r29, 0x61 ; 97 + ptr+=256; +// sck->Tx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; + + sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + sck->seqNoLastSent = HTONL(0xFF112233); + 67a8: 88 24 eor r8, r8 + 67aa: 8a 94 dec r8 + 67ac: 81 e1 ldi r24, 0x11 ; 17 + 67ae: 98 2e mov r9, r24 + 67b0: 82 e2 ldi r24, 0x22 ; 34 + 67b2: a8 2e mov r10, r24 + 67b4: 83 e3 ldi r24, 0x33 ; 51 + 67b6: b8 2e mov r11, r24 + sck->state = LISTEN; + 67b8: ff 24 eor r15, r15 + 67ba: f3 94 inc r15 + 67bc: 8c 2f mov r24, r28 + 67be: 88 5a subi r24, 0xA8 ; 168 +// sck->Rx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; +// sck->Tx = xQueueCreateExternal(255, 1, (void *)(ptr)); + ptr+=256; + + sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + 67c0: 80 31 cpi r24, 0x10 ; 16 + 67c2: 20 f4 brcc .+8 ; 0x67cc + 67c4: ce 01 movw r24, r28 + 67c6: 0e 94 cb 2a call 0x5596 ; 0x5596 + 67ca: 02 c0 rjmp .+4 ; 0x67d0 + 67cc: 88 eb ldi r24, 0xB8 ; 184 + 67ce: 91 e6 ldi r25, 0x61 ; 97 + 67d0: f8 01 movw r30, r16 + 67d2: 96 83 std Z+6, r25 ; 0x06 + 67d4: 85 83 std Z+5, r24 ; 0x05 + sck->seqNoLastSent = HTONL(0xFF112233); + 67d6: 85 86 std Z+13, r8 ; 0x0d + 67d8: 96 86 std Z+14, r9 ; 0x0e + 67da: a7 86 std Z+15, r10 ; 0x0f + 67dc: b0 8a std Z+16, r11 ; 0x10 + sck->state = LISTEN; + 67de: f0 82 st Z, r15 + sck++; + 67e0: 04 5e subi r16, 0xE4 ; 228 + 67e2: 1f 4f sbci r17, 0xFF ; 255 + 67e4: 21 96 adiw r28, 0x01 ; 1 + + uint8_t i; + uint8_t *ptr = (uint8_t *)RTOS_TCP_BUF_BASE_ADDR; + + struct TcpIpSocket *sck = sockets; + for (i=0; i < NUMBER_OF_SOCKETS; i++) + 67e6: cc 3b cpi r28, 0xBC ; 188 + 67e8: f1 e6 ldi r31, 0x61 ; 97 + 67ea: df 07 cpc r29, r31 + 67ec: 39 f7 brne .-50 ; 0x67bc + sck->localPort = (i<16) ? htons(MYTELNETPOERT + i) : (MYTELNETPOERT + 16); + sck->seqNoLastSent = HTONL(0xFF112233); + sck->state = LISTEN; + sck++; + } +} + 67ee: df 91 pop r29 + 67f0: cf 91 pop r28 + 67f2: 1f 91 pop r17 + 67f4: 0f 91 pop r16 + 67f6: ff 90 pop r15 + 67f8: bf 90 pop r11 + 67fa: af 90 pop r10 + 67fc: 9f 90 pop r9 + 67fe: 8f 90 pop r8 + 6800: 08 95 ret + +00006802 : + + return 0; +} + +void calculateTcpChecksun(uint16_t tcpLen) +{ + 6802: cf 93 push r28 + 6804: df 93 push r29 + nicState.layer4.tcp->tcpchksum = 0; + 6806: c0 91 8a 0e lds r28, 0x0E8A + 680a: d0 91 8b 0e lds r29, 0x0E8B + 680e: 19 8a std Y+17, r1 ; 0x11 + 6810: 18 8a std Y+16, r1 ; 0x10 + nicState.layer4.tcp->tcpchksum = netChecksum((uint8_t *)nicState.layer4.tcp, tcpLen); //TODO finish it + 6812: bc 01 movw r22, r24 + 6814: ce 01 movw r24, r28 + 6816: 0e 94 d5 2a call 0x55aa ; 0x55aa + 681a: 99 8b std Y+17, r25 ; 0x11 + 681c: 88 8b std Y+16, r24 ; 0x10 +} + 681e: df 91 pop r29 + 6820: cf 91 pop r28 + 6822: 08 95 ret + +00006824 : + sck->remotePort = nicState.layer4.tcp->srcport; + sck->RemoteIpAddr = nicState.layer3.ip->srcipaddr; +} + +inline uint8_t processTcpPacket(void) +{ + 6824: 6f 92 push r6 + 6826: 7f 92 push r7 + 6828: 8f 92 push r8 + 682a: 9f 92 push r9 + 682c: af 92 push r10 + 682e: bf 92 push r11 + 6830: cf 92 push r12 + 6832: df 92 push r13 + 6834: ef 92 push r14 + 6836: ff 92 push r15 + 6838: 0f 93 push r16 + 683a: 1f 93 push r17 + 683c: cf 93 push r28 + 683e: df 93 push r29 + } +} + +struct TcpIpSocket* findConnectedSocket(void) +{ + struct TcpIpSocket *result = sockets; + 6840: e0 91 bc 0e lds r30, 0x0EBC + 6844: f0 91 bd 0e lds r31, 0x0EBD + uint8_t i; + for (i=0; istate != LISTEN) && (result->state != CLOSED)) + && (result->RemoteIpAddr == nicState.layer3.ip->srcipaddr) && (result->localPort == nicState.layer4.tcp->destport) && (result->remotePort == nicState.layer4.tcp->srcport)) + 6848: 40 91 88 0e lds r20, 0x0E88 + 684c: 50 91 89 0e lds r21, 0x0E89 + 6850: 60 90 8a 0e lds r6, 0x0E8A + 6854: 70 90 8b 0e lds r7, 0x0E8B + 6858: cf 01 movw r24, r30 + 685a: 80 5d subi r24, 0xD0 ; 208 + 685c: 9d 4f sbci r25, 0xFD ; 253 + } +} + +struct TcpIpSocket* findConnectedSocket(void) +{ + struct TcpIpSocket *result = sockets; + 685e: ef 01 movw r28, r30 + uint8_t i; + for (i=0; istate != LISTEN) && (result->state != CLOSED)) + 6860: 28 81 ld r18, Y + 6862: 22 30 cpi r18, 0x02 ; 2 + 6864: f0 f1 brcs .+124 ; 0x68e2 + && (result->RemoteIpAddr == nicState.layer3.ip->srcipaddr) && (result->localPort == nicState.layer4.tcp->destport) && (result->remotePort == nicState.layer4.tcp->srcport)) + 6866: 89 80 ldd r8, Y+1 ; 0x01 + 6868: 9a 80 ldd r9, Y+2 ; 0x02 + 686a: ab 80 ldd r10, Y+3 ; 0x03 + 686c: bc 80 ldd r11, Y+4 ; 0x04 + 686e: da 01 movw r26, r20 + 6870: 1c 96 adiw r26, 0x0c ; 12 + 6872: cd 90 ld r12, X+ + 6874: dd 90 ld r13, X+ + 6876: ed 90 ld r14, X+ + 6878: fc 90 ld r15, X + 687a: 1f 97 sbiw r26, 0x0f ; 15 + 687c: 8c 14 cp r8, r12 + 687e: 9d 04 cpc r9, r13 + 6880: ae 04 cpc r10, r14 + 6882: bf 04 cpc r11, r15 + 6884: 71 f5 brne .+92 ; 0x68e2 + 6886: 0d 81 ldd r16, Y+5 ; 0x05 + 6888: 1e 81 ldd r17, Y+6 ; 0x06 + 688a: d3 01 movw r26, r6 + 688c: 12 96 adiw r26, 0x02 ; 2 + 688e: 6d 91 ld r22, X+ + 6890: 7c 91 ld r23, X + 6892: 13 97 sbiw r26, 0x03 ; 3 + 6894: 06 17 cp r16, r22 + 6896: 17 07 cpc r17, r23 + 6898: 21 f5 brne .+72 ; 0x68e2 + 689a: 0f 81 ldd r16, Y+7 ; 0x07 + 689c: 18 85 ldd r17, Y+8 ; 0x08 + 689e: 6d 91 ld r22, X+ + 68a0: 7c 91 ld r23, X + 68a2: 06 17 cp r16, r22 + 68a4: 17 07 cpc r17, r23 + 68a6: e9 f4 brne .+58 ; 0x68e2 + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 68a8: 80 91 4c 0f lds r24, 0x0F4C + 68ac: 90 91 4d 0f lds r25, 0x0F4D + 68b0: 00 97 sbiw r24, 0x00 ; 0 + 68b2: 09 f4 brne .+2 ; 0x68b6 + 68b4: 7b c0 rjmp .+246 ; 0x69ac + if (tcpDebugLevel > 2) + 68b6: 30 91 a5 0e lds r19, 0x0EA5 + 68ba: 33 30 cpi r19, 0x03 ; 3 + 68bc: 08 f4 brcc .+2 ; 0x68c0 + 68be: 76 c0 rjmp .+236 ; 0x69ac + fprintf_P(tcpDebugStream, PSTR("Found TCP socket state %d\r\n"), result->state); + 68c0: 1f 92 push r1 + 68c2: 2f 93 push r18 + 68c4: 29 e3 ldi r18, 0x39 ; 57 + 68c6: 31 e1 ldi r19, 0x11 ; 17 + 68c8: 3f 93 push r19 + 68ca: 2f 93 push r18 + 68cc: 9f 93 push r25 + 68ce: 8f 93 push r24 + 68d0: 0e 94 1a 50 call 0xa034 ; 0xa034 + 68d4: 0f 90 pop r0 + 68d6: 0f 90 pop r0 + 68d8: 0f 90 pop r0 + 68da: 0f 90 pop r0 + 68dc: 0f 90 pop r0 + 68de: 0f 90 pop r0 + 68e0: 65 c0 rjmp .+202 ; 0x69ac +#endif + return result; + } + result++; + 68e2: 6c 96 adiw r28, 0x1c ; 28 + +struct TcpIpSocket* findConnectedSocket(void) +{ + struct TcpIpSocket *result = sockets; + uint8_t i; + for (i=0; i + 68ea: ba cf rjmp .-140 ; 0x6860 + 68ec: d0 e0 ldi r29, 0x00 ; 0 + } + + result = sockets; + for (i=0; istate == LISTEN) && (result->localPort == nicState.layer4.tcp->destport)) + 68ee: 80 81 ld r24, Z + 68f0: 81 30 cpi r24, 0x01 ; 1 + 68f2: 81 f5 brne .+96 ; 0x6954 + 68f4: 25 81 ldd r18, Z+5 ; 0x05 + 68f6: 36 81 ldd r19, Z+6 ; 0x06 + 68f8: d3 01 movw r26, r6 + 68fa: 12 96 adiw r26, 0x02 ; 2 + 68fc: 8d 91 ld r24, X+ + 68fe: 9c 91 ld r25, X + 6900: 13 97 sbiw r26, 0x03 ; 3 + 6902: 28 17 cp r18, r24 + 6904: 39 07 cpc r19, r25 + 6906: 31 f5 brne .+76 ; 0x6954 + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 6908: 80 91 4c 0f lds r24, 0x0F4C + 690c: 90 91 4d 0f lds r25, 0x0F4D + 6910: 00 97 sbiw r24, 0x00 ; 0 + 6912: a1 f0 breq .+40 ; 0x693c + if (tcpDebugLevel > 2) + 6914: 20 91 a5 0e lds r18, 0x0EA5 + 6918: 23 30 cpi r18, 0x03 ; 3 + 691a: 80 f0 brcs .+32 ; 0x693c + fprintf_P(tcpDebugStream, PSTR("Found TCP socket no %d state LISTEN\r\n"), i); + 691c: 1f 92 push r1 + 691e: df 93 push r29 + 6920: 23 e1 ldi r18, 0x13 ; 19 + 6922: 31 e1 ldi r19, 0x11 ; 17 + 6924: 3f 93 push r19 + 6926: 2f 93 push r18 + 6928: 9f 93 push r25 + 692a: 8f 93 push r24 + 692c: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6930: 0f 90 pop r0 + 6932: 0f 90 pop r0 + 6934: 0f 90 pop r0 + 6936: 0f 90 pop r0 + 6938: 0f 90 pop r0 + 693a: 0f 90 pop r0 +#endif + return &sockets[i]; + 693c: 80 91 bc 0e lds r24, 0x0EBC + 6940: 90 91 bd 0e lds r25, 0x0EBD + 6944: fc 01 movw r30, r24 + 6946: 2c e1 ldi r18, 0x1C ; 28 + 6948: d2 9f mul r29, r18 + 694a: e0 0d add r30, r0 + 694c: f1 1d adc r31, r1 + 694e: 11 24 eor r1, r1 + 6950: ef 01 movw r28, r30 + 6952: 2c c0 rjmp .+88 ; 0x69ac + } + result++; + 6954: 7c 96 adiw r30, 0x1c ; 28 + } + result++; + } + + result = sockets; + for (i=0; i + return &sockets[i]; + } + result++; + } +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 695c: 80 91 4c 0f lds r24, 0x0F4C + 6960: 90 91 4d 0f lds r25, 0x0F4D + 6964: 89 2b or r24, r25 + 6966: 09 f4 brne .+2 ; 0x696a + 6968: 55 c1 rjmp .+682 ; 0x6c14 + if (tcpDebugLevel > 2) + 696a: 80 91 a5 0e lds r24, 0x0EA5 + 696e: 83 30 cpi r24, 0x03 ; 3 + 6970: 08 f4 brcc .+2 ; 0x6974 + 6972: 50 c1 rjmp .+672 ; 0x6c14 + fprintf_P(tcpDebugStream, PSTR("Can't find TCP socket with localPort %d\r\n"), htons(nicState.layer4.tcp->destport)); + 6974: d3 01 movw r26, r6 + 6976: 12 96 adiw r26, 0x02 ; 2 + 6978: 8d 91 ld r24, X+ + 697a: 9c 91 ld r25, X + 697c: 13 97 sbiw r26, 0x03 ; 3 + 697e: 0e 94 cb 2a call 0x5596 ; 0x5596 + 6982: 9f 93 push r25 + 6984: 8f 93 push r24 + 6986: 89 ee ldi r24, 0xE9 ; 233 + 6988: 90 e1 ldi r25, 0x10 ; 16 + 698a: 9f 93 push r25 + 698c: 8f 93 push r24 + 698e: 80 91 4d 0f lds r24, 0x0F4D + 6992: 8f 93 push r24 + 6994: 80 91 4c 0f lds r24, 0x0F4C + 6998: 8f 93 push r24 + 699a: 0e 94 1a 50 call 0xa034 ; 0xa034 + 699e: 0f 90 pop r0 + 69a0: 0f 90 pop r0 + 69a2: 0f 90 pop r0 + 69a4: 0f 90 pop r0 + 69a6: 0f 90 pop r0 + 69a8: 0f 90 pop r0 + 69aa: 34 c1 rjmp .+616 ; 0x6c14 + +inline uint8_t processTcpPacket(void) +{ + struct TcpIpSocket *socket = findConnectedSocket(); + + if (socket == NULL) + 69ac: 20 97 sbiw r28, 0x00 ; 0 + 69ae: 09 f4 brne .+2 ; 0x69b2 + 69b0: 31 c1 rjmp .+610 ; 0x6c14 + return 1; + + + socket->seqNoLastReceived = htonl(nicState.layer4.tcp->seqno); + 69b2: e0 91 8a 0e lds r30, 0x0E8A + 69b6: f0 91 8b 0e lds r31, 0x0E8B + 69ba: 64 81 ldd r22, Z+4 ; 0x04 + 69bc: 75 81 ldd r23, Z+5 ; 0x05 + 69be: 86 81 ldd r24, Z+6 ; 0x06 + 69c0: 97 81 ldd r25, Z+7 ; 0x07 + 69c2: 0e 94 cf 2a call 0x559e ; 0x559e + 69c6: 69 87 std Y+9, r22 ; 0x09 + 69c8: 7a 87 std Y+10, r23 ; 0x0a + 69ca: 8b 87 std Y+11, r24 ; 0x0b + 69cc: 9c 87 std Y+12, r25 ; 0x0c + + if (socket->state == LISTEN) + 69ce: 88 81 ld r24, Y + 69d0: 81 30 cpi r24, 0x01 ; 1 + 69d2: 09 f0 breq .+2 ; 0x69d6 + 69d4: a0 c0 rjmp .+320 ; 0x6b16 + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_SYN) + 69d6: e0 91 8a 0e lds r30, 0x0E8A + 69da: f0 91 8b 0e lds r31, 0x0E8B + 69de: 25 85 ldd r18, Z+13 ; 0x0d + 69e0: 80 91 4c 0f lds r24, 0x0F4C + 69e4: 90 91 4d 0f lds r25, 0x0F4D + 69e8: 12 2f mov r17, r18 + 69ea: 12 70 andi r17, 0x02 ; 2 + 69ec: 21 ff sbrs r18, 1 + 69ee: 88 c0 rjmp .+272 ; 0x6b00 + { +// uint16_t len = nicState.layer4.tcp->tcpoffset>>4; +// len *=4; +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 69f0: 00 97 sbiw r24, 0x00 ; 0 + 69f2: 81 f0 breq .+32 ; 0x6a14 + if (tcpDebugLevel > 2) + 69f4: 20 91 a5 0e lds r18, 0x0EA5 + 69f8: 23 30 cpi r18, 0x03 ; 3 + 69fa: 60 f0 brcs .+24 ; 0x6a14 + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RECEIVED\r\n")); + 69fc: 25 e0 ldi r18, 0x05 ; 5 + 69fe: 32 e1 ldi r19, 0x12 ; 18 + 6a00: 3f 93 push r19 + 6a02: 2f 93 push r18 + 6a04: 9f 93 push r25 + 6a06: 8f 93 push r24 + 6a08: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6a0c: 0f 90 pop r0 + 6a0e: 0f 90 pop r0 + 6a10: 0f 90 pop r0 + 6a12: 0f 90 pop r0 + return NULL; +} + +static inline void tcpAcceptConn(struct TcpIpSocket *sck) +{ + sck->state = SYN_RECEIVED; + 6a14: 82 e0 ldi r24, 0x02 ; 2 + 6a16: 88 83 st Y, r24 + sck->remotePort = nicState.layer4.tcp->srcport; + 6a18: 00 91 8a 0e lds r16, 0x0E8A + 6a1c: 10 91 8b 0e lds r17, 0x0E8B + 6a20: f8 01 movw r30, r16 + 6a22: 80 81 ld r24, Z + 6a24: 91 81 ldd r25, Z+1 ; 0x01 + 6a26: 98 87 std Y+8, r25 ; 0x08 + 6a28: 8f 83 std Y+7, r24 ; 0x07 + sck->RemoteIpAddr = nicState.layer3.ip->srcipaddr; + 6a2a: e0 91 88 0e lds r30, 0x0E88 + 6a2e: f0 91 89 0e lds r31, 0x0E89 + 6a32: 44 85 ldd r20, Z+12 ; 0x0c + 6a34: 55 85 ldd r21, Z+13 ; 0x0d + 6a36: 66 85 ldd r22, Z+14 ; 0x0e + 6a38: 77 85 ldd r23, Z+15 ; 0x0f + 6a3a: 49 83 std Y+1, r20 ; 0x01 + 6a3c: 5a 83 std Y+2, r21 ; 0x02 + 6a3e: 6b 83 std Y+3, r22 ; 0x03 + 6a40: 7c 83 std Y+4, r23 ; 0x04 + if (tcpDebugLevel > 2) + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change LISTEN->SYN_RECEIVED\r\n")); +#endif + tcpAcceptConn(socket); + //Preparing response + nicState.layer4.tcp->srcport = socket->localPort; + 6a42: 2d 81 ldd r18, Y+5 ; 0x05 + 6a44: 3e 81 ldd r19, Y+6 ; 0x06 + 6a46: d8 01 movw r26, r16 + 6a48: 11 96 adiw r26, 0x01 ; 1 + 6a4a: 3c 93 st X, r19 + 6a4c: 2e 93 st -X, r18 + nicState.layer4.tcp->destport = socket->remotePort; + 6a4e: 13 96 adiw r26, 0x03 ; 3 + 6a50: 9c 93 st X, r25 + 6a52: 8e 93 st -X, r24 + 6a54: 12 97 sbiw r26, 0x02 ; 2 + nicState.layer4.tcp->seqno = htonl(socket->seqNoLastSent); + 6a56: 6d 85 ldd r22, Y+13 ; 0x0d + 6a58: 7e 85 ldd r23, Y+14 ; 0x0e + 6a5a: 8f 85 ldd r24, Y+15 ; 0x0f + 6a5c: 98 89 ldd r25, Y+16 ; 0x10 + 6a5e: 0e 94 cf 2a call 0x559e ; 0x559e + 6a62: f8 01 movw r30, r16 + 6a64: 64 83 std Z+4, r22 ; 0x04 + 6a66: 75 83 std Z+5, r23 ; 0x05 + 6a68: 86 83 std Z+6, r24 ; 0x06 + 6a6a: 97 83 std Z+7, r25 ; 0x07 + nicState.layer4.tcp->ackno = htonl(socket->seqNoLastReceived+1); + 6a6c: 00 91 8a 0e lds r16, 0x0E8A + 6a70: 10 91 8b 0e lds r17, 0x0E8B + 6a74: 89 85 ldd r24, Y+9 ; 0x09 + 6a76: 9a 85 ldd r25, Y+10 ; 0x0a + 6a78: ab 85 ldd r26, Y+11 ; 0x0b + 6a7a: bc 85 ldd r27, Y+12 ; 0x0c + 6a7c: bc 01 movw r22, r24 + 6a7e: cd 01 movw r24, r26 + 6a80: 6f 5f subi r22, 0xFF ; 255 + 6a82: 7f 4f sbci r23, 0xFF ; 255 + 6a84: 8f 4f sbci r24, 0xFF ; 255 + 6a86: 9f 4f sbci r25, 0xFF ; 255 + 6a88: 0e 94 cf 2a call 0x559e ; 0x559e + 6a8c: d8 01 movw r26, r16 + 6a8e: 18 96 adiw r26, 0x08 ; 8 + 6a90: 6d 93 st X+, r22 + 6a92: 7d 93 st X+, r23 + 6a94: 8d 93 st X+, r24 + 6a96: 9c 93 st X, r25 + 6a98: 1b 97 sbiw r26, 0x0b ; 11 + nicState.layer4.tcp->tcpoffset = 5<<4; + 6a9a: 00 91 8a 0e lds r16, 0x0E8A + 6a9e: 10 91 8b 0e lds r17, 0x0E8B + 6aa2: 80 e5 ldi r24, 0x50 ; 80 + 6aa4: f8 01 movw r30, r16 + 6aa6: 84 87 std Z+12, r24 ; 0x0c + nicState.layer4.tcp->flags = TCP_FLAGS_ACK+TCP_FLAGS_SYN; + 6aa8: 82 e1 ldi r24, 0x12 ; 18 + 6aaa: 85 87 std Z+13, r24 ; 0x0d + nicState.layer4.tcp->wnd = htons(100); + 6aac: 84 e6 ldi r24, 0x64 ; 100 + 6aae: 90 e0 ldi r25, 0x00 ; 0 + 6ab0: 0e 94 cb 2a call 0x5596 ; 0x5596 + 6ab4: d8 01 movw r26, r16 + 6ab6: 1f 96 adiw r26, 0x0f ; 15 + 6ab8: 9c 93 st X, r25 + 6aba: 8e 93 st -X, r24 + 6abc: 1e 97 sbiw r26, 0x0e ; 14 + nicState.layer4.tcp->tcpchksum = 0; + 6abe: e0 91 8a 0e lds r30, 0x0E8A + 6ac2: f0 91 8b 0e lds r31, 0x0E8B + 6ac6: 11 8a std Z+17, r1 ; 0x11 + 6ac8: 10 8a std Z+16, r1 ; 0x10 + nicState.layer4.tcp->urgp = 0; + 6aca: 13 8a std Z+19, r1 ; 0x13 + 6acc: 12 8a std Z+18, r1 ; 0x12 + calculateTcpChecksun(TCP_HEADER_LEN); + 6ace: 84 e1 ldi r24, 0x14 ; 20 + 6ad0: 90 e0 ldi r25, 0x00 ; 0 + 6ad2: 0e 94 01 34 call 0x6802 ; 0x6802 + + socket->seqNoLastSent++; + 6ad6: 8d 85 ldd r24, Y+13 ; 0x0d + 6ad8: 9e 85 ldd r25, Y+14 ; 0x0e + 6ada: af 85 ldd r26, Y+15 ; 0x0f + 6adc: b8 89 ldd r27, Y+16 ; 0x10 + 6ade: 01 96 adiw r24, 0x01 ; 1 + 6ae0: a1 1d adc r26, r1 + 6ae2: b1 1d adc r27, r1 + 6ae4: 8d 87 std Y+13, r24 ; 0x0d + 6ae6: 9e 87 std Y+14, r25 ; 0x0e + 6ae8: af 87 std Y+15, r26 ; 0x0f + 6aea: b8 8b std Y+16, r27 ; 0x10 + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 6aec: 69 81 ldd r22, Y+1 ; 0x01 + 6aee: 7a 81 ldd r23, Y+2 ; 0x02 + 6af0: 8b 81 ldd r24, Y+3 ; 0x03 + 6af2: 9c 81 ldd r25, Y+4 ; 0x04 + 6af4: 24 e1 ldi r18, 0x14 ; 20 + 6af6: 30 e0 ldi r19, 0x00 ; 0 + 6af8: 46 e0 ldi r20, 0x06 ; 6 + 6afa: 0e 94 1f 2e call 0x5c3e ; 0x5c3e + 6afe: 88 c0 rjmp .+272 ; 0x6c10 + } +#if TCP_DEBUG + else + { + if (tcpDebugStream != NULL) + 6b00: 00 97 sbiw r24, 0x00 ; 0 + 6b02: 09 f4 brne .+2 ; 0x6b06 + 6b04: 85 c0 rjmp .+266 ; 0x6c10 + if (tcpDebugLevel > 1) + 6b06: 20 91 a5 0e lds r18, 0x0EA5 + 6b0a: 22 30 cpi r18, 0x02 ; 2 + 6b0c: 08 f4 brcc .+2 ; 0x6b10 + 6b0e: 80 c0 rjmp .+256 ; 0x6c10 + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: syn flag wasn't set\r\n")); + 6b10: 21 ed ldi r18, 0xD1 ; 209 + 6b12: 31 e1 ldi r19, 0x11 ; 17 + 6b14: 32 c0 rjmp .+100 ; 0x6b7a + } +#endif + return 0; + } + + if (socket->state == SYN_RECEIVED) + 6b16: 82 30 cpi r24, 0x02 ; 2 + 6b18: d9 f5 brne .+118 ; 0x6b90 + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_ACK) + 6b1a: e0 91 8a 0e lds r30, 0x0E8A + 6b1e: f0 91 8b 0e lds r31, 0x0E8B + 6b22: 25 85 ldd r18, Z+13 ; 0x0d + 6b24: 80 91 4c 0f lds r24, 0x0F4C + 6b28: 90 91 4d 0f lds r25, 0x0F4D + 6b2c: 12 2f mov r17, r18 + 6b2e: 10 71 andi r17, 0x10 ; 16 + 6b30: 24 ff sbrs r18, 4 + 6b32: 17 c0 rjmp .+46 ; 0x6b62 + { + socket->state = ESTABILISHED; + 6b34: 23 e0 ldi r18, 0x03 ; 3 + 6b36: 28 83 st Y, r18 +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 6b38: 00 97 sbiw r24, 0x00 ; 0 + 6b3a: 09 f4 brne .+2 ; 0x6b3e + 6b3c: 69 c0 rjmp .+210 ; 0x6c10 + if (tcpDebugLevel > 2) + 6b3e: 20 91 a5 0e lds r18, 0x0EA5 + 6b42: 23 30 cpi r18, 0x03 ; 3 + 6b44: 08 f4 brcc .+2 ; 0x6b48 + 6b46: 64 c0 rjmp .+200 ; 0x6c10 + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection socket state change SYN_RECEIVED->ESTABILISHED\r\n")); + 6b48: 29 e8 ldi r18, 0x89 ; 137 + 6b4a: 31 e1 ldi r19, 0x11 ; 17 + 6b4c: 3f 93 push r19 + 6b4e: 2f 93 push r18 + 6b50: 9f 93 push r25 + 6b52: 8f 93 push r24 + 6b54: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6b58: 0f 90 pop r0 + 6b5a: 0f 90 pop r0 + 6b5c: 0f 90 pop r0 + 6b5e: 0f 90 pop r0 + 6b60: 57 c0 rjmp .+174 ; 0x6c10 +#endif + + } + else + { + socket->state = LISTEN; + 6b62: 21 e0 ldi r18, 0x01 ; 1 + 6b64: 28 83 st Y, r18 +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 6b66: 00 97 sbiw r24, 0x00 ; 0 + 6b68: 09 f4 brne .+2 ; 0x6b6c + 6b6a: 52 c0 rjmp .+164 ; 0x6c10 + if (tcpDebugLevel > 1) + 6b6c: 20 91 a5 0e lds r18, 0x0EA5 + 6b70: 22 30 cpi r18, 0x02 ; 2 + 6b72: 08 f4 brcc .+2 ; 0x6b76 + 6b74: 4d c0 rjmp .+154 ; 0x6c10 + fprintf_P(tcpDebugStream, PSTR("Opening TCP connection ERROR: ack flag wasn't set\r\n")); + 6b76: 25 e5 ldi r18, 0x55 ; 85 + 6b78: 31 e1 ldi r19, 0x11 ; 17 + 6b7a: 3f 93 push r19 + 6b7c: 2f 93 push r18 + 6b7e: 9f 93 push r25 + 6b80: 8f 93 push r24 + 6b82: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6b86: 0f 90 pop r0 + 6b88: 0f 90 pop r0 + 6b8a: 0f 90 pop r0 + 6b8c: 0f 90 pop r0 + 6b8e: 43 c0 rjmp .+134 ; 0x6c16 + } + return 0; + } + + + if (socket->state == ESTABILISHED) + 6b90: 83 30 cpi r24, 0x03 ; 3 + 6b92: f1 f5 brne .+124 ; 0x6c10 + { + if (nicState.layer4.tcp->flags & TCP_FLAGS_FIN) //ESTABILISHED -> CLOSE_WAIT -> closed + 6b94: e0 91 8a 0e lds r30, 0x0E8A + 6b98: f0 91 8b 0e lds r31, 0x0E8B + 6b9c: 85 85 ldd r24, Z+13 ; 0x0d + 6b9e: 80 ff sbrs r24, 0 + 6ba0: 37 c0 rjmp .+110 ; 0x6c10 + { + socket->timer = timer100Hz; + 6ba2: 80 91 88 01 lds r24, 0x0188 + 6ba6: 8d 8b std Y+21, r24 ; 0x15 + nicState.layer4.tcp->flags = TCP_FLAGS_ACK; + 6ba8: 80 e1 ldi r24, 0x10 ; 16 + 6baa: 85 87 std Z+13, r24 ; 0x0d + + uint8_t dataFromBufLen = 0; + uint8_t *dataPtr = (uint8_t *)(nicState.layer4.tcp+1); + 6bac: 8f 01 movw r16, r30 + 6bae: 0c 5e subi r16, 0xEC ; 236 + 6bb0: 1f 4f sbci r17, 0xFF ; 255 + 6bb2: 68 01 movw r12, r16 + 6bb4: fc 2c mov r15, r12 + 6bb6: f0 1a sub r15, r16 + while (xQueueReceive(socket->Tx, dataPtr, 0) == pdTRUE) + 6bb8: 20 e0 ldi r18, 0x00 ; 0 + 6bba: 40 e0 ldi r20, 0x00 ; 0 + 6bbc: 50 e0 ldi r21, 0x00 ; 0 + 6bbe: b6 01 movw r22, r12 + 6bc0: 88 8d ldd r24, Y+24 ; 0x18 + 6bc2: 99 8d ldd r25, Y+25 ; 0x19 + 6bc4: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 6bc8: 81 30 cpi r24, 0x01 ; 1 + 6bca: 21 f4 brne .+8 ; 0x6bd4 + { + dataFromBufLen++; + dataPtr++; + 6bcc: bf ef ldi r27, 0xFF ; 255 + 6bce: cb 1a sub r12, r27 + 6bd0: db 0a sbc r13, r27 + 6bd2: f0 cf rjmp .-32 ; 0x6bb4 + } + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN + dataFromBufLen); + 6bd4: 2f 2d mov r18, r15 + 6bd6: 30 e0 ldi r19, 0x00 ; 0 + 6bd8: 2c 5e subi r18, 0xEC ; 236 + 6bda: 3f 4f sbci r19, 0xFF ; 255 + 6bdc: 69 81 ldd r22, Y+1 ; 0x01 + 6bde: 7a 81 ldd r23, Y+2 ; 0x02 + 6be0: 8b 81 ldd r24, Y+3 ; 0x03 + 6be2: 9c 81 ldd r25, Y+4 ; 0x04 + 6be4: 46 e0 ldi r20, 0x06 ; 6 + 6be6: 0e 94 1f 2e call 0x5c3e ; 0x5c3e + socket->state = CLOSE_WAIT; + 6bea: 84 e0 ldi r24, 0x04 ; 4 + 6bec: 88 83 st Y, r24 + + + nicState.layer4.tcp->flags = TCP_FLAGS_FIN; + 6bee: e0 91 8a 0e lds r30, 0x0E8A + 6bf2: f0 91 8b 0e lds r31, 0x0E8B + 6bf6: 81 e0 ldi r24, 0x01 ; 1 + 6bf8: 85 87 std Z+13, r24 ; 0x0d + ipSend(socket->RemoteIpAddr, IP_PROTO_TCP, TCP_HEADER_LEN); + 6bfa: 69 81 ldd r22, Y+1 ; 0x01 + 6bfc: 7a 81 ldd r23, Y+2 ; 0x02 + 6bfe: 8b 81 ldd r24, Y+3 ; 0x03 + 6c00: 9c 81 ldd r25, Y+4 ; 0x04 + 6c02: 24 e1 ldi r18, 0x14 ; 20 + 6c04: 30 e0 ldi r19, 0x00 ; 0 + 6c06: 46 e0 ldi r20, 0x06 ; 6 + 6c08: 0e 94 1f 2e call 0x5c3e ; 0x5c3e + socket->state = LAST_ACK; + 6c0c: 85 e0 ldi r24, 0x05 ; 5 + 6c0e: 88 83 st Y, r24 + } + return 0; + 6c10: 10 e0 ldi r17, 0x00 ; 0 + 6c12: 01 c0 rjmp .+2 ; 0x6c16 +inline uint8_t processTcpPacket(void) +{ + struct TcpIpSocket *socket = findConnectedSocket(); + + if (socket == NULL) + return 1; + 6c14: 11 e0 ldi r17, 0x01 ; 1 + } + + //Read data and put into the queue + + return 0; +} + 6c16: 81 2f mov r24, r17 + 6c18: df 91 pop r29 + 6c1a: cf 91 pop r28 + 6c1c: 1f 91 pop r17 + 6c1e: 0f 91 pop r16 + 6c20: ff 90 pop r15 + 6c22: ef 90 pop r14 + 6c24: df 90 pop r13 + 6c26: cf 90 pop r12 + 6c28: bf 90 pop r11 + 6c2a: af 90 pop r10 + 6c2c: 9f 90 pop r9 + 6c2e: 8f 90 pop r8 + 6c30: 7f 90 pop r7 + 6c32: 6f 90 pop r6 + 6c34: 08 95 ret + +00006c36 : +uint8_t sendTcpBuffer(uint8_t socketNo) +{ + (void) socketNo; + //struct TcpIpSocket *sck = &sockets[socketNo]; + return 0; +} + 6c36: 80 e0 ldi r24, 0x00 ; 0 + 6c38: 08 95 ret + +00006c3a : + +void netstackTCPIPProcess(void) +{ + 6c3a: cf 93 push r28 + 6c3c: df 93 push r29 + if (nicState.layer4.tcp->destport == htons(80)) + 6c3e: e0 91 8a 0e lds r30, 0x0E8A + 6c42: f0 91 8b 0e lds r31, 0x0E8B + 6c46: c2 81 ldd r28, Z+2 ; 0x02 + 6c48: d3 81 ldd r29, Z+3 ; 0x03 + 6c4a: 80 e5 ldi r24, 0x50 ; 80 + 6c4c: 90 e0 ldi r25, 0x00 ; 0 + 6c4e: 0e 94 cb 2a call 0x5596 ; 0x5596 + 6c52: c8 17 cp r28, r24 + 6c54: d9 07 cpc r29, r25 + 6c56: 99 f4 brne .+38 ; 0x6c7e + { +#if TCP_DEBUG + if (tcpDebugStream != NULL) + 6c58: 80 91 4c 0f lds r24, 0x0F4C + 6c5c: 90 91 4d 0f lds r25, 0x0F4D + 6c60: 00 97 sbiw r24, 0x00 ; 0 + 6c62: 89 f0 breq .+34 ; 0x6c86 + fprintf_P(tcpDebugStream, PSTR("HTTP not implemented\r\n")); + 6c64: 22 ed ldi r18, 0xD2 ; 210 + 6c66: 30 e1 ldi r19, 0x10 ; 16 + 6c68: 3f 93 push r19 + 6c6a: 2f 93 push r18 + 6c6c: 9f 93 push r25 + 6c6e: 8f 93 push r24 + 6c70: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6c74: 0f 90 pop r0 + 6c76: 0f 90 pop r0 + 6c78: 0f 90 pop r0 + 6c7a: 0f 90 pop r0 + 6c7c: 04 c0 rjmp .+8 ; 0x6c86 + } + else + { + processTcpPacket(); + } +} + 6c7e: df 91 pop r29 + 6c80: cf 91 pop r28 +#endif + ; + } + else + { + processTcpPacket(); + 6c82: 0c 94 12 34 jmp 0x6824 ; 0x6824 + } +} + 6c86: df 91 pop r29 + 6c88: cf 91 pop r28 + 6c8a: 08 95 ret + +00006c8c : + +#if TCP_DEBUG +void setTcpDebug(FILE *stream, uint8_t level) +{ + tcpDebugStream = stream; + 6c8c: 90 93 4d 0f sts 0x0F4D, r25 + 6c90: 80 93 4c 0f sts 0x0F4C, r24 + tcpDebugLevel = level; + 6c94: 60 93 a5 0e sts 0x0EA5, r22 + 6c98: 08 95 ret + +00006c9a : +} +#endif /* TCP_DEBUG */ + +void flushTcpQueues() +{ + 6c9a: 08 95 ret + +00006c9c : + } +} + + +inline void httpProcess() +{ + 6c9c: 08 95 ret + +00006c9e : +#include "udp.h" + +void udpLoadConfig() +{ + 6c9e: cf 93 push r28 + 6ca0: df 93 push r29 + udpSocket->dstIp = eeprom_read_dword(&udpIpDst_eep); + 6ca2: c0 91 a2 0e lds r28, 0x0EA2 + 6ca6: d0 91 a3 0e lds r29, 0x0EA3 + 6caa: 84 e0 ldi r24, 0x04 ; 4 + 6cac: 90 e0 ldi r25, 0x00 ; 0 + 6cae: 0e 94 4d 53 call 0xa69a ; 0xa69a + 6cb2: 6e 83 std Y+6, r22 ; 0x06 + 6cb4: 7f 83 std Y+7, r23 ; 0x07 + 6cb6: 88 87 std Y+8, r24 ; 0x08 + 6cb8: 99 87 std Y+9, r25 ; 0x09 + udpSocket->dstPortDef = eeprom_read_word(&udpPortDstEep); + 6cba: 82 e0 ldi r24, 0x02 ; 2 + 6cbc: 90 e0 ldi r25, 0x00 ; 0 + 6cbe: 0e 94 53 53 call 0xa6a6 ; 0xa6a6 + 6cc2: 99 83 std Y+1, r25 ; 0x01 + 6cc4: 88 83 st Y, r24 + udpSocket->srcPort = eeprom_read_word(&udpPortSrcEep); + 6cc6: 80 e0 ldi r24, 0x00 ; 0 + 6cc8: 90 e0 ldi r25, 0x00 ; 0 + 6cca: 0e 94 53 53 call 0xa6a6 ; 0xa6a6 + 6cce: 9d 83 std Y+5, r25 ; 0x05 + 6cd0: 8c 83 std Y+4, r24 ; 0x04 +} + 6cd2: df 91 pop r29 + 6cd4: cf 91 pop r28 + 6cd6: 08 95 ret + +00006cd8 : + +void udpInit_0(void) +{ + 6cd8: cf 93 push r28 + 6cda: df 93 push r29 +#if UDP_DEBUG + udpDbgStream = NULL; + 6cdc: 10 92 c1 0e sts 0x0EC1, r1 + 6ce0: 10 92 c0 0e sts 0x0EC0, r1 + udpDbgLevel = 0; + 6ce4: 10 92 7d 0e sts 0x0E7D, r1 +#endif + udpSocket = xmalloc(sizeof(UdpSocket_t)); + 6ce8: 8e e0 ldi r24, 0x0E ; 14 + 6cea: 90 e0 ldi r25, 0x00 ; 0 + 6cec: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 6cf0: ec 01 movw r28, r24 + 6cf2: 90 93 a3 0e sts 0x0EA3, r25 + 6cf6: 80 93 a2 0e sts 0x0EA2, r24 + + udpSocket->Rx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_RX_BUF_ADDR)); + 6cfa: 40 e0 ldi r20, 0x00 ; 0 + 6cfc: 59 e7 ldi r21, 0x79 ; 121 + 6cfe: 61 e0 ldi r22, 0x01 ; 1 + 6d00: 8f ef ldi r24, 0xFF ; 255 + 6d02: 0e 94 60 46 call 0x8cc0 ; 0x8cc0 + 6d06: 9b 87 std Y+11, r25 ; 0x0b + 6d08: 8a 87 std Y+10, r24 ; 0x0a + udpSocket->Tx = xQueueCreateExternal(255, 1, (void *)(RTOS_UDP_TX_BUF_ADDR)); + 6d0a: c0 91 a2 0e lds r28, 0x0EA2 + 6d0e: d0 91 a3 0e lds r29, 0x0EA3 + 6d12: 40 e0 ldi r20, 0x00 ; 0 + 6d14: 58 e7 ldi r21, 0x78 ; 120 + 6d16: 61 e0 ldi r22, 0x01 ; 1 + 6d18: 8f ef ldi r24, 0xFF ; 255 + 6d1a: 0e 94 60 46 call 0x8cc0 ; 0x8cc0 + 6d1e: 9d 87 std Y+13, r25 ; 0x0d + 6d20: 8c 87 std Y+12, r24 ; 0x0c +} + 6d22: df 91 pop r29 + 6d24: cf 91 pop r28 + 6d26: 08 95 ret + +00006d28 : + +#if UDP_DEBUG +void setUdpDebug(FILE *stream, uint8_t level) +{ + udpDbgStream = stream; + 6d28: 90 93 c1 0e sts 0x0EC1, r25 + 6d2c: 80 93 c0 0e sts 0x0EC0, r24 + udpDbgLevel = level; + 6d30: 60 93 7d 0e sts 0x0E7D, r22 + 6d34: 08 95 ret + +00006d36 : +} +#endif + +inline void udpSend(uint16_t len) +{ + 6d36: ef 92 push r14 + 6d38: ff 92 push r15 + 6d3a: 0f 93 push r16 + 6d3c: 1f 93 push r17 + 6d3e: cf 93 push r28 + 6d40: df 93 push r29 + 6d42: ec 01 movw r28, r24 +// make pointer to UDP header + nicState.layer4.udp->srcport = udpSocket->srcPort; + 6d44: a0 91 8a 0e lds r26, 0x0E8A + 6d48: b0 91 8b 0e lds r27, 0x0E8B + 6d4c: e0 91 a2 0e lds r30, 0x0EA2 + 6d50: f0 91 a3 0e lds r31, 0x0EA3 + 6d54: 84 81 ldd r24, Z+4 ; 0x04 + 6d56: 95 81 ldd r25, Z+5 ; 0x05 + 6d58: 8d 93 st X+, r24 + 6d5a: 9c 93 st X, r25 + nicState.layer4.udp->destport = (udpSocket->dstPortDef == 0)? udpSocket->dstPort : udpSocket->dstPortDef; //data in udpSocket are stored in network order + 6d5c: a0 91 8a 0e lds r26, 0x0E8A + 6d60: b0 91 8b 0e lds r27, 0x0E8B + 6d64: 80 81 ld r24, Z + 6d66: 91 81 ldd r25, Z+1 ; 0x01 + 6d68: 00 97 sbiw r24, 0x00 ; 0 + 6d6a: 11 f4 brne .+4 ; 0x6d70 + 6d6c: 82 81 ldd r24, Z+2 ; 0x02 + 6d6e: 93 81 ldd r25, Z+3 ; 0x03 + 6d70: 13 96 adiw r26, 0x03 ; 3 + 6d72: 9c 93 st X, r25 + 6d74: 8e 93 st -X, r24 + 6d76: 12 97 sbiw r26, 0x02 ; 2 + + nicState.layer4.udp->udplen = htons(len + UDP_HEADER_LEN); + 6d78: e0 90 8a 0e lds r14, 0x0E8A + 6d7c: f0 90 8b 0e lds r15, 0x0E8B + 6d80: 8e 01 movw r16, r28 + 6d82: 08 5f subi r16, 0xF8 ; 248 + 6d84: 1f 4f sbci r17, 0xFF ; 255 + 6d86: c8 01 movw r24, r16 + 6d88: 0e 94 cb 2a call 0x5596 ; 0x5596 + 6d8c: f7 01 movw r30, r14 + 6d8e: 95 83 std Z+5, r25 ; 0x05 + 6d90: 84 83 std Z+4, r24 ; 0x04 + nicState.layer4.udp->udpchksum = 0; + 6d92: e0 91 8a 0e lds r30, 0x0E8A + 6d96: f0 91 8b 0e lds r31, 0x0E8B + 6d9a: 17 82 std Z+7, r1 ; 0x07 + 6d9c: 16 82 std Z+6, r1 ; 0x06 + +#if UDP_DEBUG + if (udpDbgStream != NULL) + 6d9e: 40 91 c0 0e lds r20, 0x0EC0 + 6da2: 50 91 c1 0e lds r21, 0x0EC1 + 6da6: 41 15 cp r20, r1 + 6da8: 51 05 cpc r21, r1 + 6daa: a1 f0 breq .+40 ; 0x6dd4 + if (udpDbgLevel > 1) + 6dac: 80 91 7d 0e lds r24, 0x0E7D + 6db0: 82 30 cpi r24, 0x02 ; 2 + 6db2: 80 f0 brcs .+32 ; 0x6dd4 + fprintf_P(udpDbgStream, PSTR("Sending UDP packet (data length %d)\r\n"), len); + 6db4: df 93 push r29 + 6db6: cf 93 push r28 + 6db8: 8b e3 ldi r24, 0x3B ; 59 + 6dba: 93 e1 ldi r25, 0x13 ; 19 + 6dbc: 9f 93 push r25 + 6dbe: 8f 93 push r24 + 6dc0: 5f 93 push r21 + 6dc2: 4f 93 push r20 + 6dc4: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6dc8: 0f 90 pop r0 + 6dca: 0f 90 pop r0 + 6dcc: 0f 90 pop r0 + 6dce: 0f 90 pop r0 + 6dd0: 0f 90 pop r0 + 6dd2: 0f 90 pop r0 +#endif + ipSend(udpSocket->dstIp, IP_PROTO_UDP, len + UDP_HEADER_LEN); + 6dd4: e0 91 a2 0e lds r30, 0x0EA2 + 6dd8: f0 91 a3 0e lds r31, 0x0EA3 + 6ddc: 66 81 ldd r22, Z+6 ; 0x06 + 6dde: 77 81 ldd r23, Z+7 ; 0x07 + 6de0: 80 85 ldd r24, Z+8 ; 0x08 + 6de2: 91 85 ldd r25, Z+9 ; 0x09 + 6de4: 98 01 movw r18, r16 + 6de6: 41 e1 ldi r20, 0x11 ; 17 + 6de8: 0e 94 1f 2e call 0x5c3e ; 0x5c3e + + if(udpDbgStream != NULL) + 6dec: 80 91 c0 0e lds r24, 0x0EC0 + 6df0: 90 91 c1 0e lds r25, 0x0EC1 + 6df4: 00 97 sbiw r24, 0x00 ; 0 + 6df6: 81 f0 breq .+32 ; 0x6e18 + fprintf_P(udpDbgStream, PSTR("UDP tx %d bytes\r\n"), len); + 6df8: df 93 push r29 + 6dfa: cf 93 push r28 + 6dfc: 29 e2 ldi r18, 0x29 ; 41 + 6dfe: 33 e1 ldi r19, 0x13 ; 19 + 6e00: 3f 93 push r19 + 6e02: 2f 93 push r18 + 6e04: 9f 93 push r25 + 6e06: 8f 93 push r24 + 6e08: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6e0c: 0f 90 pop r0 + 6e0e: 0f 90 pop r0 + 6e10: 0f 90 pop r0 + 6e12: 0f 90 pop r0 + 6e14: 0f 90 pop r0 + 6e16: 0f 90 pop r0 +} + 6e18: df 91 pop r29 + 6e1a: cf 91 pop r28 + 6e1c: 1f 91 pop r17 + 6e1e: 0f 91 pop r16 + 6e20: ff 90 pop r15 + 6e22: ef 90 pop r14 + 6e24: 08 95 ret + +00006e26 : + +inline void netstackUDPIPProcess(void) +{ + 6e26: bf 92 push r11 + 6e28: cf 92 push r12 + 6e2a: df 92 push r13 + 6e2c: ef 92 push r14 + 6e2e: ff 92 push r15 + 6e30: 0f 93 push r16 + 6e32: 1f 93 push r17 + 6e34: cf 93 push r28 + 6e36: df 93 push r29 + uint16_t len = (uint16_t) htons(nicState.layer4.udp->udplen); + 6e38: e0 91 8a 0e lds r30, 0x0E8A + 6e3c: f0 91 8b 0e lds r31, 0x0E8B + 6e40: 84 81 ldd r24, Z+4 ; 0x04 + 6e42: 95 81 ldd r25, Z+5 ; 0x05 + 6e44: 0e 94 cb 2a call 0x5596 ; 0x5596 + 6e48: 8c 01 movw r16, r24 + uint8_t i; + + #if UDP_DEBUG + if(udpDbgStream != NULL) + 6e4a: 80 91 c0 0e lds r24, 0x0EC0 + 6e4e: 90 91 c1 0e lds r25, 0x0EC1 + 6e52: 00 97 sbiw r24, 0x00 ; 0 + 6e54: b9 f0 breq .+46 ; 0x6e84 + if (udpDbgLevel > 5) + 6e56: 20 91 7d 0e lds r18, 0x0E7D + 6e5a: 26 30 cpi r18, 0x06 ; 6 + 6e5c: 98 f0 brcs .+38 ; 0x6e84 + fprintf_P(udpDbgStream, PSTR("Proc. UDP packet (data length %d)"), len-UDP_HEADER_LEN); + 6e5e: 98 01 movw r18, r16 + 6e60: 28 50 subi r18, 0x08 ; 8 + 6e62: 31 09 sbc r19, r1 + 6e64: 3f 93 push r19 + 6e66: 2f 93 push r18 + 6e68: 27 e0 ldi r18, 0x07 ; 7 + 6e6a: 33 e1 ldi r19, 0x13 ; 19 + 6e6c: 3f 93 push r19 + 6e6e: 2f 93 push r18 + 6e70: 9f 93 push r25 + 6e72: 8f 93 push r24 + 6e74: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6e78: 0f 90 pop r0 + 6e7a: 0f 90 pop r0 + 6e7c: 0f 90 pop r0 + 6e7e: 0f 90 pop r0 + 6e80: 0f 90 pop r0 + 6e82: 0f 90 pop r0 +#endif + + if ((udpSocket->srcPort != nicState.layer4.udp->destport) || + 6e84: e0 91 a2 0e lds r30, 0x0EA2 + 6e88: f0 91 a3 0e lds r31, 0x0EA3 + 6e8c: a0 91 8a 0e lds r26, 0x0E8A + 6e90: b0 91 8b 0e lds r27, 0x0E8B + 6e94: 12 96 adiw r26, 0x02 ; 2 + 6e96: 8d 91 ld r24, X+ + 6e98: 9c 91 ld r25, X + 6e9a: 13 97 sbiw r26, 0x03 ; 3 + 6e9c: 44 81 ldd r20, Z+4 ; 0x04 + 6e9e: 55 81 ldd r21, Z+5 ; 0x05 + 6ea0: 20 91 c0 0e lds r18, 0x0EC0 + 6ea4: 30 91 c1 0e lds r19, 0x0EC1 + 6ea8: 48 17 cp r20, r24 + 6eaa: 59 07 cpc r21, r25 + 6eac: 61 f4 brne .+24 ; 0x6ec6 + 6eae: 60 81 ld r22, Z + 6eb0: 71 81 ldd r23, Z+1 ; 0x01 + 6eb2: 4d 91 ld r20, X+ + 6eb4: 5c 91 ld r21, X + 6eb6: 11 97 sbiw r26, 0x01 ; 1 + 6eb8: 67 2b or r22, r23 + 6eba: 39 f1 breq .+78 ; 0x6f0a + ((udpSocket->dstPortDef != HTONS(0)) && (udpSocket->dstPort == nicState.layer4.udp->srcport))) + 6ebc: 62 81 ldd r22, Z+2 ; 0x02 + 6ebe: 73 81 ldd r23, Z+3 ; 0x03 + 6ec0: 64 17 cp r22, r20 + 6ec2: 75 07 cpc r23, r21 + 6ec4: 21 f5 brne .+72 ; 0x6f0e + { +#if UDP_DEBUG + if(udpDbgStream != NULL) + 6ec6: 21 15 cp r18, r1 + 6ec8: 31 05 cpc r19, r1 + 6eca: 09 f4 brne .+2 ; 0x6ece + 6ecc: ac c0 rjmp .+344 ; 0x7026 + if (udpDbgLevel > 5) + 6ece: 40 91 7d 0e lds r20, 0x0E7D + 6ed2: 46 30 cpi r20, 0x06 ; 6 + 6ed4: 08 f4 brcc .+2 ; 0x6ed8 + 6ed6: a7 c0 rjmp .+334 ; 0x7026 + fprintf_P(udpDbgStream, PSTR("Skipping, wrong ports %d %d\r\n"), nicState.layer4.udp->destport, nicState.layer4.udp->srcport ); + 6ed8: 11 96 adiw r26, 0x01 ; 1 + 6eda: 4c 91 ld r20, X + 6edc: 11 97 sbiw r26, 0x01 ; 1 + 6ede: 4f 93 push r20 + 6ee0: 4c 91 ld r20, X + 6ee2: 4f 93 push r20 + 6ee4: 9f 93 push r25 + 6ee6: 8f 93 push r24 + 6ee8: 89 ee ldi r24, 0xE9 ; 233 + 6eea: 92 e1 ldi r25, 0x12 ; 18 + 6eec: 9f 93 push r25 + 6eee: 8f 93 push r24 + 6ef0: 3f 93 push r19 + 6ef2: 2f 93 push r18 + 6ef4: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6ef8: 8d b7 in r24, 0x3d ; 61 + 6efa: 9e b7 in r25, 0x3e ; 62 + 6efc: 08 96 adiw r24, 0x08 ; 8 + 6efe: 0f b6 in r0, 0x3f ; 63 + 6f00: f8 94 cli + 6f02: 9e bf out 0x3e, r25 ; 62 + 6f04: 0f be out 0x3f, r0 ; 63 + 6f06: 8d bf out 0x3d, r24 ; 61 + 6f08: 8e c0 rjmp .+284 ; 0x7026 +#endif + return; + } + + if (udpSocket->dstPortDef == HTONS(0)) + udpSocket->dstPort = nicState.layer4.udp->srcport; + 6f0a: 53 83 std Z+3, r21 ; 0x03 + 6f0c: 42 83 std Z+2, r20 ; 0x02 + uint8_t *tmp = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + 6f0e: c0 91 8a 0e lds r28, 0x0E8A + 6f12: d0 91 8b 0e lds r29, 0x0E8B + 6f16: 28 96 adiw r28, 0x08 ; 8 +#if UDP_DEBUG + if(udpDbgStream != NULL) + 6f18: 21 15 cp r18, r1 + 6f1a: 31 05 cpc r19, r1 + 6f1c: 81 f0 breq .+32 ; 0x6f3e + if (udpDbgLevel > 4) + 6f1e: 80 91 7d 0e lds r24, 0x0E7D + 6f22: 85 30 cpi r24, 0x05 ; 5 + 6f24: 60 f0 brcs .+24 ; 0x6f3e + fprintf_P(udpDbgStream, PSTR("Received UDP data:")); + 6f26: 86 ed ldi r24, 0xD6 ; 214 + 6f28: 92 e1 ldi r25, 0x12 ; 18 + 6f2a: 9f 93 push r25 + 6f2c: 8f 93 push r24 + 6f2e: 3f 93 push r19 + 6f30: 2f 93 push r18 + 6f32: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6f36: 0f 90 pop r0 + 6f38: 0f 90 pop r0 + 6f3a: 0f 90 pop r0 + 6f3c: 0f 90 pop r0 + if(udpDbgStream != NULL) + fprintf_P(udpDbgStream, PSTR("UDP tx %d bytes\r\n"), len); +} + +inline void netstackUDPIPProcess(void) +{ + 6f3e: 88 e0 ldi r24, 0x08 ; 8 + 6f40: b8 2e mov r11, r24 + for (i=UDP_HEADER_LEN; i 4) + fprintf_P(udpDbgStream, PSTR(" 0x%2x"), *tmp); + 6f42: 9f ec ldi r25, 0xCF ; 207 + 6f44: e9 2e mov r14, r25 + 6f46: 92 e1 ldi r25, 0x12 ; 18 + 6f48: f9 2e mov r15, r25 +#endif +#if UDP_DEBUG + if (xQueueSend(udpSocket->Rx, tmp, 10) == 0) + if(udpDbgStream != NULL) + if (udpDbgLevel > 0) + fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); + 6f4a: 2a eb ldi r18, 0xBA ; 186 + 6f4c: c2 2e mov r12, r18 + 6f4e: 22 e1 ldi r18, 0x12 ; 18 + 6f50: d2 2e mov r13, r18 + if(udpDbgStream != NULL) + if (udpDbgLevel > 4) + fprintf_P(udpDbgStream, PSTR("Received UDP data:")); +#endif + + for (i=UDP_HEADER_LEN; i + { +#if UDP_DEBUG + if(udpDbgStream != NULL) + 6f64: 21 15 cp r18, r1 + 6f66: 31 05 cpc r19, r1 + 6f68: 99 f0 breq .+38 ; 0x6f90 + if (udpDbgLevel > 4) + 6f6a: 80 91 7d 0e lds r24, 0x0E7D + 6f6e: 85 30 cpi r24, 0x05 ; 5 + 6f70: 78 f0 brcs .+30 ; 0x6f90 + fprintf_P(udpDbgStream, PSTR(" 0x%2x"), *tmp); + 6f72: 88 81 ld r24, Y + 6f74: 1f 92 push r1 + 6f76: 8f 93 push r24 + 6f78: ff 92 push r15 + 6f7a: ef 92 push r14 + 6f7c: 3f 93 push r19 + 6f7e: 2f 93 push r18 + 6f80: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6f84: 0f 90 pop r0 + 6f86: 0f 90 pop r0 + 6f88: 0f 90 pop r0 + 6f8a: 0f 90 pop r0 + 6f8c: 0f 90 pop r0 + 6f8e: 0f 90 pop r0 +#else + xQueueSend(udpSocket->Rx, tmp, 0); +#endif +#if UDP_DEBUG + if (xQueueSend(udpSocket->Rx, tmp, 10) == 0) + 6f90: e0 91 a2 0e lds r30, 0x0EA2 + 6f94: f0 91 a3 0e lds r31, 0x0EA3 + 6f98: 20 e0 ldi r18, 0x00 ; 0 + 6f9a: 4a e0 ldi r20, 0x0A ; 10 + 6f9c: 50 e0 ldi r21, 0x00 ; 0 + 6f9e: be 01 movw r22, r28 + 6fa0: 82 85 ldd r24, Z+10 ; 0x0a + 6fa2: 93 85 ldd r25, Z+11 ; 0x0b + 6fa4: 0e 94 a2 46 call 0x8d44 ; 0x8d44 + 6fa8: 81 11 cpse r24, r1 + 6faa: 14 c0 rjmp .+40 ; 0x6fd4 + if(udpDbgStream != NULL) + 6fac: 80 91 c0 0e lds r24, 0x0EC0 + 6fb0: 90 91 c1 0e lds r25, 0x0EC1 + 6fb4: 00 97 sbiw r24, 0x00 ; 0 + 6fb6: 71 f0 breq .+28 ; 0x6fd4 + if (udpDbgLevel > 0) + 6fb8: 20 91 7d 0e lds r18, 0x0E7D + 6fbc: 22 23 and r18, r18 + 6fbe: 51 f0 breq .+20 ; 0x6fd4 + fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); + 6fc0: df 92 push r13 + 6fc2: cf 92 push r12 + 6fc4: 9f 93 push r25 + 6fc6: 8f 93 push r24 + 6fc8: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6fcc: 0f 90 pop r0 + 6fce: 0f 90 pop r0 + 6fd0: 0f 90 pop r0 + 6fd2: 0f 90 pop r0 +#endif + tmp++; + 6fd4: 21 96 adiw r28, 0x01 ; 1 + if(udpDbgStream != NULL) + if (udpDbgLevel > 4) + fprintf_P(udpDbgStream, PSTR("Received UDP data:")); +#endif + + for (i=UDP_HEADER_LEN; i + fprintf_P(udpDbgStream, PSTR("UDP TX buffer busy\r\n")); +#endif + tmp++; + } +#if UDP_DEBUG + if(udpDbgStream != NULL) + 6fda: 21 15 cp r18, r1 + 6fdc: 31 05 cpc r19, r1 + 6fde: 19 f1 breq .+70 ; 0x7026 + { + if (udpDbgLevel > 4) + 6fe0: 80 91 7d 0e lds r24, 0x0E7D + 6fe4: 85 30 cpi r24, 0x05 ; 5 + 6fe6: 68 f0 brcs .+26 ; 0x7002 + fprintf_P(udpDbgStream, PSTR("\r\n")); + 6fe8: 87 eb ldi r24, 0xB7 ; 183 + 6fea: 92 e1 ldi r25, 0x12 ; 18 + 6fec: 9f 93 push r25 + 6fee: 8f 93 push r24 + 6ff0: 3f 93 push r19 + 6ff2: 2f 93 push r18 + 6ff4: 0e 94 1a 50 call 0xa034 ; 0xa034 + 6ff8: 0f 90 pop r0 + 6ffa: 0f 90 pop r0 + 6ffc: 0f 90 pop r0 + 6ffe: 0f 90 pop r0 + 7000: 12 c0 rjmp .+36 ; 0x7026 + else if (udpDbgLevel > 0) + 7002: 88 23 and r24, r24 + 7004: 81 f0 breq .+32 ; 0x7026 + fprintf_P(udpDbgStream, PSTR("Received UDP packet (len %d)\r\n"), len); + 7006: 1f 93 push r17 + 7008: 0f 93 push r16 + 700a: 88 e9 ldi r24, 0x98 ; 152 + 700c: 92 e1 ldi r25, 0x12 ; 18 + 700e: 9f 93 push r25 + 7010: 8f 93 push r24 + 7012: 3f 93 push r19 + 7014: 2f 93 push r18 + 7016: 0e 94 1a 50 call 0xa034 ; 0xa034 + 701a: 0f 90 pop r0 + 701c: 0f 90 pop r0 + 701e: 0f 90 pop r0 + 7020: 0f 90 pop r0 + 7022: 0f 90 pop r0 + 7024: 0f 90 pop r0 + + } +#endif +} + 7026: df 91 pop r29 + 7028: cf 91 pop r28 + 702a: 1f 91 pop r17 + 702c: 0f 91 pop r16 + 702e: ff 90 pop r15 + 7030: ef 90 pop r14 + 7032: df 90 pop r13 + 7034: cf 90 pop r12 + 7036: bf 90 pop r11 + 7038: 08 95 ret + +0000703a : + +inline void flushUdpQueues(void) +{ + 703a: 0f 93 push r16 + 703c: 1f 93 push r17 + 703e: cf 93 push r28 + 7040: df 93 push r29 + if (uxQueueMessagesWaiting(udpSocket->Tx) > 0) + 7042: e0 91 a2 0e lds r30, 0x0EA2 + 7046: f0 91 a3 0e lds r31, 0x0EA3 + 704a: 84 85 ldd r24, Z+12 ; 0x0c + 704c: 95 85 ldd r25, Z+13 ; 0x0d + 704e: 0e 94 2b 48 call 0x9056 ; 0x9056 + 7052: 88 23 and r24, r24 + 7054: 01 f1 breq .+64 ; 0x7096 + { + uint16_t len = 0; + uint8_t *data = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + 7056: c0 91 8a 0e lds r28, 0x0E8A + 705a: d0 91 8b 0e lds r29, 0x0E8B + 705e: 28 96 adiw r28, 0x08 ; 8 + +inline void flushUdpQueues(void) +{ + if (uxQueueMessagesWaiting(udpSocket->Tx) > 0) + { + uint16_t len = 0; + 7060: 00 e0 ldi r16, 0x00 ; 0 + 7062: 10 e0 ldi r17, 0x00 ; 0 + uint8_t *data = (uint8_t *)(nicState.layer4.udp) + UDP_HEADER_LEN; + while (xQueueReceive(udpSocket->Tx, data, 0) == pdTRUE) + 7064: e0 91 a2 0e lds r30, 0x0EA2 + 7068: f0 91 a3 0e lds r31, 0x0EA3 + 706c: 20 e0 ldi r18, 0x00 ; 0 + 706e: 40 e0 ldi r20, 0x00 ; 0 + 7070: 50 e0 ldi r21, 0x00 ; 0 + 7072: be 01 movw r22, r28 + 7074: 84 85 ldd r24, Z+12 ; 0x0c + 7076: 95 85 ldd r25, Z+13 ; 0x0d + 7078: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 707c: 81 30 cpi r24, 0x01 ; 1 + 707e: 21 f4 brne .+8 ; 0x7088 + { + data++; + 7080: 21 96 adiw r28, 0x01 ; 1 + len++; + 7082: 0f 5f subi r16, 0xFF ; 255 + 7084: 1f 4f sbci r17, 0xFF ; 255 + 7086: ee cf rjmp .-36 ; 0x7064 + } + udpSend(len); + 7088: c8 01 movw r24, r16 + } +} + 708a: df 91 pop r29 + 708c: cf 91 pop r28 + 708e: 1f 91 pop r17 + 7090: 0f 91 pop r16 + while (xQueueReceive(udpSocket->Tx, data, 0) == pdTRUE) + { + data++; + len++; + } + udpSend(len); + 7092: 0c 94 9b 36 jmp 0x6d36 ; 0x6d36 + } +} + 7096: df 91 pop r29 + 7098: cf 91 pop r28 + 709a: 1f 91 pop r17 + 709c: 0f 91 pop r16 + 709e: 08 95 ret + +000070a0 : + +void udpSaveConfig(void) +{ + eeprom_update_dword(&udpIpDst_eep, udpSocket->dstIp); + 70a0: e0 91 a2 0e lds r30, 0x0EA2 + 70a4: f0 91 a3 0e lds r31, 0x0EA3 + 70a8: 46 81 ldd r20, Z+6 ; 0x06 + 70aa: 57 81 ldd r21, Z+7 ; 0x07 + 70ac: 60 85 ldd r22, Z+8 ; 0x08 + 70ae: 71 85 ldd r23, Z+9 ; 0x09 + 70b0: 84 e0 ldi r24, 0x04 ; 4 + 70b2: 90 e0 ldi r25, 0x00 ; 0 + 70b4: 0e 94 7a 53 call 0xa6f4 ; 0xa6f4 + eeprom_update_word(&udpPortDstEep, udpSocket->dstPortDef); + 70b8: e0 91 a2 0e lds r30, 0x0EA2 + 70bc: f0 91 a3 0e lds r31, 0x0EA3 + 70c0: 60 81 ld r22, Z + 70c2: 71 81 ldd r23, Z+1 ; 0x01 + 70c4: 82 e0 ldi r24, 0x02 ; 2 + 70c6: 90 e0 ldi r25, 0x00 ; 0 + 70c8: 0e 94 86 53 call 0xa70c ; 0xa70c + eeprom_update_word(&udpPortSrcEep, udpSocket->srcPort); + 70cc: e0 91 a2 0e lds r30, 0x0EA2 + 70d0: f0 91 a3 0e lds r31, 0x0EA3 + 70d4: 64 81 ldd r22, Z+4 ; 0x04 + 70d6: 75 81 ldd r23, Z+5 ; 0x05 + 70d8: 80 e0 ldi r24, 0x00 ; 0 + 70da: 90 e0 ldi r25, 0x00 ; 0 + 70dc: 0c 94 86 53 jmp 0xa70c ; 0xa70c + +000070e0 : +} + +void udpPrintStatus(FILE *stream) +{ + 70e0: cf 93 push r28 + 70e2: df 93 push r29 + 70e4: ec 01 movw r28, r24 + fprintf_P(stream, PSTR("UDP config:")); + 70e6: 8c e8 ldi r24, 0x8C ; 140 + 70e8: 92 e1 ldi r25, 0x12 ; 18 + 70ea: 9f 93 push r25 + 70ec: 8f 93 push r24 + 70ee: df 93 push r29 + 70f0: cf 93 push r28 + 70f2: 0e 94 1a 50 call 0xa034 ; 0xa034 + fprintf_P(stream, PSTR("\r\n IP : ")); netPrintIPAddr(stream, udpSocket->dstIp); + 70f6: 89 e7 ldi r24, 0x79 ; 121 + 70f8: 92 e1 ldi r25, 0x12 ; 18 + 70fa: 9f 93 push r25 + 70fc: 8f 93 push r24 + 70fe: df 93 push r29 + 7100: cf 93 push r28 + 7102: 0e 94 1a 50 call 0xa034 ; 0xa034 + 7106: e0 91 a2 0e lds r30, 0x0EA2 + 710a: f0 91 a3 0e lds r31, 0x0EA3 + 710e: 46 81 ldd r20, Z+6 ; 0x06 + 7110: 57 81 ldd r21, Z+7 ; 0x07 + 7112: 60 85 ldd r22, Z+8 ; 0x08 + 7114: 71 85 ldd r23, Z+9 ; 0x09 + 7116: ce 01 movw r24, r28 + 7118: 0e 94 29 2b call 0x5652 ; 0x5652 + fprintf_P(stream, PSTR("\r\n src port : %d\r\n dst port : "), htons(udpSocket->srcPort)); + 711c: e0 91 a2 0e lds r30, 0x0EA2 + 7120: f0 91 a3 0e lds r31, 0x0EA3 + 7124: 84 81 ldd r24, Z+4 ; 0x04 + 7126: 95 81 ldd r25, Z+5 ; 0x05 + 7128: 0e 94 cb 2a call 0x5596 ; 0x5596 + 712c: 9f 93 push r25 + 712e: 8f 93 push r24 + 7130: 82 e5 ldi r24, 0x52 ; 82 + 7132: 92 e1 ldi r25, 0x12 ; 18 + 7134: 9f 93 push r25 + 7136: 8f 93 push r24 + 7138: df 93 push r29 + 713a: cf 93 push r28 + 713c: 0e 94 1a 50 call 0xa034 ; 0xa034 + if (udpSocket->dstPortDef == HTONS(0)) + 7140: e0 91 a2 0e lds r30, 0x0EA2 + 7144: f0 91 a3 0e lds r31, 0x0EA3 + 7148: 80 81 ld r24, Z + 714a: 91 81 ldd r25, Z+1 ; 0x01 + 714c: 2d b7 in r18, 0x3d ; 61 + 714e: 3e b7 in r19, 0x3e ; 62 + 7150: 22 5f subi r18, 0xF2 ; 242 + 7152: 3f 4f sbci r19, 0xFF ; 255 + 7154: 0f b6 in r0, 0x3f ; 63 + 7156: f8 94 cli + 7158: 3e bf out 0x3e, r19 ; 62 + 715a: 0f be out 0x3f, r0 ; 63 + 715c: 2d bf out 0x3d, r18 ; 61 + 715e: 00 97 sbiw r24, 0x00 ; 0 + 7160: 69 f4 brne .+26 ; 0x717c + fprintf_P(stream, PSTR("ANY\r\n")); + 7162: 8c e4 ldi r24, 0x4C ; 76 + 7164: 92 e1 ldi r25, 0x12 ; 18 + 7166: 9f 93 push r25 + 7168: 8f 93 push r24 + 716a: df 93 push r29 + 716c: cf 93 push r28 + 716e: 0e 94 1a 50 call 0xa034 ; 0xa034 + 7172: 0f 90 pop r0 + 7174: 0f 90 pop r0 + 7176: 0f 90 pop r0 + 7178: 0f 90 pop r0 + 717a: 12 c0 rjmp .+36 ; 0x71a0 + else + fprintf_P(stream, PSTR("%d\r\n"), htons(udpSocket->dstPortDef)); + 717c: 0e 94 cb 2a call 0x5596 ; 0x5596 + 7180: 9f 93 push r25 + 7182: 8f 93 push r24 + 7184: 87 e4 ldi r24, 0x47 ; 71 + 7186: 92 e1 ldi r25, 0x12 ; 18 + 7188: 9f 93 push r25 + 718a: 8f 93 push r24 + 718c: df 93 push r29 + 718e: cf 93 push r28 + 7190: 0e 94 1a 50 call 0xa034 ; 0xa034 + 7194: 0f 90 pop r0 + 7196: 0f 90 pop r0 + 7198: 0f 90 pop r0 + 719a: 0f 90 pop r0 + 719c: 0f 90 pop r0 + 719e: 0f 90 pop r0 +} + 71a0: df 91 pop r29 + 71a2: cf 91 pop r28 + 71a4: 08 95 ret + +000071a6 <_crc_xmodem_update>: + : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + : "r" (__data), "0" (__crc) + : "r0" + ); + return __ret; +} + 71a6: 96 27 eor r25, r22 + 71a8: 09 2e mov r0, r25 + 71aa: 02 94 swap r0 + 71ac: 20 2d mov r18, r0 + 71ae: 2f 70 andi r18, 0x0F ; 15 + 71b0: 29 27 eor r18, r25 + 71b2: 69 2f mov r22, r25 + 71b4: 60 25 eor r22, r0 + 71b6: 66 0f add r22, r22 + 71b8: 60 7e andi r22, 0xE0 ; 224 + 71ba: 26 27 eor r18, r22 + 71bc: 60 2d mov r22, r0 + 71be: 69 27 eor r22, r25 + 71c0: 60 7f andi r22, 0xF0 ; 240 + 71c2: 66 95 lsr r22 + 71c4: 09 2e mov r0, r25 + 71c6: 00 0c add r0, r0 + 71c8: 66 1f adc r22, r22 + 71ca: 96 95 lsr r25 + 71cc: 96 95 lsr r25 + 71ce: 96 95 lsr r25 + 71d0: 9f 71 andi r25, 0x1F ; 31 + 71d2: 96 27 eor r25, r22 + 71d4: 98 27 eor r25, r24 + 71d6: 82 2f mov r24, r18 + 71d8: 08 95 ret + 71da: 08 95 ret + 71dc: 08 95 ret + 71de: 08 95 ret + 71e0: 81 e0 ldi r24, 0x01 ; 1 + 71e2: 08 95 ret + 71e4: 81 e0 ldi r24, 0x01 ; 1 + 71e6: 08 95 ret + +000071e8 : + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + 71e8: 8e e6 ldi r24, 0x6E ; 110 + 71ea: 90 e0 ldi r25, 0x00 ; 0 + 71ec: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 71f0: 90 93 a9 0e sts 0x0EA9, r25 + 71f4: 80 93 a8 0e sts 0x0EA8, r24 + POSSIBILITY OF SUCH DAMAGE. */ + 71f8: 2e e6 ldi r18, 0x6E ; 110 + 71fa: fc 01 movw r30, r24 + 71fc: 11 92 st Z+, r1 + 71fe: 2a 95 dec r18 + 7200: e9 f7 brne .-6 ; 0x71fc + 7202: 08 95 ret + +00007204 : + "rol %2" "\n\t" + "lsr %B0" "\n\t" + "lsr %B0" "\n\t" + "lsr %B0" "\n\t" + "andi %B0,0x1f" "\n\t" + "eor %B0,%2" "\n\t" + 7204: 9f 92 push r9 + 7206: af 92 push r10 + 7208: bf 92 push r11 + 720a: cf 92 push r12 + 720c: df 92 push r13 + 720e: ef 92 push r14 + 7210: ff 92 push r15 + 7212: 0f 93 push r16 + 7214: 1f 93 push r17 + 7216: cf 93 push r28 + 7218: df 93 push r29 + 721a: e8 2e mov r14, r24 + 721c: 99 2e mov r9, r25 + "eor %B0,%A0" "\n\t" /* ret.hi is now ready. */ + "mov %A0,%1" "\n\t" /* ret.lo is now ready. */ + 721e: 00 91 a8 0e lds r16, 0x0EA8 + 7222: 10 91 a9 0e lds r17, 0x0EA9 + 7226: e8 01 movw r28, r16 + 7228: 25 96 adiw r28, 0x05 ; 5 + 722a: 0d 58 subi r16, 0x8D ; 141 + 722c: 1f 4f sbci r17, 0xFF ; 255 + "lsr %B0" "\n\t" + "lsr %B0" "\n\t" + "lsr %B0" "\n\t" + "andi %B0,0x1f" "\n\t" + "eor %B0,%2" "\n\t" + "eor %B0,%A0" "\n\t" /* ret.hi is now ready. */ + 722e: f1 2c mov r15, r1 + : "r" (__data), "0" (__crc) + : "r0" + ); + return __ret; +} + + 7230: 84 ee ldi r24, 0xE4 ; 228 + 7232: a8 2e mov r10, r24 + 7234: 83 e1 ldi r24, 0x13 ; 19 + 7236: b8 2e mov r11, r24 +/** \ingroup util_crc + Optimized CRC-CCITT calculation. + 7238: 99 ec ldi r25, 0xC9 ; 201 + 723a: c9 2e mov r12, r25 + 723c: 93 e1 ldi r25, 0x13 ; 19 + 723e: d9 2e mov r13, r25 + 7240: fe 01 movw r30, r28 + 7242: 34 97 sbiw r30, 0x04 ; 4 + "mov %A0,%1" "\n\t" /* ret.lo is now ready. */ + : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + : "r" (__data), "0" (__crc) + : "r0" + ); + return __ret; + 7244: 80 81 ld r24, Z + 7246: 88 23 and r24, r24 + 7248: 19 f1 breq .+70 ; 0x7290 + 724a: 32 96 adiw r30, 0x02 ; 2 +} + + 724c: 20 81 ld r18, Z + 724e: 2f 73 andi r18, 0x3F ; 63 + 7250: 1f 92 push r1 + 7252: 2f 93 push r18 + 7254: 31 97 sbiw r30, 0x01 ; 1 + 7256: 20 81 ld r18, Z + 7258: 2f 73 andi r18, 0x3F ; 63 + 725a: 1f 92 push r1 + 725c: 2f 93 push r18 + 725e: 1f 92 push r1 + 7260: 8f 93 push r24 + 7262: bf 92 push r11 + 7264: af 92 push r10 + 7266: 9f 92 push r9 + 7268: ef 92 push r14 + 726a: 0e 94 1a 50 call 0xa034 ; 0xa034 +/** \ingroup util_crc + Optimized CRC-CCITT calculation. + 726e: df 93 push r29 + 7270: cf 93 push r28 + 7272: df 92 push r13 + 7274: cf 92 push r12 + 7276: 9f 92 push r9 + 7278: ef 92 push r14 + 727a: 0e 94 1a 50 call 0xa034 ; 0xa034 + + 727e: f3 94 inc r15 + 7280: 8d b7 in r24, 0x3d ; 61 + 7282: 9e b7 in r25, 0x3e ; 62 + 7284: 40 96 adiw r24, 0x10 ; 16 + 7286: 0f b6 in r0, 0x3f ; 63 + 7288: f8 94 cli + 728a: 9e bf out 0x3e, r25 ; 62 + 728c: 0f be out 0x3f, r0 ; 63 + 728e: 8d bf out 0x3d, r24 ; 61 + 7290: 2b 96 adiw r28, 0x0b ; 11 + "eor %B0,%2" "\n\t" + "eor %B0,%A0" "\n\t" /* ret.hi is now ready. */ + "mov %A0,%1" "\n\t" /* ret.lo is now ready. */ + : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + : "r" (__data), "0" (__crc) + : "r0" + 7292: c0 17 cp r28, r16 + 7294: d1 07 cpc r29, r17 + 7296: a1 f6 brne .-88 ; 0x7240 + Initial value: 0xffff + + This is the CRC used by PPP and IrDA. + + See RFC1171 (PPP protocol) and IrDA IrLAP 1.1 + + 7298: 8f 2d mov r24, r15 + 729a: df 91 pop r29 + 729c: cf 91 pop r28 + 729e: 1f 91 pop r17 + 72a0: 0f 91 pop r16 + 72a2: ff 90 pop r15 + 72a4: ef 90 pop r14 + 72a6: df 90 pop r13 + 72a8: cf 90 pop r12 + 72aa: bf 90 pop r11 + 72ac: af 90 pop r10 + 72ae: 9f 90 pop r9 + 72b0: 08 95 ret + +000072b2 : + \note Although the CCITT polynomial is the same as that used by the Xmodem + protocol, they are quite different. The difference is in how the bits are + shifted through the alorgithm. Xmodem shifts the MSB of the CRC and the + input first, while CCITT shifts the LSB of the CRC and the input first. + 72b2: ef 92 push r14 + 72b4: ff 92 push r15 + 72b6: 0f 93 push r16 + 72b8: 1f 93 push r17 + 72ba: cf 93 push r28 + 72bc: df 93 push r29 + 72be: 00 d0 rcall .+0 ; 0x72c0 + 72c0: 00 d0 rcall .+0 ; 0x72c2 + 72c2: cd b7 in r28, 0x3d ; 61 + 72c4: de b7 in r29, 0x3e ; 62 + 72c6: 18 2f mov r17, r24 + + 72c8: 0e 94 bf 0c call 0x197e ; 0x197e +#define _UTIL_CRC16_H_ + +#include + +/** \file */ +/** \defgroup util_crc : CRC Computations + 72cc: 6a e5 ldi r22, 0x5A ; 90 + 72ce: 80 e0 ldi r24, 0x00 ; 0 + 72d0: 90 e0 ldi r25, 0x00 ; 0 + 72d2: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 72d6: 7c 01 movw r14, r24 + \code#include \endcode + 72d8: 8a e5 ldi r24, 0x5A ; 90 + 72da: 0e 94 2b 0c call 0x1856 ; 0x1856 + + This header file provides a optimized inline functions for calculating + 72de: 61 2f mov r22, r17 + 72e0: c7 01 movw r24, r14 + 72e2: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 72e6: 7c 01 movw r14, r24 + cyclic redundancy checks (CRC) using common polynomials. + 72e8: 81 2f mov r24, r17 + 72ea: 0e 94 2b 0c call 0x1856 ; 0x1856 + + \par References: + 72ee: 60 e8 ldi r22, 0x80 ; 128 + 72f0: c7 01 movw r24, r14 + 72f2: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 72f6: 8c 01 movw r16, r24 + + 72f8: 80 e8 ldi r24, 0x80 ; 128 + 72fa: 0e 94 2b 0c call 0x1856 ; 0x1856 + \par + + 72fe: 68 e0 ldi r22, 0x08 ; 8 + 7300: c8 01 movw r24, r16 + 7302: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7306: 08 2f mov r16, r24 + See the Dallas Semiconductor app note 27 for 8051 assembler example and + 7308: 88 e0 ldi r24, 0x08 ; 8 + 730a: 9c 83 std Y+4, r25 ; 0x04 + 730c: 0e 94 2b 0c call 0x1856 ; 0x1856 + general CRC optimization suggestions. The table on the last page of the + app note is the key to understanding these implementations. + 7310: 10 e0 ldi r17, 0x00 ; 0 + 7312: 9c 81 ldd r25, Y+4 ; 0x04 + + \par + 7314: 61 2f mov r22, r17 + 7316: 80 2f mov r24, r16 + 7318: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 731c: 08 2f mov r16, r24 + + 731e: 81 2f mov r24, r17 + 7320: 9c 83 std Y+4, r25 ; 0x04 + 7322: 0e 94 2b 0c call 0x1856 ; 0x1856 + + \par + + See the Dallas Semiconductor app note 27 for 8051 assembler example and + general CRC optimization suggestions. The table on the last page of the + app note is the key to understanding these implementations. + 7326: 1f 5f subi r17, 0xFF ; 255 + 7328: 9c 81 ldd r25, Y+4 ; 0x04 + 732a: 18 30 cpi r17, 0x08 ; 8 + 732c: 99 f7 brne .-26 ; 0x7314 + + \par + + Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e + Embedded \e Systems \e Programming. This may be difficult to find, but it + 732e: 89 2f mov r24, r25 + 7330: 0e 94 2b 0c call 0x1856 ; 0x1856 + explains CRC's in very clear and concise terms. Well worth the effort to + 7334: 80 2f mov r24, r16 + 7336: 0e 94 2b 0c call 0x1856 ; 0x1856 + \code + // Dallas iButton test vector. + uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + + int + checkcrc(void) + 733a: 64 e1 ldi r22, 0x14 ; 20 + 733c: ce 01 movw r24, r28 + 733e: 03 96 adiw r24, 0x03 ; 3 + 7340: 0e 94 42 0c call 0x1884 ; 0x1884 + 7344: 88 23 and r24, r24 + 7346: 09 f4 brne .+2 ; 0x734a + 7348: 77 c0 rjmp .+238 ; 0x7438 + { + uint8_t crc = 0, i; + + 734a: 8b 81 ldd r24, Y+3 ; 0x03 + 734c: 8a 35 cpi r24, 0x5A ; 90 + 734e: 09 f0 breq .+2 ; 0x7352 + 7350: 75 c0 rjmp .+234 ; 0x743c + for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + crc = _crc_ibutton_update(crc, serno[i]); + 7352: 6a e5 ldi r22, 0x5A ; 90 + 7354: 80 e0 ldi r24, 0x00 ; 0 + 7356: 90 e0 ldi r25, 0x00 ; 0 + 7358: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 735c: 8c 01 movw r16, r24 + + return crc; // must be 0 + } + 735e: 61 e0 ldi r22, 0x01 ; 1 + 7360: ce 01 movw r24, r28 + 7362: 03 96 adiw r24, 0x03 ; 3 + 7364: 0e 94 42 0c call 0x1884 ; 0x1884 + 7368: 88 23 and r24, r24 + 736a: 09 f4 brne .+2 ; 0x736e + 736c: 69 c0 rjmp .+210 ; 0x7440 + \endcode +*/ + + 736e: 8b 81 ldd r24, Y+3 ; 0x03 + 7370: 81 11 cpse r24, r1 + 7372: 68 c0 rjmp .+208 ; 0x7444 +/** \ingroup util_crc + Optimized CRC-16 calculation. + + 7374: 60 e0 ldi r22, 0x00 ; 0 + 7376: c8 01 movw r24, r16 + 7378: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 737c: 8c 01 movw r16, r24 + Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ Initial value: 0xffff + + 737e: 61 e0 ldi r22, 0x01 ; 1 + 7380: ce 01 movw r24, r28 + 7382: 03 96 adiw r24, 0x03 ; 3 + 7384: 0e 94 42 0c call 0x1884 ; 0x1884 + 7388: 88 23 and r24, r24 + 738a: 09 f4 brne .+2 ; 0x738e + 738c: 5d c0 rjmp .+186 ; 0x7448 + This CRC is normally used in disk-drive controllers. + + 738e: 8b 81 ldd r24, Y+3 ; 0x03 + 7390: 80 38 cpi r24, 0x80 ; 128 + 7392: 09 f0 breq .+2 ; 0x7396 + 7394: 5b c0 rjmp .+182 ; 0x744c + The following is the equivalent functionality written in C. + + 7396: 60 e8 ldi r22, 0x80 ; 128 + 7398: c8 01 movw r24, r16 + 739a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 739e: 8c 01 movw r16, r24 + \code + uint16_t + crc16_update(uint16_t crc, uint8_t a) + 73a0: 61 e0 ldi r22, 0x01 ; 1 + 73a2: ce 01 movw r24, r28 + 73a4: 03 96 adiw r24, 0x03 ; 3 + 73a6: 0e 94 42 0c call 0x1884 ; 0x1884 + 73aa: 88 23 and r24, r24 + 73ac: 09 f4 brne .+2 ; 0x73b0 + 73ae: 50 c0 rjmp .+160 ; 0x7450 + { + int i; + 73b0: 8b 81 ldd r24, Y+3 ; 0x03 + 73b2: 88 30 cpi r24, 0x08 ; 8 + 73b4: 09 f0 breq .+2 ; 0x73b8 + 73b6: 4e c0 rjmp .+156 ; 0x7454 + + crc ^= a; + 73b8: 68 e0 ldi r22, 0x08 ; 8 + 73ba: c8 01 movw r24, r16 + 73bc: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 73c0: 08 2f mov r16, r24 + 73c2: f9 2e mov r15, r25 + for (i = 0; i < 8; ++i) + { + if (crc & 1) + crc = (crc >> 1) ^ 0xA001; + 73c4: 10 e0 ldi r17, 0x00 ; 0 + else + crc = (crc >> 1); + 73c6: 65 e0 ldi r22, 0x05 ; 5 + 73c8: ce 01 movw r24, r28 + 73ca: 03 96 adiw r24, 0x03 ; 3 + 73cc: 0e 94 42 0c call 0x1884 ; 0x1884 + 73d0: 81 11 cpse r24, r1 + 73d2: 03 c0 rjmp .+6 ; 0x73da + } + 73d4: 11 0f add r17, r17 + 73d6: 17 5f subi r17, 0xF7 ; 247 + 73d8: 44 c0 rjmp .+136 ; 0x7462 + + 73da: 6b 81 ldd r22, Y+3 ; 0x03 + 73dc: 80 2f mov r24, r16 + 73de: 9f 2d mov r25, r15 + 73e0: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 73e4: 08 2f mov r16, r24 + 73e6: f9 2e mov r15, r25 + return crc; + 73e8: 8b 81 ldd r24, Y+3 ; 0x03 + 73ea: 81 17 cp r24, r17 + 73ec: 19 f0 breq .+6 ; 0x73f4 + } + 73ee: 11 0f add r17, r17 + 73f0: 16 5f subi r17, 0xF6 ; 246 + 73f2: 37 c0 rjmp .+110 ; 0x7462 + + crc ^= a; + for (i = 0; i < 8; ++i) + { + if (crc & 1) + crc = (crc >> 1) ^ 0xA001; + 73f4: 1f 5f subi r17, 0xFF ; 255 + 73f6: 18 30 cpi r17, 0x08 ; 8 + 73f8: 31 f7 brne .-52 ; 0x73c6 + } + + \endcode */ + +static __inline__ uint16_t +_crc16_update(uint16_t __crc, uint8_t __data) + 73fa: 61 e0 ldi r22, 0x01 ; 1 + 73fc: ce 01 movw r24, r28 + 73fe: 02 96 adiw r24, 0x02 ; 2 + 7400: 0e 94 42 0c call 0x1884 ; 0x1884 + 7404: 81 30 cpi r24, 0x01 ; 1 + 7406: 41 f5 brne .+80 ; 0x7458 +{ + uint8_t __tmp; + uint16_t __ret; + 7408: 20 e0 ldi r18, 0x00 ; 0 + 740a: 41 e0 ldi r20, 0x01 ; 1 + 740c: 50 e0 ldi r21, 0x00 ; 0 + 740e: be 01 movw r22, r28 + 7410: 6f 5f subi r22, 0xFF ; 255 + 7412: 7f 4f sbci r23, 0xFF ; 255 + 7414: 80 91 9c 0e lds r24, 0x0E9C + 7418: 90 91 9d 0e lds r25, 0x0E9D + 741c: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 7420: 81 30 cpi r24, 0x01 ; 1 + 7422: e1 f4 brne .+56 ; 0x745c + + __asm__ __volatile__ ( + "eor %A0,%2" "\n\t" + 7424: 8a 81 ldd r24, Y+2 ; 0x02 + 7426: 8f 11 cpse r24, r15 + 7428: 1b c0 rjmp .+54 ; 0x7460 + "mov %1,%A0" "\n\t" + "swap %1" "\n\t" + 742a: 11 e0 ldi r17, 0x01 ; 1 + 742c: 89 81 ldd r24, Y+1 ; 0x01 + 742e: 80 13 cpse r24, r16 + 7430: 01 c0 rjmp .+2 ; 0x7434 + 7432: 10 e0 ldi r17, 0x00 ; 0 + 7434: 11 95 neg r17 + 7436: 15 c0 rjmp .+42 ; 0x7462 + // Dallas iButton test vector. + uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + + int + checkcrc(void) + { + 7438: 11 e0 ldi r17, 0x01 ; 1 + 743a: 13 c0 rjmp .+38 ; 0x7462 + uint8_t crc = 0, i; + + for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + 743c: 12 e0 ldi r17, 0x02 ; 2 + 743e: 11 c0 rjmp .+34 ; 0x7462 + crc = _crc_ibutton_update(crc, serno[i]); + + return crc; // must be 0 + } + \endcode + 7440: 13 e0 ldi r17, 0x03 ; 3 + 7442: 0f c0 rjmp .+30 ; 0x7462 +*/ + +/** \ingroup util_crc + 7444: 14 e0 ldi r17, 0x04 ; 4 + 7446: 0d c0 rjmp .+26 ; 0x7462 + Optimized CRC-16 calculation. + + Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ Initial value: 0xffff + + This CRC is normally used in disk-drive controllers. + 7448: 15 e0 ldi r17, 0x05 ; 5 + 744a: 0b c0 rjmp .+22 ; 0x7462 + + The following is the equivalent functionality written in C. + 744c: 16 e0 ldi r17, 0x06 ; 6 + 744e: 09 c0 rjmp .+18 ; 0x7462 + + \code + uint16_t + crc16_update(uint16_t crc, uint8_t a) + { + 7450: 17 e0 ldi r17, 0x07 ; 7 + 7452: 07 c0 rjmp .+14 ; 0x7462 + int i; + + 7454: 18 e0 ldi r17, 0x08 ; 8 + 7456: 05 c0 rjmp .+10 ; 0x7462 + + \endcode */ + +static __inline__ uint16_t +_crc16_update(uint16_t __crc, uint8_t __data) +{ + 7458: 1b e1 ldi r17, 0x1B ; 27 + 745a: 03 c0 rjmp .+6 ; 0x7462 + uint8_t __tmp; + uint16_t __ret; + + 745c: 1c e1 ldi r17, 0x1C ; 28 + 745e: 01 c0 rjmp .+2 ; 0x7462 + __asm__ __volatile__ ( + "eor %A0,%2" "\n\t" + "mov %1,%A0" "\n\t" + 7460: 1e ef ldi r17, 0xFE ; 254 + input first, while CCITT shifts the LSB of the CRC and the input first. + + The following is the equivalent functionality written in C. + + \code + uint16_t + 7462: 0e 94 a2 0c call 0x1944 ; 0x1944 + crc_ccitt_update (uint16_t crc, uint8_t data) + { + 7466: 0e 94 ca 0c call 0x1994 ; 0x1994 + data ^= lo8 (crc); + data ^= data << 4; + 746a: 81 2f mov r24, r17 + 746c: 0f 90 pop r0 + 746e: 0f 90 pop r0 + 7470: 0f 90 pop r0 + 7472: 0f 90 pop r0 + 7474: df 91 pop r29 + 7476: cf 91 pop r28 + 7478: 1f 91 pop r17 + 747a: 0f 91 pop r16 + 747c: ff 90 pop r15 + 747e: ef 90 pop r14 + 7480: 08 95 ret + +00007482 : + + return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) + ^ ((uint16_t)data << 3)); + 7482: cf 92 push r12 + 7484: df 92 push r13 + 7486: ef 92 push r14 + 7488: ff 92 push r15 + 748a: 0f 93 push r16 + 748c: 1f 93 push r17 + 748e: cf 93 push r28 + 7490: df 93 push r29 + 7492: 00 d0 rcall .+0 ; 0x7494 + 7494: 00 d0 rcall .+0 ; 0x7496 + 7496: cd b7 in r28, 0x3d ; 61 + 7498: de b7 in r29, 0x3e ; 62 + 749a: f8 2e mov r15, r24 + } + \endcode */ + +static __inline__ uint16_t + 749c: 80 91 a8 0e lds r24, 0x0EA8 + 74a0: 90 91 a9 0e lds r25, 0x0EA9 + 74a4: fc 01 movw r30, r24 + 74a6: 31 96 adiw r30, 0x01 ; 1 + 74a8: 81 59 subi r24, 0x91 ; 145 + 74aa: 9f 4f sbci r25, 0xFF ; 255 + data ^= lo8 (crc); + data ^= data << 4; + + return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) + ^ ((uint16_t)data << 3)); + } + 74ac: 00 e0 ldi r16, 0x00 ; 0 + 74ae: 10 e0 ldi r17, 0x00 ; 0 + 74b0: 9f 01 movw r18, r30 + 74b2: 21 50 subi r18, 0x01 ; 1 + 74b4: 31 09 sbc r19, r1 + \endcode */ + +static __inline__ uint16_t + 74b6: 40 81 ld r20, Z + 74b8: 4f 11 cpse r20, r15 + 74ba: 01 c0 rjmp .+2 ; 0x74be +_crc_ccitt_update (uint16_t __crc, uint8_t __data) + 74bc: 89 01 movw r16, r18 + 74be: 3b 96 adiw r30, 0x0b ; 11 + + return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) + ^ ((uint16_t)data << 3)); + } + \endcode */ + + 74c0: e8 17 cp r30, r24 + 74c2: f9 07 cpc r31, r25 + 74c4: a9 f7 brne .-22 ; 0x74b0 +static __inline__ uint16_t +_crc_ccitt_update (uint16_t __crc, uint8_t __data) +{ + uint16_t __ret; + 74c6: 8f 2d mov r24, r15 + 74c8: 0e 94 59 39 call 0x72b2 ; 0x72b2 + 74cc: 81 11 cpse r24, r1 + 74ce: 23 c0 rjmp .+70 ; 0x7516 + + __asm__ __volatile__ ( + 74d0: 01 15 cp r16, r1 + 74d2: 11 05 cpc r17, r1 + 74d4: d1 f4 brne .+52 ; 0x750a + "eor %A0,%1" "\n\t" + + "mov __tmp_reg__,%A0" "\n\t" + "swap %A0" "\n\t" + 74d6: 80 91 a8 0e lds r24, 0x0EA8 + 74da: 90 91 a9 0e lds r25, 0x0EA9 + 74de: fc 01 movw r30, r24 + 74e0: 31 96 adiw r30, 0x01 ; 1 + 74e2: 81 59 subi r24, 0x91 ; 145 + 74e4: 9f 4f sbci r25, 0xFF ; 255 + 74e6: 8f 01 movw r16, r30 + 74e8: 01 50 subi r16, 0x01 ; 1 + 74ea: 11 09 sbc r17, r1 + 74ec: 20 81 ld r18, Z + 74ee: 21 11 cpse r18, r1 + 74f0: 07 c0 rjmp .+14 ; 0x7500 + "andi %A0,0xf0" "\n\t" + "eor %A0,__tmp_reg__" "\n\t" + + 74f2: f8 01 movw r30, r16 + 74f4: f1 82 std Z+1, r15 ; 0x01 + "mov __tmp_reg__,%B0" "\n\t" + + "mov %B0,%A0" "\n\t" + + "swap %A0" "\n\t" + 74f6: 01 15 cp r16, r1 + 74f8: 11 05 cpc r17, r1 + 74fa: 39 f4 brne .+14 ; 0x750a + "andi %A0,0x0f" "\n\t" + "eor __tmp_reg__,%A0" "\n\t" + + "lsr %A0" "\n\t" + "eor %B0,%A0" "\n\t" + + 74fc: 81 e0 ldi r24, 0x01 ; 1 + 74fe: e0 c0 rjmp .+448 ; 0x76c0 + 7500: 3b 96 adiw r30, 0x0b ; 11 +{ + uint16_t __ret; + + __asm__ __volatile__ ( + "eor %A0,%1" "\n\t" + + 7502: e8 17 cp r30, r24 + 7504: f9 07 cpc r31, r25 + 7506: 79 f7 brne .-34 ; 0x74e6 + 7508: f9 cf rjmp .-14 ; 0x74fc + + "mov %B0,%A0" "\n\t" + + "swap %A0" "\n\t" + "andi %A0,0x0f" "\n\t" + "eor __tmp_reg__,%A0" "\n\t" + 750a: f8 01 movw r30, r16 + 750c: 80 81 ld r24, Z + 750e: 8e 7f andi r24, 0xFE ; 254 + 7510: 80 83 st Z, r24 + + 7512: f1 82 std Z+1, r15 ; 0x01 + 7514: 0c c0 rjmp .+24 ; 0x752e + "eor %B0,%A0" "\n\t" + + "eor %A0,%B0" "\n\t" + "lsl %A0" "\n\t" + "lsl %A0" "\n\t" + "lsl %A0" "\n\t" + 7516: 01 15 cp r16, r1 + 7518: 11 05 cpc r17, r1 + 751a: 49 f0 breq .+18 ; 0x752e + "eor %A0,__tmp_reg__" + + 751c: f8 01 movw r30, r16 + 751e: 80 81 ld r24, Z + 7520: 80 fd sbrc r24, 0 + : "=d" (__ret) + : "r" (__data), "0" (__crc) + 7522: 11 82 std Z+1, r1 ; 0x01 + : "r0" + ); + 7524: 81 60 ori r24, 0x01 ; 1 + 7526: f8 01 movw r30, r16 + 7528: 80 83 st Z, r24 + return __ret; + 752a: 82 e0 ldi r24, 0x02 ; 2 + 752c: c9 c0 rjmp .+402 ; 0x76c0 +} + +/** \ingroup util_crc + Optimized Dallas (now Maxim) iButton 8-bit CRC calculation. + 752e: 0e 94 bf 0c call 0x197e ; 0x197e + "lsr %1" "\n\t" + "lsr %1" "\n\t" + "eor %1,__tmp_reg__" "\n\t" + "mov __tmp_reg__,%1" "\n\t" + "lsr %1" "\n\t" + "eor %1,__tmp_reg__" "\n\t" + 7532: 6a e5 ldi r22, 0x5A ; 90 + 7534: 80 e0 ldi r24, 0x00 ; 0 + 7536: 90 e0 ldi r25, 0x00 ; 0 + 7538: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 753c: 6c 01 movw r12, r24 + "andi %1,0x07" "\n\t" + 753e: 8a e5 ldi r24, 0x5A ; 90 + 7540: 0e 94 2b 0c call 0x1856 ; 0x1856 + "mov __tmp_reg__,%A0" "\n\t" + "mov %A0,%B0" "\n\t" + 7544: 6f 2d mov r22, r15 + 7546: c6 01 movw r24, r12 + 7548: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 754c: 6c 01 movw r12, r24 + "lsr %1" "\n\t" + 754e: 8f 2d mov r24, r15 + 7550: 0e 94 2b 0c call 0x1856 ; 0x1856 + "ror __tmp_reg__" "\n\t" + "ror %1" "\n\t" + 7554: 62 e8 ldi r22, 0x82 ; 130 + 7556: c6 01 movw r24, r12 + 7558: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 755c: 7c 01 movw r14, r24 + "mov %B0,__tmp_reg__" "\n\t" + 755e: 82 e8 ldi r24, 0x82 ; 130 + 7560: 0e 94 2b 0c call 0x1856 ; 0x1856 + "eor %A0,%1" "\n\t" + "lsr __tmp_reg__" "\n\t" + 7564: 60 e0 ldi r22, 0x00 ; 0 + 7566: c7 01 movw r24, r14 + 7568: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 756c: f8 2e mov r15, r24 + "ror %1" "\n\t" + 756e: 80 e0 ldi r24, 0x00 ; 0 + 7570: 9c 83 std Y+4, r25 ; 0x04 + 7572: 0e 94 2b 0c call 0x1856 ; 0x1856 + "eor %B0,__tmp_reg__" "\n\t" + "eor %A0,%1" + 7576: 9c 81 ldd r25, Y+4 ; 0x04 + 7578: 89 2f mov r24, r25 + 757a: 0e 94 2b 0c call 0x1856 ; 0x1856 + : "=r" (__ret), "=d" (__tmp) + 757e: 8f 2d mov r24, r15 + 7580: 0e 94 2b 0c call 0x1856 ; 0x1856 + ); + return __ret; +} + +/** \ingroup util_crc + Optimized CRC-XMODEM calculation. + 7584: 64 e1 ldi r22, 0x14 ; 20 + 7586: ce 01 movw r24, r28 + 7588: 03 96 adiw r24, 0x03 ; 3 + 758a: 0e 94 42 0c call 0x1884 ; 0x1884 + 758e: 88 23 and r24, r24 + 7590: 09 f4 brne .+2 ; 0x7594 + 7592: 7b c0 rjmp .+246 ; 0x768a + + Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ Initial value: 0x0 + 7594: 8b 81 ldd r24, Y+3 ; 0x03 + 7596: 8a 35 cpi r24, 0x5A ; 90 + 7598: 09 f0 breq .+2 ; 0x759c + 759a: 79 c0 rjmp .+242 ; 0x768e + + This is the CRC used by the Xmodem-CRC protocol. + 759c: 6a e5 ldi r22, 0x5A ; 90 + 759e: 80 e0 ldi r24, 0x00 ; 0 + 75a0: 90 e0 ldi r25, 0x00 ; 0 + 75a2: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 75a6: 7c 01 movw r14, r24 + + The following is the equivalent functionality written in C. + + 75a8: 61 e0 ldi r22, 0x01 ; 1 + 75aa: ce 01 movw r24, r28 + 75ac: 03 96 adiw r24, 0x03 ; 3 + 75ae: 0e 94 42 0c call 0x1884 ; 0x1884 + 75b2: 88 23 and r24, r24 + 75b4: 09 f4 brne .+2 ; 0x75b8 + 75b6: 6d c0 rjmp .+218 ; 0x7692 + \code + uint16_t + crc_xmodem_update (uint16_t crc, uint8_t data) + 75b8: 8b 81 ldd r24, Y+3 ; 0x03 + 75ba: 81 11 cpse r24, r1 + 75bc: 6c c0 rjmp .+216 ; 0x7696 + { + int i; + + 75be: 60 e0 ldi r22, 0x00 ; 0 + 75c0: c7 01 movw r24, r14 + 75c2: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 75c6: 7c 01 movw r14, r24 + crc = crc ^ ((uint16_t)data << 8); + for (i=0; i<8; i++) + { + 75c8: 61 e0 ldi r22, 0x01 ; 1 + 75ca: ce 01 movw r24, r28 + 75cc: 03 96 adiw r24, 0x03 ; 3 + 75ce: 0e 94 42 0c call 0x1884 ; 0x1884 + 75d2: 88 23 and r24, r24 + 75d4: 09 f4 brne .+2 ; 0x75d8 + 75d6: 61 c0 rjmp .+194 ; 0x769a + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + 75d8: 8b 81 ldd r24, Y+3 ; 0x03 + 75da: 82 38 cpi r24, 0x82 ; 130 + 75dc: 09 f0 breq .+2 ; 0x75e0 + 75de: 5f c0 rjmp .+190 ; 0x769e + else + crc <<= 1; + 75e0: 62 e8 ldi r22, 0x82 ; 130 + 75e2: c7 01 movw r24, r14 + 75e4: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 75e8: 7c 01 movw r14, r24 + } + + return crc; + 75ea: 61 e0 ldi r22, 0x01 ; 1 + 75ec: ce 01 movw r24, r28 + 75ee: 03 96 adiw r24, 0x03 ; 3 + 75f0: 0e 94 42 0c call 0x1884 ; 0x1884 + 75f4: 88 23 and r24, r24 + 75f6: 09 f4 brne .+2 ; 0x75fa + 75f8: 54 c0 rjmp .+168 ; 0x76a2 + } + \endcode */ + 75fa: 6b 81 ldd r22, Y+3 ; 0x03 + 75fc: 69 30 cpi r22, 0x09 ; 9 + 75fe: 08 f0 brcs .+2 ; 0x7602 + 7600: 52 c0 rjmp .+164 ; 0x76a6 +} + +/** \ingroup util_crc + Optimized Dallas (now Maxim) iButton 8-bit CRC calculation. + + Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)
+ 7602: 0e 5f subi r16, 0xFE ; 254 + 7604: 1f 4f sbci r17, 0xFF ; 255 + return crc; + } + \endcode */ + +static __inline__ uint16_t +_crc_xmodem_update(uint16_t __crc, uint8_t __data) + 7606: c7 01 movw r24, r14 + 7608: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 760c: f8 2e mov r15, r24 + 760e: e9 2e mov r14, r25 +{ + 7610: 88 e0 ldi r24, 0x08 ; 8 + 7612: f8 01 movw r30, r16 + 7614: 11 92 st Z+, r1 + 7616: 8a 95 dec r24 + 7618: e9 f7 brne .-6 ; 0x7614 + uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + 761a: db 80 ldd r13, Y+3 ; 0x03 + uint8_t __tmp1; /* %1 */ + uint8_t __tmp2; /* %2 */ + 761c: 1b 82 std Y+3, r1 ; 0x03 + 761e: 8b 81 ldd r24, Y+3 ; 0x03 + 7620: 8d 15 cp r24, r13 + 7622: 98 f4 brcc .+38 ; 0x764a + /* %3 __data */ + + 7624: 65 e0 ldi r22, 0x05 ; 5 + 7626: c8 01 movw r24, r16 + 7628: 0e 94 42 0c call 0x1884 ; 0x1884 + 762c: 88 23 and r24, r24 + 762e: e9 f1 breq .+122 ; 0x76aa + __asm__ __volatile__ ( + "eor %B0,%3" "\n\t" /* crc.hi ^ data */ + 7630: f8 01 movw r30, r16 + 7632: 61 91 ld r22, Z+ + 7634: 8f 01 movw r16, r30 + 7636: 8f 2d mov r24, r15 + 7638: 9e 2d mov r25, r14 + 763a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 763e: f8 2e mov r15, r24 + 7640: e9 2e mov r14, r25 +static __inline__ uint16_t +_crc_xmodem_update(uint16_t __crc, uint8_t __data) +{ + uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + uint8_t __tmp1; /* %1 */ + uint8_t __tmp2; /* %2 */ + 7642: 8b 81 ldd r24, Y+3 ; 0x03 + 7644: 8f 5f subi r24, 0xFF ; 255 + 7646: 8b 83 std Y+3, r24 ; 0x03 + 7648: ea cf rjmp .-44 ; 0x761e + "mov __tmp_reg__,%B0" "\n\t" + "swap __tmp_reg__" "\n\t" /* swap(crc.hi ^ data) */ + + /* Calculate the ret.lo of the CRC. */ + "mov %1,__tmp_reg__" "\n\t" + "andi %1,0x0f" "\n\t" + 764a: 61 e0 ldi r22, 0x01 ; 1 + 764c: ce 01 movw r24, r28 + 764e: 02 96 adiw r24, 0x02 ; 2 + 7650: 0e 94 42 0c call 0x1884 ; 0x1884 + 7654: 81 30 cpi r24, 0x01 ; 1 + 7656: 59 f5 brne .+86 ; 0x76ae + "eor %1,%B0" "\n\t" + "mov %2,%B0" "\n\t" + "eor %2,__tmp_reg__" "\n\t" + 7658: 20 e0 ldi r18, 0x00 ; 0 + 765a: 41 e0 ldi r20, 0x01 ; 1 + 765c: 50 e0 ldi r21, 0x00 ; 0 + 765e: be 01 movw r22, r28 + 7660: 6f 5f subi r22, 0xFF ; 255 + 7662: 7f 4f sbci r23, 0xFF ; 255 + 7664: 80 91 9c 0e lds r24, 0x0E9C + 7668: 90 91 9d 0e lds r25, 0x0E9D + 766c: 0e 94 5e 47 call 0x8ebc ; 0x8ebc + 7670: 81 30 cpi r24, 0x01 ; 1 + 7672: f9 f4 brne .+62 ; 0x76b2 + "lsl %2" "\n\t" + "andi %2,0xe0" "\n\t" + "eor %1,%2" "\n\t" /* __tmp1 is now ret.lo. */ + 7674: 8a 81 ldd r24, Y+2 ; 0x02 + 7676: 8e 11 cpse r24, r14 + 7678: 1e c0 rjmp .+60 ; 0x76b6 + + /* Calculate the ret.hi of the CRC. */ + 767a: 91 e0 ldi r25, 0x01 ; 1 + 767c: 89 81 ldd r24, Y+1 ; 0x01 + 767e: 8f 11 cpse r24, r15 + 7680: 01 c0 rjmp .+2 ; 0x7684 + 7682: 90 e0 ldi r25, 0x00 ; 0 + 7684: 89 2f mov r24, r25 + 7686: 81 95 neg r24 + 7688: 17 c0 rjmp .+46 ; 0x76b8 + return __ret; +} + +/** \ingroup util_crc + Optimized CRC-XMODEM calculation. + + 768a: 88 e0 ldi r24, 0x08 ; 8 + 768c: 15 c0 rjmp .+42 ; 0x76b8 + Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ Initial value: 0x0 + + 768e: 82 e0 ldi r24, 0x02 ; 2 + 7690: 13 c0 rjmp .+38 ; 0x76b8 + This is the CRC used by the Xmodem-CRC protocol. + + The following is the equivalent functionality written in C. + + \code + 7692: 83 e0 ldi r24, 0x03 ; 3 + 7694: 11 c0 rjmp .+34 ; 0x76b8 + uint16_t + crc_xmodem_update (uint16_t crc, uint8_t data) + { + 7696: 84 e0 ldi r24, 0x04 ; 4 + 7698: 0f c0 rjmp .+30 ; 0x76b8 + int i; + + crc = crc ^ ((uint16_t)data << 8); + for (i=0; i<8; i++) + { + if (crc & 0x8000) + 769a: 85 e0 ldi r24, 0x05 ; 5 + 769c: 0d c0 rjmp .+26 ; 0x76b8 + crc = (crc << 1) ^ 0x1021; + else + 769e: 86 e0 ldi r24, 0x06 ; 6 + 76a0: 0b c0 rjmp .+22 ; 0x76b8 + crc <<= 1; + } + + return crc; + } + 76a2: 87 e0 ldi r24, 0x07 ; 7 + 76a4: 09 c0 rjmp .+18 ; 0x76b8 + \endcode */ + + 76a6: 81 e0 ldi r24, 0x01 ; 1 + 76a8: 07 c0 rjmp .+14 ; 0x76b8 + uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + uint8_t __tmp1; /* %1 */ + uint8_t __tmp2; /* %2 */ + /* %3 __data */ + + __asm__ __volatile__ ( + 76aa: 84 e1 ldi r24, 0x14 ; 20 + 76ac: 05 c0 rjmp .+10 ; 0x76b8 + "swap __tmp_reg__" "\n\t" /* swap(crc.hi ^ data) */ + + /* Calculate the ret.lo of the CRC. */ + "mov %1,__tmp_reg__" "\n\t" + "andi %1,0x0f" "\n\t" + "eor %1,%B0" "\n\t" + 76ae: 85 e1 ldi r24, 0x15 ; 21 + 76b0: 03 c0 rjmp .+6 ; 0x76b8 + "mov %2,%B0" "\n\t" + "eor %2,__tmp_reg__" "\n\t" + "lsl %2" "\n\t" + 76b2: 86 e1 ldi r24, 0x16 ; 22 + 76b4: 01 c0 rjmp .+2 ; 0x76b8 + "andi %2,0xe0" "\n\t" + "eor %1,%2" "\n\t" /* __tmp1 is now ret.lo. */ + + 76b6: 8e ef ldi r24, 0xFE ; 254 + +/** \ingroup util_crc + Optimized Dallas (now Maxim) iButton 8-bit CRC calculation. + + Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)
+ Initial value: 0x0 + 76b8: 8c 83 std Y+4, r24 ; 0x04 + 76ba: 0e 94 ca 0c call 0x1994 ; 0x1994 + 76be: 8c 81 ldd r24, Y+4 ; 0x04 + + See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27 + 76c0: 0f 90 pop r0 + 76c2: 0f 90 pop r0 + 76c4: 0f 90 pop r0 + 76c6: 0f 90 pop r0 + 76c8: df 91 pop r29 + 76ca: cf 91 pop r28 + 76cc: 1f 91 pop r17 + 76ce: 0f 91 pop r16 + 76d0: ff 90 pop r15 + 76d2: ef 90 pop r14 + 76d4: df 90 pop r13 + 76d6: cf 90 pop r12 + 76d8: 08 95 ret + +000076da : + + The following is the equivalent functionality written in C. + + \code + 76da: 7f 92 push r7 + 76dc: 8f 92 push r8 + 76de: 9f 92 push r9 + 76e0: af 92 push r10 + 76e2: bf 92 push r11 + 76e4: cf 92 push r12 + 76e6: df 92 push r13 + 76e8: ef 92 push r14 + 76ea: ff 92 push r15 + 76ec: 0f 93 push r16 + 76ee: 1f 93 push r17 + 76f0: cf 93 push r28 + 76f2: df 93 push r29 + 76f4: 00 d0 rcall .+0 ; 0x76f6 + 76f6: 1f 92 push r1 + 76f8: cd b7 in r28, 0x3d ; 61 + 76fa: de b7 in r29, 0x3e ; 62 + 76fc: 6c 01 movw r12, r24 + 76fe: e6 2e mov r14, r22 + 7700: 8a 01 movw r16, r20 + _crc_ibutton_update(uint8_t crc, uint8_t data) + { + uint8_t i; + + crc = crc ^ data; + for (i = 0; i < 8; i++) + 7702: 0e 94 bf 0c call 0x197e ; 0x197e + { + if (crc & 0x01) + crc = (crc >> 1) ^ 0x8C; + 7706: 6a e5 ldi r22, 0x5A ; 90 + 7708: 80 e0 ldi r24, 0x00 ; 0 + 770a: 90 e0 ldi r25, 0x00 ; 0 + 770c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7710: 5c 01 movw r10, r24 + 7712: 8a e5 ldi r24, 0x5A ; 90 + 7714: 0e 94 2b 0c call 0x1856 ; 0x1856 + else + 7718: 6e 2d mov r22, r14 + 771a: c5 01 movw r24, r10 + 771c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7720: 5c 01 movw r10, r24 + 7722: 8e 2d mov r24, r14 + 7724: 0e 94 2b 0c call 0x1856 ; 0x1856 + crc >>= 1; + 7728: 61 e8 ldi r22, 0x81 ; 129 + 772a: c5 01 movw r24, r10 + 772c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7730: 5c 01 movw r10, r24 + 7732: 81 e8 ldi r24, 0x81 ; 129 + 7734: 0e 94 2b 0c call 0x1856 ; 0x1856 + } + 7738: 61 e0 ldi r22, 0x01 ; 1 + 773a: c5 01 movw r24, r10 + 773c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7740: 5c 01 movw r10, r24 + 7742: 81 e0 ldi r24, 0x01 ; 1 + 7744: 0e 94 2b 0c call 0x1856 ; 0x1856 + + 7748: 6e 2d mov r22, r14 + 774a: c5 01 movw r24, r10 + 774c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7750: f8 2e mov r15, r24 + 7752: 8e 2d mov r24, r14 + 7754: 9b 83 std Y+3, r25 ; 0x03 + 7756: 0e 94 2b 0c call 0x1856 ; 0x1856 + return crc; + 775a: 9b 81 ldd r25, Y+3 ; 0x03 + 775c: 89 2f mov r24, r25 + 775e: 0e 94 2b 0c call 0x1856 ; 0x1856 + } + 7762: 8f 2d mov r24, r15 + 7764: 0e 94 2b 0c call 0x1856 ; 0x1856 + \endcode +*/ + +static __inline__ uint8_t +_crc_ibutton_update(uint8_t __crc, uint8_t __data) + 7768: 64 e6 ldi r22, 0x64 ; 100 + 776a: ce 01 movw r24, r28 + 776c: 02 96 adiw r24, 0x02 ; 2 + 776e: 0e 94 42 0c call 0x1884 ; 0x1884 + 7772: 81 30 cpi r24, 0x01 ; 1 + 7774: 81 f0 breq .+32 ; 0x7796 +{ + uint8_t __i, __pattern; + __asm__ __volatile__ ( + 7776: 01 15 cp r16, r1 + 7778: 11 05 cpc r17, r1 + 777a: 79 f0 breq .+30 ; 0x779a + " eor %0, %4" "\n\t" + 777c: 88 eb ldi r24, 0xB8 ; 184 + 777e: 93 e1 ldi r25, 0x13 ; 19 + 7780: 9f 93 push r25 + 7782: 8f 93 push r24 + 7784: 1f 93 push r17 + 7786: 0f 93 push r16 + 7788: 0e 94 1a 50 call 0xa034 ; 0xa034 + 778c: 0f 90 pop r0 + 778e: 0f 90 pop r0 + 7790: 0f 90 pop r0 + 7792: 0f 90 pop r0 + 7794: 02 c0 rjmp .+4 ; 0x779a + + The following is the equivalent functionality written in C. + + \code + uint8_t + _crc_ibutton_update(uint8_t crc, uint8_t data) + 7796: f1 2c mov r15, r1 + 7798: 02 c0 rjmp .+4 ; 0x779e +*/ + +static __inline__ uint8_t +_crc_ibutton_update(uint8_t __crc, uint8_t __data) +{ + uint8_t __i, __pattern; + 779a: ff 24 eor r15, r15 + 779c: f3 94 inc r15 + __asm__ __volatile__ ( + " eor %0, %4" "\n\t" + " ldi %1, 8" "\n\t" + " ldi %2, 0x8C" "\n\t" + 779e: 6a 81 ldd r22, Y+2 ; 0x02 + 77a0: 80 e0 ldi r24, 0x00 ; 0 + 77a2: 90 e0 ldi r25, 0x00 ; 0 + 77a4: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 77a8: 5c 01 movw r10, r24 + 77aa: 9a 81 ldd r25, Y+2 ; 0x02 + "1: lsr %0" "\n\t" + " brcc 2f" "\n\t" + 77ac: f1 10 cpse r15, r1 + 77ae: 13 c0 rjmp .+38 ; 0x77d6 + 77b0: 93 34 cpi r25, 0x43 ; 67 + 77b2: 89 f4 brne .+34 ; 0x77d6 + " eor %0, %2" "\n\t" + "2: dec %1" "\n\t" + " brne 1b" "\n\t" + 77b4: 01 15 cp r16, r1 + 77b6: 11 05 cpc r17, r1 + 77b8: 09 f4 brne .+2 ; 0x77bc + 77ba: c6 c0 rjmp .+396 ; 0x7948 + : "=r" (__crc), "=d" (__i), "=d" (__pattern) + 77bc: 8b e8 ldi r24, 0x8B ; 139 + 77be: 93 e1 ldi r25, 0x13 ; 19 + 77c0: 9f 93 push r25 + 77c2: 8f 93 push r24 + 77c4: 1f 93 push r17 + 77c6: 0f 93 push r16 + 77c8: 0e 94 1a 50 call 0xa034 ; 0xa034 + 77cc: 0f 90 pop r0 + 77ce: 0f 90 pop r0 + 77d0: 0f 90 pop r0 + 77d2: 0f 90 pop r0 + 77d4: b9 c0 rjmp .+370 ; 0x7948 + : "0" (__crc), "r" (__data)); + return __crc; +} + + 77d6: 9a 35 cpi r25, 0x5A ; 90 + 77d8: 09 f0 breq .+2 ; 0x77dc + 77da: 71 c0 rjmp .+226 ; 0x78be +/** \ingroup util_crc + Optimized CRC-8-CCITT calculation. + + Polynomial: x^8 + x^2 + x + 1 (0xE0)
+ + For use with simple CRC-8
+ 77dc: f1 10 cpse r15, r1 + 77de: 6f c0 rjmp .+222 ; 0x78be + Initial value: 0x0 + + 77e0: 61 e0 ldi r22, 0x01 ; 1 + 77e2: ce 01 movw r24, r28 + 77e4: 02 96 adiw r24, 0x02 ; 2 + 77e6: 0e 94 42 0c call 0x1884 ; 0x1884 + 77ea: 81 30 cpi r24, 0x01 ; 1 + 77ec: 31 f4 brne .+12 ; 0x77fa + For use with CRC-8-ROHC
+ Initial value: 0xff
+ Reference: http://tools.ietf.org/html/rfc3095#section-5.9.1 + + 77ee: 8a 81 ldd r24, Y+2 ; 0x02 + 77f0: 88 23 and r24, r24 + 77f2: 29 f0 breq .+10 ; 0x77fe + For use with CRC-8-ATM/ITU
+ 77f4: b4 e0 ldi r27, 0x04 ; 4 + 77f6: fb 2e mov r15, r27 + 77f8: 02 c0 rjmp .+4 ; 0x77fe + Polynomial: x^8 + x^2 + x + 1 (0xE0)
+ + For use with simple CRC-8
+ Initial value: 0x0 + + For use with CRC-8-ROHC
+ 77fa: a3 e0 ldi r26, 0x03 ; 3 + 77fc: fa 2e mov r15, r26 + Initial value: 0xff
+ Reference: http://tools.ietf.org/html/rfc3095#section-5.9.1 + + For use with CRC-8-ATM/ITU
+ Initial value: 0xff
+ Final XOR value: 0x55
+ 77fe: 6a 81 ldd r22, Y+2 ; 0x02 + 7800: c5 01 movw r24, r10 + 7802: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7806: 5c 01 movw r10, r24 + Reference: http://www.itu.int/rec/T-REC-I.432.1-199902-I/en + + The C equivalent has been originally written by Dave Hylands. + Assembly code is based on _crc_ibutton_update optimization. + 7808: f1 10 cpse r15, r1 + 780a: 59 c0 rjmp .+178 ; 0x78be + + The following is the equivalent functionality written in C. + 780c: 61 e0 ldi r22, 0x01 ; 1 + 780e: ce 01 movw r24, r28 + 7810: 02 96 adiw r24, 0x02 ; 2 + 7812: 0e 94 42 0c call 0x1884 ; 0x1884 + 7816: 81 30 cpi r24, 0x01 ; 1 + 7818: 31 f4 brne .+12 ; 0x7826 + + \code + uint8_t + _crc8_ccitt_update (uint8_t inCrc, uint8_t inData) + 781a: 8a 81 ldd r24, Y+2 ; 0x02 + 781c: 81 38 cpi r24, 0x81 ; 129 + 781e: 29 f0 breq .+10 ; 0x782a + { + 7820: f6 e0 ldi r31, 0x06 ; 6 + 7822: ff 2e mov r15, r31 + 7824: 02 c0 rjmp .+4 ; 0x782a + + The C equivalent has been originally written by Dave Hylands. + Assembly code is based on _crc_ibutton_update optimization. + + The following is the equivalent functionality written in C. + + 7826: e5 e0 ldi r30, 0x05 ; 5 + 7828: fe 2e mov r15, r30 + \code + uint8_t + _crc8_ccitt_update (uint8_t inCrc, uint8_t inData) + { + uint8_t i; + uint8_t data; + 782a: 6a 81 ldd r22, Y+2 ; 0x02 + 782c: c5 01 movw r24, r10 + 782e: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7832: 5c 01 movw r10, r24 + + data = inCrc ^ inData; + + for ( i = 0; i < 8; i++ ) + 7834: f1 10 cpse r15, r1 + 7836: 43 c0 rjmp .+134 ; 0x78be + { + if (( data & 0x80 ) != 0 ) + 7838: 61 e0 ldi r22, 0x01 ; 1 + 783a: ce 01 movw r24, r28 + 783c: 02 96 adiw r24, 0x02 ; 2 + 783e: 0e 94 42 0c call 0x1884 ; 0x1884 + 7842: 81 30 cpi r24, 0x01 ; 1 + 7844: 31 f4 brne .+12 ; 0x7852 + { + data <<= 1; + data ^= 0x07; + } + 7846: 8a 81 ldd r24, Y+2 ; 0x02 + 7848: 81 30 cpi r24, 0x01 ; 1 + 784a: 29 f0 breq .+10 ; 0x7856 + else + 784c: 78 e0 ldi r23, 0x08 ; 8 + 784e: f7 2e mov r15, r23 + 7850: 02 c0 rjmp .+4 ; 0x7856 + data = inCrc ^ inData; + + for ( i = 0; i < 8; i++ ) + { + if (( data & 0x80 ) != 0 ) + { + 7852: 67 e0 ldi r22, 0x07 ; 7 + 7854: f6 2e mov r15, r22 + data <<= 1; + data ^= 0x07; + } + else + { + data <<= 1; + 7856: 6a 81 ldd r22, Y+2 ; 0x02 + 7858: c5 01 movw r24, r10 + 785a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 785e: 5c 01 movw r10, r24 + } + } + return data; + } + 7860: f1 10 cpse r15, r1 + 7862: 2d c0 rjmp .+90 ; 0x78be + \endcode +*/ + 7864: 61 e0 ldi r22, 0x01 ; 1 + 7866: ce 01 movw r24, r28 + 7868: 02 96 adiw r24, 0x02 ; 2 + 786a: 0e 94 42 0c call 0x1884 ; 0x1884 + 786e: 81 30 cpi r24, 0x01 ; 1 + 7870: 31 f4 brne .+12 ; 0x787e + +static __inline__ uint8_t +_crc8_ccitt_update(uint8_t __crc, uint8_t __data) +{ + 7872: 8a 81 ldd r24, Y+2 ; 0x02 + 7874: 8e 15 cp r24, r14 + 7876: 29 f0 breq .+10 ; 0x7882 + uint8_t __i, __pattern; + 7878: 5a e0 ldi r21, 0x0A ; 10 + 787a: f5 2e mov r15, r21 + 787c: 02 c0 rjmp .+4 ; 0x7882 + } + return data; + } + \endcode +*/ + + 787e: 49 e0 ldi r20, 0x09 ; 9 + 7880: f4 2e mov r15, r20 +static __inline__ uint8_t +_crc8_ccitt_update(uint8_t __crc, uint8_t __data) +{ + uint8_t __i, __pattern; + __asm__ __volatile__ ( + " eor %0, %4" "\n\t" + 7882: 6a 81 ldd r22, Y+2 ; 0x02 + 7884: c5 01 movw r24, r10 + 7886: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 788a: b8 2e mov r11, r24 + 788c: a9 2e mov r10, r25 + " ldi %1, 8" "\n\t" + " ldi %2, 0x07" "\n\t" + "1: lsl %0" "\n\t" + " brcc 2f" "\n\t" + 788e: f1 10 cpse r15, r1 + 7890: 16 c0 rjmp .+44 ; 0x78be + " eor %0, %2" "\n\t" + "2: dec %1" "\n\t" + 7892: 61 e0 ldi r22, 0x01 ; 1 + 7894: ce 01 movw r24, r28 + 7896: 01 96 adiw r24, 0x01 ; 1 + 7898: 0e 94 42 0c call 0x1884 ; 0x1884 + 789c: 81 30 cpi r24, 0x01 ; 1 + 789e: 79 f4 brne .+30 ; 0x78be + " brne 1b" "\n\t" + : "=r" (__crc), "=d" (__i), "=d" (__pattern) + : "0" (__crc), "r" (__data)); + return __crc; + 78a0: 89 81 ldd r24, Y+1 ; 0x01 + 78a2: 8a 11 cpse r24, r10 + 78a4: 0c c0 rjmp .+24 ; 0x78be +#endif /* _UTIL_CRC16_H_ */ + 78a6: 61 e0 ldi r22, 0x01 ; 1 + 78a8: ce 01 movw r24, r28 + 78aa: 01 96 adiw r24, 0x01 ; 1 + 78ac: 0e 94 42 0c call 0x1884 ; 0x1884 + 78b0: f8 2e mov r15, r24 + 78b2: a1 e0 ldi r26, 0x01 ; 1 + 78b4: 8a 13 cpse r24, r26 + 78b6: 03 c0 rjmp .+6 ; 0x78be + 78b8: 89 81 ldd r24, Y+1 ; 0x01 + 78ba: 8b 15 cp r24, r11 + 78bc: 39 f0 breq .+14 ; 0x78cc + 78be: 0e 94 ca 0c call 0x1994 ; 0x1994 + 78c2: 0e 94 a2 0c call 0x1944 ; 0x1944 + 78c6: ff 24 eor r15, r15 + 78c8: f3 94 inc r15 + 78ca: 12 c1 rjmp .+548 ; 0x7af0 + 78cc: 84 e6 ldi r24, 0x64 ; 100 + 78ce: 90 e0 ldi r25, 0x00 ; 0 + 78d0: 0e 94 81 43 call 0x8702 ; 0x8702 + 78d4: 6a e5 ldi r22, 0x5A ; 90 + 78d6: 80 e0 ldi r24, 0x00 ; 0 + 78d8: 90 e0 ldi r25, 0x00 ; 0 + 78da: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 78de: 5c 01 movw r10, r24 + 78e0: 8a e5 ldi r24, 0x5A ; 90 + 78e2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 78e6: 6e 2d mov r22, r14 + 78e8: c5 01 movw r24, r10 + 78ea: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 78ee: 5c 01 movw r10, r24 + 78f0: 8e 2d mov r24, r14 + 78f2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 78f6: 61 e8 ldi r22, 0x81 ; 129 + 78f8: c5 01 movw r24, r10 + 78fa: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 78fe: 5c 01 movw r10, r24 + 7900: 81 e8 ldi r24, 0x81 ; 129 + 7902: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7906: 61 e0 ldi r22, 0x01 ; 1 + 7908: c5 01 movw r24, r10 + 790a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 790e: 5c 01 movw r10, r24 + 7910: 81 e0 ldi r24, 0x01 ; 1 + 7912: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7916: 6e 2d mov r22, r14 + 7918: c5 01 movw r24, r10 + 791a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 791e: b8 2e mov r11, r24 + 7920: 8e 2d mov r24, r14 + 7922: 9b 83 std Y+3, r25 ; 0x03 + 7924: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7928: 9b 81 ldd r25, Y+3 ; 0x03 + 792a: 89 2f mov r24, r25 + 792c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7930: 8b 2d mov r24, r11 + 7932: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7936: 66 e9 ldi r22, 0x96 ; 150 + 7938: ce 01 movw r24, r28 + 793a: 02 96 adiw r24, 0x02 ; 2 + 793c: 0e 94 42 0c call 0x1884 ; 0x1884 + 7940: 8a 81 ldd r24, Y+2 ; 0x02 + 7942: 83 34 cpi r24, 0x43 ; 67 + 7944: 09 f0 breq .+2 ; 0x7948 + 7946: bd c0 rjmp .+378 ; 0x7ac2 + 7948: d6 01 movw r26, r12 + 794a: 14 96 adiw r26, 0x04 ; 4 + 794c: ed 91 ld r30, X+ + 794e: fc 91 ld r31, X + 7950: 15 97 sbiw r26, 0x05 ; 5 + 7952: e2 80 ldd r14, Z+2 ; 0x02 + 7954: ee 0c add r14, r14 + 7956: 81 81 ldd r24, Z+1 ; 0x01 + 7958: 80 38 cpi r24, 0x80 ; 128 + 795a: 09 f4 brne .+2 ; 0x795e + 795c: e3 94 inc r14 + 795e: 81 e0 ldi r24, 0x01 ; 1 + 7960: 89 83 std Y+1, r24 ; 0x01 + 7962: b1 2c mov r11, r1 + 7964: f1 2c mov r15, r1 + 7966: 36 e6 ldi r19, 0x66 ; 102 + 7968: 83 2e mov r8, r19 + 796a: 31 e0 ldi r19, 0x01 ; 1 + 796c: 93 2e mov r9, r19 + 796e: 89 81 ldd r24, Y+1 ; 0x01 + 7970: e8 16 cp r14, r24 + 7972: 08 f4 brcc .+2 ; 0x7976 + 7974: 8a c0 rjmp .+276 ; 0x7a8a + 7976: 81 e0 ldi r24, 0x01 ; 1 + 7978: 0e 94 2b 0c call 0x1856 ; 0x1856 + 797c: 89 81 ldd r24, Y+1 ; 0x01 + 797e: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7982: 89 81 ldd r24, Y+1 ; 0x01 + 7984: 80 95 com r24 + 7986: 8a 83 std Y+2, r24 ; 0x02 + 7988: 0e 94 2b 0c call 0x1856 ; 0x1856 + 798c: f1 2c mov r15, r1 + 798e: a1 2c mov r10, r1 + 7990: 71 2c mov r7, r1 + 7992: be 01 movw r22, r28 + 7994: 6e 5f subi r22, 0xFE ; 254 + 7996: 7f 4f sbci r23, 0xFF ; 255 + 7998: c6 01 movw r24, r12 + 799a: 0e 94 74 1c call 0x38e8 ; 0x38e8 + 799e: 81 11 cpse r24, r1 + 79a0: 1a 82 std Y+2, r1 ; 0x02 + 79a2: 6a 81 ldd r22, Y+2 ; 0x02 + 79a4: 8a 2d mov r24, r10 + 79a6: 97 2d mov r25, r7 + 79a8: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 79ac: a8 2e mov r10, r24 + 79ae: 79 2e mov r7, r25 + 79b0: 8a 81 ldd r24, Y+2 ; 0x02 + 79b2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 79b6: f3 94 inc r15 + 79b8: b0 e8 ldi r27, 0x80 ; 128 + 79ba: fb 12 cpse r15, r27 + 79bc: ea cf rjmp .-44 ; 0x7992 + 79be: 87 2d mov r24, r7 + 79c0: 0e 94 2b 0c call 0x1856 ; 0x1856 + 79c4: 8a 2d mov r24, r10 + 79c6: 0e 94 2b 0c call 0x1856 ; 0x1856 + 79ca: 64 e6 ldi r22, 0x64 ; 100 + 79cc: ce 01 movw r24, r28 + 79ce: 02 96 adiw r24, 0x02 ; 2 + 79d0: 0e 94 42 0c call 0x1884 ; 0x1884 + 79d4: 81 30 cpi r24, 0x01 ; 1 + 79d6: 59 f0 breq .+22 ; 0x79ee + 79d8: 01 15 cp r16, r1 + 79da: 11 05 cpc r17, r1 + 79dc: 29 f0 breq .+10 ; 0x79e8 + 79de: b8 01 movw r22, r16 + 79e0: 83 e2 ldi r24, 0x23 ; 35 + 79e2: 90 e0 ldi r25, 0x00 ; 0 + 79e4: 0e 94 37 50 call 0xa06e ; 0xa06e + 79e8: 1a 82 std Y+2, r1 ; 0x02 + 79ea: 2a ef ldi r18, 0xFA ; 250 + 79ec: f2 2e mov r15, r18 + 79ee: 0e 94 a2 0c call 0x1944 ; 0x1944 + 79f2: 8a 81 ldd r24, Y+2 ; 0x02 + 79f4: 86 30 cpi r24, 0x06 ; 6 + 79f6: d9 f4 brne .+54 ; 0x7a2e + 79f8: 89 81 ldd r24, Y+1 ; 0x01 + 79fa: 8f 5f subi r24, 0xFF ; 255 + 79fc: 89 83 std Y+1, r24 ; 0x01 + 79fe: 01 15 cp r16, r1 + 7a00: 11 05 cpc r17, r1 + 7a02: 91 f0 breq .+36 ; 0x7a28 + 7a04: b8 01 movw r22, r16 + 7a06: 8e e2 ldi r24, 0x2E ; 46 + 7a08: 90 e0 ldi r25, 0x00 ; 0 + 7a0a: 0e 94 37 50 call 0xa06e ; 0xa06e + 7a0e: 89 81 ldd r24, Y+1 ; 0x01 + 7a10: 8f 70 andi r24, 0x0F ; 15 + 7a12: 51 f4 brne .+20 ; 0x7a28 + 7a14: b8 01 movw r22, r16 + 7a16: 8d e0 ldi r24, 0x0D ; 13 + 7a18: 90 e0 ldi r25, 0x00 ; 0 + 7a1a: 0e 94 37 50 call 0xa06e ; 0xa06e + 7a1e: b8 01 movw r22, r16 + 7a20: 8a e0 ldi r24, 0x0A ; 10 + 7a22: 90 e0 ldi r25, 0x00 ; 0 + 7a24: 0e 94 37 50 call 0xa06e ; 0xa06e + 7a28: b1 2c mov r11, r1 + 7a2a: f1 2c mov r15, r1 + 7a2c: a0 cf rjmp .-192 ; 0x796e + 7a2e: 88 31 cpi r24, 0x18 ; 24 + 7a30: 51 f4 brne .+20 ; 0x7a46 + 7a32: 01 15 cp r16, r1 + 7a34: 11 05 cpc r17, r1 + 7a36: 09 f4 brne .+2 ; 0x7a3a + 7a38: 58 c0 rjmp .+176 ; 0x7aea + 7a3a: b8 01 movw r22, r16 + 7a3c: 83 e4 ldi r24, 0x43 ; 67 + 7a3e: 90 e0 ldi r25, 0x00 ; 0 + 7a40: 0e 94 37 50 call 0xa06e ; 0xa06e + 7a44: 52 c0 rjmp .+164 ; 0x7aea + 7a46: 01 15 cp r16, r1 + 7a48: 11 05 cpc r17, r1 + 7a4a: c1 f0 breq .+48 ; 0x7a7c + 7a4c: 85 31 cpi r24, 0x15 ; 21 + 7a4e: 29 f4 brne .+10 ; 0x7a5a + 7a50: b8 01 movw r22, r16 + 7a52: 8e e4 ldi r24, 0x4E ; 78 + 7a54: 90 e0 ldi r25, 0x00 ; 0 + 7a56: 0e 94 37 50 call 0xa06e ; 0xa06e + 7a5a: 8a 81 ldd r24, Y+2 ; 0x02 + 7a5c: 88 23 and r24, r24 + 7a5e: 71 f0 breq .+28 ; 0x7a7c + 7a60: 1f 92 push r1 + 7a62: 8f 93 push r24 + 7a64: 9f 92 push r9 + 7a66: 8f 92 push r8 + 7a68: 1f 93 push r17 + 7a6a: 0f 93 push r16 + 7a6c: 0e 94 0a 50 call 0xa014 ; 0xa014 + 7a70: 0f 90 pop r0 + 7a72: 0f 90 pop r0 + 7a74: 0f 90 pop r0 + 7a76: 0f 90 pop r0 + 7a78: 0f 90 pop r0 + 7a7a: 0f 90 pop r0 + 7a7c: b3 94 inc r11 + 7a7e: 83 e0 ldi r24, 0x03 ; 3 + 7a80: b8 12 cpse r11, r24 + 7a82: 75 cf rjmp .-278 ; 0x796e + 7a84: 88 ef ldi r24, 0xF8 ; 248 + 7a86: f8 2e mov r15, r24 + 7a88: 17 c0 rjmp .+46 ; 0x7ab8 + 7a8a: f1 10 cpse r15, r1 + 7a8c: 15 c0 rjmp .+42 ; 0x7ab8 + 7a8e: 84 e0 ldi r24, 0x04 ; 4 + 7a90: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7a94: 69 e1 ldi r22, 0x19 ; 25 + 7a96: ce 01 movw r24, r28 + 7a98: 02 96 adiw r24, 0x02 ; 2 + 7a9a: 0e 94 42 0c call 0x1884 ; 0x1884 + 7a9e: 81 30 cpi r24, 0x01 ; 1 + 7aa0: 59 f4 brne .+22 ; 0x7ab8 + 7aa2: 8a 81 ldd r24, Y+2 ; 0x02 + 7aa4: 86 30 cpi r24, 0x06 ; 6 + 7aa6: 41 f4 brne .+16 ; 0x7ab8 + 7aa8: 84 e0 ldi r24, 0x04 ; 4 + 7aaa: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7aae: 69 e1 ldi r22, 0x19 ; 25 + 7ab0: ce 01 movw r24, r28 + 7ab2: 02 96 adiw r24, 0x02 ; 2 + 7ab4: 0e 94 42 0c call 0x1884 ; 0x1884 + 7ab8: 0e 94 a2 0c call 0x1944 ; 0x1944 + 7abc: 0e 94 ca 0c call 0x1994 ; 0x1994 + 7ac0: 17 c0 rjmp .+46 ; 0x7af0 + 7ac2: 0e 94 ca 0c call 0x1994 ; 0x1994 + 7ac6: 0e 94 a2 0c call 0x1944 ; 0x1944 + 7aca: 01 15 cp r16, r1 + 7acc: 11 05 cpc r17, r1 + 7ace: 81 f0 breq .+32 ; 0x7af0 + 7ad0: 81 e6 ldi r24, 0x61 ; 97 + 7ad2: 93 e1 ldi r25, 0x13 ; 19 + 7ad4: 9f 93 push r25 + 7ad6: 8f 93 push r24 + 7ad8: 1f 93 push r17 + 7ada: 0f 93 push r16 + 7adc: 0e 94 1a 50 call 0xa034 ; 0xa034 + 7ae0: 0f 90 pop r0 + 7ae2: 0f 90 pop r0 + 7ae4: 0f 90 pop r0 + 7ae6: 0f 90 pop r0 + 7ae8: 03 c0 rjmp .+6 ; 0x7af0 + 7aea: 99 ef ldi r25, 0xF9 ; 249 + 7aec: f9 2e mov r15, r25 + 7aee: e4 cf rjmp .-56 ; 0x7ab8 + 7af0: 8f 2d mov r24, r15 + 7af2: 0f 90 pop r0 + 7af4: 0f 90 pop r0 + 7af6: 0f 90 pop r0 + 7af8: df 91 pop r29 + 7afa: cf 91 pop r28 + 7afc: 1f 91 pop r17 + 7afe: 0f 91 pop r16 + 7b00: ff 90 pop r15 + 7b02: ef 90 pop r14 + 7b04: df 90 pop r13 + 7b06: cf 90 pop r12 + 7b08: bf 90 pop r11 + 7b0a: af 90 pop r10 + 7b0c: 9f 90 pop r9 + 7b0e: 8f 90 pop r8 + 7b10: 7f 90 pop r7 + 7b12: 08 95 ret + +00007b14 : + 7b14: df 92 push r13 + 7b16: ef 92 push r14 + 7b18: ff 92 push r15 + 7b1a: 0f 93 push r16 + 7b1c: 1f 93 push r17 + 7b1e: cf 93 push r28 + 7b20: df 93 push r29 + 7b22: 1f 92 push r1 + 7b24: cd b7 in r28, 0x3d ; 61 + 7b26: de b7 in r29, 0x3e ; 62 + 7b28: e8 2e mov r14, r24 + 7b2a: f6 2e mov r15, r22 + 7b2c: d4 2e mov r13, r20 + 7b2e: 6a e5 ldi r22, 0x5A ; 90 + 7b30: 80 e0 ldi r24, 0x00 ; 0 + 7b32: 90 e0 ldi r25, 0x00 ; 0 + 7b34: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b38: 8c 01 movw r16, r24 + 7b3a: 8a e5 ldi r24, 0x5A ; 90 + 7b3c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b40: 6e 2d mov r22, r14 + 7b42: c8 01 movw r24, r16 + 7b44: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b48: 8c 01 movw r16, r24 + 7b4a: 8e 2d mov r24, r14 + 7b4c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b50: f1 10 cpse r15, r1 + 7b52: 07 c0 rjmp .+14 ; 0x7b62 + 7b54: 60 e2 ldi r22, 0x20 ; 32 + 7b56: c8 01 movw r24, r16 + 7b58: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b5c: 8c 01 movw r16, r24 + 7b5e: 80 e2 ldi r24, 0x20 ; 32 + 7b60: 06 c0 rjmp .+12 ; 0x7b6e + 7b62: 61 e2 ldi r22, 0x21 ; 33 + 7b64: c8 01 movw r24, r16 + 7b66: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b6a: 8c 01 movw r16, r24 + 7b6c: 81 e2 ldi r24, 0x21 ; 33 + 7b6e: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b72: 61 e0 ldi r22, 0x01 ; 1 + 7b74: c8 01 movw r24, r16 + 7b76: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b7a: 8c 01 movw r16, r24 + 7b7c: 81 e0 ldi r24, 0x01 ; 1 + 7b7e: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b82: 6d 2d mov r22, r13 + 7b84: c8 01 movw r24, r16 + 7b86: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7b8a: 18 2f mov r17, r24 + 7b8c: 8d 2d mov r24, r13 + 7b8e: 99 83 std Y+1, r25 ; 0x01 + 7b90: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b94: 99 81 ldd r25, Y+1 ; 0x01 + 7b96: 89 2f mov r24, r25 + 7b98: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7b9c: 81 2f mov r24, r17 + 7b9e: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7ba2: 80 e0 ldi r24, 0x00 ; 0 + 7ba4: 0f 90 pop r0 + 7ba6: df 91 pop r29 + 7ba8: cf 91 pop r28 + 7baa: 1f 91 pop r17 + 7bac: 0f 91 pop r16 + 7bae: ff 90 pop r15 + 7bb0: ef 90 pop r14 + 7bb2: df 90 pop r13 + 7bb4: 08 95 ret + +00007bb6 : + 7bb6: df 92 push r13 + 7bb8: ef 92 push r14 + 7bba: ff 92 push r15 + 7bbc: 0f 93 push r16 + 7bbe: 1f 93 push r17 + 7bc0: cf 93 push r28 + 7bc2: df 93 push r29 + 7bc4: 1f 92 push r1 + 7bc6: cd b7 in r28, 0x3d ; 61 + 7bc8: de b7 in r29, 0x3e ; 62 + 7bca: e8 2e mov r14, r24 + 7bcc: f6 2e mov r15, r22 + 7bce: d4 2e mov r13, r20 + 7bd0: 6a e5 ldi r22, 0x5A ; 90 + 7bd2: 80 e0 ldi r24, 0x00 ; 0 + 7bd4: 90 e0 ldi r25, 0x00 ; 0 + 7bd6: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7bda: 8c 01 movw r16, r24 + 7bdc: 8a e5 ldi r24, 0x5A ; 90 + 7bde: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7be2: 6e 2d mov r22, r14 + 7be4: c8 01 movw r24, r16 + 7be6: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7bea: 8c 01 movw r16, r24 + 7bec: 8e 2d mov r24, r14 + 7bee: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7bf2: 6f 2d mov r22, r15 + 7bf4: c8 01 movw r24, r16 + 7bf6: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7bfa: 61 e0 ldi r22, 0x01 ; 1 + 7bfc: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c00: 8c 01 movw r16, r24 + 7c02: 81 e0 ldi r24, 0x01 ; 1 + 7c04: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c08: 6d 2d mov r22, r13 + 7c0a: c8 01 movw r24, r16 + 7c0c: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c10: 18 2f mov r17, r24 + 7c12: 8d 2d mov r24, r13 + 7c14: 99 83 std Y+1, r25 ; 0x01 + 7c16: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c1a: 99 81 ldd r25, Y+1 ; 0x01 + 7c1c: 89 2f mov r24, r25 + 7c1e: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c22: 81 2f mov r24, r17 + 7c24: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c28: 80 e0 ldi r24, 0x00 ; 0 + 7c2a: 0f 90 pop r0 + 7c2c: df 91 pop r29 + 7c2e: cf 91 pop r28 + 7c30: 1f 91 pop r17 + 7c32: 0f 91 pop r16 + 7c34: ff 90 pop r15 + 7c36: ef 90 pop r14 + 7c38: df 90 pop r13 + 7c3a: 08 95 ret + +00007c3c : + 7c3c: ef 92 push r14 + 7c3e: ff 92 push r15 + 7c40: 0f 93 push r16 + 7c42: 1f 93 push r17 + 7c44: cf 93 push r28 + 7c46: df 93 push r29 + 7c48: 1f 92 push r1 + 7c4a: cd b7 in r28, 0x3d ; 61 + 7c4c: de b7 in r29, 0x3e ; 62 + 7c4e: f8 2e mov r15, r24 + 7c50: e6 2e mov r14, r22 + 7c52: 6a e5 ldi r22, 0x5A ; 90 + 7c54: 80 e0 ldi r24, 0x00 ; 0 + 7c56: 90 e0 ldi r25, 0x00 ; 0 + 7c58: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c5c: 8c 01 movw r16, r24 + 7c5e: 8a e5 ldi r24, 0x5A ; 90 + 7c60: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c64: 6f 2d mov r22, r15 + 7c66: c8 01 movw r24, r16 + 7c68: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c6c: 8c 01 movw r16, r24 + 7c6e: 8f 2d mov r24, r15 + 7c70: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c74: 60 e4 ldi r22, 0x40 ; 64 + 7c76: c8 01 movw r24, r16 + 7c78: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c7c: 8c 01 movw r16, r24 + 7c7e: 80 e4 ldi r24, 0x40 ; 64 + 7c80: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c84: 61 e0 ldi r22, 0x01 ; 1 + 7c86: c8 01 movw r24, r16 + 7c88: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c8c: 8c 01 movw r16, r24 + 7c8e: 81 e0 ldi r24, 0x01 ; 1 + 7c90: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7c94: 6e 2d mov r22, r14 + 7c96: c8 01 movw r24, r16 + 7c98: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7c9c: 18 2f mov r17, r24 + 7c9e: 8e 2d mov r24, r14 + 7ca0: 99 83 std Y+1, r25 ; 0x01 + 7ca2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7ca6: 99 81 ldd r25, Y+1 ; 0x01 + 7ca8: 89 2f mov r24, r25 + 7caa: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7cae: 81 2f mov r24, r17 + 7cb0: 0f 90 pop r0 + 7cb2: df 91 pop r29 + 7cb4: cf 91 pop r28 + 7cb6: 1f 91 pop r17 + 7cb8: 0f 91 pop r16 + 7cba: ff 90 pop r15 + 7cbc: ef 90 pop r14 + 7cbe: 0c 94 2b 0c jmp 0x1856 ; 0x1856 + +00007cc2 : + 7cc2: ff 92 push r15 + 7cc4: 0f 93 push r16 + 7cc6: 1f 93 push r17 + 7cc8: cf 93 push r28 + 7cca: df 93 push r29 + 7ccc: 1f 92 push r1 + 7cce: cd b7 in r28, 0x3d ; 61 + 7cd0: de b7 in r29, 0x3e ; 62 + 7cd2: f8 2e mov r15, r24 + 7cd4: 6a e5 ldi r22, 0x5A ; 90 + 7cd6: 80 e0 ldi r24, 0x00 ; 0 + 7cd8: 90 e0 ldi r25, 0x00 ; 0 + 7cda: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7cde: 8c 01 movw r16, r24 + 7ce0: 8a e5 ldi r24, 0x5A ; 90 + 7ce2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7ce6: 6f 2d mov r22, r15 + 7ce8: c8 01 movw r24, r16 + 7cea: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7cee: 8c 01 movw r16, r24 + 7cf0: 8f 2d mov r24, r15 + 7cf2: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7cf6: 61 e4 ldi r22, 0x41 ; 65 + 7cf8: c8 01 movw r24, r16 + 7cfa: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7cfe: 8c 01 movw r16, r24 + 7d00: 81 e4 ldi r24, 0x41 ; 65 + 7d02: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d06: 60 e0 ldi r22, 0x00 ; 0 + 7d08: c8 01 movw r24, r16 + 7d0a: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d0e: 18 2f mov r17, r24 + 7d10: 80 e0 ldi r24, 0x00 ; 0 + 7d12: 99 83 std Y+1, r25 ; 0x01 + 7d14: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d18: 99 81 ldd r25, Y+1 ; 0x01 + 7d1a: 89 2f mov r24, r25 + 7d1c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d20: 81 2f mov r24, r17 + 7d22: 0f 90 pop r0 + 7d24: df 91 pop r29 + 7d26: cf 91 pop r28 + 7d28: 1f 91 pop r17 + 7d2a: 0f 91 pop r16 + 7d2c: ff 90 pop r15 + 7d2e: 0c 94 2b 0c jmp 0x1856 ; 0x1856 + +00007d32 : + 7d32: df 92 push r13 + 7d34: ef 92 push r14 + 7d36: ff 92 push r15 + 7d38: 0f 93 push r16 + 7d3a: 1f 93 push r17 + 7d3c: cf 93 push r28 + 7d3e: df 93 push r29 + 7d40: 1f 92 push r1 + 7d42: cd b7 in r28, 0x3d ; 61 + 7d44: de b7 in r29, 0x3e ; 62 + 7d46: e8 2e mov r14, r24 + 7d48: f6 2e mov r15, r22 + 7d4a: d4 2e mov r13, r20 + 7d4c: 6a e5 ldi r22, 0x5A ; 90 + 7d4e: 80 e0 ldi r24, 0x00 ; 0 + 7d50: 90 e0 ldi r25, 0x00 ; 0 + 7d52: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d56: 8c 01 movw r16, r24 + 7d58: 8a e5 ldi r24, 0x5A ; 90 + 7d5a: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d5e: 6e 2d mov r22, r14 + 7d60: c8 01 movw r24, r16 + 7d62: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d66: 8c 01 movw r16, r24 + 7d68: 8e 2d mov r24, r14 + 7d6a: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d6e: f1 10 cpse r15, r1 + 7d70: 07 c0 rjmp .+14 ; 0x7d80 + 7d72: 60 e1 ldi r22, 0x10 ; 16 + 7d74: c8 01 movw r24, r16 + 7d76: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d7a: 8c 01 movw r16, r24 + 7d7c: 80 e1 ldi r24, 0x10 ; 16 + 7d7e: 06 c0 rjmp .+12 ; 0x7d8c + 7d80: 61 e1 ldi r22, 0x11 ; 17 + 7d82: c8 01 movw r24, r16 + 7d84: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d88: 8c 01 movw r16, r24 + 7d8a: 81 e1 ldi r24, 0x11 ; 17 + 7d8c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7d90: 61 e0 ldi r22, 0x01 ; 1 + 7d92: c8 01 movw r24, r16 + 7d94: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7d98: 8c 01 movw r16, r24 + 7d9a: 81 e0 ldi r24, 0x01 ; 1 + 7d9c: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7da0: 6d 2d mov r22, r13 + 7da2: c8 01 movw r24, r16 + 7da4: 0e 94 d3 38 call 0x71a6 ; 0x71a6 <_crc_xmodem_update> + 7da8: 18 2f mov r17, r24 + 7daa: 8d 2d mov r24, r13 + 7dac: 99 83 std Y+1, r25 ; 0x01 + 7dae: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7db2: 99 81 ldd r25, Y+1 ; 0x01 + 7db4: 89 2f mov r24, r25 + 7db6: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7dba: 81 2f mov r24, r17 + 7dbc: 0e 94 2b 0c call 0x1856 ; 0x1856 + 7dc0: 80 e0 ldi r24, 0x00 ; 0 + 7dc2: 0f 90 pop r0 + 7dc4: df 91 pop r29 + 7dc6: cf 91 pop r28 + 7dc8: 1f 91 pop r17 + 7dca: 0f 91 pop r16 + 7dcc: ff 90 pop r15 + 7dce: ef 90 pop r14 + 7dd0: df 90 pop r13 + 7dd2: 08 95 ret + +00007dd4 : + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + 7dd4: 0e 94 81 4b call 0x9702 ; 0x9702 + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif + } + 7dd8: fd cf rjmp .-6 ; 0x7dd4 + +00007dda : +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) + { + 7dda: 2f 92 push r2 + 7ddc: 3f 92 push r3 + 7dde: 4f 92 push r4 + 7de0: 5f 92 push r5 + 7de2: 6f 92 push r6 + 7de4: 7f 92 push r7 + 7de6: 8f 92 push r8 + 7de8: 9f 92 push r9 + 7dea: af 92 push r10 + 7dec: bf 92 push r11 + 7dee: cf 92 push r12 + 7df0: df 92 push r13 + 7df2: ef 92 push r14 + 7df4: ff 92 push r15 + 7df6: 0f 93 push r16 + 7df8: 1f 93 push r17 + 7dfa: cf 93 push r28 + 7dfc: df 93 push r29 + 7dfe: 1f 92 push r1 + 7e00: cd b7 in r28, 0x3d ; 61 + 7e02: de b7 in r29, 0x3e ; 62 + 7e04: 4c 01 movw r8, r24 + 7e06: 1b 01 movw r2, r22 + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned short usStackRemaining; + + /* Write the details of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + 7e08: db 01 movw r26, r22 + 7e0a: 11 96 adiw r26, 0x01 ; 1 + 7e0c: ed 91 ld r30, X+ + 7e0e: fc 91 ld r31, X + 7e10: 12 97 sbiw r26, 0x02 ; 2 + 7e12: 82 81 ldd r24, Z+2 ; 0x02 + 7e14: 93 81 ldd r25, Z+3 ; 0x03 + 7e16: 12 96 adiw r26, 0x02 ; 2 + 7e18: 9c 93 st X, r25 + 7e1a: 8e 93 st -X, r24 + 7e1c: 11 97 sbiw r26, 0x01 ; 1 + 7e1e: 3b 01 movw r6, r22 + 7e20: b3 e0 ldi r27, 0x03 ; 3 + 7e22: 6b 0e add r6, r27 + 7e24: 71 1c adc r7, r1 + 7e26: 86 15 cp r24, r6 + 7e28: 97 05 cpc r25, r7 + 7e2a: 41 f4 brne .+16 ; 0x7e3c + 7e2c: f3 01 movw r30, r6 + 7e2e: 82 81 ldd r24, Z+2 ; 0x02 + 7e30: 93 81 ldd r25, Z+3 ; 0x03 + 7e32: db 01 movw r26, r22 + 7e34: 12 96 adiw r26, 0x02 ; 2 + 7e36: 9c 93 st X, r25 + 7e38: 8e 93 st -X, r24 + 7e3a: 11 97 sbiw r26, 0x01 ; 1 + 7e3c: d1 01 movw r26, r2 + 7e3e: 11 96 adiw r26, 0x01 ; 1 + 7e40: ed 91 ld r30, X+ + 7e42: fc 91 ld r31, X + 7e44: 12 97 sbiw r26, 0x02 ; 2 + 7e46: a6 80 ldd r10, Z+6 ; 0x06 + 7e48: b7 80 ldd r11, Z+7 ; 0x07 + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + } + #endif + + sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber ); + 7e4a: 44 2e mov r4, r20 + 7e4c: 04 2e mov r0, r20 + 7e4e: 00 0c add r0, r0 + 7e50: 55 08 sbc r5, r5 + 7e52: 81 e7 ldi r24, 0x71 ; 113 + 7e54: c8 2e mov r12, r24 + 7e56: 81 e0 ldi r24, 0x01 ; 1 + 7e58: d8 2e mov r13, r24 + 7e5a: 95 e9 ldi r25, 0x95 ; 149 + 7e5c: e9 2e mov r14, r25 + 7e5e: 91 e0 ldi r25, 0x01 ; 1 + 7e60: f9 2e mov r15, r25 + + /* Write the details of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + 7e62: d1 01 movw r26, r2 + 7e64: 11 96 adiw r26, 0x01 ; 1 + 7e66: ed 91 ld r30, X+ + 7e68: fc 91 ld r31, X + 7e6a: 12 97 sbiw r26, 0x02 ; 2 + 7e6c: 82 81 ldd r24, Z+2 ; 0x02 + 7e6e: 93 81 ldd r25, Z+3 ; 0x03 + 7e70: 12 96 adiw r26, 0x02 ; 2 + 7e72: 9c 93 st X, r25 + 7e74: 8e 93 st -X, r24 + 7e76: 11 97 sbiw r26, 0x01 ; 1 + 7e78: 86 15 cp r24, r6 + 7e7a: 97 05 cpc r25, r7 + 7e7c: 41 f4 brne .+16 ; 0x7e8e + 7e7e: 15 96 adiw r26, 0x05 ; 5 + 7e80: 8d 91 ld r24, X+ + 7e82: 9c 91 ld r25, X + 7e84: 16 97 sbiw r26, 0x06 ; 6 + 7e86: 12 96 adiw r26, 0x02 ; 2 + 7e88: 9c 93 st X, r25 + 7e8a: 8e 93 st -X, r24 + 7e8c: 11 97 sbiw r26, 0x01 ; 1 + 7e8e: d1 01 movw r26, r2 + 7e90: 11 96 adiw r26, 0x01 ; 1 + 7e92: ed 91 ld r30, X+ + 7e94: fc 91 ld r31, X + 7e96: 12 97 sbiw r26, 0x02 ; 2 + 7e98: 06 81 ldd r16, Z+6 ; 0x06 + 7e9a: 17 81 ldd r17, Z+7 ; 0x07 + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); + } + #else + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + 7e9c: f8 01 movw r30, r16 + 7e9e: 27 89 ldd r18, Z+23 ; 0x17 + 7ea0: 30 8d ldd r19, Z+24 ; 0x18 + 7ea2: f9 01 movw r30, r18 + 7ea4: cf 01 movw r24, r30 + 7ea6: 82 1b sub r24, r18 + 7ea8: 93 0b sbc r25, r19 + + static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) + { + register unsigned short usCount = 0; + + while( *pucStackByte == tskSTACK_FILL_BYTE ) + 7eaa: 51 91 ld r21, Z+ + 7eac: 55 3a cpi r21, 0xA5 ; 165 + 7eae: d1 f3 breq .-12 ; 0x7ea4 + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + } + #endif + + sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber ); + 7eb0: d8 01 movw r26, r16 + 7eb2: 93 96 adiw r26, 0x23 ; 35 + 7eb4: 3c 91 ld r19, X + 7eb6: 93 97 sbiw r26, 0x23 ; 35 + 7eb8: 56 96 adiw r26, 0x16 ; 22 + 7eba: 2c 91 ld r18, X + 7ebc: 1f 92 push r1 + 7ebe: 3f 93 push r19 + 7ec0: 9f 93 push r25 + 7ec2: 8f 93 push r24 + 7ec4: 1f 92 push r1 + 7ec6: 2f 93 push r18 + 7ec8: 5f 92 push r5 + 7eca: 4f 93 push r20 + 7ecc: c8 01 movw r24, r16 + 7ece: 49 96 adiw r24, 0x19 ; 25 + 7ed0: 9f 93 push r25 + 7ed2: 8f 93 push r24 + 7ed4: df 92 push r13 + 7ed6: cf 92 push r12 + 7ed8: ff 92 push r15 + 7eda: ef 92 push r14 + 7edc: 49 83 std Y+1, r20 ; 0x01 + 7ede: 0e 94 9b 50 call 0xa136 ; 0xa136 + strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString ); + 7ee2: 65 e9 ldi r22, 0x95 ; 149 + 7ee4: 71 e0 ldi r23, 0x01 ; 1 + 7ee6: c4 01 movw r24, r8 + 7ee8: 0e 94 86 4f call 0x9f0c ; 0x9f0c + + } while( pxNextTCB != pxFirstTCB ); + 7eec: 0f b6 in r0, 0x3f ; 63 + 7eee: f8 94 cli + 7ef0: de bf out 0x3e, r29 ; 62 + 7ef2: 0f be out 0x3f, r0 ; 63 + 7ef4: cd bf out 0x3d, r28 ; 61 + 7ef6: 49 81 ldd r20, Y+1 ; 0x01 + 7ef8: 0a 15 cp r16, r10 + 7efa: 1b 05 cpc r17, r11 + 7efc: 09 f0 breq .+2 ; 0x7f00 + 7efe: b1 cf rjmp .-158 ; 0x7e62 + } + 7f00: 0f 90 pop r0 + 7f02: df 91 pop r29 + 7f04: cf 91 pop r28 + 7f06: 1f 91 pop r17 + 7f08: 0f 91 pop r16 + 7f0a: ff 90 pop r15 + 7f0c: ef 90 pop r14 + 7f0e: df 90 pop r13 + 7f10: cf 90 pop r12 + 7f12: bf 90 pop r11 + 7f14: af 90 pop r10 + 7f16: 9f 90 pop r9 + 7f18: 8f 90 pop r8 + 7f1a: 7f 90 pop r7 + 7f1c: 6f 90 pop r6 + 7f1e: 5f 90 pop r5 + 7f20: 4f 90 pop r4 + 7f22: 3f 90 pop r3 + 7f24: 2f 90 pop r2 + 7f26: 08 95 ret + +00007f28 : +/*----------------------------------------------------------- + * TASK CREATION API documented in task.h + *----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ + 7f28: 4f 92 push r4 + 7f2a: 5f 92 push r5 + 7f2c: 6f 92 push r6 + 7f2e: 7f 92 push r7 + 7f30: 8f 92 push r8 + 7f32: 9f 92 push r9 + 7f34: af 92 push r10 + 7f36: bf 92 push r11 + 7f38: cf 92 push r12 + 7f3a: df 92 push r13 + 7f3c: ef 92 push r14 + 7f3e: ff 92 push r15 + 7f40: 0f 93 push r16 + 7f42: 1f 93 push r17 + 7f44: cf 93 push r28 + 7f46: df 93 push r29 + 7f48: 5c 01 movw r10, r24 + 7f4a: 3b 01 movw r6, r22 + 7f4c: ea 01 movw r28, r20 + 7f4e: 49 01 movw r8, r18 +{ +tskTCB *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) ); + 7f50: 84 e2 ldi r24, 0x24 ; 36 + 7f52: 90 e0 ldi r25, 0x00 ; 0 + 7f54: 0e 94 a9 4a call 0x9552 ; 0x9552 + 7f58: 2c 01 movw r4, r24 + + if( pxNewTCB != NULL ) + 7f5a: 89 2b or r24, r25 + 7f5c: 09 f4 brne .+2 ; 0x7f60 + 7f5e: c4 c0 rjmp .+392 ; 0x80e8 + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); + 7f60: c1 14 cp r12, r1 + 7f62: d1 04 cpc r13, r1 + 7f64: 21 f4 brne .+8 ; 0x7f6e + 7f66: ce 01 movw r24, r28 + 7f68: 0e 94 a9 4a call 0x9552 ; 0x9552 + 7f6c: 01 c0 rjmp .+2 ; 0x7f70 + 7f6e: c6 01 movw r24, r12 + 7f70: f2 01 movw r30, r4 + 7f72: 90 8f std Z+24, r25 ; 0x18 + 7f74: 87 8b std Z+23, r24 ; 0x17 + + if( pxNewTCB->pxStack == NULL ) + 7f76: 00 97 sbiw r24, 0x00 ; 0 + 7f78: 21 f4 brne .+8 ; 0x7f82 + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + 7f7a: c2 01 movw r24, r4 + 7f7c: 0e 94 cf 4a call 0x959e ; 0x959e + 7f80: b3 c0 rjmp .+358 ; 0x80e8 + pxNewTCB = NULL; + } + else + { + /* Just to help debugging. */ + memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) ); + 7f82: ae 01 movw r20, r28 + 7f84: 65 ea ldi r22, 0xA5 ; 165 + 7f86: 70 e0 ldi r23, 0x00 ; 0 + 7f88: 0e 94 7f 4f call 0x9efe ; 0x9efe + stack grows from high memory to low (as per the 80x86) or visa versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + 7f8c: 21 97 sbiw r28, 0x01 ; 1 + 7f8e: f2 01 movw r30, r4 + 7f90: c7 88 ldd r12, Z+23 ; 0x17 + 7f92: d0 8c ldd r13, Z+24 ; 0x18 + 7f94: cc 0e add r12, r28 + 7f96: dd 1e adc r13, r29 +{ + /* Store the function name in the TCB. */ + #if configMAX_TASK_NAME_LEN > 1 + { + /* Don't bring strncpy into the build unnecessarily. */ + strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN ); + 7f98: 4a e0 ldi r20, 0x0A ; 10 + 7f9a: 50 e0 ldi r21, 0x00 ; 0 + 7f9c: b3 01 movw r22, r6 + 7f9e: c2 01 movw r24, r4 + 7fa0: 49 96 adiw r24, 0x19 ; 25 + 7fa2: 0e 94 a6 4f call 0x9f4c ; 0x9f4c + } + #endif + pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0'; + 7fa6: f2 01 movw r30, r4 + 7fa8: 12 a2 std Z+34, r1 ; 0x22 + 7faa: 10 2f mov r17, r16 + 7fac: 03 30 cpi r16, 0x03 ; 3 + 7fae: 08 f0 brcs .+2 ; 0x7fb2 + 7fb0: 12 e0 ldi r17, 0x02 ; 2 + if( uxPriority >= configMAX_PRIORITIES ) + { + uxPriority = configMAX_PRIORITIES - 1; + } + + pxTCB->uxPriority = uxPriority; + 7fb2: f2 01 movw r30, r4 + 7fb4: 16 8b std Z+22, r17 ; 0x16 + { + pxTCB->uxBasePriority = uxPriority; + } + #endif + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + 7fb6: e2 01 movw r28, r4 + 7fb8: 22 96 adiw r28, 0x02 ; 2 + 7fba: ce 01 movw r24, r28 + 7fbc: 0e 94 5d 48 call 0x90ba ; 0x90ba + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + 7fc0: c2 01 movw r24, r4 + 7fc2: 0c 96 adiw r24, 0x0c ; 12 + 7fc4: 0e 94 5d 48 call 0x90ba ; 0x90ba + + /* Set the pxTCB as a link back from the xListItem. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + 7fc8: f2 01 movw r30, r4 + 7fca: 51 86 std Z+9, r5 ; 0x09 + 7fcc: 40 86 std Z+8, r4 ; 0x08 + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + 7fce: 83 e0 ldi r24, 0x03 ; 3 + 7fd0: 90 e0 ldi r25, 0x00 ; 0 + 7fd2: 81 1b sub r24, r17 + 7fd4: 91 09 sbc r25, r1 + 7fd6: 95 87 std Z+13, r25 ; 0x0d + 7fd8: 84 87 std Z+12, r24 ; 0x0c + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + 7fda: 53 8a std Z+19, r5 ; 0x13 + 7fdc: 42 8a std Z+18, r4 ; 0x12 + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + 7fde: a4 01 movw r20, r8 + 7fe0: b5 01 movw r22, r10 + 7fe2: c6 01 movw r24, r12 + 7fe4: 0e 94 de 4a call 0x95bc ; 0x95bc + 7fe8: f2 01 movw r30, r4 + 7fea: 91 83 std Z+1, r25 ; 0x01 + 7fec: 80 83 st Z, r24 + } + #endif + + /* We are going to manipulate the task queues to add this task to a + ready list, so must make sure no interrupts occur. */ + portENTER_CRITICAL(); + 7fee: 0f b6 in r0, 0x3f ; 63 + 7ff0: f8 94 cli + 7ff2: 0f 92 push r0 + { + uxCurrentNumberOfTasks++; + 7ff4: 80 91 d8 01 lds r24, 0x01D8 + 7ff8: 8f 5f subi r24, 0xFF ; 255 + 7ffa: 80 93 d8 01 sts 0x01D8, r24 + if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) + 7ffe: 80 91 d8 01 lds r24, 0x01D8 + 8002: 81 30 cpi r24, 0x01 ; 1 + 8004: 69 f5 brne .+90 ; 0x8060 + { + /* As this is the first task it must also be the current task. */ + pxCurrentTCB = pxNewTCB; + 8006: 50 92 94 01 sts 0x0194, r5 + 800a: 40 92 93 01 sts 0x0193, r4 +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) ); + 800e: 81 e0 ldi r24, 0x01 ; 1 + 8010: 92 e0 ldi r25, 0x02 ; 2 + 8012: 0e 94 4f 48 call 0x909e ; 0x909e + 8016: 8a e0 ldi r24, 0x0A ; 10 + 8018: 92 e0 ldi r25, 0x02 ; 2 + 801a: 0e 94 4f 48 call 0x909e ; 0x909e + 801e: 83 e1 ldi r24, 0x13 ; 19 + 8020: 92 e0 ldi r25, 0x02 ; 2 + 8022: 0e 94 4f 48 call 0x909e ; 0x909e + } + + vListInitialise( ( xList * ) &xDelayedTaskList1 ); + 8026: 88 ef ldi r24, 0xF8 ; 248 + 8028: 91 e0 ldi r25, 0x01 ; 1 + 802a: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( ( xList * ) &xDelayedTaskList2 ); + 802e: 8f ee ldi r24, 0xEF ; 239 + 8030: 91 e0 ldi r25, 0x01 ; 1 + 8032: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( ( xList * ) &xPendingReadyList ); + 8036: 82 ee ldi r24, 0xE2 ; 226 + 8038: 91 e0 ldi r25, 0x01 ; 1 + 803a: 0e 94 4f 48 call 0x909e ; 0x909e + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( ( xList * ) &xSuspendedTaskList ); + 803e: 89 ed ldi r24, 0xD9 ; 217 + 8040: 91 e0 ldi r25, 0x01 ; 1 + 8042: 0e 94 4f 48 call 0x909e ; 0x909e + } + #endif + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + 8046: 88 ef ldi r24, 0xF8 ; 248 + 8048: 91 e0 ldi r25, 0x01 ; 1 + 804a: 90 93 ee 01 sts 0x01EE, r25 + 804e: 80 93 ed 01 sts 0x01ED, r24 + pxOverflowDelayedTaskList = &xDelayedTaskList2; + 8052: 8f ee ldi r24, 0xEF ; 239 + 8054: 91 e0 ldi r25, 0x01 ; 1 + 8056: 90 93 ec 01 sts 0x01EC, r25 + 805a: 80 93 eb 01 sts 0x01EB, r24 + 805e: 0f c0 rjmp .+30 ; 0x807e + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + 8060: 80 91 d3 01 lds r24, 0x01D3 + 8064: 81 11 cpse r24, r1 + 8066: 0b c0 rjmp .+22 ; 0x807e + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + 8068: e0 91 93 01 lds r30, 0x0193 + 806c: f0 91 94 01 lds r31, 0x0194 + 8070: 86 89 ldd r24, Z+22 ; 0x16 + 8072: 08 17 cp r16, r24 + 8074: 20 f0 brcs .+8 ; 0x807e + { + pxCurrentTCB = pxNewTCB; + 8076: 50 92 94 01 sts 0x0194, r5 + 807a: 40 92 93 01 sts 0x0193, r4 + } + } + + /* Remember the top priority to make context switching faster. Use + the priority in pxNewTCB as this has been capped to a valid value. */ + if( pxNewTCB->uxPriority > uxTopUsedPriority ) + 807e: f2 01 movw r30, r4 + 8080: 86 89 ldd r24, Z+22 ; 0x16 + 8082: 90 91 d5 01 lds r25, 0x01D5 + 8086: 98 17 cp r25, r24 + 8088: 10 f4 brcc .+4 ; 0x808e + { + uxTopUsedPriority = pxNewTCB->uxPriority; + 808a: 80 93 d5 01 sts 0x01D5, r24 + } + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + 808e: 90 91 ce 01 lds r25, 0x01CE + 8092: f2 01 movw r30, r4 + 8094: 93 a3 std Z+35, r25 ; 0x23 + } + #endif + uxTaskNumber++; + 8096: 9f 5f subi r25, 0xFF ; 255 + 8098: 90 93 ce 01 sts 0x01CE, r25 + + prvAddTaskToReadyQueue( pxNewTCB ); + 809c: 90 91 d4 01 lds r25, 0x01D4 + 80a0: 98 17 cp r25, r24 + 80a2: 10 f4 brcc .+4 ; 0x80a8 + 80a4: 80 93 d4 01 sts 0x01D4, r24 + 80a8: f9 e0 ldi r31, 0x09 ; 9 + 80aa: 8f 9f mul r24, r31 + 80ac: c0 01 movw r24, r0 + 80ae: 11 24 eor r1, r1 + 80b0: be 01 movw r22, r28 + 80b2: 8f 5f subi r24, 0xFF ; 255 + 80b4: 9d 4f sbci r25, 0xFD ; 253 + 80b6: 0e 94 61 48 call 0x90c2 ; 0x90c2 + + xReturn = pdPASS; + traceTASK_CREATE( pxNewTCB ); + } + portEXIT_CRITICAL(); + 80ba: 0f 90 pop r0 + 80bc: 0f be out 0x3f, r0 ; 63 + traceTASK_CREATE_FAILED( pxNewTCB ); + } + + if( xReturn == pdPASS ) + { + if( ( void * ) pxCreatedTask != NULL ) + 80be: e1 14 cp r14, r1 + 80c0: f1 04 cpc r15, r1 + 80c2: 19 f0 breq .+6 ; 0x80ca + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( xTaskHandle ) pxNewTCB; + 80c4: f7 01 movw r30, r14 + 80c6: 51 82 std Z+1, r5 ; 0x01 + 80c8: 40 82 st Z, r4 + } + + if( xSchedulerRunning != pdFALSE ) + 80ca: 80 91 d3 01 lds r24, 0x01D3 + 80ce: 88 23 and r24, r24 + 80d0: 49 f0 breq .+18 ; 0x80e4 + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + 80d2: e0 91 93 01 lds r30, 0x0193 + 80d6: f0 91 94 01 lds r31, 0x0194 + 80da: 86 89 ldd r24, Z+22 ; 0x16 + 80dc: 80 17 cp r24, r16 + 80de: 10 f4 brcc .+4 ; 0x80e4 + { + portYIELD_WITHIN_API(); + 80e0: 0e 94 81 4b call 0x9702 ; 0x9702 + #endif + uxTaskNumber++; + + prvAddTaskToReadyQueue( pxNewTCB ); + + xReturn = pdPASS; + 80e4: 81 e0 ldi r24, 0x01 ; 1 + 80e6: 01 c0 rjmp .+2 ; 0x80ea + } + portEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + 80e8: 8f ef ldi r24, 0xFF ; 255 + } + } + } + + return xReturn; +} + 80ea: df 91 pop r29 + 80ec: cf 91 pop r28 + 80ee: 1f 91 pop r17 + 80f0: 0f 91 pop r16 + 80f2: ff 90 pop r15 + 80f4: ef 90 pop r14 + 80f6: df 90 pop r13 + 80f8: cf 90 pop r12 + 80fa: bf 90 pop r11 + 80fc: af 90 pop r10 + 80fe: 9f 90 pop r9 + 8100: 8f 90 pop r8 + 8102: 7f 90 pop r7 + 8104: 6f 90 pop r6 + 8106: 5f 90 pop r5 + 8108: 4f 90 pop r4 + 810a: 08 95 ret + +0000810c : + unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxReturn; + + portENTER_CRITICAL(); + 810c: 0f b6 in r0, 0x3f ; 63 + 810e: f8 94 cli + 8110: 0f 92 push r0 + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + 8112: 00 97 sbiw r24, 0x00 ; 0 + 8114: 21 f4 brne .+8 ; 0x811e + 8116: 80 91 93 01 lds r24, 0x0193 + 811a: 90 91 94 01 lds r25, 0x0194 + uxReturn = pxTCB->uxPriority; + } + portEXIT_CRITICAL(); + 811e: 0f 90 pop r0 + 8120: 0f be out 0x3f, r0 ; 63 + + return uxReturn; + } + 8122: fc 01 movw r30, r24 + 8124: 86 89 ldd r24, Z+22 ; 0x16 + 8126: 08 95 ret + +00008128 : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) + { + 8128: ef 92 push r14 + 812a: ff 92 push r15 + 812c: 1f 93 push r17 + 812e: cf 93 push r28 + 8130: df 93 push r29 + 8132: ec 01 movw r28, r24 + 8134: 63 30 cpi r22, 0x03 ; 3 + 8136: 08 f0 brcs .+2 ; 0x813a + 8138: 62 e0 ldi r22, 0x02 ; 2 + if( uxNewPriority >= configMAX_PRIORITIES ) + { + uxNewPriority = configMAX_PRIORITIES - 1; + } + + portENTER_CRITICAL(); + 813a: 0f b6 in r0, 0x3f ; 63 + 813c: f8 94 cli + 813e: 0f 92 push r0 + { + if( pxTask == pxCurrentTCB ) + 8140: 80 91 93 01 lds r24, 0x0193 + 8144: 90 91 94 01 lds r25, 0x0194 + 8148: c8 17 cp r28, r24 + 814a: d9 07 cpc r29, r25 + 814c: 11 f0 breq .+4 ; 0x8152 + pxTask = NULL; + } + + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + 814e: 20 97 sbiw r28, 0x00 ; 0 + 8150: 39 f4 brne .+14 ; 0x8160 + 8152: c0 91 93 01 lds r28, 0x0193 + 8156: d0 91 94 01 lds r29, 0x0194 + 815a: 20 e0 ldi r18, 0x00 ; 0 + 815c: 30 e0 ldi r19, 0x00 ; 0 + 815e: 01 c0 rjmp .+2 ; 0x8162 + 8160: 9e 01 movw r18, r28 + { + uxCurrentPriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentPriority = pxTCB->uxPriority; + 8162: 8e 89 ldd r24, Y+22 ; 0x16 + } + #endif + + if( uxCurrentPriority != uxNewPriority ) + 8164: 86 17 cp r24, r22 + 8166: b1 f1 breq .+108 ; 0x81d4 + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentPriority ) + { + if( pxTask != NULL ) + 8168: 11 e0 ldi r17, 0x01 ; 1 + + if( uxCurrentPriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentPriority ) + 816a: 86 17 cp r24, r22 + 816c: 18 f4 brcc .+6 ; 0x8174 + { + if( pxTask != NULL ) + 816e: 23 2b or r18, r19 + 8170: 21 f4 brne .+8 ; 0x817a + 8172: 02 c0 rjmp .+4 ; 0x8178 + there would be no need to switch as it must have already + been the highest priority task. */ + xYieldRequired = pdTRUE; + } + } + else if( pxTask == NULL ) + 8174: 23 2b or r18, r19 + 8176: 09 f0 breq .+2 ; 0x817a + 8178: 10 e0 ldi r17, 0x00 ; 0 + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + 817a: 6e 8b std Y+22, r22 ; 0x16 + } + #endif + + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); + 817c: 23 e0 ldi r18, 0x03 ; 3 + 817e: 30 e0 ldi r19, 0x00 ; 0 + 8180: 26 1b sub r18, r22 + 8182: 31 09 sbc r19, r1 + 8184: 3d 87 std Y+13, r19 ; 0x0d + 8186: 2c 87 std Y+12, r18 ; 0x0c + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the queue appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) ) + 8188: 29 e0 ldi r18, 0x09 ; 9 + 818a: 82 9f mul r24, r18 + 818c: c0 01 movw r24, r0 + 818e: 11 24 eor r1, r1 + 8190: 8f 5f subi r24, 0xFF ; 255 + 8192: 9d 4f sbci r25, 0xFD ; 253 + 8194: 2a 85 ldd r18, Y+10 ; 0x0a + 8196: 3b 85 ldd r19, Y+11 ; 0x0b + 8198: 28 17 cp r18, r24 + 819a: 39 07 cpc r19, r25 + 819c: b9 f4 brne .+46 ; 0x81cc + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + 819e: 7e 01 movw r14, r28 + 81a0: 82 e0 ldi r24, 0x02 ; 2 + 81a2: e8 0e add r14, r24 + 81a4: f1 1c adc r15, r1 + 81a6: c7 01 movw r24, r14 + 81a8: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddTaskToReadyQueue( pxTCB ); + 81ac: 9e 89 ldd r25, Y+22 ; 0x16 + 81ae: 80 91 d4 01 lds r24, 0x01D4 + 81b2: 89 17 cp r24, r25 + 81b4: 10 f4 brcc .+4 ; 0x81ba + 81b6: 90 93 d4 01 sts 0x01D4, r25 + 81ba: 29 e0 ldi r18, 0x09 ; 9 + 81bc: 92 9f mul r25, r18 + 81be: c0 01 movw r24, r0 + 81c0: 11 24 eor r1, r1 + 81c2: b7 01 movw r22, r14 + 81c4: 8f 5f subi r24, 0xFF ; 255 + 81c6: 9d 4f sbci r25, 0xFD ; 253 + 81c8: 0e 94 61 48 call 0x90c2 ; 0x90c2 + } + + if( xYieldRequired == pdTRUE ) + 81cc: 11 30 cpi r17, 0x01 ; 1 + 81ce: 11 f4 brne .+4 ; 0x81d4 + { + portYIELD_WITHIN_API(); + 81d0: 0e 94 81 4b call 0x9702 ; 0x9702 + } + } + } + portEXIT_CRITICAL(); + 81d4: 0f 90 pop r0 + 81d6: 0f be out 0x3f, r0 ; 63 + } + 81d8: df 91 pop r29 + 81da: cf 91 pop r28 + 81dc: 1f 91 pop r17 + 81de: ff 90 pop r15 + 81e0: ef 90 pop r14 + 81e2: 08 95 ret + +000081e4 : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + 81e4: ef 92 push r14 + 81e6: ff 92 push r15 + 81e8: 0f 93 push r16 + 81ea: 1f 93 push r17 + 81ec: cf 93 push r28 + 81ee: df 93 push r29 + 81f0: ec 01 movw r28, r24 + tskTCB *pxTCB; + + portENTER_CRITICAL(); + 81f2: 0f b6 in r0, 0x3f ; 63 + 81f4: f8 94 cli + 81f6: 0f 92 push r0 + { + /* Ensure a yield is performed if the current task is being + suspended. */ + if( pxTaskToSuspend == pxCurrentTCB ) + 81f8: 80 91 93 01 lds r24, 0x0193 + 81fc: 90 91 94 01 lds r25, 0x0194 + 8200: c8 17 cp r28, r24 + 8202: d9 07 cpc r29, r25 + 8204: 11 f0 breq .+4 ; 0x820a + { + pxTaskToSuspend = NULL; + } + + /* If null is passed in here then we are suspending ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToSuspend ); + 8206: 20 97 sbiw r28, 0x00 ; 0 + 8208: 39 f4 brne .+14 ; 0x8218 + 820a: 00 91 93 01 lds r16, 0x0193 + 820e: 10 91 94 01 lds r17, 0x0194 + 8212: c0 e0 ldi r28, 0x00 ; 0 + 8214: d0 e0 ldi r29, 0x00 ; 0 + 8216: 01 c0 rjmp .+2 ; 0x821a + 8218: 8e 01 movw r16, r28 + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the suspended list. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + 821a: 78 01 movw r14, r16 + 821c: 82 e0 ldi r24, 0x02 ; 2 + 821e: e8 0e add r14, r24 + 8220: f1 1c adc r15, r1 + 8222: c7 01 movw r24, r14 + 8224: 0e 94 bb 48 call 0x9176 ; 0x9176 + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + 8228: f8 01 movw r30, r16 + 822a: 84 89 ldd r24, Z+20 ; 0x14 + 822c: 95 89 ldd r25, Z+21 ; 0x15 + 822e: 89 2b or r24, r25 + 8230: 21 f0 breq .+8 ; 0x823a + { + vListRemove( &( pxTCB->xEventListItem ) ); + 8232: c8 01 movw r24, r16 + 8234: 0c 96 adiw r24, 0x0c ; 12 + 8236: 0e 94 bb 48 call 0x9176 ; 0x9176 + } + + vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + 823a: b7 01 movw r22, r14 + 823c: 89 ed ldi r24, 0xD9 ; 217 + 823e: 91 e0 ldi r25, 0x01 ; 1 + 8240: 0e 94 61 48 call 0x90c2 ; 0x90c2 + } + portEXIT_CRITICAL(); + 8244: 0f 90 pop r0 + 8246: 0f be out 0x3f, r0 ; 63 + + /* We may have just suspended the current task. */ + if( ( void * ) pxTaskToSuspend == NULL ) + 8248: cd 2b or r28, r29 + 824a: 11 f4 brne .+4 ; 0x8250 + { + portYIELD_WITHIN_API(); + 824c: 0e 94 81 4b call 0x9702 ; 0x9702 + } + } + 8250: df 91 pop r29 + 8252: cf 91 pop r28 + 8254: 1f 91 pop r17 + 8256: 0f 91 pop r16 + 8258: ff 90 pop r15 + 825a: ef 90 pop r14 + 825c: 08 95 ret + +0000825e : + portBASE_TYPE xReturn = pdFALSE; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + /* Is the task we are attempting to resume actually in the + suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + 825e: fc 01 movw r30, r24 + 8260: 22 85 ldd r18, Z+10 ; 0x0a + 8262: 33 85 ldd r19, Z+11 ; 0x0b + 8264: 29 5d subi r18, 0xD9 ; 217 + 8266: 31 40 sbci r19, 0x01 ; 1 + 8268: 51 f4 brne .+20 ; 0x827e + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) + 826a: fc 01 movw r30, r24 + 826c: 24 89 ldd r18, Z+20 ; 0x14 + 826e: 35 89 ldd r19, Z+21 ; 0x15 + 8270: f1 e0 ldi r31, 0x01 ; 1 + 8272: 22 3e cpi r18, 0xE2 ; 226 + 8274: 3f 07 cpc r19, r31 + 8276: 19 f0 breq .+6 ; 0x827e + { + /* Is it in the suspended list because it is in the + Suspended state? It is possible to be in the suspended + list because it is blocked on a task with no timeout + specified. */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE ) + 8278: 81 e0 ldi r24, 0x01 ; 1 + 827a: 23 2b or r18, r19 + 827c: 09 f0 breq .+2 ; 0x8280 + +#if ( INCLUDE_vTaskSuspend == 1 ) + + signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) + { + portBASE_TYPE xReturn = pdFALSE; + 827e: 80 e0 ldi r24, 0x00 ; 0 + } + } + } + + return xReturn; + } + 8280: 08 95 ret + +00008282 : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( xTaskHandle pxTaskToResume ) + { + 8282: 0f 93 push r16 + 8284: 1f 93 push r17 + 8286: cf 93 push r28 + 8288: df 93 push r29 + it in the ready list. */ + pxTCB = ( tskTCB * ) pxTaskToResume; + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + 828a: 00 97 sbiw r24, 0x00 ; 0 + 828c: 89 f1 breq .+98 ; 0x82f0 + 828e: 20 91 93 01 lds r18, 0x0193 + 8292: 30 91 94 01 lds r19, 0x0194 + 8296: 82 17 cp r24, r18 + 8298: 93 07 cpc r25, r19 + 829a: 51 f1 breq .+84 ; 0x82f0 + 829c: ec 01 movw r28, r24 + { + portENTER_CRITICAL(); + 829e: 0f b6 in r0, 0x3f ; 63 + 82a0: f8 94 cli + 82a2: 0f 92 push r0 + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + 82a4: 0e 94 2f 41 call 0x825e ; 0x825e + 82a8: 81 30 cpi r24, 0x01 ; 1 + 82aa: 01 f5 brne .+64 ; 0x82ec + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + 82ac: 8e 01 movw r16, r28 + 82ae: 0e 5f subi r16, 0xFE ; 254 + 82b0: 1f 4f sbci r17, 0xFF ; 255 + 82b2: c8 01 movw r24, r16 + 82b4: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddTaskToReadyQueue( pxTCB ); + 82b8: 9e 89 ldd r25, Y+22 ; 0x16 + 82ba: 80 91 d4 01 lds r24, 0x01D4 + 82be: 89 17 cp r24, r25 + 82c0: 10 f4 brcc .+4 ; 0x82c6 + 82c2: 90 93 d4 01 sts 0x01D4, r25 + 82c6: 29 e0 ldi r18, 0x09 ; 9 + 82c8: 92 9f mul r25, r18 + 82ca: c0 01 movw r24, r0 + 82cc: 11 24 eor r1, r1 + 82ce: b8 01 movw r22, r16 + 82d0: 8f 5f subi r24, 0xFF ; 255 + 82d2: 9d 4f sbci r25, 0xFD ; 253 + 82d4: 0e 94 61 48 call 0x90c2 ; 0x90c2 + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 82d8: e0 91 93 01 lds r30, 0x0193 + 82dc: f0 91 94 01 lds r31, 0x0194 + 82e0: 9e 89 ldd r25, Y+22 ; 0x16 + 82e2: 86 89 ldd r24, Z+22 ; 0x16 + 82e4: 98 17 cp r25, r24 + 82e6: 10 f0 brcs .+4 ; 0x82ec + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + portYIELD_WITHIN_API(); + 82e8: 0e 94 81 4b call 0x9702 ; 0x9702 + } + } + } + portEXIT_CRITICAL(); + 82ec: 0f 90 pop r0 + 82ee: 0f be out 0x3f, r0 ; 63 + } + } + 82f0: df 91 pop r29 + 82f2: cf 91 pop r28 + 82f4: 1f 91 pop r17 + 82f6: 0f 91 pop r16 + 82f8: 08 95 ret + +000082fa : +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + 82fa: ef 92 push r14 + 82fc: ff 92 push r15 + 82fe: 1f 93 push r17 + 8300: cf 93 push r28 + 8302: df 93 push r29 + 8304: ec 01 movw r28, r24 + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + pxTCB = ( tskTCB * ) pxTaskToResume; + + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + 8306: 0e 94 2f 41 call 0x825e ; 0x825e + 830a: 81 30 cpi r24, 0x01 ; 1 + 830c: 69 f5 brne .+90 ; 0x8368 + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 830e: 80 91 d2 01 lds r24, 0x01D2 + 8312: 81 11 cpse r24, r1 + 8314: 22 c0 rjmp .+68 ; 0x835a + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + 8316: e0 91 93 01 lds r30, 0x0193 + 831a: f0 91 94 01 lds r31, 0x0194 + 831e: 11 e0 ldi r17, 0x01 ; 1 + 8320: 9e 89 ldd r25, Y+22 ; 0x16 + 8322: 86 89 ldd r24, Z+22 ; 0x16 + 8324: 98 17 cp r25, r24 + 8326: 08 f4 brcc .+2 ; 0x832a + 8328: 10 e0 ldi r17, 0x00 ; 0 + vListRemove( &( pxTCB->xGenericListItem ) ); + 832a: 7e 01 movw r14, r28 + 832c: 32 e0 ldi r19, 0x02 ; 2 + 832e: e3 0e add r14, r19 + 8330: f1 1c adc r15, r1 + 8332: c7 01 movw r24, r14 + 8334: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddTaskToReadyQueue( pxTCB ); + 8338: 2e 89 ldd r18, Y+22 ; 0x16 + 833a: 80 91 d4 01 lds r24, 0x01D4 + 833e: 82 17 cp r24, r18 + 8340: 10 f4 brcc .+4 ; 0x8346 + 8342: 20 93 d4 01 sts 0x01D4, r18 + 8346: 39 e0 ldi r19, 0x09 ; 9 + 8348: 23 9f mul r18, r19 + 834a: c0 01 movw r24, r0 + 834c: 11 24 eor r1, r1 + 834e: b7 01 movw r22, r14 + 8350: 8f 5f subi r24, 0xFF ; 255 + 8352: 9d 4f sbci r25, 0xFD ; 253 + 8354: 0e 94 61 48 call 0x90c2 ; 0x90c2 + 8358: 08 c0 rjmp .+16 ; 0x836a + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be performed if necessary. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + 835a: be 01 movw r22, r28 + 835c: 64 5f subi r22, 0xF4 ; 244 + 835e: 7f 4f sbci r23, 0xFF ; 255 + 8360: 82 ee ldi r24, 0xE2 ; 226 + 8362: 91 e0 ldi r25, 0x01 ; 1 + 8364: 0e 94 61 48 call 0x90c2 ; 0x90c2 + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + 8368: 10 e0 ldi r17, 0x00 ; 0 + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + + return xYieldRequired; + } + 836a: 81 2f mov r24, r17 + 836c: df 91 pop r29 + 836e: cf 91 pop r28 + 8370: 1f 91 pop r17 + 8372: ff 90 pop r15 + 8374: ef 90 pop r14 + 8376: 08 95 ret + +00008378 : + * PUBLIC SCHEDULER CONTROL documented in task.h + *----------------------------------------------------------*/ + + +void vTaskStartScheduler( void ) +{ + 8378: af 92 push r10 + 837a: bf 92 push r11 + 837c: cf 92 push r12 + 837e: df 92 push r13 + 8380: ef 92 push r14 + 8382: ff 92 push r15 + 8384: 0f 93 push r16 +portBASE_TYPE xReturn; + + /* Add the idle task at the lowest priority. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL ); + 8386: a1 2c mov r10, r1 + 8388: b1 2c mov r11, r1 + 838a: c1 2c mov r12, r1 + 838c: d1 2c mov r13, r1 + 838e: e1 2c mov r14, r1 + 8390: f1 2c mov r15, r1 + 8392: 00 e0 ldi r16, 0x00 ; 0 + 8394: 20 e0 ldi r18, 0x00 ; 0 + 8396: 30 e0 ldi r19, 0x00 ; 0 + 8398: 44 e6 ldi r20, 0x64 ; 100 + 839a: 50 e0 ldi r21, 0x00 ; 0 + 839c: 63 e8 ldi r22, 0x83 ; 131 + 839e: 71 e0 ldi r23, 0x01 ; 1 + 83a0: 8a ee ldi r24, 0xEA ; 234 + 83a2: 9e e3 ldi r25, 0x3E ; 62 + 83a4: 0e 94 94 3f call 0x7f28 ; 0x7f28 + + if( xReturn == pdPASS ) + 83a8: 81 30 cpi r24, 0x01 ; 1 + 83aa: 81 f4 brne .+32 ; 0x83cc + so interrupts will automatically get re-enabled when the first task + starts to run. + + STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE + DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ + portDISABLE_INTERRUPTS(); + 83ac: f8 94 cli + + xSchedulerRunning = pdTRUE; + 83ae: 80 93 d3 01 sts 0x01D3, r24 + xTickCount = ( portTickType ) 0; + 83b2: 10 92 d7 01 sts 0x01D7, r1 + 83b6: 10 92 d6 01 sts 0x01D6, r1 + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} + 83ba: 0f 91 pop r16 + 83bc: ff 90 pop r15 + 83be: ef 90 pop r14 + 83c0: df 90 pop r13 + 83c2: cf 90 pop r12 + 83c4: bf 90 pop r11 + 83c6: af 90 pop r10 + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() ) + 83c8: 0c 94 4a 4b jmp 0x9694 ; 0x9694 + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} + 83cc: 0f 91 pop r16 + 83ce: ff 90 pop r15 + 83d0: ef 90 pop r14 + 83d2: df 90 pop r13 + 83d4: cf 90 pop r12 + 83d6: bf 90 pop r11 + 83d8: af 90 pop r10 + 83da: 08 95 ret + +000083dc : +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + 83dc: f8 94 cli + xSchedulerRunning = pdFALSE; + 83de: 10 92 d3 01 sts 0x01D3, r1 + vPortEndScheduler(); + 83e2: 0c 94 80 4b jmp 0x9700 ; 0x9700 + +000083e6 : + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + portBASE_TYPE. */ + ++uxSchedulerSuspended; + 83e6: 80 91 d2 01 lds r24, 0x01D2 + 83ea: 8f 5f subi r24, 0xFF ; 255 + 83ec: 80 93 d2 01 sts 0x01D2, r24 + 83f0: 08 95 ret + +000083f2 : +portTickType xTaskGetTickCount( void ) +{ +portTickType xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portENTER_CRITICAL(); + 83f2: 0f b6 in r0, 0x3f ; 63 + 83f4: f8 94 cli + 83f6: 0f 92 push r0 + { + xTicks = xTickCount; + 83f8: 80 91 d6 01 lds r24, 0x01D6 + 83fc: 90 91 d7 01 lds r25, 0x01D7 + } + portEXIT_CRITICAL(); + 8400: 0f 90 pop r0 + 8402: 0f be out 0x3f, r0 ; 63 + + return xTicks; +} + 8404: 08 95 ret + +00008406 : + +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + portBASE_TYPE. */ + return uxCurrentNumberOfTasks; + 8406: 80 91 d8 01 lds r24, 0x01D8 +} + 840a: 08 95 ret + +0000840c : + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) + { + portENTER_CRITICAL(); + 840c: 0f b6 in r0, 0x3f ; 63 + 840e: f8 94 cli + 8410: 0f 92 push r0 + { + pcTraceBuffer = ( signed char * )pcBuffer; + 8412: 90 93 cd 01 sts 0x01CD, r25 + 8416: 80 93 cc 01 sts 0x01CC, r24 + pcTraceBufferStart = pcBuffer; + 841a: 90 93 cb 01 sts 0x01CB, r25 + 841e: 80 93 ca 01 sts 0x01CA, r24 + pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); + 8422: 48 50 subi r20, 0x08 ; 8 + 8424: 51 09 sbc r21, r1 + 8426: 48 0f add r20, r24 + 8428: 59 1f adc r21, r25 + 842a: 50 93 c9 01 sts 0x01C9, r21 + 842e: 40 93 c8 01 sts 0x01C8, r20 + xTracing = pdTRUE; + 8432: 81 e0 ldi r24, 0x01 ; 1 + 8434: 80 93 c7 01 sts 0x01C7, r24 + } + portEXIT_CRITICAL(); + 8438: 0f 90 pop r0 + 843a: 0f be out 0x3f, r0 ; 63 + 843c: 08 95 ret + +0000843e : + + unsigned long ulTaskEndTrace( void ) + { + unsigned long ulBufferLength; + + portENTER_CRITICAL(); + 843e: 0f b6 in r0, 0x3f ; 63 + 8440: f8 94 cli + 8442: 0f 92 push r0 + xTracing = pdFALSE; + 8444: 10 92 c7 01 sts 0x01C7, r1 + portEXIT_CRITICAL(); + 8448: 0f 90 pop r0 + 844a: 0f be out 0x3f, r0 ; 63 + + ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); + 844c: 60 91 cc 01 lds r22, 0x01CC + 8450: 70 91 cd 01 lds r23, 0x01CD + 8454: 80 91 ca 01 lds r24, 0x01CA + 8458: 90 91 cb 01 lds r25, 0x01CB + 845c: 68 1b sub r22, r24 + 845e: 79 0b sbc r23, r25 + 8460: 07 2e mov r0, r23 + 8462: 00 0c add r0, r0 + 8464: 88 0b sbc r24, r24 + 8466: 99 0b sbc r25, r25 + + return ulBufferLength; + } + 8468: 08 95 ret + +0000846a : + * documented in task.h + *----------------------------------------------------------*/ + + +void vTaskIncrementTick( void ) +{ + 846a: ff 92 push r15 + 846c: 0f 93 push r16 + 846e: 1f 93 push r17 + 8470: cf 93 push r28 + 8472: df 93 push r29 + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 8474: 80 91 d2 01 lds r24, 0x01D2 + 8478: 81 11 cpse r24, r1 + 847a: 5f c0 rjmp .+190 ; 0x853a + { + ++xTickCount; + 847c: 80 91 d6 01 lds r24, 0x01D6 + 8480: 90 91 d7 01 lds r25, 0x01D7 + 8484: 01 96 adiw r24, 0x01 ; 1 + 8486: 90 93 d7 01 sts 0x01D7, r25 + 848a: 80 93 d6 01 sts 0x01D6, r24 + if( xTickCount == ( portTickType ) 0 ) + 848e: 80 91 d6 01 lds r24, 0x01D6 + 8492: 90 91 d7 01 lds r25, 0x01D7 + 8496: 89 2b or r24, r25 + 8498: a9 f4 brne .+42 ; 0x84c4 + xList *pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. + If there are any items in pxDelayedTaskList here then there is + an error! */ + pxTemp = pxDelayedTaskList; + 849a: 80 91 ed 01 lds r24, 0x01ED + 849e: 90 91 ee 01 lds r25, 0x01EE + pxDelayedTaskList = pxOverflowDelayedTaskList; + 84a2: 20 91 eb 01 lds r18, 0x01EB + 84a6: 30 91 ec 01 lds r19, 0x01EC + 84aa: 30 93 ee 01 sts 0x01EE, r19 + 84ae: 20 93 ed 01 sts 0x01ED, r18 + pxOverflowDelayedTaskList = pxTemp; + 84b2: 90 93 ec 01 sts 0x01EC, r25 + 84b6: 80 93 eb 01 sts 0x01EB, r24 + xNumOfOverflows++; + 84ba: 80 91 cf 01 lds r24, 0x01CF + 84be: 8f 5f subi r24, 0xFF ; 255 + 84c0: 80 93 cf 01 sts 0x01CF, r24 + } + + /* See if this tick has made a timeout expire. */ + prvCheckDelayedTasks(); + 84c4: 89 e0 ldi r24, 0x09 ; 9 + 84c6: f8 2e mov r15, r24 + 84c8: e0 91 ed 01 lds r30, 0x01ED + 84cc: f0 91 ee 01 lds r31, 0x01EE + 84d0: 80 81 ld r24, Z + 84d2: 88 23 and r24, r24 + 84d4: c9 f1 breq .+114 ; 0x8548 + 84d6: e0 91 ed 01 lds r30, 0x01ED + 84da: f0 91 ee 01 lds r31, 0x01EE + 84de: 05 80 ldd r0, Z+5 ; 0x05 + 84e0: f6 81 ldd r31, Z+6 ; 0x06 + 84e2: e0 2d mov r30, r0 + 84e4: c6 81 ldd r28, Z+6 ; 0x06 + 84e6: d7 81 ldd r29, Z+7 ; 0x07 + 84e8: 20 97 sbiw r28, 0x00 ; 0 + 84ea: 71 f1 breq .+92 ; 0x8548 + 84ec: 20 91 d6 01 lds r18, 0x01D6 + 84f0: 30 91 d7 01 lds r19, 0x01D7 + 84f4: 8a 81 ldd r24, Y+2 ; 0x02 + 84f6: 9b 81 ldd r25, Y+3 ; 0x03 + 84f8: 28 17 cp r18, r24 + 84fa: 39 07 cpc r19, r25 + 84fc: 28 f1 brcs .+74 ; 0x8548 + 84fe: 8e 01 movw r16, r28 + 8500: 0e 5f subi r16, 0xFE ; 254 + 8502: 1f 4f sbci r17, 0xFF ; 255 + 8504: c8 01 movw r24, r16 + 8506: 0e 94 bb 48 call 0x9176 ; 0x9176 + 850a: 8c 89 ldd r24, Y+20 ; 0x14 + 850c: 9d 89 ldd r25, Y+21 ; 0x15 + 850e: 89 2b or r24, r25 + 8510: 21 f0 breq .+8 ; 0x851a + 8512: ce 01 movw r24, r28 + 8514: 0c 96 adiw r24, 0x0c ; 12 + 8516: 0e 94 bb 48 call 0x9176 ; 0x9176 + 851a: 9e 89 ldd r25, Y+22 ; 0x16 + 851c: 80 91 d4 01 lds r24, 0x01D4 + 8520: 89 17 cp r24, r25 + 8522: 10 f4 brcc .+4 ; 0x8528 + 8524: 90 93 d4 01 sts 0x01D4, r25 + 8528: f9 9e mul r15, r25 + 852a: c0 01 movw r24, r0 + 852c: 11 24 eor r1, r1 + 852e: b8 01 movw r22, r16 + 8530: 8f 5f subi r24, 0xFF ; 255 + 8532: 9d 4f sbci r25, 0xFD ; 253 + 8534: 0e 94 61 48 call 0x90c2 ; 0x90c2 + 8538: c7 cf rjmp .-114 ; 0x84c8 + } + else + { + ++uxMissedTicks; + 853a: 80 91 d1 01 lds r24, 0x01D1 + 853e: 8f 5f subi r24, 0xFF ; 255 + 8540: 80 93 d1 01 sts 0x01D1, r24 + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + extern void vApplicationTickHook( void ); + + vApplicationTickHook(); + 8544: 0e 94 5b 0b call 0x16b6 ; 0x16b6 + { + extern void vApplicationTickHook( void ); + + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked. */ + if( uxMissedTicks == 0 ) + 8548: 80 91 d1 01 lds r24, 0x01D1 + 854c: 81 11 cpse r24, r1 + 854e: 07 c0 rjmp .+14 ; 0x855e + } + } + #endif + + traceTASK_INCREMENT_TICK( xTickCount ); +} + 8550: df 91 pop r29 + 8552: cf 91 pop r28 + 8554: 1f 91 pop r17 + 8556: 0f 91 pop r16 + 8558: ff 90 pop r15 + + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked. */ + if( uxMissedTicks == 0 ) + { + vApplicationTickHook(); + 855a: 0c 94 5b 0b jmp 0x16b6 ; 0x16b6 + } + } + #endif + + traceTASK_INCREMENT_TICK( xTickCount ); +} + 855e: df 91 pop r29 + 8560: cf 91 pop r28 + 8562: 1f 91 pop r17 + 8564: 0f 91 pop r16 + 8566: ff 90 pop r15 + 8568: 08 95 ret + +0000856a : + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ + 856a: ef 92 push r14 + 856c: ff 92 push r15 + 856e: 0f 93 push r16 + 8570: 1f 93 push r17 + 8572: cf 93 push r28 + 8574: df 93 push r29 + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + portENTER_CRITICAL(); + 8576: 0f b6 in r0, 0x3f ; 63 + 8578: f8 94 cli + 857a: 0f 92 push r0 + { + --uxSchedulerSuspended; + 857c: 80 91 d2 01 lds r24, 0x01D2 + 8580: 81 50 subi r24, 0x01 ; 1 + 8582: 80 93 d2 01 sts 0x01D2, r24 + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 8586: 80 91 d2 01 lds r24, 0x01D2 + 858a: 88 23 and r24, r24 + 858c: 11 f0 breq .+4 ; 0x8592 +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ +register tskTCB *pxTCB; +signed portBASE_TYPE xAlreadyYielded = pdFALSE; + 858e: 80 e0 ldi r24, 0x00 ; 0 + 8590: 54 c0 rjmp .+168 ; 0x863a + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 ) + 8592: 80 91 d8 01 lds r24, 0x01D8 + 8596: 88 23 and r24, r24 + 8598: d1 f3 breq .-12 ; 0x858e + 859a: 10 e0 ldi r17, 0x00 ; 0 + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + 859c: 09 e0 ldi r16, 0x09 ; 9 + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + 859e: 80 91 e2 01 lds r24, 0x01E2 + 85a2: 81 11 cpse r24, r1 + 85a4: 05 c0 rjmp .+10 ; 0x85b0 + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + 85a6: 80 91 d1 01 lds r24, 0x01D1 + 85aa: 81 11 cpse r24, r1 + 85ac: 30 c0 rjmp .+96 ; 0x860e + 85ae: 2c c0 rjmp .+88 ; 0x8608 + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + 85b0: e0 91 e7 01 lds r30, 0x01E7 + 85b4: f0 91 e8 01 lds r31, 0x01E8 + 85b8: c6 81 ldd r28, Z+6 ; 0x06 + 85ba: d7 81 ldd r29, Z+7 ; 0x07 + 85bc: 20 97 sbiw r28, 0x00 ; 0 + 85be: 99 f3 breq .-26 ; 0x85a6 + { + vListRemove( &( pxTCB->xEventListItem ) ); + 85c0: ce 01 movw r24, r28 + 85c2: 0c 96 adiw r24, 0x0c ; 12 + 85c4: 0e 94 bb 48 call 0x9176 ; 0x9176 + vListRemove( &( pxTCB->xGenericListItem ) ); + 85c8: 7e 01 movw r14, r28 + 85ca: 82 e0 ldi r24, 0x02 ; 2 + 85cc: e8 0e add r14, r24 + 85ce: f1 1c adc r15, r1 + 85d0: c7 01 movw r24, r14 + 85d2: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddTaskToReadyQueue( pxTCB ); + 85d6: 9e 89 ldd r25, Y+22 ; 0x16 + 85d8: 80 91 d4 01 lds r24, 0x01D4 + 85dc: 89 17 cp r24, r25 + 85de: 10 f4 brcc .+4 ; 0x85e4 + 85e0: 90 93 d4 01 sts 0x01D4, r25 + 85e4: 09 9f mul r16, r25 + 85e6: c0 01 movw r24, r0 + 85e8: 11 24 eor r1, r1 + 85ea: b7 01 movw r22, r14 + 85ec: 8f 5f subi r24, 0xFF ; 255 + 85ee: 9d 4f sbci r25, 0xFD ; 253 + 85f0: 0e 94 61 48 call 0x90c2 ; 0x90c2 + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 85f4: e0 91 93 01 lds r30, 0x0193 + 85f8: f0 91 94 01 lds r31, 0x0194 + 85fc: 9e 89 ldd r25, Y+22 ; 0x16 + 85fe: 86 89 ldd r24, Z+22 ; 0x16 + 8600: 98 17 cp r25, r24 + 8602: 68 f2 brcs .-102 ; 0x859e + { + xYieldRequired = pdTRUE; + 8604: 11 e0 ldi r17, 0x01 ; 1 + 8606: cb cf rjmp .-106 ; 0x859e + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + 8608: 11 30 cpi r17, 0x01 ; 1 + 860a: 69 f4 brne .+26 ; 0x8626 + 860c: 11 c0 rjmp .+34 ; 0x8630 + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + 860e: 80 91 d1 01 lds r24, 0x01D1 + 8612: 88 23 and r24, r24 + 8614: c9 f3 breq .-14 ; 0x8608 + { + vTaskIncrementTick(); + 8616: 0e 94 35 42 call 0x846a ; 0x846a + --uxMissedTicks; + 861a: 80 91 d1 01 lds r24, 0x01D1 + 861e: 81 50 subi r24, 0x01 ; 1 + 8620: 80 93 d1 01 sts 0x01D1, r24 + 8624: f4 cf rjmp .-24 ; 0x860e + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + 8626: 80 91 d0 01 lds r24, 0x01D0 + 862a: 81 30 cpi r24, 0x01 ; 1 + 862c: 09 f0 breq .+2 ; 0x8630 + 862e: af cf rjmp .-162 ; 0x858e + { + xAlreadyYielded = pdTRUE; + xMissedYield = pdFALSE; + 8630: 10 92 d0 01 sts 0x01D0, r1 + portYIELD_WITHIN_API(); + 8634: 0e 94 81 4b call 0x9702 ; 0x9702 + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + { + xAlreadyYielded = pdTRUE; + 8638: 81 e0 ldi r24, 0x01 ; 1 + portYIELD_WITHIN_API(); + } + } + } + } + portEXIT_CRITICAL(); + 863a: 0f 90 pop r0 + 863c: 0f be out 0x3f, r0 ; 63 + + return xAlreadyYielded; +} + 863e: df 91 pop r29 + 8640: cf 91 pop r28 + 8642: 1f 91 pop r17 + 8644: 0f 91 pop r16 + 8646: ff 90 pop r15 + 8648: ef 90 pop r14 + 864a: 08 95 ret + +0000864c : + *----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + 864c: 0f 93 push r16 + 864e: 1f 93 push r17 + 8650: cf 93 push r28 + 8652: df 93 push r29 + 8654: 8c 01 movw r16, r24 + 8656: eb 01 movw r28, r22 + portTickType xTimeToWake; + portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; + + vTaskSuspendAll(); + 8658: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + { + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + 865c: f8 01 movw r30, r16 + 865e: 20 81 ld r18, Z + 8660: 31 81 ldd r19, Z+1 ; 0x01 + 8662: c2 0f add r28, r18 + 8664: d3 1f adc r29, r19 + + if( xTickCount < *pxPreviousWakeTime ) + 8666: 80 91 d6 01 lds r24, 0x01D6 + 866a: 90 91 d7 01 lds r25, 0x01D7 + 866e: 82 17 cp r24, r18 + 8670: 93 07 cpc r25, r19 + 8672: 20 f4 brcc .+8 ; 0x867c + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) ) + 8674: c2 17 cp r28, r18 + 8676: d3 07 cpc r29, r19 + 8678: 60 f4 brcc .+24 ; 0x8692 + 867a: 03 c0 rjmp .+6 ; 0x8682 + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ) + 867c: c2 17 cp r28, r18 + 867e: d3 07 cpc r29, r19 + 8680: 50 f0 brcs .+20 ; 0x8696 + 8682: 20 91 d6 01 lds r18, 0x01D6 + 8686: 30 91 d7 01 lds r19, 0x01D7 + 868a: 91 e0 ldi r25, 0x01 ; 1 + 868c: 2c 17 cp r18, r28 + 868e: 3d 07 cpc r19, r29 + 8690: 18 f0 brcs .+6 ; 0x8698 +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + portTickType xTimeToWake; + portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; + 8692: 90 e0 ldi r25, 0x00 ; 0 + 8694: 01 c0 rjmp .+2 ; 0x8698 + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ) + { + xShouldDelay = pdTRUE; + 8696: 91 e0 ldi r25, 0x01 ; 1 + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + 8698: f8 01 movw r30, r16 + 869a: d1 83 std Z+1, r29 ; 0x01 + 869c: c0 83 st Z, r28 + + if( xShouldDelay ) + 869e: 99 23 and r25, r25 + 86a0: 29 f1 breq .+74 ; 0x86ec + traceTASK_DELAY_UNTIL(); + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 86a2: 80 91 93 01 lds r24, 0x0193 + 86a6: 90 91 94 01 lds r25, 0x0194 + 86aa: 02 96 adiw r24, 0x02 ; 2 + 86ac: 0e 94 bb 48 call 0x9176 ; 0x9176 + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + 86b0: e0 91 93 01 lds r30, 0x0193 + 86b4: f0 91 94 01 lds r31, 0x0194 + 86b8: d3 83 std Z+3, r29 ; 0x03 + 86ba: c2 83 std Z+2, r28 ; 0x02 + + if( xTimeToWake < xTickCount ) + 86bc: 80 91 d6 01 lds r24, 0x01D6 + 86c0: 90 91 d7 01 lds r25, 0x01D7 + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 86c4: 60 91 93 01 lds r22, 0x0193 + 86c8: 70 91 94 01 lds r23, 0x0194 + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + 86cc: c8 17 cp r28, r24 + 86ce: d9 07 cpc r29, r25 + 86d0: 28 f4 brcc .+10 ; 0x86dc + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 86d2: 80 91 eb 01 lds r24, 0x01EB + 86d6: 90 91 ec 01 lds r25, 0x01EC + 86da: 04 c0 rjmp .+8 ; 0x86e4 + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 86dc: 80 91 ed 01 lds r24, 0x01ED + 86e0: 90 91 ee 01 lds r25, 0x01EE + 86e4: 6e 5f subi r22, 0xFE ; 254 + 86e6: 7f 4f sbci r23, 0xFF ; 255 + 86e8: 0e 94 84 48 call 0x9108 ; 0x9108 + } + } + } + xAlreadyYielded = xTaskResumeAll(); + 86ec: 0e 94 b5 42 call 0x856a ; 0x856a + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + 86f0: 81 11 cpse r24, r1 + 86f2: 02 c0 rjmp .+4 ; 0x86f8 + { + portYIELD_WITHIN_API(); + 86f4: 0e 94 81 4b call 0x9702 ; 0x9702 + } + } + 86f8: df 91 pop r29 + 86fa: cf 91 pop r28 + 86fc: 1f 91 pop r17 + 86fe: 0f 91 pop r16 + 8700: 08 95 ret + +00008702 : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( portTickType xTicksToDelay ) + { + 8702: cf 93 push r28 + 8704: df 93 push r29 + 8706: ec 01 movw r28, r24 + portTickType xTimeToWake; + signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( portTickType ) 0 ) + 8708: 89 2b or r24, r25 + 870a: 19 f4 brne .+6 ; 0x8712 + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + { + portYIELD_WITHIN_API(); + 870c: 0e 94 81 4b call 0x9702 ; 0x9702 + 8710: 31 c0 rjmp .+98 ; 0x8774 + signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( portTickType ) 0 ) + { + vTaskSuspendAll(); + 8712: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + This task cannot be in an event list as it is the currently + executing task. */ + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xTickCount + xTicksToDelay; + 8716: 20 91 d6 01 lds r18, 0x01D6 + 871a: 30 91 d7 01 lds r19, 0x01D7 + 871e: c2 0f add r28, r18 + 8720: d3 1f adc r29, r19 + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 8722: 80 91 93 01 lds r24, 0x0193 + 8726: 90 91 94 01 lds r25, 0x0194 + 872a: 02 96 adiw r24, 0x02 ; 2 + 872c: 0e 94 bb 48 call 0x9176 ; 0x9176 + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + 8730: e0 91 93 01 lds r30, 0x0193 + 8734: f0 91 94 01 lds r31, 0x0194 + 8738: d3 83 std Z+3, r29 ; 0x03 + 873a: c2 83 std Z+2, r28 ; 0x02 + + if( xTimeToWake < xTickCount ) + 873c: 80 91 d6 01 lds r24, 0x01D6 + 8740: 90 91 d7 01 lds r25, 0x01D7 + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 8744: 60 91 93 01 lds r22, 0x0193 + 8748: 70 91 94 01 lds r23, 0x0194 + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + 874c: c8 17 cp r28, r24 + 874e: d9 07 cpc r29, r25 + 8750: 28 f4 brcc .+10 ; 0x875c + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 8752: 80 91 eb 01 lds r24, 0x01EB + 8756: 90 91 ec 01 lds r25, 0x01EC + 875a: 04 c0 rjmp .+8 ; 0x8764 + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 875c: 80 91 ed 01 lds r24, 0x01ED + 8760: 90 91 ee 01 lds r25, 0x01EE + 8764: 6e 5f subi r22, 0xFE ; 254 + 8766: 7f 4f sbci r23, 0xFF ; 255 + 8768: 0e 94 84 48 call 0x9108 ; 0x9108 + } + } + xAlreadyYielded = xTaskResumeAll(); + 876c: 0e 94 b5 42 call 0x856a ; 0x856a + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + 8770: 88 23 and r24, r24 + 8772: 61 f2 breq .-104 ; 0x870c + { + portYIELD_WITHIN_API(); + } + } + 8774: df 91 pop r29 + 8776: cf 91 pop r28 + 8778: 08 95 ret + +0000877a : +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskList( signed char *pcWriteBuffer ) + { + 877a: 0f 93 push r16 + 877c: 1f 93 push r17 + 877e: cf 93 push r28 + 8780: df 93 push r29 + 8782: ec 01 movw r28, r24 + unsigned portBASE_TYPE uxQueue; + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + 8784: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + { + /* Run through all the lists that could potentially contain a TCB and + report the task name, state and stack high water mark. */ + + pcWriteBuffer[ 0 ] = ( signed char ) 0x00; + 8788: 18 82 st Y, r1 + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + 878a: 6a e2 ldi r22, 0x2A ; 42 + 878c: 71 e0 ldi r23, 0x01 ; 1 + 878e: ce 01 movw r24, r28 + 8790: 0e 94 86 4f call 0x9f0c ; 0x9f0c + + uxQueue = uxTopUsedPriority + 1; + 8794: 10 91 d5 01 lds r17, 0x01D5 + 8798: 1f 5f subi r17, 0xFF ; 255 + + do + { + uxQueue--; + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + 879a: 09 e0 ldi r16, 0x09 ; 9 + + uxQueue = uxTopUsedPriority + 1; + + do + { + uxQueue--; + 879c: 11 50 subi r17, 0x01 ; 1 + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + 879e: 01 9f mul r16, r17 + 87a0: b0 01 movw r22, r0 + 87a2: 11 24 eor r1, r1 + 87a4: 6f 5f subi r22, 0xFF ; 255 + 87a6: 7d 4f sbci r23, 0xFD ; 253 + 87a8: fb 01 movw r30, r22 + 87aa: 80 81 ld r24, Z + 87ac: 88 23 and r24, r24 + 87ae: 21 f0 breq .+8 ; 0x87b8 + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); + 87b0: 42 e5 ldi r20, 0x52 ; 82 + 87b2: ce 01 movw r24, r28 + 87b4: 0e 94 ed 3e call 0x7dda ; 0x7dda + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + 87b8: 11 11 cpse r17, r1 + 87ba: f0 cf rjmp .-32 ; 0x879c + + if( !listLIST_IS_EMPTY( pxDelayedTaskList ) ) + 87bc: e0 91 ed 01 lds r30, 0x01ED + 87c0: f0 91 ee 01 lds r31, 0x01EE + 87c4: 80 81 ld r24, Z + 87c6: 88 23 and r24, r24 + 87c8: 41 f0 breq .+16 ; 0x87da + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); + 87ca: 60 91 ed 01 lds r22, 0x01ED + 87ce: 70 91 ee 01 lds r23, 0x01EE + 87d2: 42 e4 ldi r20, 0x42 ; 66 + 87d4: ce 01 movw r24, r28 + 87d6: 0e 94 ed 3e call 0x7dda ; 0x7dda + } + + if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + 87da: e0 91 eb 01 lds r30, 0x01EB + 87de: f0 91 ec 01 lds r31, 0x01EC + 87e2: 80 81 ld r24, Z + 87e4: 88 23 and r24, r24 + 87e6: 41 f0 breq .+16 ; 0x87f8 + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR ); + 87e8: 60 91 eb 01 lds r22, 0x01EB + 87ec: 70 91 ec 01 lds r23, 0x01EC + 87f0: 42 e4 ldi r20, 0x42 ; 66 + 87f2: ce 01 movw r24, r28 + 87f4: 0e 94 ed 3e call 0x7dda ; 0x7dda + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + 87f8: 80 91 d9 01 lds r24, 0x01D9 + 87fc: 88 23 and r24, r24 + 87fe: 31 f0 breq .+12 ; 0x880c + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR ); + 8800: 43 e5 ldi r20, 0x53 ; 83 + 8802: 69 ed ldi r22, 0xD9 ; 217 + 8804: 71 e0 ldi r23, 0x01 ; 1 + 8806: ce 01 movw r24, r28 + 8808: 0e 94 ed 3e call 0x7dda ; 0x7dda + } + } + #endif + } + xTaskResumeAll(); + } + 880c: df 91 pop r29 + 880e: cf 91 pop r28 + 8810: 1f 91 pop r17 + 8812: 0f 91 pop r16 + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR ); + } + } + #endif + } + xTaskResumeAll(); + 8814: 0c 94 b5 42 jmp 0x856a ; 0x856a + +00008818 : +#endif +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) + 8818: 80 91 d2 01 lds r24, 0x01D2 + 881c: 88 23 and r24, r24 + 881e: 21 f0 breq .+8 ; 0x8828 + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xMissedYield = pdTRUE; + 8820: 81 e0 ldi r24, 0x01 ; 1 + 8822: 80 93 d0 01 sts 0x01D0, r24 + return; + 8826: 08 95 ret + + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + /* Find the highest priority queue that contains ready tasks. */ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) + 8828: 99 e0 ldi r25, 0x09 ; 9 + 882a: e0 91 d4 01 lds r30, 0x01D4 + 882e: 9e 9f mul r25, r30 + 8830: f0 01 movw r30, r0 + 8832: 11 24 eor r1, r1 + 8834: ef 5f subi r30, 0xFF ; 255 + 8836: fd 4f sbci r31, 0xFD ; 253 + 8838: 80 81 ld r24, Z + 883a: 81 11 cpse r24, r1 + 883c: 06 c0 rjmp .+12 ; 0x884a + { + --uxTopReadyPriority; + 883e: 80 91 d4 01 lds r24, 0x01D4 + 8842: 81 50 subi r24, 0x01 ; 1 + 8844: 80 93 d4 01 sts 0x01D4, r24 + 8848: f0 cf rjmp .-32 ; 0x882a + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the + same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); + 884a: 80 91 d4 01 lds r24, 0x01D4 + 884e: 90 e0 ldi r25, 0x00 ; 0 + 8850: 49 e0 ldi r20, 0x09 ; 9 + 8852: 48 9f mul r20, r24 + 8854: 90 01 movw r18, r0 + 8856: 49 9f mul r20, r25 + 8858: 30 0d add r19, r0 + 885a: 11 24 eor r1, r1 + 885c: f9 01 movw r30, r18 + 885e: ef 5f subi r30, 0xFF ; 255 + 8860: fd 4f sbci r31, 0xFD ; 253 + 8862: a1 81 ldd r26, Z+1 ; 0x01 + 8864: b2 81 ldd r27, Z+2 ; 0x02 + 8866: 12 96 adiw r26, 0x02 ; 2 + 8868: 0d 90 ld r0, X+ + 886a: bc 91 ld r27, X + 886c: a0 2d mov r26, r0 + 886e: b2 83 std Z+2, r27 ; 0x02 + 8870: a1 83 std Z+1, r26 ; 0x01 + 8872: 2c 5f subi r18, 0xFC ; 252 + 8874: 3d 4f sbci r19, 0xFD ; 253 + 8876: a2 17 cp r26, r18 + 8878: b3 07 cpc r27, r19 + 887a: 31 f4 brne .+12 ; 0x8888 + 887c: 12 96 adiw r26, 0x02 ; 2 + 887e: 2d 91 ld r18, X+ + 8880: 3c 91 ld r19, X + 8882: 13 97 sbiw r26, 0x03 ; 3 + 8884: 32 83 std Z+2, r19 ; 0x02 + 8886: 21 83 std Z+1, r18 ; 0x01 + 8888: 29 e0 ldi r18, 0x09 ; 9 + 888a: 28 9f mul r18, r24 + 888c: f0 01 movw r30, r0 + 888e: 29 9f mul r18, r25 + 8890: f0 0d add r31, r0 + 8892: 11 24 eor r1, r1 + 8894: ef 5f subi r30, 0xFF ; 255 + 8896: fd 4f sbci r31, 0xFD ; 253 + 8898: 01 80 ldd r0, Z+1 ; 0x01 + 889a: f2 81 ldd r31, Z+2 ; 0x02 + 889c: e0 2d mov r30, r0 + 889e: 86 81 ldd r24, Z+6 ; 0x06 + 88a0: 97 81 ldd r25, Z+7 ; 0x07 + 88a2: 90 93 94 01 sts 0x0194, r25 + 88a6: 80 93 93 01 sts 0x0193, r24 + + traceTASK_SWITCHED_IN(); + vWriteTraceToBuffer(); + 88aa: 80 91 c7 01 lds r24, 0x01C7 + 88ae: 88 23 and r24, r24 + 88b0: 09 f4 brne .+2 ; 0x88b4 + 88b2: 4c c0 rjmp .+152 ; 0x894c + 88b4: e0 91 93 01 lds r30, 0x0193 + 88b8: f0 91 94 01 lds r31, 0x0194 + 88bc: 90 91 04 01 lds r25, 0x0104 + 88c0: 83 a1 ldd r24, Z+35 ; 0x23 + 88c2: 98 17 cp r25, r24 + 88c4: 09 f4 brne .+2 ; 0x88c8 + 88c6: 42 c0 rjmp .+132 ; 0x894c + 88c8: 80 91 cc 01 lds r24, 0x01CC + 88cc: 90 91 cd 01 lds r25, 0x01CD + 88d0: 08 96 adiw r24, 0x08 ; 8 + 88d2: 20 91 c8 01 lds r18, 0x01C8 + 88d6: 30 91 c9 01 lds r19, 0x01C9 + 88da: 82 17 cp r24, r18 + 88dc: 93 07 cpc r25, r19 + 88de: a0 f5 brcc .+104 ; 0x8948 + 88e0: e0 91 93 01 lds r30, 0x0193 + 88e4: f0 91 94 01 lds r31, 0x0194 + 88e8: 83 a1 ldd r24, Z+35 ; 0x23 + 88ea: 80 93 04 01 sts 0x0104, r24 + 88ee: e0 91 cc 01 lds r30, 0x01CC + 88f2: f0 91 cd 01 lds r31, 0x01CD + 88f6: 40 91 d6 01 lds r20, 0x01D6 + 88fa: 50 91 d7 01 lds r21, 0x01D7 + 88fe: 60 e0 ldi r22, 0x00 ; 0 + 8900: 70 e0 ldi r23, 0x00 ; 0 + 8902: 40 83 st Z, r20 + 8904: 51 83 std Z+1, r21 ; 0x01 + 8906: 62 83 std Z+2, r22 ; 0x02 + 8908: 73 83 std Z+3, r23 ; 0x03 + 890a: 20 91 cc 01 lds r18, 0x01CC + 890e: 30 91 cd 01 lds r19, 0x01CD + 8912: 2c 5f subi r18, 0xFC ; 252 + 8914: 3f 4f sbci r19, 0xFF ; 255 + 8916: 30 93 cd 01 sts 0x01CD, r19 + 891a: 20 93 cc 01 sts 0x01CC, r18 + 891e: e0 91 cc 01 lds r30, 0x01CC + 8922: f0 91 cd 01 lds r31, 0x01CD + 8926: 90 e0 ldi r25, 0x00 ; 0 + 8928: a0 e0 ldi r26, 0x00 ; 0 + 892a: b0 e0 ldi r27, 0x00 ; 0 + 892c: 80 83 st Z, r24 + 892e: 91 83 std Z+1, r25 ; 0x01 + 8930: a2 83 std Z+2, r26 ; 0x02 + 8932: b3 83 std Z+3, r27 ; 0x03 + 8934: 80 91 cc 01 lds r24, 0x01CC + 8938: 90 91 cd 01 lds r25, 0x01CD + 893c: 04 96 adiw r24, 0x04 ; 4 + 893e: 90 93 cd 01 sts 0x01CD, r25 + 8942: 80 93 cc 01 sts 0x01CC, r24 + 8946: 08 95 ret + 8948: 10 92 c7 01 sts 0x01C7, r1 + 894c: 08 95 ret + +0000894e : +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) +{ + 894e: cf 93 push r28 + 8950: df 93 push r29 + 8952: eb 01 movw r28, r22 + SCHEDULER SUSPENDED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. */ + vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); + 8954: 20 91 93 01 lds r18, 0x0193 + 8958: 30 91 94 01 lds r19, 0x0194 + 895c: b9 01 movw r22, r18 + 895e: 64 5f subi r22, 0xF4 ; 244 + 8960: 7f 4f sbci r23, 0xFF ; 255 + 8962: 0e 94 84 48 call 0x9108 ; 0x9108 + + /* We must remove ourselves from the ready list before adding ourselves + to the blocked list as the same list item is used for both lists. We have + exclusive access to the ready lists as the scheduler is locked. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 8966: 80 91 93 01 lds r24, 0x0193 + 896a: 90 91 94 01 lds r25, 0x0194 + 896e: 02 96 adiw r24, 0x02 ; 2 + 8970: 0e 94 bb 48 call 0x9176 ; 0x9176 + + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + 8974: cf 3f cpi r28, 0xFF ; 255 + 8976: 8f ef ldi r24, 0xFF ; 255 + 8978: d8 07 cpc r29, r24 + 897a: 61 f4 brne .+24 ; 0x8994 + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 897c: 60 91 93 01 lds r22, 0x0193 + 8980: 70 91 94 01 lds r23, 0x0194 + 8984: 6e 5f subi r22, 0xFE ; 254 + 8986: 7f 4f sbci r23, 0xFF ; 255 + 8988: 89 ed ldi r24, 0xD9 ; 217 + 898a: 91 e0 ldi r25, 0x01 ; 1 + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} + 898c: df 91 pop r29 + 898e: cf 91 pop r28 + if( xTicksToWait == portMAX_DELAY ) + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 8990: 0c 94 61 48 jmp 0x90c2 ; 0x90c2 + } + else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + 8994: 80 91 d6 01 lds r24, 0x01D6 + 8998: 90 91 d7 01 lds r25, 0x01D7 + 899c: be 01 movw r22, r28 + 899e: 68 0f add r22, r24 + 89a0: 79 1f adc r23, r25 + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + 89a2: e0 91 93 01 lds r30, 0x0193 + 89a6: f0 91 94 01 lds r31, 0x0194 + 89aa: 73 83 std Z+3, r23 ; 0x03 + 89ac: 62 83 std Z+2, r22 ; 0x02 + + if( xTimeToWake < xTickCount ) + 89ae: 80 91 d6 01 lds r24, 0x01D6 + 89b2: 90 91 d7 01 lds r25, 0x01D7 + 89b6: 68 17 cp r22, r24 + 89b8: 79 07 cpc r23, r25 + 89ba: 48 f4 brcc .+18 ; 0x89ce + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 89bc: 60 91 93 01 lds r22, 0x0193 + 89c0: 70 91 94 01 lds r23, 0x0194 + 89c4: 80 91 eb 01 lds r24, 0x01EB + 89c8: 90 91 ec 01 lds r25, 0x01EC + 89cc: 08 c0 rjmp .+16 ; 0x89de + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 89ce: 60 91 93 01 lds r22, 0x0193 + 89d2: 70 91 94 01 lds r23, 0x0194 + 89d6: 80 91 ed 01 lds r24, 0x01ED + 89da: 90 91 ee 01 lds r25, 0x01EE + 89de: 6e 5f subi r22, 0xFE ; 254 + 89e0: 7f 4f sbci r23, 0xFF ; 255 + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} + 89e2: df 91 pop r29 + 89e4: cf 91 pop r28 + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 89e6: 0c 94 84 48 jmp 0x9108 ; 0x9108 + +000089ea : + #endif +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) +{ + 89ea: 0f 93 push r16 + 89ec: 1f 93 push r17 + 89ee: cf 93 push r28 + 89f0: df 93 push r29 + it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means we can always expect exclusive access to the event list here. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + 89f2: dc 01 movw r26, r24 + 89f4: 2c 91 ld r18, X + 89f6: 22 23 and r18, r18 + 89f8: 39 f0 breq .+14 ; 0x8a08 + 89fa: 15 96 adiw r26, 0x05 ; 5 + 89fc: ed 91 ld r30, X+ + 89fe: fc 91 ld r31, X + 8a00: 16 97 sbiw r26, 0x06 ; 6 + 8a02: c6 81 ldd r28, Z+6 ; 0x06 + 8a04: d7 81 ldd r29, Z+7 ; 0x07 + 8a06: 02 c0 rjmp .+4 ; 0x8a0c + 8a08: c0 e0 ldi r28, 0x00 ; 0 + 8a0a: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedTCB->xEventListItem ) ); + 8a0c: 8e 01 movw r16, r28 + 8a0e: 04 5f subi r16, 0xF4 ; 244 + 8a10: 1f 4f sbci r17, 0xFF ; 255 + 8a12: c8 01 movw r24, r16 + 8a14: 0e 94 bb 48 call 0x9176 ; 0x9176 + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 8a18: 80 91 d2 01 lds r24, 0x01D2 + 8a1c: 81 11 cpse r24, r1 + 8a1e: 14 c0 rjmp .+40 ; 0x8a48 + { + vListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + 8a20: 0a 50 subi r16, 0x0A ; 10 + 8a22: 11 09 sbc r17, r1 + 8a24: c8 01 movw r24, r16 + 8a26: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddTaskToReadyQueue( pxUnblockedTCB ); + 8a2a: 9e 89 ldd r25, Y+22 ; 0x16 + 8a2c: 80 91 d4 01 lds r24, 0x01D4 + 8a30: 89 17 cp r24, r25 + 8a32: 10 f4 brcc .+4 ; 0x8a38 + 8a34: 90 93 d4 01 sts 0x01D4, r25 + 8a38: b9 e0 ldi r27, 0x09 ; 9 + 8a3a: 9b 9f mul r25, r27 + 8a3c: c0 01 movw r24, r0 + 8a3e: 11 24 eor r1, r1 + 8a40: b8 01 movw r22, r16 + 8a42: 8f 5f subi r24, 0xFF ; 255 + 8a44: 9d 4f sbci r25, 0xFD ; 253 + 8a46: 03 c0 rjmp .+6 ; 0x8a4e + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + 8a48: b8 01 movw r22, r16 + 8a4a: 82 ee ldi r24, 0xE2 ; 226 + 8a4c: 91 e0 ldi r25, 0x01 ; 1 + 8a4e: 0e 94 61 48 call 0x90c2 ; 0x90c2 + } + + if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 8a52: e0 91 93 01 lds r30, 0x0193 + 8a56: f0 91 94 01 lds r31, 0x0194 + 8a5a: 81 e0 ldi r24, 0x01 ; 1 + 8a5c: 2e 89 ldd r18, Y+22 ; 0x16 + 8a5e: 96 89 ldd r25, Z+22 ; 0x16 + 8a60: 29 17 cp r18, r25 + 8a62: 08 f4 brcc .+2 ; 0x8a66 + 8a64: 80 e0 ldi r24, 0x00 ; 0 + { + xReturn = pdFALSE; + } + + return xReturn; +} + 8a66: df 91 pop r29 + 8a68: cf 91 pop r28 + 8a6a: 1f 91 pop r17 + 8a6c: 0f 91 pop r16 + 8a6e: 08 95 ret + +00008a70 : +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) +{ + pxTimeOut->xOverflowCount = xNumOfOverflows; + 8a70: 20 91 cf 01 lds r18, 0x01CF + 8a74: fc 01 movw r30, r24 + 8a76: 20 83 st Z, r18 + pxTimeOut->xTimeOnEntering = xTickCount; + 8a78: 20 91 d6 01 lds r18, 0x01D6 + 8a7c: 30 91 d7 01 lds r19, 0x01D7 + 8a80: 32 83 std Z+2, r19 ; 0x02 + 8a82: 21 83 std Z+1, r18 ; 0x01 + 8a84: 08 95 ret + +00008a86 : + +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + portENTER_CRITICAL(); + 8a86: 0f b6 in r0, 0x3f ; 63 + 8a88: f8 94 cli + 8a8a: 0f 92 push r0 + { + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + 8a8c: db 01 movw r26, r22 + 8a8e: 2d 91 ld r18, X+ + 8a90: 3c 91 ld r19, X + 8a92: 2f 3f cpi r18, 0xFF ; 255 + 8a94: bf ef ldi r27, 0xFF ; 255 + 8a96: 3b 07 cpc r19, r27 + 8a98: 31 f1 breq .+76 ; 0x8ae6 + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) ) + 8a9a: 50 91 cf 01 lds r21, 0x01CF + 8a9e: fc 01 movw r30, r24 + 8aa0: 40 81 ld r20, Z + 8aa2: 01 80 ldd r0, Z+1 ; 0x01 + 8aa4: f2 81 ldd r31, Z+2 ; 0x02 + 8aa6: e0 2d mov r30, r0 + 8aa8: 54 17 cp r21, r20 + 8aaa: 39 f0 breq .+14 ; 0x8aba + 8aac: 40 91 d6 01 lds r20, 0x01D6 + 8ab0: 50 91 d7 01 lds r21, 0x01D7 + 8ab4: 4e 17 cp r20, r30 + 8ab6: 5f 07 cpc r21, r31 + 8ab8: c0 f4 brcc .+48 ; 0x8aea + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait ) + 8aba: 40 91 d6 01 lds r20, 0x01D6 + 8abe: 50 91 d7 01 lds r21, 0x01D7 + 8ac2: 4e 1b sub r20, r30 + 8ac4: 5f 0b sbc r21, r31 + 8ac6: 42 17 cp r20, r18 + 8ac8: 53 07 cpc r21, r19 + 8aca: 78 f4 brcc .+30 ; 0x8aea + 8acc: db 01 movw r26, r22 + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ); + 8ace: 40 91 d6 01 lds r20, 0x01D6 + 8ad2: 50 91 d7 01 lds r21, 0x01D7 + 8ad6: 4e 1b sub r20, r30 + 8ad8: 5f 0b sbc r21, r31 + 8ada: 24 1b sub r18, r20 + 8adc: 35 0b sbc r19, r21 + 8ade: 2d 93 st X+, r18 + 8ae0: 3c 93 st X, r19 + vTaskSetTimeOutState( pxTimeOut ); + 8ae2: 0e 94 38 45 call 0x8a70 ; 0x8a70 + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + 8ae6: 80 e0 ldi r24, 0x00 ; 0 + 8ae8: 01 c0 rjmp .+2 ; 0x8aec + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + 8aea: 81 e0 ldi r24, 0x01 ; 1 + else + { + xReturn = pdTRUE; + } + } + portEXIT_CRITICAL(); + 8aec: 0f 90 pop r0 + 8aee: 0f be out 0x3f, r0 ; 63 + + return xReturn; +} + 8af0: 08 95 ret + +00008af2 : +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xMissedYield = pdTRUE; + 8af2: 81 e0 ldi r24, 0x01 ; 1 + 8af4: 80 93 d0 01 sts 0x01D0, r24 + 8af8: 08 95 ret + +00008afa : + vPortFree( pxQueue ); +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) +{ + 8afa: cf 93 push r28 + 8afc: df 93 push r29 + 8afe: ec 01 movw r28, r24 + 8b00: 94 2f mov r25, r20 + if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) + 8b02: 8c 8d ldd r24, Y+28 ; 0x1c + 8b04: 88 23 and r24, r24 + 8b06: 99 f1 breq .+102 ; 0x8b6e + 8b08: 48 2f mov r20, r24 + 8b0a: 50 e0 ldi r21, 0x00 ; 0 + pxQueue->pxMutexHolder = NULL; + } + } + #endif + } + else if( xPosition == queueSEND_TO_BACK ) + 8b0c: 91 11 cpse r25, r1 + 8b0e: 15 c0 rjmp .+42 ; 0x8b3a + { + memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + 8b10: 8c 81 ldd r24, Y+4 ; 0x04 + 8b12: 9d 81 ldd r25, Y+5 ; 0x05 + 8b14: 0e 94 76 4f call 0x9eec ; 0x9eec + pxQueue->pcWriteTo += pxQueue->uxItemSize; + 8b18: 2c 8d ldd r18, Y+28 ; 0x1c + 8b1a: 8c 81 ldd r24, Y+4 ; 0x04 + 8b1c: 9d 81 ldd r25, Y+5 ; 0x05 + 8b1e: 82 0f add r24, r18 + 8b20: 91 1d adc r25, r1 + 8b22: 9d 83 std Y+5, r25 ; 0x05 + 8b24: 8c 83 std Y+4, r24 ; 0x04 + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) + 8b26: 2a 81 ldd r18, Y+2 ; 0x02 + 8b28: 3b 81 ldd r19, Y+3 ; 0x03 + 8b2a: 82 17 cp r24, r18 + 8b2c: 93 07 cpc r25, r19 + 8b2e: f8 f0 brcs .+62 ; 0x8b6e + { + pxQueue->pcWriteTo = pxQueue->pcHead; + 8b30: 88 81 ld r24, Y + 8b32: 99 81 ldd r25, Y+1 ; 0x01 + 8b34: 9d 83 std Y+5, r25 ; 0x05 + 8b36: 8c 83 std Y+4, r24 ; 0x04 + 8b38: 1a c0 rjmp .+52 ; 0x8b6e + } + } + else + { + memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + 8b3a: 8e 81 ldd r24, Y+6 ; 0x06 + 8b3c: 9f 81 ldd r25, Y+7 ; 0x07 + 8b3e: 0e 94 76 4f call 0x9eec ; 0x9eec + pxQueue->pcReadFrom -= pxQueue->uxItemSize; + 8b42: 8c 8d ldd r24, Y+28 ; 0x1c + 8b44: 90 e0 ldi r25, 0x00 ; 0 + 8b46: 91 95 neg r25 + 8b48: 81 95 neg r24 + 8b4a: 91 09 sbc r25, r1 + 8b4c: 2e 81 ldd r18, Y+6 ; 0x06 + 8b4e: 3f 81 ldd r19, Y+7 ; 0x07 + 8b50: 28 0f add r18, r24 + 8b52: 39 1f adc r19, r25 + 8b54: 3f 83 std Y+7, r19 ; 0x07 + 8b56: 2e 83 std Y+6, r18 ; 0x06 + if( pxQueue->pcReadFrom < pxQueue->pcHead ) + 8b58: 48 81 ld r20, Y + 8b5a: 59 81 ldd r21, Y+1 ; 0x01 + 8b5c: 24 17 cp r18, r20 + 8b5e: 35 07 cpc r19, r21 + 8b60: 30 f4 brcc .+12 ; 0x8b6e + { + pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + 8b62: 2a 81 ldd r18, Y+2 ; 0x02 + 8b64: 3b 81 ldd r19, Y+3 ; 0x03 + 8b66: 82 0f add r24, r18 + 8b68: 93 1f adc r25, r19 + 8b6a: 9f 83 std Y+7, r25 ; 0x07 + 8b6c: 8e 83 std Y+6, r24 ; 0x06 + } + } + + ++( pxQueue->uxMessagesWaiting ); + 8b6e: 8a 8d ldd r24, Y+26 ; 0x1a + 8b70: 8f 5f subi r24, 0xFF ; 255 + 8b72: 8a 8f std Y+26, r24 ; 0x1a +} + 8b74: df 91 pop r29 + 8b76: cf 91 pop r28 + 8b78: 08 95 ret + +00008b7a : +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) +{ + 8b7a: fc 01 movw r30, r24 + 8b7c: cb 01 movw r24, r22 + if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) + 8b7e: a0 81 ld r26, Z + 8b80: b1 81 ldd r27, Z+1 ; 0x01 + 8b82: 10 97 sbiw r26, 0x00 ; 0 + 8b84: 99 f0 breq .+38 ; 0x8bac + { + pxQueue->pcReadFrom += pxQueue->uxItemSize; + 8b86: 44 8d ldd r20, Z+28 ; 0x1c + 8b88: 50 e0 ldi r21, 0x00 ; 0 + 8b8a: 26 81 ldd r18, Z+6 ; 0x06 + 8b8c: 37 81 ldd r19, Z+7 ; 0x07 + 8b8e: 24 0f add r18, r20 + 8b90: 35 1f adc r19, r21 + 8b92: 37 83 std Z+7, r19 ; 0x07 + 8b94: 26 83 std Z+6, r18 ; 0x06 + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + 8b96: 62 81 ldd r22, Z+2 ; 0x02 + 8b98: 73 81 ldd r23, Z+3 ; 0x03 + 8b9a: 26 17 cp r18, r22 + 8b9c: 37 07 cpc r19, r23 + 8b9e: 10 f0 brcs .+4 ; 0x8ba4 + { + pxQueue->pcReadFrom = pxQueue->pcHead; + 8ba0: b7 83 std Z+7, r27 ; 0x07 + 8ba2: a6 83 std Z+6, r26 ; 0x06 + } + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + 8ba4: 66 81 ldd r22, Z+6 ; 0x06 + 8ba6: 77 81 ldd r23, Z+7 ; 0x07 + 8ba8: 0c 94 76 4f jmp 0x9eec ; 0x9eec + 8bac: 08 95 ret + +00008bae : + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( xQueueHandle pxQueue ) +{ + 8bae: 0f 93 push r16 + 8bb0: 1f 93 push r17 + 8bb2: cf 93 push r28 + 8bb4: df 93 push r29 + 8bb6: ec 01 movw r28, r24 + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + 8bb8: 0f b6 in r0, 0x3f ; 63 + 8bba: f8 94 cli + 8bbc: 0f 92 push r0 + blocked waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 8bbe: 8c 01 movw r16, r24 + 8bc0: 0f 5e subi r16, 0xEF ; 239 + 8bc2: 1f 4f sbci r17, 0xFF ; 255 + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + /* See if data was added to the queue while it was locked. */ + while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) + 8bc4: 9e 8d ldd r25, Y+30 ; 0x1e + 8bc6: 19 16 cp r1, r25 + 8bc8: 6c f4 brge .+26 ; 0x8be4 + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 8bca: 89 89 ldd r24, Y+17 ; 0x11 + 8bcc: 88 23 and r24, r24 + 8bce: 51 f0 breq .+20 ; 0x8be4 + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 8bd0: c8 01 movw r24, r16 + 8bd2: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8bd6: 81 11 cpse r24, r1 + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + 8bd8: 0e 94 79 45 call 0x8af2 ; 0x8af2 + } + + --( pxQueue->xTxLock ); + 8bdc: 9e 8d ldd r25, Y+30 ; 0x1e + 8bde: 91 50 subi r25, 0x01 ; 1 + 8be0: 9e 8f std Y+30, r25 ; 0x1e + 8be2: f0 cf rjmp .-32 ; 0x8bc4 + { + break; + } + } + + pxQueue->xTxLock = queueUNLOCKED; + 8be4: 8f ef ldi r24, 0xFF ; 255 + 8be6: 8e 8f std Y+30, r24 ; 0x1e + } + taskEXIT_CRITICAL(); + 8be8: 0f 90 pop r0 + 8bea: 0f be out 0x3f, r0 ; 63 + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + 8bec: 0f b6 in r0, 0x3f ; 63 + 8bee: f8 94 cli + 8bf0: 0f 92 push r0 + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 8bf2: 8e 01 movw r16, r28 + 8bf4: 08 5f subi r16, 0xF8 ; 248 + 8bf6: 1f 4f sbci r17, 0xFF ; 255 + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + 8bf8: 9d 8d ldd r25, Y+29 ; 0x1d + 8bfa: 19 16 cp r1, r25 + 8bfc: 6c f4 brge .+26 ; 0x8c18 + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 8bfe: 88 85 ldd r24, Y+8 ; 0x08 + 8c00: 88 23 and r24, r24 + 8c02: 51 f0 breq .+20 ; 0x8c18 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 8c04: c8 01 movw r24, r16 + 8c06: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8c0a: 81 11 cpse r24, r1 + { + vTaskMissedYield(); + 8c0c: 0e 94 79 45 call 0x8af2 ; 0x8af2 + } + + --( pxQueue->xRxLock ); + 8c10: 9d 8d ldd r25, Y+29 ; 0x1d + 8c12: 91 50 subi r25, 0x01 ; 1 + 8c14: 9d 8f std Y+29, r25 ; 0x1d + 8c16: f0 cf rjmp .-32 ; 0x8bf8 + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + 8c18: 8f ef ldi r24, 0xFF ; 255 + 8c1a: 8d 8f std Y+29, r24 ; 0x1d + } + taskEXIT_CRITICAL(); + 8c1c: 0f 90 pop r0 + 8c1e: 0f be out 0x3f, r0 ; 63 +} + 8c20: df 91 pop r29 + 8c22: cf 91 pop r28 + 8c24: 1f 91 pop r17 + 8c26: 0f 91 pop r16 + 8c28: 08 95 ret + +00008c2a : +/*----------------------------------------------------------- + * PUBLIC QUEUE MANAGEMENT API documented in queue.h + *----------------------------------------------------------*/ + +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) +{ + 8c2a: cf 92 push r12 + 8c2c: df 92 push r13 + 8c2e: ef 92 push r14 + 8c30: ff 92 push r15 + 8c32: 0f 93 push r16 + 8c34: 1f 93 push r17 + 8c36: cf 93 push r28 + 8c38: df 93 push r29 +xQUEUE *pxNewQueue; +size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + 8c3a: 88 23 and r24, r24 + 8c3c: b1 f1 breq .+108 ; 0x8caa + 8c3e: f6 2e mov r15, r22 + 8c40: e8 2e mov r14, r24 + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + 8c42: 8f e1 ldi r24, 0x1F ; 31 + 8c44: 90 e0 ldi r25, 0x00 ; 0 + 8c46: 0e 94 a9 4a call 0x9552 ; 0x9552 + 8c4a: ec 01 movw r28, r24 + if( pxNewQueue != NULL ) + 8c4c: 89 2b or r24, r25 + 8c4e: 69 f1 breq .+90 ; 0x8caa + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + 8c50: cf 2c mov r12, r15 + 8c52: d1 2c mov r13, r1 + 8c54: ef 9c mul r14, r15 + 8c56: 80 01 movw r16, r0 + 8c58: 11 24 eor r1, r1 + + pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes ); + 8c5a: c8 01 movw r24, r16 + 8c5c: 01 96 adiw r24, 0x01 ; 1 + 8c5e: 0e 94 a9 4a call 0x9552 ; 0x9552 + 8c62: 99 83 std Y+1, r25 ; 0x01 + 8c64: 88 83 st Y, r24 + if( pxNewQueue->pcHead != NULL ) + 8c66: 00 97 sbiw r24, 0x00 ; 0 + 8c68: e9 f0 breq .+58 ; 0x8ca4 + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + 8c6a: 9c 01 movw r18, r24 + 8c6c: 20 0f add r18, r16 + 8c6e: 31 1f adc r19, r17 + 8c70: 3b 83 std Y+3, r19 ; 0x03 + 8c72: 2a 83 std Y+2, r18 ; 0x02 + pxNewQueue->uxMessagesWaiting = 0; + 8c74: 1a 8e std Y+26, r1 ; 0x1a + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + 8c76: 9d 83 std Y+5, r25 ; 0x05 + 8c78: 8c 83 std Y+4, r24 ; 0x04 + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + 8c7a: 0c 19 sub r16, r12 + 8c7c: 1d 09 sbc r17, r13 + 8c7e: 08 0f add r16, r24 + 8c80: 19 1f adc r17, r25 + 8c82: 1f 83 std Y+7, r17 ; 0x07 + 8c84: 0e 83 std Y+6, r16 ; 0x06 + pxNewQueue->uxLength = uxQueueLength; + 8c86: eb 8e std Y+27, r14 ; 0x1b + pxNewQueue->uxItemSize = uxItemSize; + 8c88: fc 8e std Y+28, r15 ; 0x1c + pxNewQueue->xRxLock = queueUNLOCKED; + 8c8a: 8f ef ldi r24, 0xFF ; 255 + 8c8c: 8d 8f std Y+29, r24 ; 0x1d + pxNewQueue->xTxLock = queueUNLOCKED; + 8c8e: 8e 8f std Y+30, r24 ; 0x1e + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + 8c90: ce 01 movw r24, r28 + 8c92: 08 96 adiw r24, 0x08 ; 8 + 8c94: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + 8c98: ce 01 movw r24, r28 + 8c9a: 41 96 adiw r24, 0x11 ; 17 + 8c9c: 0e 94 4f 48 call 0x909e ; 0x909e + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + 8ca0: ce 01 movw r24, r28 + 8ca2: 05 c0 rjmp .+10 ; 0x8cae + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + 8ca4: ce 01 movw r24, r28 + 8ca6: 0e 94 cf 4a call 0x959e ; 0x959e + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; + 8caa: 80 e0 ldi r24, 0x00 ; 0 + 8cac: 90 e0 ldi r25, 0x00 ; 0 +} + 8cae: df 91 pop r29 + 8cb0: cf 91 pop r28 + 8cb2: 1f 91 pop r17 + 8cb4: 0f 91 pop r16 + 8cb6: ff 90 pop r15 + 8cb8: ef 90 pop r14 + 8cba: df 90 pop r13 + 8cbc: cf 90 pop r12 + 8cbe: 08 95 ret + +00008cc0 : + +xQueueHandle xQueueCreateExternal( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, void *address ) +{ + 8cc0: ef 92 push r14 + 8cc2: ff 92 push r15 + 8cc4: 0f 93 push r16 + 8cc6: 1f 93 push r17 + 8cc8: cf 93 push r28 + 8cca: df 93 push r29 + xQUEUE *pxNewQueue; + //size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + 8ccc: 88 23 and r24, r24 + 8cce: 89 f1 breq .+98 ; 0x8d32 + 8cd0: 8a 01 movw r16, r20 + 8cd2: f6 2e mov r15, r22 + 8cd4: e8 2e mov r14, r24 + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + 8cd6: 8f e1 ldi r24, 0x1F ; 31 + 8cd8: 90 e0 ldi r25, 0x00 ; 0 + 8cda: 0e 94 a9 4a call 0x9552 ; 0x9552 + 8cde: ec 01 movw r28, r24 + if( pxNewQueue != NULL ) + 8ce0: 00 97 sbiw r24, 0x00 ; 0 + 8ce2: 39 f1 breq .+78 ; 0x8d32 + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + //xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + + pxNewQueue->pcHead = ( signed char * ) (address); + 8ce4: 19 83 std Y+1, r17 ; 0x01 + 8ce6: 08 83 st Y, r16 + if( pxNewQueue->pcHead != NULL ) + 8ce8: 01 15 cp r16, r1 + 8cea: 11 05 cpc r17, r1 + 8cec: 01 f1 breq .+64 ; 0x8d2e + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + 8cee: ef 9c mul r14, r15 + 8cf0: a0 01 movw r20, r0 + 8cf2: 11 24 eor r1, r1 + 8cf4: c8 01 movw r24, r16 + 8cf6: 84 0f add r24, r20 + 8cf8: 95 1f adc r25, r21 + 8cfa: 9b 83 std Y+3, r25 ; 0x03 + 8cfc: 8a 83 std Y+2, r24 ; 0x02 + pxNewQueue->uxMessagesWaiting = 0; + 8cfe: 1a 8e std Y+26, r1 ; 0x1a + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + 8d00: 1d 83 std Y+5, r17 ; 0x05 + 8d02: 0c 83 std Y+4, r16 ; 0x04 + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + 8d04: 4f 19 sub r20, r15 + 8d06: 51 09 sbc r21, r1 + 8d08: 04 0f add r16, r20 + 8d0a: 15 1f adc r17, r21 + 8d0c: 1f 83 std Y+7, r17 ; 0x07 + 8d0e: 0e 83 std Y+6, r16 ; 0x06 + pxNewQueue->uxLength = uxQueueLength; + 8d10: eb 8e std Y+27, r14 ; 0x1b + pxNewQueue->uxItemSize = uxItemSize; + 8d12: fc 8e std Y+28, r15 ; 0x1c + pxNewQueue->xRxLock = queueUNLOCKED; + 8d14: 8f ef ldi r24, 0xFF ; 255 + 8d16: 8d 8f std Y+29, r24 ; 0x1d + pxNewQueue->xTxLock = queueUNLOCKED; + 8d18: 8e 8f std Y+30, r24 ; 0x1e + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + 8d1a: ce 01 movw r24, r28 + 8d1c: 08 96 adiw r24, 0x08 ; 8 + 8d1e: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + 8d22: ce 01 movw r24, r28 + 8d24: 41 96 adiw r24, 0x11 ; 17 + 8d26: 0e 94 4f 48 call 0x909e ; 0x909e + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + 8d2a: ce 01 movw r24, r28 + 8d2c: 04 c0 rjmp .+8 ; 0x8d36 + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + 8d2e: 0e 94 cf 4a call 0x959e ; 0x959e + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; + 8d32: 80 e0 ldi r24, 0x00 ; 0 + 8d34: 90 e0 ldi r25, 0x00 ; 0 +} + 8d36: df 91 pop r29 + 8d38: cf 91 pop r28 + 8d3a: 1f 91 pop r17 + 8d3c: 0f 91 pop r16 + 8d3e: ff 90 pop r15 + 8d40: ef 90 pop r14 + 8d42: 08 95 ret + +00008d44 : + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) +{ + 8d44: af 92 push r10 + 8d46: bf 92 push r11 + 8d48: df 92 push r13 + 8d4a: ef 92 push r14 + 8d4c: ff 92 push r15 + 8d4e: 0f 93 push r16 + 8d50: 1f 93 push r17 + 8d52: cf 93 push r28 + 8d54: df 93 push r29 + 8d56: 00 d0 rcall .+0 ; 0x8d58 + 8d58: 00 d0 rcall .+0 ; 0x8d5a + 8d5a: 1f 92 push r1 + 8d5c: cd b7 in r28, 0x3d ; 61 + 8d5e: de b7 in r29, 0x3e ; 62 + 8d60: 8c 01 movw r16, r24 + 8d62: 7b 01 movw r14, r22 + 8d64: 5d 83 std Y+5, r21 ; 0x05 + 8d66: 4c 83 std Y+4, r20 ; 0x04 + 8d68: d2 2e mov r13, r18 +signed portBASE_TYPE xEntryTimeSet = pdFALSE; + 8d6a: 90 e0 ldi r25, 0x00 ; 0 + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + 8d6c: 58 01 movw r10, r16 + 8d6e: 88 e0 ldi r24, 0x08 ; 8 + 8d70: a8 0e add r10, r24 + 8d72: b1 1c adc r11, r1 + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + 8d74: 0f b6 in r0, 0x3f ; 63 + 8d76: f8 94 cli + 8d78: 0f 92 push r0 + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 8d7a: f8 01 movw r30, r16 + 8d7c: 22 8d ldd r18, Z+26 ; 0x1a + 8d7e: 83 8d ldd r24, Z+27 ; 0x1b + 8d80: 28 17 cp r18, r24 + 8d82: a8 f4 brcc .+42 ; 0x8dae + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + 8d84: 4d 2d mov r20, r13 + 8d86: b7 01 movw r22, r14 + 8d88: c8 01 movw r24, r16 + 8d8a: 0e 94 7d 45 call 0x8afa ; 0x8afa + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + 8d8e: f8 01 movw r30, r16 + 8d90: 81 89 ldd r24, Z+17 ; 0x11 + 8d92: 88 23 and r24, r24 + 8d94: 41 f0 breq .+16 ; 0x8da6 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + 8d96: c8 01 movw r24, r16 + 8d98: 41 96 adiw r24, 0x11 ; 17 + 8d9a: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8d9e: 81 30 cpi r24, 0x01 ; 1 + 8da0: 11 f4 brne .+4 ; 0x8da6 + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + portYIELD_WITHIN_API(); + 8da2: 0e 94 81 4b call 0x9702 ; 0x9702 + } + } + + taskEXIT_CRITICAL(); + 8da6: 0f 90 pop r0 + 8da8: 0f be out 0x3f, r0 ; 63 + + /* Return to the original privilege level before exiting the + function. */ + return pdPASS; + 8daa: 81 e0 ldi r24, 0x01 ; 1 + 8dac: 50 c0 rjmp .+160 ; 0x8e4e + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + 8dae: 2c 81 ldd r18, Y+4 ; 0x04 + 8db0: 3d 81 ldd r19, Y+5 ; 0x05 + 8db2: 23 2b or r18, r19 + 8db4: 19 f4 brne .+6 ; 0x8dbc + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + 8db6: 0f 90 pop r0 + 8db8: 0f be out 0x3f, r0 ; 63 + 8dba: 48 c0 rjmp .+144 ; 0x8e4c + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + 8dbc: 91 11 cpse r25, r1 + 8dbe: 04 c0 rjmp .+8 ; 0x8dc8 + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + 8dc0: ce 01 movw r24, r28 + 8dc2: 01 96 adiw r24, 0x01 ; 1 + 8dc4: 0e 94 38 45 call 0x8a70 ; 0x8a70 + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + 8dc8: 0f 90 pop r0 + 8dca: 0f be out 0x3f, r0 ; 63 + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + 8dcc: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + prvLockQueue( pxQueue ); + 8dd0: 0f b6 in r0, 0x3f ; 63 + 8dd2: f8 94 cli + 8dd4: 0f 92 push r0 + 8dd6: f8 01 movw r30, r16 + 8dd8: 85 8d ldd r24, Z+29 ; 0x1d + 8dda: 8f 3f cpi r24, 0xFF ; 255 + 8ddc: 09 f4 brne .+2 ; 0x8de0 + 8dde: 15 8e std Z+29, r1 ; 0x1d + 8de0: f8 01 movw r30, r16 + 8de2: 86 8d ldd r24, Z+30 ; 0x1e + 8de4: 8f 3f cpi r24, 0xFF ; 255 + 8de6: 09 f4 brne .+2 ; 0x8dea + 8de8: 16 8e std Z+30, r1 ; 0x1e + 8dea: 0f 90 pop r0 + 8dec: 0f be out 0x3f, r0 ; 63 + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + 8dee: be 01 movw r22, r28 + 8df0: 6c 5f subi r22, 0xFC ; 252 + 8df2: 7f 4f sbci r23, 0xFF ; 255 + 8df4: ce 01 movw r24, r28 + 8df6: 01 96 adiw r24, 0x01 ; 1 + 8df8: 0e 94 43 45 call 0x8a86 ; 0x8a86 + 8dfc: 81 11 cpse r24, r1 + 8dfe: 21 c0 rjmp .+66 ; 0x8e42 + +static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + 8e00: 0f b6 in r0, 0x3f ; 63 + 8e02: f8 94 cli + 8e04: 0f 92 push r0 + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + 8e06: f8 01 movw r30, r16 + 8e08: 92 8d ldd r25, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 8e0a: 0f 90 pop r0 + 8e0c: 0f be out 0x3f, r0 ; 63 + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + 8e0e: 83 8d ldd r24, Z+27 ; 0x1b + 8e10: 98 13 cpse r25, r24 + 8e12: 11 c0 rjmp .+34 ; 0x8e36 + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + 8e14: 6c 81 ldd r22, Y+4 ; 0x04 + 8e16: 7d 81 ldd r23, Y+5 ; 0x05 + 8e18: c5 01 movw r24, r10 + 8e1a: 0e 94 a7 44 call 0x894e ; 0x894e + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + 8e1e: c8 01 movw r24, r16 + 8e20: 0e 94 d7 45 call 0x8bae ; 0x8bae + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( !xTaskResumeAll() ) + 8e24: 0e 94 b5 42 call 0x856a ; 0x856a + 8e28: 88 23 and r24, r24 + 8e2a: 11 f0 breq .+4 ; 0x8e30 + 8e2c: 91 e0 ldi r25, 0x01 ; 1 + 8e2e: a2 cf rjmp .-188 ; 0x8d74 + { + portYIELD_WITHIN_API(); + 8e30: 0e 94 81 4b call 0x9702 ; 0x9702 + 8e34: fb cf rjmp .-10 ; 0x8e2c + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + 8e36: c8 01 movw r24, r16 + 8e38: 0e 94 d7 45 call 0x8bae ; 0x8bae + ( void ) xTaskResumeAll(); + 8e3c: 0e 94 b5 42 call 0x856a ; 0x856a + 8e40: f5 cf rjmp .-22 ; 0x8e2c + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + 8e42: c8 01 movw r24, r16 + 8e44: 0e 94 d7 45 call 0x8bae ; 0x8bae + ( void ) xTaskResumeAll(); + 8e48: 0e 94 b5 42 call 0x856a ; 0x856a + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + 8e4c: 80 e0 ldi r24, 0x00 ; 0 + } + } +} + 8e4e: 0f 90 pop r0 + 8e50: 0f 90 pop r0 + 8e52: 0f 90 pop r0 + 8e54: 0f 90 pop r0 + 8e56: 0f 90 pop r0 + 8e58: df 91 pop r29 + 8e5a: cf 91 pop r28 + 8e5c: 1f 91 pop r17 + 8e5e: 0f 91 pop r16 + 8e60: ff 90 pop r15 + 8e62: ef 90 pop r14 + 8e64: df 90 pop r13 + 8e66: bf 90 pop r11 + 8e68: af 90 pop r10 + 8e6a: 08 95 ret + +00008e6c : + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) +{ + 8e6c: 0f 93 push r16 + 8e6e: 1f 93 push r17 + 8e70: cf 93 push r28 + 8e72: df 93 push r29 + 8e74: ec 01 movw r28, r24 + queue read, instead we return a flag to say whether a context switch is + required or not (i.e. has a task with a higher priority than us been woken + by this post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 8e76: 9a 8d ldd r25, Y+26 ; 0x1a + 8e78: 8b 8d ldd r24, Y+27 ; 0x1b + 8e7a: 98 17 cp r25, r24 + 8e7c: c8 f4 brcc .+50 ; 0x8eb0 + 8e7e: 8a 01 movw r16, r20 + { + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + 8e80: 42 2f mov r20, r18 + 8e82: ce 01 movw r24, r28 + 8e84: 0e 94 7d 45 call 0x8afa ; 0x8afa + + /* If the queue is locked we do not alter the event list. This will + be done when the queue is unlocked later. */ + if( pxQueue->xTxLock == queueUNLOCKED ) + 8e88: 8e 8d ldd r24, Y+30 ; 0x1e + 8e8a: 8f 3f cpi r24, 0xFF ; 255 + 8e8c: 69 f4 brne .+26 ; 0x8ea8 + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 8e8e: 89 89 ldd r24, Y+17 ; 0x11 + 8e90: 88 23 and r24, r24 + 8e92: 61 f0 breq .+24 ; 0x8eac + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 8e94: ce 01 movw r24, r28 + 8e96: 41 96 adiw r24, 0x11 ; 17 + 8e98: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8e9c: 88 23 and r24, r24 + 8e9e: 31 f0 breq .+12 ; 0x8eac + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + *pxHigherPriorityTaskWoken = pdTRUE; + 8ea0: 81 e0 ldi r24, 0x01 ; 1 + 8ea2: f8 01 movw r30, r16 + 8ea4: 80 83 st Z, r24 + 8ea6: 05 c0 rjmp .+10 ; 0x8eb2 + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++( pxQueue->xTxLock ); + 8ea8: 8f 5f subi r24, 0xFF ; 255 + 8eaa: 8e 8f std Y+30, r24 ; 0x1e + } + + xReturn = pdPASS; + 8eac: 81 e0 ldi r24, 0x01 ; 1 + 8eae: 01 c0 rjmp .+2 ; 0x8eb2 + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + 8eb0: 80 e0 ldi r24, 0x00 ; 0 + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} + 8eb2: df 91 pop r29 + 8eb4: cf 91 pop r28 + 8eb6: 1f 91 pop r17 + 8eb8: 0f 91 pop r16 + 8eba: 08 95 ret + +00008ebc : +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) +{ + 8ebc: af 92 push r10 + 8ebe: bf 92 push r11 + 8ec0: df 92 push r13 + 8ec2: ef 92 push r14 + 8ec4: ff 92 push r15 + 8ec6: 0f 93 push r16 + 8ec8: 1f 93 push r17 + 8eca: cf 93 push r28 + 8ecc: df 93 push r29 + 8ece: 00 d0 rcall .+0 ; 0x8ed0 + 8ed0: 00 d0 rcall .+0 ; 0x8ed2 + 8ed2: 1f 92 push r1 + 8ed4: cd b7 in r28, 0x3d ; 61 + 8ed6: de b7 in r29, 0x3e ; 62 + 8ed8: 8c 01 movw r16, r24 + 8eda: 7b 01 movw r14, r22 + 8edc: 5d 83 std Y+5, r21 ; 0x05 + 8ede: 4c 83 std Y+4, r20 ; 0x04 + 8ee0: d2 2e mov r13, r18 +signed portBASE_TYPE xEntryTimeSet = pdFALSE; + 8ee2: 90 e0 ldi r25, 0x00 ; 0 + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + 8ee4: 58 01 movw r10, r16 + 8ee6: 81 e1 ldi r24, 0x11 ; 17 + 8ee8: a8 0e add r10, r24 + 8eea: b1 1c adc r11, r1 + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + 8eec: 0f b6 in r0, 0x3f ; 63 + 8eee: f8 94 cli + 8ef0: 0f 92 push r0 + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 8ef2: f8 01 movw r30, r16 + 8ef4: 82 8d ldd r24, Z+26 ; 0x1a + 8ef6: 88 23 and r24, r24 + 8ef8: 39 f1 breq .+78 ; 0x8f48 + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + 8efa: a6 80 ldd r10, Z+6 ; 0x06 + 8efc: b7 80 ldd r11, Z+7 ; 0x07 + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + 8efe: b7 01 movw r22, r14 + 8f00: c8 01 movw r24, r16 + 8f02: 0e 94 bd 45 call 0x8b7a ; 0x8b7a + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + 8f06: f8 01 movw r30, r16 + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + 8f08: d1 10 cpse r13, r1 + 8f0a: 0f c0 rjmp .+30 ; 0x8f2a + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + 8f0c: 82 8d ldd r24, Z+26 ; 0x1a + 8f0e: 81 50 subi r24, 0x01 ; 1 + 8f10: 82 8f std Z+26, r24 ; 0x1a + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + 8f12: 80 85 ldd r24, Z+8 ; 0x08 + 8f14: 88 23 and r24, r24 + 8f16: a1 f0 breq .+40 ; 0x8f40 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + 8f18: c8 01 movw r24, r16 + 8f1a: 08 96 adiw r24, 0x08 ; 8 + 8f1c: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8f20: 81 30 cpi r24, 0x01 ; 1 + 8f22: 71 f4 brne .+28 ; 0x8f40 + { + portYIELD_WITHIN_API(); + 8f24: 0e 94 81 4b call 0x9702 ; 0x9702 + 8f28: 0b c0 rjmp .+22 ; 0x8f40 + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + 8f2a: b7 82 std Z+7, r11 ; 0x07 + 8f2c: a6 82 std Z+6, r10 ; 0x06 + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 8f2e: 81 89 ldd r24, Z+17 ; 0x11 + 8f30: 88 23 and r24, r24 + 8f32: 31 f0 breq .+12 ; 0x8f40 + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 8f34: c8 01 movw r24, r16 + 8f36: 41 96 adiw r24, 0x11 ; 17 + 8f38: 0e 94 f5 44 call 0x89ea ; 0x89ea + 8f3c: 81 11 cpse r24, r1 + 8f3e: f2 cf rjmp .-28 ; 0x8f24 + } + } + + } + + taskEXIT_CRITICAL(); + 8f40: 0f 90 pop r0 + 8f42: 0f be out 0x3f, r0 ; 63 + return pdPASS; + 8f44: 81 e0 ldi r24, 0x01 ; 1 + 8f46: 4f c0 rjmp .+158 ; 0x8fe6 + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + 8f48: 2c 81 ldd r18, Y+4 ; 0x04 + 8f4a: 3d 81 ldd r19, Y+5 ; 0x05 + 8f4c: 23 2b or r18, r19 + 8f4e: 19 f4 brne .+6 ; 0x8f56 + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + 8f50: 0f 90 pop r0 + 8f52: 0f be out 0x3f, r0 ; 63 + 8f54: 47 c0 rjmp .+142 ; 0x8fe4 + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + 8f56: 91 11 cpse r25, r1 + 8f58: 04 c0 rjmp .+8 ; 0x8f62 + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + 8f5a: ce 01 movw r24, r28 + 8f5c: 01 96 adiw r24, 0x01 ; 1 + 8f5e: 0e 94 38 45 call 0x8a70 ; 0x8a70 + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + 8f62: 0f 90 pop r0 + 8f64: 0f be out 0x3f, r0 ; 63 + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + 8f66: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + prvLockQueue( pxQueue ); + 8f6a: 0f b6 in r0, 0x3f ; 63 + 8f6c: f8 94 cli + 8f6e: 0f 92 push r0 + 8f70: f8 01 movw r30, r16 + 8f72: 85 8d ldd r24, Z+29 ; 0x1d + 8f74: 8f 3f cpi r24, 0xFF ; 255 + 8f76: 09 f4 brne .+2 ; 0x8f7a + 8f78: 15 8e std Z+29, r1 ; 0x1d + 8f7a: f8 01 movw r30, r16 + 8f7c: 86 8d ldd r24, Z+30 ; 0x1e + 8f7e: 8f 3f cpi r24, 0xFF ; 255 + 8f80: 09 f4 brne .+2 ; 0x8f84 + 8f82: 16 8e std Z+30, r1 ; 0x1e + 8f84: 0f 90 pop r0 + 8f86: 0f be out 0x3f, r0 ; 63 + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + 8f88: be 01 movw r22, r28 + 8f8a: 6c 5f subi r22, 0xFC ; 252 + 8f8c: 7f 4f sbci r23, 0xFF ; 255 + 8f8e: ce 01 movw r24, r28 + 8f90: 01 96 adiw r24, 0x01 ; 1 + 8f92: 0e 94 43 45 call 0x8a86 ; 0x8a86 + 8f96: 81 11 cpse r24, r1 + 8f98: 20 c0 rjmp .+64 ; 0x8fda + +static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + 8f9a: 0f b6 in r0, 0x3f ; 63 + 8f9c: f8 94 cli + 8f9e: 0f 92 push r0 + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + 8fa0: f8 01 movw r30, r16 + 8fa2: 82 8d ldd r24, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 8fa4: 0f 90 pop r0 + 8fa6: 0f be out 0x3f, r0 ; 63 + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) ) + 8fa8: 81 11 cpse r24, r1 + 8faa: 11 c0 rjmp .+34 ; 0x8fce + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + 8fac: 6c 81 ldd r22, Y+4 ; 0x04 + 8fae: 7d 81 ldd r23, Y+5 ; 0x05 + 8fb0: c5 01 movw r24, r10 + 8fb2: 0e 94 a7 44 call 0x894e ; 0x894e + prvUnlockQueue( pxQueue ); + 8fb6: c8 01 movw r24, r16 + 8fb8: 0e 94 d7 45 call 0x8bae ; 0x8bae + if( !xTaskResumeAll() ) + 8fbc: 0e 94 b5 42 call 0x856a ; 0x856a + 8fc0: 88 23 and r24, r24 + 8fc2: 11 f0 breq .+4 ; 0x8fc8 + 8fc4: 91 e0 ldi r25, 0x01 ; 1 + 8fc6: 92 cf rjmp .-220 ; 0x8eec + { + portYIELD_WITHIN_API(); + 8fc8: 0e 94 81 4b call 0x9702 ; 0x9702 + 8fcc: fb cf rjmp .-10 ; 0x8fc4 + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + 8fce: c8 01 movw r24, r16 + 8fd0: 0e 94 d7 45 call 0x8bae ; 0x8bae + ( void ) xTaskResumeAll(); + 8fd4: 0e 94 b5 42 call 0x856a ; 0x856a + 8fd8: f5 cf rjmp .-22 ; 0x8fc4 + } + } + else + { + prvUnlockQueue( pxQueue ); + 8fda: c8 01 movw r24, r16 + 8fdc: 0e 94 d7 45 call 0x8bae ; 0x8bae + ( void ) xTaskResumeAll(); + 8fe0: 0e 94 b5 42 call 0x856a ; 0x856a + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + 8fe4: 80 e0 ldi r24, 0x00 ; 0 + } + } +} + 8fe6: 0f 90 pop r0 + 8fe8: 0f 90 pop r0 + 8fea: 0f 90 pop r0 + 8fec: 0f 90 pop r0 + 8fee: 0f 90 pop r0 + 8ff0: df 91 pop r29 + 8ff2: cf 91 pop r28 + 8ff4: 1f 91 pop r17 + 8ff6: 0f 91 pop r16 + 8ff8: ff 90 pop r15 + 8ffa: ef 90 pop r14 + 8ffc: df 90 pop r13 + 8ffe: bf 90 pop r11 + 9000: af 90 pop r10 + 9002: 08 95 ret + +00009004 : +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) +{ + 9004: 0f 93 push r16 + 9006: 1f 93 push r17 + 9008: cf 93 push r28 + 900a: df 93 push r29 +unsigned portBASE_TYPE uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* We cannot block from an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 900c: fc 01 movw r30, r24 + 900e: 22 8d ldd r18, Z+26 ; 0x1a + 9010: 22 23 and r18, r18 + 9012: d9 f0 breq .+54 ; 0x904a + 9014: 8a 01 movw r16, r20 + 9016: ec 01 movw r28, r24 + { + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + 9018: 0e 94 bd 45 call 0x8b7a ; 0x8b7a + --( pxQueue->uxMessagesWaiting ); + 901c: 8a 8d ldd r24, Y+26 ; 0x1a + 901e: 81 50 subi r24, 0x01 ; 1 + 9020: 8a 8f std Y+26, r24 ; 0x1a + + /* If the queue is locked we will not modify the event list. Instead + we update the lock count so the task that unlocks the queue will know + that an ISR has removed data while the queue was locked. */ + if( pxQueue->xRxLock == queueUNLOCKED ) + 9022: 8d 8d ldd r24, Y+29 ; 0x1d + 9024: 8f 3f cpi r24, 0xFF ; 255 + 9026: 69 f4 brne .+26 ; 0x9042 + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 9028: 88 85 ldd r24, Y+8 ; 0x08 + 902a: 88 23 and r24, r24 + 902c: 61 f0 breq .+24 ; 0x9046 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 902e: ce 01 movw r24, r28 + 9030: 08 96 adiw r24, 0x08 ; 8 + 9032: 0e 94 f5 44 call 0x89ea ; 0x89ea + 9036: 88 23 and r24, r24 + 9038: 31 f0 breq .+12 ; 0x9046 + { + /* The task waiting has a higher priority than us so + force a context switch. */ + *pxTaskWoken = pdTRUE; + 903a: 81 e0 ldi r24, 0x01 ; 1 + 903c: f8 01 movw r30, r16 + 903e: 80 83 st Z, r24 + 9040: 05 c0 rjmp .+10 ; 0x904c + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++( pxQueue->xRxLock ); + 9042: 8f 5f subi r24, 0xFF ; 255 + 9044: 8d 8f std Y+29, r24 ; 0x1d + } + + xReturn = pdPASS; + 9046: 81 e0 ldi r24, 0x01 ; 1 + 9048: 01 c0 rjmp .+2 ; 0x904c + } + else + { + xReturn = pdFAIL; + 904a: 80 e0 ldi r24, 0x00 ; 0 + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} + 904c: df 91 pop r29 + 904e: cf 91 pop r28 + 9050: 1f 91 pop r17 + 9052: 0f 91 pop r16 + 9054: 08 95 ret + +00009056 : + +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + taskENTER_CRITICAL(); + 9056: 0f b6 in r0, 0x3f ; 63 + 9058: f8 94 cli + 905a: 0f 92 push r0 + uxReturn = pxQueue->uxMessagesWaiting; + 905c: fc 01 movw r30, r24 + 905e: 82 8d ldd r24, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 9060: 0f 90 pop r0 + 9062: 0f be out 0x3f, r0 ; 63 + + return uxReturn; +} + 9064: 08 95 ret + +00009066 : + +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + uxReturn = pxQueue->uxMessagesWaiting; + 9066: fc 01 movw r30, r24 + 9068: 82 8d ldd r24, Z+26 ; 0x1a + + return uxReturn; +} + 906a: 08 95 ret + +0000906c : +/*-----------------------------------------------------------*/ + +void vQueueDelete( xQueueHandle pxQueue ) +{ + 906c: cf 93 push r28 + 906e: df 93 push r29 + 9070: ec 01 movw r28, r24 + traceQUEUE_DELETE( pxQueue ); + vQueueUnregisterQueue( pxQueue ); + vPortFree( pxQueue->pcHead ); + 9072: 88 81 ld r24, Y + 9074: 99 81 ldd r25, Y+1 ; 0x01 + 9076: 0e 94 cf 4a call 0x959e ; 0x959e + vPortFree( pxQueue ); + 907a: ce 01 movw r24, r28 +} + 907c: df 91 pop r29 + 907e: cf 91 pop r28 +void vQueueDelete( xQueueHandle pxQueue ) +{ + traceQUEUE_DELETE( pxQueue ); + vQueueUnregisterQueue( pxQueue ); + vPortFree( pxQueue->pcHead ); + vPortFree( pxQueue ); + 9080: 0c 94 cf 4a jmp 0x959e ; 0x959e + +00009084 : + +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + 9084: fc 01 movw r30, r24 + 9086: 92 8d ldd r25, Z+26 ; 0x1a + 9088: 81 e0 ldi r24, 0x01 ; 1 + 908a: 91 11 cpse r25, r1 + 908c: 80 e0 ldi r24, 0x00 ; 0 + + return xReturn; +} + 908e: 08 95 ret + +00009090 : + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) +{ + 9090: fc 01 movw r30, r24 +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + 9092: 22 8d ldd r18, Z+26 ; 0x1a + 9094: 81 e0 ldi r24, 0x01 ; 1 + 9096: 93 8d ldd r25, Z+27 ; 0x1b + 9098: 29 13 cpse r18, r25 + 909a: 80 e0 ldi r24, 0x00 ; 0 + + return xReturn; +} + 909c: 08 95 ret + +0000909e : +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( xList *pxList ) +{ + 909e: fc 01 movw r30, r24 + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); + 90a0: 03 96 adiw r24, 0x03 ; 3 + 90a2: 92 83 std Z+2, r25 ; 0x02 + 90a4: 81 83 std Z+1, r24 ; 0x01 + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + 90a6: 2f ef ldi r18, 0xFF ; 255 + 90a8: 3f ef ldi r19, 0xFF ; 255 + 90aa: 34 83 std Z+4, r19 ; 0x04 + 90ac: 23 83 std Z+3, r18 ; 0x03 + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); + 90ae: 96 83 std Z+6, r25 ; 0x06 + 90b0: 85 83 std Z+5, r24 ; 0x05 + pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd ); + 90b2: 90 87 std Z+8, r25 ; 0x08 + 90b4: 87 83 std Z+7, r24 ; 0x07 + + pxList->uxNumberOfItems = 0; + 90b6: 10 82 st Z, r1 + 90b8: 08 95 ret + +000090ba : +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( xListItem *pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; + 90ba: fc 01 movw r30, r24 + 90bc: 11 86 std Z+9, r1 ; 0x09 + 90be: 10 86 std Z+8, r1 ; 0x08 + 90c0: 08 95 ret + +000090c2 : +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ) +{ + 90c2: cf 93 push r28 + 90c4: df 93 push r29 + 90c6: dc 01 movw r26, r24 + 90c8: fb 01 movw r30, r22 + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by + the pxIndex member. */ + pxIndex = pxList->pxIndex; + 90ca: 11 96 adiw r26, 0x01 ; 1 + 90cc: 2d 91 ld r18, X+ + 90ce: 3c 91 ld r19, X + 90d0: 12 97 sbiw r26, 0x02 ; 2 + + pxNewListItem->pxNext = pxIndex->pxNext; + 90d2: e9 01 movw r28, r18 + 90d4: 8a 81 ldd r24, Y+2 ; 0x02 + 90d6: 9b 81 ldd r25, Y+3 ; 0x03 + 90d8: 93 83 std Z+3, r25 ; 0x03 + 90da: 82 83 std Z+2, r24 ; 0x02 + pxNewListItem->pxPrevious = pxList->pxIndex; + 90dc: 35 83 std Z+5, r19 ; 0x05 + 90de: 24 83 std Z+4, r18 ; 0x04 + pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + 90e0: 8a 81 ldd r24, Y+2 ; 0x02 + 90e2: 9b 81 ldd r25, Y+3 ; 0x03 + 90e4: ec 01 movw r28, r24 + 90e6: 7d 83 std Y+5, r23 ; 0x05 + 90e8: 6c 83 std Y+4, r22 ; 0x04 + pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem; + 90ea: e9 01 movw r28, r18 + 90ec: 7b 83 std Y+3, r23 ; 0x03 + 90ee: 6a 83 std Y+2, r22 ; 0x02 + pxList->pxIndex = ( volatile xListItem * ) pxNewListItem; + 90f0: 12 96 adiw r26, 0x02 ; 2 + 90f2: 7c 93 st X, r23 + 90f4: 6e 93 st -X, r22 + 90f6: 11 97 sbiw r26, 0x01 ; 1 + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + 90f8: b1 87 std Z+9, r27 ; 0x09 + 90fa: a0 87 std Z+8, r26 ; 0x08 + + ( pxList->uxNumberOfItems )++; + 90fc: 8c 91 ld r24, X + 90fe: 8f 5f subi r24, 0xFF ; 255 + 9100: 8c 93 st X, r24 +} + 9102: df 91 pop r29 + 9104: cf 91 pop r28 + 9106: 08 95 ret + +00009108 : +/*-----------------------------------------------------------*/ + +void vListInsert( xList *pxList, xListItem *pxNewListItem ) +{ + 9108: cf 93 push r28 + 910a: df 93 push r29 + 910c: ac 01 movw r20, r24 + 910e: db 01 movw r26, r22 +volatile xListItem *pxIterator; +portTickType xValueOfInsertion; + + /* Insert the new list item into the list, sorted in ulListItem order. */ + xValueOfInsertion = pxNewListItem->xItemValue; + 9110: 8d 91 ld r24, X+ + 9112: 9c 91 ld r25, X + 9114: 11 97 sbiw r26, 0x01 ; 1 + are stored in ready lists (all of which have the same ulListItem value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + 9116: 8f 3f cpi r24, 0xFF ; 255 + 9118: 2f ef ldi r18, 0xFF ; 255 + 911a: 92 07 cpc r25, r18 + 911c: 21 f4 brne .+8 ; 0x9126 + { + pxIterator = pxList->xListEnd.pxPrevious; + 911e: ea 01 movw r28, r20 + 9120: ef 81 ldd r30, Y+7 ; 0x07 + 9122: f8 85 ldd r31, Y+8 ; 0x08 + 9124: 0e c0 rjmp .+28 ; 0x9142 + } + else + { + for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) + 9126: fa 01 movw r30, r20 + 9128: 33 96 adiw r30, 0x03 ; 3 + 912a: 22 81 ldd r18, Z+2 ; 0x02 + 912c: 33 81 ldd r19, Z+3 ; 0x03 + 912e: e9 01 movw r28, r18 + 9130: 28 81 ld r18, Y + 9132: 39 81 ldd r19, Y+1 ; 0x01 + 9134: 82 17 cp r24, r18 + 9136: 93 07 cpc r25, r19 + 9138: 20 f0 brcs .+8 ; 0x9142 + 913a: 02 80 ldd r0, Z+2 ; 0x02 + 913c: f3 81 ldd r31, Z+3 ; 0x03 + 913e: e0 2d mov r30, r0 + 9140: f4 cf rjmp .-24 ; 0x912a + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + 9142: 82 81 ldd r24, Z+2 ; 0x02 + 9144: 93 81 ldd r25, Z+3 ; 0x03 + 9146: 13 96 adiw r26, 0x03 ; 3 + 9148: 9c 93 st X, r25 + 914a: 8e 93 st -X, r24 + 914c: 12 97 sbiw r26, 0x02 ; 2 + pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + 914e: ec 01 movw r28, r24 + 9150: bd 83 std Y+5, r27 ; 0x05 + 9152: ac 83 std Y+4, r26 ; 0x04 + pxNewListItem->pxPrevious = pxIterator; + 9154: 15 96 adiw r26, 0x05 ; 5 + 9156: fc 93 st X, r31 + 9158: ee 93 st -X, r30 + 915a: 14 97 sbiw r26, 0x04 ; 4 + pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem; + 915c: b3 83 std Z+3, r27 ; 0x03 + 915e: a2 83 std Z+2, r26 ; 0x02 + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + 9160: 19 96 adiw r26, 0x09 ; 9 + 9162: 5c 93 st X, r21 + 9164: 4e 93 st -X, r20 + 9166: 18 97 sbiw r26, 0x08 ; 8 + + ( pxList->uxNumberOfItems )++; + 9168: fa 01 movw r30, r20 + 916a: 80 81 ld r24, Z + 916c: 8f 5f subi r24, 0xFF ; 255 + 916e: 80 83 st Z, r24 +} + 9170: df 91 pop r29 + 9172: cf 91 pop r28 + 9174: 08 95 ret + +00009176 : +/*-----------------------------------------------------------*/ + +void vListRemove( xListItem *pxItemToRemove ) +{ + 9176: cf 93 push r28 + 9178: df 93 push r29 + 917a: fc 01 movw r30, r24 +xList * pxList; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + 917c: a2 81 ldd r26, Z+2 ; 0x02 + 917e: b3 81 ldd r27, Z+3 ; 0x03 + 9180: 84 81 ldd r24, Z+4 ; 0x04 + 9182: 95 81 ldd r25, Z+5 ; 0x05 + 9184: 15 96 adiw r26, 0x05 ; 5 + 9186: 9c 93 st X, r25 + 9188: 8e 93 st -X, r24 + 918a: 14 97 sbiw r26, 0x04 ; 4 + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + 918c: c4 81 ldd r28, Z+4 ; 0x04 + 918e: d5 81 ldd r29, Z+5 ; 0x05 + 9190: bb 83 std Y+3, r27 ; 0x03 + 9192: aa 83 std Y+2, r26 ; 0x02 + + /* The list item knows which list it is in. Obtain the list from the list + item. */ + pxList = ( xList * ) pxItemToRemove->pvContainer; + 9194: a0 85 ldd r26, Z+8 ; 0x08 + 9196: b1 85 ldd r27, Z+9 ; 0x09 + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + 9198: 11 96 adiw r26, 0x01 ; 1 + 919a: 8d 91 ld r24, X+ + 919c: 9c 91 ld r25, X + 919e: 12 97 sbiw r26, 0x02 ; 2 + 91a0: 8e 17 cp r24, r30 + 91a2: 9f 07 cpc r25, r31 + 91a4: 21 f4 brne .+8 ; 0x91ae + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + 91a6: 12 96 adiw r26, 0x02 ; 2 + 91a8: dc 93 st X, r29 + 91aa: ce 93 st -X, r28 + 91ac: 11 97 sbiw r26, 0x01 ; 1 + } + + pxItemToRemove->pvContainer = NULL; + 91ae: 11 86 std Z+9, r1 ; 0x09 + 91b0: 10 86 std Z+8, r1 ; 0x08 + ( pxList->uxNumberOfItems )--; + 91b2: 8c 91 ld r24, X + 91b4: 81 50 subi r24, 0x01 ; 1 + 91b6: 8c 93 st X, r24 +} + 91b8: df 91 pop r29 + 91ba: cf 91 pop r28 + 91bc: 08 95 ret + +000091be : +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) +{ + 91be: ef 92 push r14 + 91c0: ff 92 push r15 + 91c2: 0f 93 push r16 + 91c4: 1f 93 push r17 + 91c6: cf 93 push r28 + 91c8: df 93 push r29 + 91ca: 7c 01 movw r14, r24 + 91cc: 14 2f mov r17, r20 +signed portBASE_TYPE xReturn; +corCRCB *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); + 91ce: 8a e1 ldi r24, 0x1A ; 26 + 91d0: 90 e0 ldi r25, 0x00 ; 0 + 91d2: 0e 94 a9 4a call 0x9552 ; 0x9552 + 91d6: ec 01 movw r28, r24 + if( pxCoRoutine ) + 91d8: 89 2b or r24, r25 + 91da: 09 f4 brne .+2 ; 0x91de + 91dc: 4f c0 rjmp .+158 ; 0x927c + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + 91de: 80 91 1c 02 lds r24, 0x021C + 91e2: 90 91 1d 02 lds r25, 0x021D + 91e6: 89 2b or r24, r25 + 91e8: 01 f5 brne .+64 ; 0x922a + { + pxCurrentCoRoutine = pxCoRoutine; + 91ea: d0 93 1d 02 sts 0x021D, r29 + 91ee: c0 93 1c 02 sts 0x021C, r28 +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + 91f2: 84 e4 ldi r24, 0x44 ; 68 + 91f4: 92 e0 ldi r25, 0x02 ; 2 + 91f6: 0e 94 4f 48 call 0x909e ; 0x909e + } + + vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); + 91fa: 8b e3 ldi r24, 0x3B ; 59 + 91fc: 92 e0 ldi r25, 0x02 ; 2 + 91fe: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); + 9202: 82 e3 ldi r24, 0x32 ; 50 + 9204: 92 e0 ldi r25, 0x02 ; 2 + 9206: 0e 94 4f 48 call 0x909e ; 0x909e + vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); + 920a: 85 e2 ldi r24, 0x25 ; 37 + 920c: 92 e0 ldi r25, 0x02 ; 2 + 920e: 0e 94 4f 48 call 0x909e ; 0x909e + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + 9212: 8b e3 ldi r24, 0x3B ; 59 + 9214: 92 e0 ldi r25, 0x02 ; 2 + 9216: 90 93 31 02 sts 0x0231, r25 + 921a: 80 93 30 02 sts 0x0230, r24 + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; + 921e: 82 e3 ldi r24, 0x32 ; 50 + 9220: 92 e0 ldi r25, 0x02 ; 2 + 9222: 90 93 2f 02 sts 0x022F, r25 + 9226: 80 93 2e 02 sts 0x022E, r24 + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + 922a: 19 8e std Y+25, r1 ; 0x19 + 922c: 18 8e std Y+24, r1 ; 0x18 + pxCoRoutine->uxPriority = uxPriority; + 922e: 1e 8a std Y+22, r1 ; 0x16 + pxCoRoutine->uxIndex = uxIndex; + 9230: 1f 8b std Y+23, r17 ; 0x17 + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + 9232: fe 01 movw r30, r28 + 9234: e1 92 st Z+, r14 + 9236: f1 92 st Z+, r15 + 9238: 8f 01 movw r16, r30 + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + 923a: cf 01 movw r24, r30 + 923c: 0e 94 5d 48 call 0x90ba ; 0x90ba + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + 9240: ce 01 movw r24, r28 + 9242: 0c 96 adiw r24, 0x0c ; 12 + 9244: 0e 94 5d 48 call 0x90ba ; 0x90ba + + /* Set the co-routine control block as a link back from the xListItem. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + 9248: d9 87 std Y+9, r29 ; 0x09 + 924a: c8 87 std Y+8, r28 ; 0x08 + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + 924c: db 8b std Y+19, r29 ; 0x13 + 924e: ca 8b std Y+18, r28 ; 0x12 + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + 9250: 83 e0 ldi r24, 0x03 ; 3 + 9252: 90 e0 ldi r25, 0x00 ; 0 + 9254: 9d 87 std Y+13, r25 ; 0x0d + 9256: 8c 87 std Y+12, r24 ; 0x0c + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + 9258: 9e 89 ldd r25, Y+22 ; 0x16 + 925a: 80 91 24 02 lds r24, 0x0224 + 925e: 89 17 cp r24, r25 + 9260: 10 f4 brcc .+4 ; 0x9266 + 9262: 90 93 24 02 sts 0x0224, r25 + 9266: f9 e0 ldi r31, 0x09 ; 9 + 9268: 9f 9f mul r25, r31 + 926a: c0 01 movw r24, r0 + 926c: 11 24 eor r1, r1 + 926e: b8 01 movw r22, r16 + 9270: 8c 5b subi r24, 0xBC ; 188 + 9272: 9d 4f sbci r25, 0xFD ; 253 + 9274: 0e 94 61 48 call 0x90c2 ; 0x90c2 + + xReturn = pdPASS; + 9278: 81 e0 ldi r24, 0x01 ; 1 + 927a: 01 c0 rjmp .+2 ; 0x927e + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + 927c: 8f ef ldi r24, 0xFF ; 255 + } + + return xReturn; +} + 927e: df 91 pop r29 + 9280: cf 91 pop r28 + 9282: 1f 91 pop r17 + 9284: 0f 91 pop r16 + 9286: ff 90 pop r15 + 9288: ef 90 pop r14 + 928a: 08 95 ret + +0000928c : +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) +{ + 928c: 0f 93 push r16 + 928e: 1f 93 push r17 + 9290: cf 93 push r28 + 9292: df 93 push r29 + 9294: 8b 01 movw r16, r22 +portTickType xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + 9296: c0 91 22 02 lds r28, 0x0222 + 929a: d0 91 23 02 lds r29, 0x0223 + 929e: c8 0f add r28, r24 + 92a0: d9 1f adc r29, r25 + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 92a2: 80 91 1c 02 lds r24, 0x021C + 92a6: 90 91 1d 02 lds r25, 0x021D + 92aa: 02 96 adiw r24, 0x02 ; 2 + 92ac: 0e 94 bb 48 call 0x9176 ; 0x9176 + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + 92b0: e0 91 1c 02 lds r30, 0x021C + 92b4: f0 91 1d 02 lds r31, 0x021D + 92b8: d3 83 std Z+3, r29 ; 0x03 + 92ba: c2 83 std Z+2, r28 ; 0x02 + + if( xTimeToWake < xCoRoutineTickCount ) + 92bc: 80 91 22 02 lds r24, 0x0222 + 92c0: 90 91 23 02 lds r25, 0x0223 + 92c4: bf 01 movw r22, r30 + 92c6: 6e 5f subi r22, 0xFE ; 254 + 92c8: 7f 4f sbci r23, 0xFF ; 255 + 92ca: c8 17 cp r28, r24 + 92cc: d9 07 cpc r29, r25 + 92ce: 28 f4 brcc .+10 ; 0x92da + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 92d0: 80 91 2e 02 lds r24, 0x022E + 92d4: 90 91 2f 02 lds r25, 0x022F + 92d8: 04 c0 rjmp .+8 ; 0x92e2 + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 92da: 80 91 30 02 lds r24, 0x0230 + 92de: 90 91 31 02 lds r25, 0x0231 + 92e2: 0e 94 84 48 call 0x9108 ; 0x9108 + } + + if( pxEventList ) + 92e6: 01 15 cp r16, r1 + 92e8: 11 05 cpc r17, r1 + 92ea: 69 f0 breq .+26 ; 0x9306 + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + 92ec: 60 91 1c 02 lds r22, 0x021C + 92f0: 70 91 1d 02 lds r23, 0x021D + 92f4: 64 5f subi r22, 0xF4 ; 244 + 92f6: 7f 4f sbci r23, 0xFF ; 255 + 92f8: c8 01 movw r24, r16 + } +} + 92fa: df 91 pop r29 + 92fc: cf 91 pop r28 + 92fe: 1f 91 pop r17 + 9300: 0f 91 pop r16 + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + 9302: 0c 94 84 48 jmp 0x9108 ; 0x9108 + } +} + 9306: df 91 pop r29 + 9308: cf 91 pop r28 + 930a: 1f 91 pop r17 + 930c: 0f 91 pop r16 + 930e: 08 95 ret + +00009310 : + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + 9310: ff 92 push r15 + 9312: 0f 93 push r16 + 9314: 1f 93 push r17 + 9316: cf 93 push r28 + 9318: df 93 push r29 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + 931a: 99 e0 ldi r25, 0x09 ; 9 + 931c: f9 2e mov r15, r25 +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) ) + 931e: 80 91 25 02 lds r24, 0x0225 + 9322: 88 23 and r24, r24 + 9324: 49 f1 breq .+82 ; 0x9378 + { + corCRCB *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + 9326: f8 94 cli + { + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + 9328: 80 91 25 02 lds r24, 0x0225 + 932c: 88 23 and r24, r24 + 932e: 39 f0 breq .+14 ; 0x933e + 9330: e0 91 2a 02 lds r30, 0x022A + 9334: f0 91 2b 02 lds r31, 0x022B + 9338: c6 81 ldd r28, Z+6 ; 0x06 + 933a: d7 81 ldd r29, Z+7 ; 0x07 + 933c: 02 c0 rjmp .+4 ; 0x9342 + 933e: c0 e0 ldi r28, 0x00 ; 0 + 9340: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + 9342: ce 01 movw r24, r28 + 9344: 0c 96 adiw r24, 0x0c ; 12 + 9346: 0e 94 bb 48 call 0x9176 ; 0x9176 + } + portENABLE_INTERRUPTS(); + 934a: 78 94 sei + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + 934c: 8e 01 movw r16, r28 + 934e: 0e 5f subi r16, 0xFE ; 254 + 9350: 1f 4f sbci r17, 0xFF ; 255 + 9352: c8 01 movw r24, r16 + 9354: 0e 94 bb 48 call 0x9176 ; 0x9176 + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + 9358: 9e 89 ldd r25, Y+22 ; 0x16 + 935a: 80 91 24 02 lds r24, 0x0224 + 935e: 89 17 cp r24, r25 + 9360: 10 f4 brcc .+4 ; 0x9366 + 9362: 90 93 24 02 sts 0x0224, r25 + 9366: f9 9e mul r15, r25 + 9368: c0 01 movw r24, r0 + 936a: 11 24 eor r1, r1 + 936c: b8 01 movw r22, r16 + 936e: 8c 5b subi r24, 0xBC ; 188 + 9370: 9d 4f sbci r25, 0xFD ; 253 + 9372: 0e 94 61 48 call 0x90c2 ; 0x90c2 + 9376: d3 cf rjmp .-90 ; 0x931e + +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + 9378: 0e 94 f9 41 call 0x83f2 ; 0x83f2 + 937c: 20 91 20 02 lds r18, 0x0220 + 9380: 30 91 21 02 lds r19, 0x0221 + 9384: 82 1b sub r24, r18 + 9386: 93 0b sbc r25, r19 + 9388: 90 93 1f 02 sts 0x021F, r25 + 938c: 80 93 1e 02 sts 0x021E, r24 + vListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + 9390: 89 e0 ldi r24, 0x09 ; 9 + 9392: f8 2e mov r15, r24 +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + 9394: 20 91 1e 02 lds r18, 0x021E + 9398: 30 91 1f 02 lds r19, 0x021F + 939c: 80 91 22 02 lds r24, 0x0222 + 93a0: 90 91 23 02 lds r25, 0x0223 + 93a4: 21 15 cp r18, r1 + 93a6: 31 05 cpc r19, r1 + 93a8: 09 f4 brne .+2 ; 0x93ac + 93aa: 56 c0 rjmp .+172 ; 0x9458 + { + xCoRoutineTickCount++; + 93ac: 01 96 adiw r24, 0x01 ; 1 + 93ae: 90 93 23 02 sts 0x0223, r25 + 93b2: 80 93 22 02 sts 0x0222, r24 + xPassedTicks--; + 93b6: 21 50 subi r18, 0x01 ; 1 + 93b8: 31 09 sbc r19, r1 + 93ba: 30 93 1f 02 sts 0x021F, r19 + 93be: 20 93 1e 02 sts 0x021E, r18 + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + 93c2: 89 2b or r24, r25 + 93c4: 09 f0 breq .+2 ; 0x93c8 + 93c6: 40 c0 rjmp .+128 ; 0x9448 + { + xList * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + 93c8: 80 91 30 02 lds r24, 0x0230 + 93cc: 90 91 31 02 lds r25, 0x0231 + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + 93d0: 20 91 2e 02 lds r18, 0x022E + 93d4: 30 91 2f 02 lds r19, 0x022F + 93d8: 30 93 31 02 sts 0x0231, r19 + 93dc: 20 93 30 02 sts 0x0230, r18 + pxOverflowDelayedCoRoutineList = pxTemp; + 93e0: 90 93 2f 02 sts 0x022F, r25 + 93e4: 80 93 2e 02 sts 0x022E, r24 + 93e8: 2f c0 rjmp .+94 ; 0x9448 + } + + /* See if this tick has made a timeout expire. */ + while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) + 93ea: 05 80 ldd r0, Z+5 ; 0x05 + 93ec: f6 81 ldd r31, Z+6 ; 0x06 + 93ee: e0 2d mov r30, r0 + 93f0: c6 81 ldd r28, Z+6 ; 0x06 + 93f2: d7 81 ldd r29, Z+7 ; 0x07 + 93f4: 20 97 sbiw r28, 0x00 ; 0 + 93f6: 71 f2 breq .-100 ; 0x9394 + { + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + 93f8: 20 91 22 02 lds r18, 0x0222 + 93fc: 30 91 23 02 lds r19, 0x0223 + 9400: 8a 81 ldd r24, Y+2 ; 0x02 + 9402: 9b 81 ldd r25, Y+3 ; 0x03 + 9404: 28 17 cp r18, r24 + 9406: 39 07 cpc r19, r25 + 9408: 28 f2 brcs .-118 ; 0x9394 + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + 940a: f8 94 cli + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + vListRemove( &( pxCRCB->xGenericListItem ) ); + 940c: 8e 01 movw r16, r28 + 940e: 0e 5f subi r16, 0xFE ; 254 + 9410: 1f 4f sbci r17, 0xFF ; 255 + 9412: c8 01 movw r24, r16 + 9414: 0e 94 bb 48 call 0x9176 ; 0x9176 + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + 9418: 8c 89 ldd r24, Y+20 ; 0x14 + 941a: 9d 89 ldd r25, Y+21 ; 0x15 + 941c: 89 2b or r24, r25 + 941e: 21 f0 breq .+8 ; 0x9428 + { + vListRemove( &( pxCRCB->xEventListItem ) ); + 9420: ce 01 movw r24, r28 + 9422: 0c 96 adiw r24, 0x0c ; 12 + 9424: 0e 94 bb 48 call 0x9176 ; 0x9176 + } + } + portENABLE_INTERRUPTS(); + 9428: 78 94 sei + + prvAddCoRoutineToReadyQueue( pxCRCB ); + 942a: 9e 89 ldd r25, Y+22 ; 0x16 + 942c: 80 91 24 02 lds r24, 0x0224 + 9430: 89 17 cp r24, r25 + 9432: 10 f4 brcc .+4 ; 0x9438 + 9434: 90 93 24 02 sts 0x0224, r25 + 9438: f9 9e mul r15, r25 + 943a: c0 01 movw r24, r0 + 943c: 11 24 eor r1, r1 + 943e: b8 01 movw r22, r16 + 9440: 8c 5b subi r24, 0xBC ; 188 + 9442: 9d 4f sbci r25, 0xFD ; 253 + 9444: 0e 94 61 48 call 0x90c2 ; 0x90c2 + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) + 9448: e0 91 30 02 lds r30, 0x0230 + 944c: f0 91 31 02 lds r31, 0x0231 + 9450: 80 81 ld r24, Z + 9452: 81 11 cpse r24, r1 + 9454: ca cf rjmp .-108 ; 0x93ea + 9456: 9e cf rjmp .-196 ; 0x9394 + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; + 9458: 90 93 21 02 sts 0x0221, r25 + 945c: 80 93 20 02 sts 0x0220, r24 + 9460: 80 91 24 02 lds r24, 0x0224 + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + 9464: 69 e0 ldi r22, 0x09 ; 9 + 9466: 48 2f mov r20, r24 + 9468: 50 e0 ldi r21, 0x00 ; 0 + 946a: 64 9f mul r22, r20 + 946c: 90 01 movw r18, r0 + 946e: 65 9f mul r22, r21 + 9470: 30 0d add r19, r0 + 9472: 11 24 eor r1, r1 + 9474: f9 01 movw r30, r18 + 9476: ec 5b subi r30, 0xBC ; 188 + 9478: fd 4f sbci r31, 0xFD ; 253 + 947a: 90 81 ld r25, Z + 947c: 91 11 cpse r25, r1 + 947e: 0c c0 rjmp .+24 ; 0x9498 + { + if( uxTopCoRoutineReadyPriority == 0 ) + 9480: 81 11 cpse r24, r1 + 9482: 08 c0 rjmp .+16 ; 0x9494 + 9484: 10 92 24 02 sts 0x0224, r1 + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} + 9488: df 91 pop r29 + 948a: cf 91 pop r28 + 948c: 1f 91 pop r17 + 948e: 0f 91 pop r16 + 9490: ff 90 pop r15 + 9492: 08 95 ret + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + 9494: 81 50 subi r24, 0x01 ; 1 + 9496: e7 cf rjmp .-50 ; 0x9466 + 9498: 80 93 24 02 sts 0x0224, r24 + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + 949c: a1 81 ldd r26, Z+1 ; 0x01 + 949e: b2 81 ldd r27, Z+2 ; 0x02 + 94a0: 12 96 adiw r26, 0x02 ; 2 + 94a2: 0d 90 ld r0, X+ + 94a4: bc 91 ld r27, X + 94a6: a0 2d mov r26, r0 + 94a8: b2 83 std Z+2, r27 ; 0x02 + 94aa: a1 83 std Z+1, r26 ; 0x01 + 94ac: 29 5b subi r18, 0xB9 ; 185 + 94ae: 3d 4f sbci r19, 0xFD ; 253 + 94b0: a2 17 cp r26, r18 + 94b2: b3 07 cpc r27, r19 + 94b4: 31 f4 brne .+12 ; 0x94c2 + 94b6: 12 96 adiw r26, 0x02 ; 2 + 94b8: 8d 91 ld r24, X+ + 94ba: 9c 91 ld r25, X + 94bc: 13 97 sbiw r26, 0x03 ; 3 + 94be: 92 83 std Z+2, r25 ; 0x02 + 94c0: 81 83 std Z+1, r24 ; 0x01 + 94c2: 89 e0 ldi r24, 0x09 ; 9 + 94c4: 84 9f mul r24, r20 + 94c6: f0 01 movw r30, r0 + 94c8: 85 9f mul r24, r21 + 94ca: f0 0d add r31, r0 + 94cc: 11 24 eor r1, r1 + 94ce: ec 5b subi r30, 0xBC ; 188 + 94d0: fd 4f sbci r31, 0xFD ; 253 + 94d2: 01 80 ldd r0, Z+1 ; 0x01 + 94d4: f2 81 ldd r31, Z+2 ; 0x02 + 94d6: e0 2d mov r30, r0 + 94d8: 86 81 ldd r24, Z+6 ; 0x06 + 94da: 97 81 ldd r25, Z+7 ; 0x07 + 94dc: 90 93 1d 02 sts 0x021D, r25 + 94e0: 80 93 1c 02 sts 0x021C, r24 + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + 94e4: dc 01 movw r26, r24 + 94e6: ed 91 ld r30, X+ + 94e8: fc 91 ld r31, X + 94ea: 11 97 sbiw r26, 0x01 ; 1 + 94ec: 57 96 adiw r26, 0x17 ; 23 + 94ee: 6c 91 ld r22, X + + return; +} + 94f0: df 91 pop r29 + 94f2: cf 91 pop r28 + 94f4: 1f 91 pop r17 + 94f6: 0f 91 pop r16 + 94f8: ff 90 pop r15 + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + 94fa: 09 94 ijmp + +000094fc : + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) +{ + 94fc: 0f 93 push r16 + 94fe: 1f 93 push r17 + 9500: cf 93 push r28 + 9502: df 93 push r29 +corCRCB *pxUnblockedCRCB; +signed portBASE_TYPE xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. */ + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + 9504: dc 01 movw r26, r24 + 9506: 2c 91 ld r18, X + 9508: 22 23 and r18, r18 + 950a: 39 f0 breq .+14 ; 0x951a + 950c: 15 96 adiw r26, 0x05 ; 5 + 950e: ed 91 ld r30, X+ + 9510: fc 91 ld r31, X + 9512: 16 97 sbiw r26, 0x06 ; 6 + 9514: c6 81 ldd r28, Z+6 ; 0x06 + 9516: d7 81 ldd r29, Z+7 ; 0x07 + 9518: 02 c0 rjmp .+4 ; 0x951e + 951a: c0 e0 ldi r28, 0x00 ; 0 + 951c: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + 951e: 8e 01 movw r16, r28 + 9520: 04 5f subi r16, 0xF4 ; 244 + 9522: 1f 4f sbci r17, 0xFF ; 255 + 9524: c8 01 movw r24, r16 + 9526: 0e 94 bb 48 call 0x9176 ; 0x9176 + vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + 952a: b8 01 movw r22, r16 + 952c: 85 e2 ldi r24, 0x25 ; 37 + 952e: 92 e0 ldi r25, 0x02 ; 2 + 9530: 0e 94 61 48 call 0x90c2 ; 0x90c2 + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + 9534: e0 91 1c 02 lds r30, 0x021C + 9538: f0 91 1d 02 lds r31, 0x021D + 953c: 81 e0 ldi r24, 0x01 ; 1 + 953e: 2e 89 ldd r18, Y+22 ; 0x16 + 9540: 96 89 ldd r25, Z+22 ; 0x16 + 9542: 29 17 cp r18, r25 + 9544: 08 f4 brcc .+2 ; 0x9548 + 9546: 80 e0 ldi r24, 0x00 ; 0 + { + xReturn = pdFALSE; + } + + return xReturn; +} + 9548: df 91 pop r29 + 954a: cf 91 pop r28 + 954c: 1f 91 pop r17 + 954e: 0f 91 pop r16 + 9550: 08 95 ret + +00009552 : + +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ + 9552: 0f 93 push r16 + 9554: 1f 93 push r17 + 9556: cf 93 push r28 + 9558: df 93 push r29 + 955a: 8c 01 movw r16, r24 + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + #endif + + vTaskSuspendAll(); + 955c: 0e 94 f3 41 call 0x83e6 ; 0x83e6 + { + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) && + 9560: c0 91 4d 02 lds r28, 0x024D + 9564: d0 91 4e 02 lds r29, 0x024E + 9568: c8 01 movw r24, r16 + 956a: 8c 0f add r24, r28 + 956c: 9d 1f adc r25, r29 + 956e: 8c 31 cpi r24, 0x1C ; 28 + 9570: 2c e0 ldi r18, 0x0C ; 12 + 9572: 92 07 cpc r25, r18 + 9574: 50 f4 brcc .+20 ; 0x958a + 9576: c8 17 cp r28, r24 + 9578: d9 07 cpc r29, r25 + 957a: 38 f4 brcc .+14 ; 0x958a + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + 957c: c1 5b subi r28, 0xB1 ; 177 + 957e: dd 4f sbci r29, 0xFD ; 253 + xNextFreeByte += xWantedSize; + 9580: 90 93 4e 02 sts 0x024E, r25 + 9584: 80 93 4d 02 sts 0x024D, r24 + 9588: 02 c0 rjmp .+4 ; 0x958e +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; + 958a: c0 e0 ldi r28, 0x00 ; 0 + 958c: d0 e0 ldi r29, 0x00 ; 0 + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + xNextFreeByte += xWantedSize; + } + } + xTaskResumeAll(); + 958e: 0e 94 b5 42 call 0x856a ; 0x856a + } + } + #endif + + return pvReturn; +} + 9592: ce 01 movw r24, r28 + 9594: df 91 pop r29 + 9596: cf 91 pop r28 + 9598: 1f 91 pop r17 + 959a: 0f 91 pop r16 + 959c: 08 95 ret + +0000959e : +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + 959e: 08 95 ret + +000095a0 : +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; + 95a0: 10 92 4e 02 sts 0x024E, r1 + 95a4: 10 92 4d 02 sts 0x024D, r1 + 95a8: 08 95 ret + +000095aa : +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configTOTAL_HEAP_SIZE - xNextFreeByte ); + 95aa: 20 91 4d 02 lds r18, 0x024D + 95ae: 30 91 4e 02 lds r19, 0x024E +} + 95b2: 8c e1 ldi r24, 0x1C ; 28 + 95b4: 9c e0 ldi r25, 0x0C ; 12 + 95b6: 82 1b sub r24, r18 + 95b8: 93 0b sbc r25, r19 + 95ba: 08 95 ret + +000095bc : +unsigned portSHORT usAddress; + + /* Place a few bytes of known values on the bottom of the stack. + This is just useful for debugging. */ + + *pxTopOfStack = 0x11; + 95bc: 31 e1 ldi r19, 0x11 ; 17 + 95be: fc 01 movw r30, r24 + 95c0: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = 0x22; + 95c2: 31 97 sbiw r30, 0x01 ; 1 + 95c4: 22 e2 ldi r18, 0x22 ; 34 + 95c6: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = 0x33; + 95c8: 31 97 sbiw r30, 0x01 ; 1 + 95ca: a3 e3 ldi r26, 0x33 ; 51 + 95cc: a0 83 st Z, r26 + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* The start of the task code will be popped off the stack last, so place + it on first. */ + usAddress = ( unsigned portSHORT ) pxCode; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 95ce: 31 97 sbiw r30, 0x01 ; 1 + 95d0: 60 83 st Z, r22 + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 95d2: 31 97 sbiw r30, 0x01 ; 1 + 95d4: 70 83 st Z, r23 + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + portSAVE_CONTEXT places the flags on the stack immediately after r0 + to ensure the interrupts get disabled as soon as possible, and so ensuring + the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */ + 95d6: 31 97 sbiw r30, 0x01 ; 1 + 95d8: 10 82 st Z, r1 + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + 95da: 31 97 sbiw r30, 0x01 ; 1 + 95dc: 60 e8 ldi r22, 0x80 ; 128 + 95de: 60 83 st Z, r22 + pxTopOfStack--; + + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */ + 95e0: 31 97 sbiw r30, 0x01 ; 1 + 95e2: 10 82 st Z, r1 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */ + 95e4: 31 97 sbiw r30, 0x01 ; 1 + 95e6: 62 e0 ldi r22, 0x02 ; 2 + 95e8: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */ + 95ea: 31 97 sbiw r30, 0x01 ; 1 + 95ec: 63 e0 ldi r22, 0x03 ; 3 + 95ee: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */ + 95f0: 31 97 sbiw r30, 0x01 ; 1 + 95f2: 64 e0 ldi r22, 0x04 ; 4 + 95f4: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */ + 95f6: 31 97 sbiw r30, 0x01 ; 1 + 95f8: 65 e0 ldi r22, 0x05 ; 5 + 95fa: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */ + 95fc: 31 97 sbiw r30, 0x01 ; 1 + 95fe: 66 e0 ldi r22, 0x06 ; 6 + 9600: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */ + 9602: 31 97 sbiw r30, 0x01 ; 1 + 9604: 67 e0 ldi r22, 0x07 ; 7 + 9606: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */ + 9608: 31 97 sbiw r30, 0x01 ; 1 + 960a: 68 e0 ldi r22, 0x08 ; 8 + 960c: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */ + 960e: 31 97 sbiw r30, 0x01 ; 1 + 9610: 69 e0 ldi r22, 0x09 ; 9 + 9612: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */ + 9614: 31 97 sbiw r30, 0x01 ; 1 + 9616: 60 e1 ldi r22, 0x10 ; 16 + 9618: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */ + 961a: 31 97 sbiw r30, 0x01 ; 1 + 961c: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */ + 961e: 31 97 sbiw r30, 0x01 ; 1 + 9620: 32 e1 ldi r19, 0x12 ; 18 + 9622: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */ + 9624: 31 97 sbiw r30, 0x01 ; 1 + 9626: 33 e1 ldi r19, 0x13 ; 19 + 9628: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */ + 962a: 31 97 sbiw r30, 0x01 ; 1 + 962c: 34 e1 ldi r19, 0x14 ; 20 + 962e: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */ + 9630: 31 97 sbiw r30, 0x01 ; 1 + 9632: 35 e1 ldi r19, 0x15 ; 21 + 9634: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */ + 9636: 31 97 sbiw r30, 0x01 ; 1 + 9638: 36 e1 ldi r19, 0x16 ; 22 + 963a: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */ + 963c: 31 97 sbiw r30, 0x01 ; 1 + 963e: 37 e1 ldi r19, 0x17 ; 23 + 9640: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */ + 9642: 31 97 sbiw r30, 0x01 ; 1 + 9644: 38 e1 ldi r19, 0x18 ; 24 + 9646: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */ + 9648: 31 97 sbiw r30, 0x01 ; 1 + 964a: 39 e1 ldi r19, 0x19 ; 25 + 964c: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */ + 964e: 31 97 sbiw r30, 0x01 ; 1 + 9650: 30 e2 ldi r19, 0x20 ; 32 + 9652: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */ + 9654: 31 97 sbiw r30, 0x01 ; 1 + 9656: 31 e2 ldi r19, 0x21 ; 33 + 9658: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */ + 965a: 31 97 sbiw r30, 0x01 ; 1 + 965c: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */ + 965e: 31 97 sbiw r30, 0x01 ; 1 + 9660: 23 e2 ldi r18, 0x23 ; 35 + 9662: 20 83 st Z, r18 + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( unsigned portSHORT ) pvParameters; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 9664: 31 97 sbiw r30, 0x01 ; 1 + 9666: 40 83 st Z, r20 + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 9668: 31 97 sbiw r30, 0x01 ; 1 + 966a: 50 83 st Z, r21 + pxTopOfStack--; + + *pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */ + 966c: 31 97 sbiw r30, 0x01 ; 1 + 966e: 26 e2 ldi r18, 0x26 ; 38 + 9670: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */ + 9672: 31 97 sbiw r30, 0x01 ; 1 + 9674: 27 e2 ldi r18, 0x27 ; 39 + 9676: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */ + 9678: 31 97 sbiw r30, 0x01 ; 1 + 967a: 28 e2 ldi r18, 0x28 ; 40 + 967c: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */ + 967e: 31 97 sbiw r30, 0x01 ; 1 + 9680: 29 e2 ldi r18, 0x29 ; 41 + 9682: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */ + 9684: 31 97 sbiw r30, 0x01 ; 1 + 9686: 20 e3 ldi r18, 0x30 ; 48 + 9688: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */ + 968a: 31 97 sbiw r30, 0x01 ; 1 + 968c: 21 e3 ldi r18, 0x31 ; 49 + 968e: 20 83 st Z, r18 + pxTopOfStack--; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} + 9690: 86 97 sbiw r24, 0x26 ; 38 + 9692: 08 95 ret + +00009694 : + /* Setup compare match value for compare match A. Interrupts are disabled + before this is called so we need not worry here. */ + ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + ulCompareMatch >>= 8; + ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + OCR1AH = ucHighByte; + 9694: 83 e1 ldi r24, 0x13 ; 19 + 9696: 8b bd out 0x2b, r24 ; 43 + OCR1AL = ucLowByte; + 9698: 87 e8 ldi r24, 0x87 ; 135 + 969a: 8a bd out 0x2a, r24 ; 42 + + /* Setup clock source and compare match behaviour. */ + ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64; + TCCR1B = ucLowByte; + 969c: 8b e0 ldi r24, 0x0B ; 11 + 969e: 8e bd out 0x2e, r24 ; 46 + + /* Enable the interrupt - this is okay as interrupt are currently globally + disabled. */ + ucLowByte = TIMSK; + 96a0: 87 b7 in r24, 0x37 ; 55 + ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE; + 96a2: 80 61 ori r24, 0x10 ; 16 + TIMSK = ucLowByte; + 96a4: 87 bf out 0x37, r24 ; 55 +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + 96a6: a0 91 93 01 lds r26, 0x0193 + 96aa: b0 91 94 01 lds r27, 0x0194 + 96ae: cd 91 ld r28, X+ + 96b0: cd bf out 0x3d, r28 ; 61 + 96b2: dd 91 ld r29, X+ + 96b4: de bf out 0x3e, r29 ; 62 + 96b6: ff 91 pop r31 + 96b8: ef 91 pop r30 + 96ba: df 91 pop r29 + 96bc: cf 91 pop r28 + 96be: bf 91 pop r27 + 96c0: af 91 pop r26 + 96c2: 9f 91 pop r25 + 96c4: 8f 91 pop r24 + 96c6: 7f 91 pop r23 + 96c8: 6f 91 pop r22 + 96ca: 5f 91 pop r21 + 96cc: 4f 91 pop r20 + 96ce: 3f 91 pop r19 + 96d0: 2f 91 pop r18 + 96d2: 1f 91 pop r17 + 96d4: 0f 91 pop r16 + 96d6: ff 90 pop r15 + 96d8: ef 90 pop r14 + 96da: df 90 pop r13 + 96dc: cf 90 pop r12 + 96de: bf 90 pop r11 + 96e0: af 90 pop r10 + 96e2: 9f 90 pop r9 + 96e4: 8f 90 pop r8 + 96e6: 7f 90 pop r7 + 96e8: 6f 90 pop r6 + 96ea: 5f 90 pop r5 + 96ec: 4f 90 pop r4 + 96ee: 3f 90 pop r3 + 96f0: 2f 90 pop r2 + 96f2: 1f 90 pop r1 + 96f4: 0f 90 pop r0 + 96f6: 0f be out 0x3f, r0 ; 63 + 96f8: 0f 90 pop r0 + + /* Simulate a function call end as generated by the compiler. We will now + jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + 96fa: 08 95 ret + + /* Should not get here. */ + return pdTRUE; +} + 96fc: 81 e0 ldi r24, 0x01 ; 1 + 96fe: 08 95 ret + +00009700 : +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + 9700: 08 95 ret + +00009702 : + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__ ( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + 9702: 0f 92 push r0 + 9704: 0f b6 in r0, 0x3f ; 63 + 9706: f8 94 cli + 9708: 0f 92 push r0 + 970a: 1f 92 push r1 + 970c: 11 24 eor r1, r1 + 970e: 2f 92 push r2 + 9710: 3f 92 push r3 + 9712: 4f 92 push r4 + 9714: 5f 92 push r5 + 9716: 6f 92 push r6 + 9718: 7f 92 push r7 + 971a: 8f 92 push r8 + 971c: 9f 92 push r9 + 971e: af 92 push r10 + 9720: bf 92 push r11 + 9722: cf 92 push r12 + 9724: df 92 push r13 + 9726: ef 92 push r14 + 9728: ff 92 push r15 + 972a: 0f 93 push r16 + 972c: 1f 93 push r17 + 972e: 2f 93 push r18 + 9730: 3f 93 push r19 + 9732: 4f 93 push r20 + 9734: 5f 93 push r21 + 9736: 6f 93 push r22 + 9738: 7f 93 push r23 + 973a: 8f 93 push r24 + 973c: 9f 93 push r25 + 973e: af 93 push r26 + 9740: bf 93 push r27 + 9742: cf 93 push r28 + 9744: df 93 push r29 + 9746: ef 93 push r30 + 9748: ff 93 push r31 + 974a: a0 91 93 01 lds r26, 0x0193 + 974e: b0 91 94 01 lds r27, 0x0194 + 9752: 0d b6 in r0, 0x3d ; 61 + 9754: 0d 92 st X+, r0 + 9756: 0e b6 in r0, 0x3e ; 62 + 9758: 0d 92 st X+, r0 + vTaskSwitchContext(); + 975a: 0e 94 0c 44 call 0x8818 ; 0x8818 + portRESTORE_CONTEXT(); + 975e: a0 91 93 01 lds r26, 0x0193 + 9762: b0 91 94 01 lds r27, 0x0194 + 9766: cd 91 ld r28, X+ + 9768: cd bf out 0x3d, r28 ; 61 + 976a: dd 91 ld r29, X+ + 976c: de bf out 0x3e, r29 ; 62 + 976e: ff 91 pop r31 + 9770: ef 91 pop r30 + 9772: df 91 pop r29 + 9774: cf 91 pop r28 + 9776: bf 91 pop r27 + 9778: af 91 pop r26 + 977a: 9f 91 pop r25 + 977c: 8f 91 pop r24 + 977e: 7f 91 pop r23 + 9780: 6f 91 pop r22 + 9782: 5f 91 pop r21 + 9784: 4f 91 pop r20 + 9786: 3f 91 pop r19 + 9788: 2f 91 pop r18 + 978a: 1f 91 pop r17 + 978c: 0f 91 pop r16 + 978e: ff 90 pop r15 + 9790: ef 90 pop r14 + 9792: df 90 pop r13 + 9794: cf 90 pop r12 + 9796: bf 90 pop r11 + 9798: af 90 pop r10 + 979a: 9f 90 pop r9 + 979c: 8f 90 pop r8 + 979e: 7f 90 pop r7 + 97a0: 6f 90 pop r6 + 97a2: 5f 90 pop r5 + 97a4: 4f 90 pop r4 + 97a6: 3f 90 pop r3 + 97a8: 2f 90 pop r2 + 97aa: 1f 90 pop r1 + 97ac: 0f 90 pop r0 + 97ae: 0f be out 0x3f, r0 ; 63 + 97b0: 0f 90 pop r0 + + asm volatile ( "ret" ); + 97b2: 08 95 ret + +000097b4 : + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + 97b4: 0f 92 push r0 + 97b6: 0f b6 in r0, 0x3f ; 63 + 97b8: f8 94 cli + 97ba: 0f 92 push r0 + 97bc: 1f 92 push r1 + 97be: 11 24 eor r1, r1 + 97c0: 2f 92 push r2 + 97c2: 3f 92 push r3 + 97c4: 4f 92 push r4 + 97c6: 5f 92 push r5 + 97c8: 6f 92 push r6 + 97ca: 7f 92 push r7 + 97cc: 8f 92 push r8 + 97ce: 9f 92 push r9 + 97d0: af 92 push r10 + 97d2: bf 92 push r11 + 97d4: cf 92 push r12 + 97d6: df 92 push r13 + 97d8: ef 92 push r14 + 97da: ff 92 push r15 + 97dc: 0f 93 push r16 + 97de: 1f 93 push r17 + 97e0: 2f 93 push r18 + 97e2: 3f 93 push r19 + 97e4: 4f 93 push r20 + 97e6: 5f 93 push r21 + 97e8: 6f 93 push r22 + 97ea: 7f 93 push r23 + 97ec: 8f 93 push r24 + 97ee: 9f 93 push r25 + 97f0: af 93 push r26 + 97f2: bf 93 push r27 + 97f4: cf 93 push r28 + 97f6: df 93 push r29 + 97f8: ef 93 push r30 + 97fa: ff 93 push r31 + 97fc: a0 91 93 01 lds r26, 0x0193 + 9800: b0 91 94 01 lds r27, 0x0194 + 9804: 0d b6 in r0, 0x3d ; 61 + 9806: 0d 92 st X+, r0 + 9808: 0e b6 in r0, 0x3e ; 62 + 980a: 0d 92 st X+, r0 + vTaskIncrementTick(); + 980c: 0e 94 35 42 call 0x846a ; 0x846a + vTaskSwitchContext(); + 9810: 0e 94 0c 44 call 0x8818 ; 0x8818 + portRESTORE_CONTEXT(); + 9814: a0 91 93 01 lds r26, 0x0193 + 9818: b0 91 94 01 lds r27, 0x0194 + 981c: cd 91 ld r28, X+ + 981e: cd bf out 0x3d, r28 ; 61 + 9820: dd 91 ld r29, X+ + 9822: de bf out 0x3e, r29 ; 62 + 9824: ff 91 pop r31 + 9826: ef 91 pop r30 + 9828: df 91 pop r29 + 982a: cf 91 pop r28 + 982c: bf 91 pop r27 + 982e: af 91 pop r26 + 9830: 9f 91 pop r25 + 9832: 8f 91 pop r24 + 9834: 7f 91 pop r23 + 9836: 6f 91 pop r22 + 9838: 5f 91 pop r21 + 983a: 4f 91 pop r20 + 983c: 3f 91 pop r19 + 983e: 2f 91 pop r18 + 9840: 1f 91 pop r17 + 9842: 0f 91 pop r16 + 9844: ff 90 pop r15 + 9846: ef 90 pop r14 + 9848: df 90 pop r13 + 984a: cf 90 pop r12 + 984c: bf 90 pop r11 + 984e: af 90 pop r10 + 9850: 9f 90 pop r9 + 9852: 8f 90 pop r8 + 9854: 7f 90 pop r7 + 9856: 6f 90 pop r6 + 9858: 5f 90 pop r5 + 985a: 4f 90 pop r4 + 985c: 3f 90 pop r3 + 985e: 2f 90 pop r2 + 9860: 1f 90 pop r1 + 9862: 0f 90 pop r0 + 9864: 0f be out 0x3f, r0 ; 63 + 9866: 0f 90 pop r0 + + asm volatile ( "ret" ); + 9868: 08 95 ret + +0000986a <__vector_12>: + 986a: 1f 92 push r1 + 986c: 0f 92 push r0 + 986e: 0f b6 in r0, 0x3f ; 63 + 9870: 0f 92 push r0 + 9872: 11 24 eor r1, r1 + 9874: 0b b6 in r0, 0x3b ; 59 + 9876: 0f 92 push r0 + 9878: 2f 93 push r18 + 987a: 3f 93 push r19 + 987c: 4f 93 push r20 + 987e: 5f 93 push r21 + 9880: 6f 93 push r22 + 9882: 7f 93 push r23 + 9884: 8f 93 push r24 + 9886: 9f 93 push r25 + 9888: af 93 push r26 + 988a: bf 93 push r27 + 988c: ef 93 push r30 + 988e: ff 93 push r31 + 9890: 0e 94 35 42 call 0x846a ; 0x846a + 9894: ff 91 pop r31 + 9896: ef 91 pop r30 + 9898: bf 91 pop r27 + 989a: af 91 pop r26 + 989c: 9f 91 pop r25 + 989e: 8f 91 pop r24 + 98a0: 7f 91 pop r23 + 98a2: 6f 91 pop r22 + 98a4: 5f 91 pop r21 + 98a6: 4f 91 pop r20 + 98a8: 3f 91 pop r19 + 98aa: 2f 91 pop r18 + 98ac: 0f 90 pop r0 + 98ae: 0b be out 0x3b, r0 ; 59 + 98b0: 0f 90 pop r0 + 98b2: 0f be out 0x3f, r0 ; 63 + 98b4: 0f 90 pop r0 + 98b6: 1f 90 pop r1 + 98b8: 18 95 reti + +000098ba
: +FILE udpStream; + +streamBuffers_t udpBuffers; + +portSHORT main( void ) +{ + 98ba: af 92 push r10 + 98bc: bf 92 push r11 + 98be: cf 92 push r12 + 98c0: df 92 push r13 + 98c2: ef 92 push r14 + 98c4: ff 92 push r15 + 98c6: 0f 93 push r16 + ramDyskInit(); //Inicjalizacja Ram dysku + 98c8: 0e 94 46 1b call 0x368c ; 0x368c + hardwareInit(); + 98cc: 0e 94 82 0d call 0x1b04 ; 0x1b04 + spiInit(disableAllSpiDevices); + 98d0: 80 e2 ldi r24, 0x20 ; 32 + 98d2: 9f e0 ldi r25, 0x0F ; 15 + 98d4: 0e 94 15 1a call 0x342a ; 0x342a + +// VTY on serial + xSerialPortInitMinimal(); + 98d8: 0e 94 9f 0b call 0x173e ; 0x173e + CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + 98dc: 83 e2 ldi r24, 0x23 ; 35 + 98de: 90 e0 ldi r25, 0x00 ; 0 + 98e0: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 98e4: 90 93 9f 0e sts 0x0E9F, r25 + 98e8: 80 93 9e 0e sts 0x0E9E, r24 + CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + 98ec: 83 e2 ldi r24, 0x23 ; 35 + 98ee: 90 e0 ldi r25, 0x00 ; 0 + 98f0: 0e 94 52 1a call 0x34a4 ; 0x34a4 + 98f4: 90 93 5f 0f sts 0x0F5F, r25 + 98f8: 80 93 5e 0f sts 0x0F5E, r24 + + +// cmdStateClear(newCmdState); + + sensorsTaskInit(); + 98fc: 0e 94 96 0f call 0x1f2c ; 0x1f2c + loadConfiguration(); + 9900: 0e 94 67 0b call 0x16ce ; 0x16ce + + initQueueStreamUSB(&usbStream); + 9904: 8b e6 ldi r24, 0x6B ; 107 + 9906: 9e e0 ldi r25, 0x0E ; 14 + 9908: 0e 94 91 0b call 0x1722 ; 0x1722 + VtyInit(CLIStateSerialUsb, &usbStream); + 990c: 6b e6 ldi r22, 0x6B ; 107 + 990e: 7e e0 ldi r23, 0x0E ; 14 + 9910: 80 91 9e 0e lds r24, 0x0E9E + 9914: 90 91 9f 0e lds r25, 0x0E9F + 9918: 0e 94 32 17 call 0x2e64 ; 0x2e64 + + udpInit_0(); + 991c: 0e 94 6c 36 call 0x6cd8 ; 0x6cd8 + socketInit(); + 9920: 0e 94 b5 33 call 0x676a ; 0x676a + initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + 9924: e0 91 a2 0e lds r30, 0x0EA2 + 9928: f0 91 a3 0e lds r31, 0x0EA3 + 992c: 24 85 ldd r18, Z+12 ; 0x0c + 992e: 35 85 ldd r19, Z+13 ; 0x0d + 9930: 42 85 ldd r20, Z+10 ; 0x0a + 9932: 53 85 ldd r21, Z+11 ; 0x0b + 9934: 65 ec ldi r22, 0xC5 ; 197 + 9936: 7e e0 ldi r23, 0x0E ; 14 + 9938: 8e e8 ldi r24, 0x8E ; 142 + 993a: 9e e0 ldi r25, 0x0E ; 14 + 993c: 0e 94 67 2a call 0x54ce ; 0x54ce + VtyInit(CLIStateSerialUdp, &udpStream); + 9940: 6e e8 ldi r22, 0x8E ; 142 + 9942: 7e e0 ldi r23, 0x0E ; 14 + 9944: 80 91 5e 0f lds r24, 0x0F5E + 9948: 90 91 5f 0f lds r25, 0x0F5F + 994c: 0e 94 32 17 call 0x2e64 ; 0x2e64 + +//xTaskCreate(encTask, NULL /*"ENC" */, STACK_SIZE_ENC, (void *)CLIStateSerialUsb->myStdInOut, 0, &xHandleEnc); + xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb), 1, &xHandleVTY_USB); + 9950: 20 91 9e 0e lds r18, 0x0E9E + 9954: 30 91 9f 0e lds r19, 0x0E9F + 9958: a1 2c mov r10, r1 + 995a: b1 2c mov r11, r1 + 995c: c1 2c mov r12, r1 + 995e: d1 2c mov r13, r1 + 9960: 8a eb ldi r24, 0xBA ; 186 + 9962: e8 2e mov r14, r24 + 9964: 8e e0 ldi r24, 0x0E ; 14 + 9966: f8 2e mov r15, r24 + 9968: 01 e0 ldi r16, 0x01 ; 1 + 996a: 4c eb ldi r20, 0xBC ; 188 + 996c: 52 e0 ldi r21, 0x02 ; 2 + 996e: 60 e0 ldi r22, 0x00 ; 0 + 9970: 70 e0 ldi r23, 0x00 ; 0 + 9972: 8a ed ldi r24, 0xDA ; 218 + 9974: 99 e1 ldi r25, 0x19 ; 25 + 9976: 0e 94 94 3f call 0x7f28 ; 0x7f28 +//xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp), 1, &xHandleVTY_UDP); + xTaskCreate(sensorsTask, NULL /*"Sensors"*/, STACK_SIZE_SENSORS, NULL, 1, &xHandleSensors); + 997a: 96 ea ldi r25, 0xA6 ; 166 + 997c: e9 2e mov r14, r25 + 997e: 9e e0 ldi r25, 0x0E ; 14 + 9980: f9 2e mov r15, r25 + 9982: 20 e0 ldi r18, 0x00 ; 0 + 9984: 30 e0 ldi r19, 0x00 ; 0 + 9986: 44 ef ldi r20, 0xF4 ; 244 + 9988: 51 e0 ldi r21, 0x01 ; 1 + 998a: 60 e0 ldi r22, 0x00 ; 0 + 998c: 70 e0 ldi r23, 0x00 ; 0 + 998e: 8a e9 ldi r24, 0x9A ; 154 + 9990: 9f e0 ldi r25, 0x0F ; 15 + 9992: 0e 94 94 3f call 0x7f28 ; 0x7f28 + vTaskStartScheduler(); + 9996: 0e 94 bc 41 call 0x8378 ; 0x8378 + return 0; +} + 999a: 80 e0 ldi r24, 0x00 ; 0 + 999c: 90 e0 ldi r25, 0x00 ; 0 + 999e: 0f 91 pop r16 + 99a0: ff 90 pop r15 + 99a2: ef 90 pop r14 + 99a4: df 90 pop r13 + 99a6: cf 90 pop r12 + 99a8: bf 90 pop r11 + 99aa: af 90 pop r10 + 99ac: 08 95 ret + +000099ae <__udivmodqi4>: + 99ae: 99 1b sub r25, r25 + 99b0: 79 e0 ldi r23, 0x09 ; 9 + 99b2: 04 c0 rjmp .+8 ; 0x99bc <__udivmodqi4_ep> + +000099b4 <__udivmodqi4_loop>: + 99b4: 99 1f adc r25, r25 + 99b6: 96 17 cp r25, r22 + 99b8: 08 f0 brcs .+2 ; 0x99bc <__udivmodqi4_ep> + 99ba: 96 1b sub r25, r22 + +000099bc <__udivmodqi4_ep>: + 99bc: 88 1f adc r24, r24 + 99be: 7a 95 dec r23 + 99c0: c9 f7 brne .-14 ; 0x99b4 <__udivmodqi4_loop> + 99c2: 80 95 com r24 + 99c4: 08 95 ret + +000099c6 <__udivmodhi4>: + 99c6: aa 1b sub r26, r26 + 99c8: bb 1b sub r27, r27 + 99ca: 51 e1 ldi r21, 0x11 ; 17 + 99cc: 07 c0 rjmp .+14 ; 0x99dc <__udivmodhi4_ep> + +000099ce <__udivmodhi4_loop>: + 99ce: aa 1f adc r26, r26 + 99d0: bb 1f adc r27, r27 + 99d2: a6 17 cp r26, r22 + 99d4: b7 07 cpc r27, r23 + 99d6: 10 f0 brcs .+4 ; 0x99dc <__udivmodhi4_ep> + 99d8: a6 1b sub r26, r22 + 99da: b7 0b sbc r27, r23 + +000099dc <__udivmodhi4_ep>: + 99dc: 88 1f adc r24, r24 + 99de: 99 1f adc r25, r25 + 99e0: 5a 95 dec r21 + 99e2: a9 f7 brne .-22 ; 0x99ce <__udivmodhi4_loop> + 99e4: 80 95 com r24 + 99e6: 90 95 com r25 + 99e8: bc 01 movw r22, r24 + 99ea: cd 01 movw r24, r26 + 99ec: 08 95 ret + +000099ee <__bswapsi2>: + 99ee: 69 27 eor r22, r25 + 99f0: 96 27 eor r25, r22 + 99f2: 69 27 eor r22, r25 + 99f4: 78 27 eor r23, r24 + 99f6: 87 27 eor r24, r23 + 99f8: 78 27 eor r23, r24 + 99fa: 08 95 ret + +000099fc : + 99fc: cf 93 push r28 + 99fe: df 93 push r29 + 9a00: 82 30 cpi r24, 0x02 ; 2 + 9a02: 91 05 cpc r25, r1 + 9a04: 10 f4 brcc .+4 ; 0x9a0a + 9a06: 82 e0 ldi r24, 0x02 ; 2 + 9a08: 90 e0 ldi r25, 0x00 ; 0 + 9a0a: e0 91 d8 0f lds r30, 0x0FD8 + 9a0e: f0 91 d9 0f lds r31, 0x0FD9 + 9a12: 20 e0 ldi r18, 0x00 ; 0 + 9a14: 30 e0 ldi r19, 0x00 ; 0 + 9a16: c0 e0 ldi r28, 0x00 ; 0 + 9a18: d0 e0 ldi r29, 0x00 ; 0 + 9a1a: 30 97 sbiw r30, 0x00 ; 0 + 9a1c: 11 f1 breq .+68 ; 0x9a62 + 9a1e: 40 81 ld r20, Z + 9a20: 51 81 ldd r21, Z+1 ; 0x01 + 9a22: 48 17 cp r20, r24 + 9a24: 59 07 cpc r21, r25 + 9a26: c0 f0 brcs .+48 ; 0x9a58 + 9a28: 48 17 cp r20, r24 + 9a2a: 59 07 cpc r21, r25 + 9a2c: 61 f4 brne .+24 ; 0x9a46 + 9a2e: 82 81 ldd r24, Z+2 ; 0x02 + 9a30: 93 81 ldd r25, Z+3 ; 0x03 + 9a32: 20 97 sbiw r28, 0x00 ; 0 + 9a34: 19 f0 breq .+6 ; 0x9a3c + 9a36: 9b 83 std Y+3, r25 ; 0x03 + 9a38: 8a 83 std Y+2, r24 ; 0x02 + 9a3a: 2b c0 rjmp .+86 ; 0x9a92 + 9a3c: 90 93 d9 0f sts 0x0FD9, r25 + 9a40: 80 93 d8 0f sts 0x0FD8, r24 + 9a44: 26 c0 rjmp .+76 ; 0x9a92 + 9a46: 21 15 cp r18, r1 + 9a48: 31 05 cpc r19, r1 + 9a4a: 19 f0 breq .+6 ; 0x9a52 + 9a4c: 42 17 cp r20, r18 + 9a4e: 53 07 cpc r21, r19 + 9a50: 18 f4 brcc .+6 ; 0x9a58 + 9a52: 9a 01 movw r18, r20 + 9a54: be 01 movw r22, r28 + 9a56: df 01 movw r26, r30 + 9a58: ef 01 movw r28, r30 + 9a5a: 02 80 ldd r0, Z+2 ; 0x02 + 9a5c: f3 81 ldd r31, Z+3 ; 0x03 + 9a5e: e0 2d mov r30, r0 + 9a60: dc cf rjmp .-72 ; 0x9a1a + 9a62: 21 15 cp r18, r1 + 9a64: 31 05 cpc r19, r1 + 9a66: 09 f1 breq .+66 ; 0x9aaa + 9a68: 28 1b sub r18, r24 + 9a6a: 39 0b sbc r19, r25 + 9a6c: 24 30 cpi r18, 0x04 ; 4 + 9a6e: 31 05 cpc r19, r1 + 9a70: 90 f4 brcc .+36 ; 0x9a96 + 9a72: 12 96 adiw r26, 0x02 ; 2 + 9a74: 8d 91 ld r24, X+ + 9a76: 9c 91 ld r25, X + 9a78: 13 97 sbiw r26, 0x03 ; 3 + 9a7a: 61 15 cp r22, r1 + 9a7c: 71 05 cpc r23, r1 + 9a7e: 21 f0 breq .+8 ; 0x9a88 + 9a80: fb 01 movw r30, r22 + 9a82: 93 83 std Z+3, r25 ; 0x03 + 9a84: 82 83 std Z+2, r24 ; 0x02 + 9a86: 04 c0 rjmp .+8 ; 0x9a90 + 9a88: 90 93 d9 0f sts 0x0FD9, r25 + 9a8c: 80 93 d8 0f sts 0x0FD8, r24 + 9a90: fd 01 movw r30, r26 + 9a92: 32 96 adiw r30, 0x02 ; 2 + 9a94: 44 c0 rjmp .+136 ; 0x9b1e + 9a96: fd 01 movw r30, r26 + 9a98: e2 0f add r30, r18 + 9a9a: f3 1f adc r31, r19 + 9a9c: 81 93 st Z+, r24 + 9a9e: 91 93 st Z+, r25 + 9aa0: 22 50 subi r18, 0x02 ; 2 + 9aa2: 31 09 sbc r19, r1 + 9aa4: 2d 93 st X+, r18 + 9aa6: 3c 93 st X, r19 + 9aa8: 3a c0 rjmp .+116 ; 0x9b1e + 9aaa: 20 91 d6 0f lds r18, 0x0FD6 + 9aae: 30 91 d7 0f lds r19, 0x0FD7 + 9ab2: 23 2b or r18, r19 + 9ab4: 41 f4 brne .+16 ; 0x9ac6 + 9ab6: 20 91 07 01 lds r18, 0x0107 + 9aba: 30 91 08 01 lds r19, 0x0108 + 9abe: 30 93 d7 0f sts 0x0FD7, r19 + 9ac2: 20 93 d6 0f sts 0x0FD6, r18 + 9ac6: 20 91 05 01 lds r18, 0x0105 + 9aca: 30 91 06 01 lds r19, 0x0106 + 9ace: 21 15 cp r18, r1 + 9ad0: 31 05 cpc r19, r1 + 9ad2: 41 f4 brne .+16 ; 0x9ae4 + 9ad4: 2d b7 in r18, 0x3d ; 61 + 9ad6: 3e b7 in r19, 0x3e ; 62 + 9ad8: 40 91 09 01 lds r20, 0x0109 + 9adc: 50 91 0a 01 lds r21, 0x010A + 9ae0: 24 1b sub r18, r20 + 9ae2: 35 0b sbc r19, r21 + 9ae4: e0 91 d6 0f lds r30, 0x0FD6 + 9ae8: f0 91 d7 0f lds r31, 0x0FD7 + 9aec: e2 17 cp r30, r18 + 9aee: f3 07 cpc r31, r19 + 9af0: a0 f4 brcc .+40 ; 0x9b1a + 9af2: 2e 1b sub r18, r30 + 9af4: 3f 0b sbc r19, r31 + 9af6: 28 17 cp r18, r24 + 9af8: 39 07 cpc r19, r25 + 9afa: 78 f0 brcs .+30 ; 0x9b1a + 9afc: ac 01 movw r20, r24 + 9afe: 4e 5f subi r20, 0xFE ; 254 + 9b00: 5f 4f sbci r21, 0xFF ; 255 + 9b02: 24 17 cp r18, r20 + 9b04: 35 07 cpc r19, r21 + 9b06: 48 f0 brcs .+18 ; 0x9b1a + 9b08: 4e 0f add r20, r30 + 9b0a: 5f 1f adc r21, r31 + 9b0c: 50 93 d7 0f sts 0x0FD7, r21 + 9b10: 40 93 d6 0f sts 0x0FD6, r20 + 9b14: 81 93 st Z+, r24 + 9b16: 91 93 st Z+, r25 + 9b18: 02 c0 rjmp .+4 ; 0x9b1e + 9b1a: e0 e0 ldi r30, 0x00 ; 0 + 9b1c: f0 e0 ldi r31, 0x00 ; 0 + 9b1e: cf 01 movw r24, r30 + 9b20: df 91 pop r29 + 9b22: cf 91 pop r28 + 9b24: 08 95 ret + +00009b26 : + 9b26: 0f 93 push r16 + 9b28: 1f 93 push r17 + 9b2a: cf 93 push r28 + 9b2c: df 93 push r29 + 9b2e: 00 97 sbiw r24, 0x00 ; 0 + 9b30: 09 f4 brne .+2 ; 0x9b34 + 9b32: 8c c0 rjmp .+280 ; 0x9c4c + 9b34: fc 01 movw r30, r24 + 9b36: 32 97 sbiw r30, 0x02 ; 2 + 9b38: 13 82 std Z+3, r1 ; 0x03 + 9b3a: 12 82 std Z+2, r1 ; 0x02 + 9b3c: 00 91 d8 0f lds r16, 0x0FD8 + 9b40: 10 91 d9 0f lds r17, 0x0FD9 + 9b44: 01 15 cp r16, r1 + 9b46: 11 05 cpc r17, r1 + 9b48: 81 f4 brne .+32 ; 0x9b6a + 9b4a: 20 81 ld r18, Z + 9b4c: 31 81 ldd r19, Z+1 ; 0x01 + 9b4e: 82 0f add r24, r18 + 9b50: 93 1f adc r25, r19 + 9b52: 20 91 d6 0f lds r18, 0x0FD6 + 9b56: 30 91 d7 0f lds r19, 0x0FD7 + 9b5a: 28 17 cp r18, r24 + 9b5c: 39 07 cpc r19, r25 + 9b5e: 79 f5 brne .+94 ; 0x9bbe + 9b60: f0 93 d7 0f sts 0x0FD7, r31 + 9b64: e0 93 d6 0f sts 0x0FD6, r30 + 9b68: 71 c0 rjmp .+226 ; 0x9c4c + 9b6a: d8 01 movw r26, r16 + 9b6c: 40 e0 ldi r20, 0x00 ; 0 + 9b6e: 50 e0 ldi r21, 0x00 ; 0 + 9b70: ae 17 cp r26, r30 + 9b72: bf 07 cpc r27, r31 + 9b74: 50 f4 brcc .+20 ; 0x9b8a + 9b76: 12 96 adiw r26, 0x02 ; 2 + 9b78: 2d 91 ld r18, X+ + 9b7a: 3c 91 ld r19, X + 9b7c: 13 97 sbiw r26, 0x03 ; 3 + 9b7e: ad 01 movw r20, r26 + 9b80: 21 15 cp r18, r1 + 9b82: 31 05 cpc r19, r1 + 9b84: 09 f1 breq .+66 ; 0x9bc8 + 9b86: d9 01 movw r26, r18 + 9b88: f3 cf rjmp .-26 ; 0x9b70 + 9b8a: 9d 01 movw r18, r26 + 9b8c: da 01 movw r26, r20 + 9b8e: 33 83 std Z+3, r19 ; 0x03 + 9b90: 22 83 std Z+2, r18 ; 0x02 + 9b92: 60 81 ld r22, Z + 9b94: 71 81 ldd r23, Z+1 ; 0x01 + 9b96: 86 0f add r24, r22 + 9b98: 97 1f adc r25, r23 + 9b9a: 82 17 cp r24, r18 + 9b9c: 93 07 cpc r25, r19 + 9b9e: 69 f4 brne .+26 ; 0x9bba + 9ba0: ec 01 movw r28, r24 + 9ba2: 28 81 ld r18, Y + 9ba4: 39 81 ldd r19, Y+1 ; 0x01 + 9ba6: 26 0f add r18, r22 + 9ba8: 37 1f adc r19, r23 + 9baa: 2e 5f subi r18, 0xFE ; 254 + 9bac: 3f 4f sbci r19, 0xFF ; 255 + 9bae: 31 83 std Z+1, r19 ; 0x01 + 9bb0: 20 83 st Z, r18 + 9bb2: 8a 81 ldd r24, Y+2 ; 0x02 + 9bb4: 9b 81 ldd r25, Y+3 ; 0x03 + 9bb6: 93 83 std Z+3, r25 ; 0x03 + 9bb8: 82 83 std Z+2, r24 ; 0x02 + 9bba: 45 2b or r20, r21 + 9bbc: 29 f4 brne .+10 ; 0x9bc8 + 9bbe: f0 93 d9 0f sts 0x0FD9, r31 + 9bc2: e0 93 d8 0f sts 0x0FD8, r30 + 9bc6: 42 c0 rjmp .+132 ; 0x9c4c + 9bc8: 13 96 adiw r26, 0x03 ; 3 + 9bca: fc 93 st X, r31 + 9bcc: ee 93 st -X, r30 + 9bce: 12 97 sbiw r26, 0x02 ; 2 + 9bd0: ed 01 movw r28, r26 + 9bd2: 49 91 ld r20, Y+ + 9bd4: 59 91 ld r21, Y+ + 9bd6: 9e 01 movw r18, r28 + 9bd8: 24 0f add r18, r20 + 9bda: 35 1f adc r19, r21 + 9bdc: e2 17 cp r30, r18 + 9bde: f3 07 cpc r31, r19 + 9be0: 71 f4 brne .+28 ; 0x9bfe + 9be2: 80 81 ld r24, Z + 9be4: 91 81 ldd r25, Z+1 ; 0x01 + 9be6: 84 0f add r24, r20 + 9be8: 95 1f adc r25, r21 + 9bea: 02 96 adiw r24, 0x02 ; 2 + 9bec: 11 96 adiw r26, 0x01 ; 1 + 9bee: 9c 93 st X, r25 + 9bf0: 8e 93 st -X, r24 + 9bf2: 82 81 ldd r24, Z+2 ; 0x02 + 9bf4: 93 81 ldd r25, Z+3 ; 0x03 + 9bf6: 13 96 adiw r26, 0x03 ; 3 + 9bf8: 9c 93 st X, r25 + 9bfa: 8e 93 st -X, r24 + 9bfc: 12 97 sbiw r26, 0x02 ; 2 + 9bfe: e0 e0 ldi r30, 0x00 ; 0 + 9c00: f0 e0 ldi r31, 0x00 ; 0 + 9c02: d8 01 movw r26, r16 + 9c04: 12 96 adiw r26, 0x02 ; 2 + 9c06: 8d 91 ld r24, X+ + 9c08: 9c 91 ld r25, X + 9c0a: 13 97 sbiw r26, 0x03 ; 3 + 9c0c: 00 97 sbiw r24, 0x00 ; 0 + 9c0e: 19 f0 breq .+6 ; 0x9c16 + 9c10: f8 01 movw r30, r16 + 9c12: 8c 01 movw r16, r24 + 9c14: f6 cf rjmp .-20 ; 0x9c02 + 9c16: 8d 91 ld r24, X+ + 9c18: 9c 91 ld r25, X + 9c1a: 98 01 movw r18, r16 + 9c1c: 2e 5f subi r18, 0xFE ; 254 + 9c1e: 3f 4f sbci r19, 0xFF ; 255 + 9c20: 82 0f add r24, r18 + 9c22: 93 1f adc r25, r19 + 9c24: 20 91 d6 0f lds r18, 0x0FD6 + 9c28: 30 91 d7 0f lds r19, 0x0FD7 + 9c2c: 28 17 cp r18, r24 + 9c2e: 39 07 cpc r19, r25 + 9c30: 69 f4 brne .+26 ; 0x9c4c + 9c32: 30 97 sbiw r30, 0x00 ; 0 + 9c34: 29 f4 brne .+10 ; 0x9c40 + 9c36: 10 92 d9 0f sts 0x0FD9, r1 + 9c3a: 10 92 d8 0f sts 0x0FD8, r1 + 9c3e: 02 c0 rjmp .+4 ; 0x9c44 + 9c40: 13 82 std Z+3, r1 ; 0x03 + 9c42: 12 82 std Z+2, r1 ; 0x02 + 9c44: 10 93 d7 0f sts 0x0FD7, r17 + 9c48: 00 93 d6 0f sts 0x0FD6, r16 + 9c4c: df 91 pop r29 + 9c4e: cf 91 pop r28 + 9c50: 1f 91 pop r17 + 9c52: 0f 91 pop r16 + 9c54: 08 95 ret + +00009c56 : + 9c56: 2f 92 push r2 + 9c58: 3f 92 push r3 + 9c5a: 4f 92 push r4 + 9c5c: 5f 92 push r5 + 9c5e: 6f 92 push r6 + 9c60: 7f 92 push r7 + 9c62: 8f 92 push r8 + 9c64: 9f 92 push r9 + 9c66: af 92 push r10 + 9c68: bf 92 push r11 + 9c6a: cf 92 push r12 + 9c6c: df 92 push r13 + 9c6e: ef 92 push r14 + 9c70: ff 92 push r15 + 9c72: 0f 93 push r16 + 9c74: 1f 93 push r17 + 9c76: cf 93 push r28 + 9c78: df 93 push r29 + 9c7a: 5c 01 movw r10, r24 + 9c7c: 6b 01 movw r12, r22 + 9c7e: 7a 01 movw r14, r20 + 9c80: 61 15 cp r22, r1 + 9c82: 71 05 cpc r23, r1 + 9c84: 19 f0 breq .+6 ; 0x9c8c + 9c86: fb 01 movw r30, r22 + 9c88: 91 83 std Z+1, r25 ; 0x01 + 9c8a: 80 83 st Z, r24 + 9c8c: e1 14 cp r14, r1 + 9c8e: f1 04 cpc r15, r1 + 9c90: 29 f0 breq .+10 ; 0x9c9c + 9c92: c7 01 movw r24, r14 + 9c94: 02 97 sbiw r24, 0x02 ; 2 + 9c96: 83 97 sbiw r24, 0x23 ; 35 + 9c98: 08 f0 brcs .+2 ; 0x9c9c + 9c9a: f1 c0 rjmp .+482 ; 0x9e7e + 9c9c: e5 01 movw r28, r10 + 9c9e: 21 96 adiw r28, 0x01 ; 1 + 9ca0: f5 01 movw r30, r10 + 9ca2: 10 81 ld r17, Z + 9ca4: 81 2f mov r24, r17 + 9ca6: 90 e0 ldi r25, 0x00 ; 0 + 9ca8: 0e 94 56 4f call 0x9eac ; 0x9eac + 9cac: 89 2b or r24, r25 + 9cae: 11 f0 breq .+4 ; 0x9cb4 + 9cb0: 5e 01 movw r10, r28 + 9cb2: f4 cf rjmp .-24 ; 0x9c9c + 9cb4: 1d 32 cpi r17, 0x2D ; 45 + 9cb6: 29 f4 brne .+10 ; 0x9cc2 + 9cb8: 21 96 adiw r28, 0x01 ; 1 + 9cba: f5 01 movw r30, r10 + 9cbc: 11 81 ldd r17, Z+1 ; 0x01 + 9cbe: 01 e0 ldi r16, 0x01 ; 1 + 9cc0: 07 c0 rjmp .+14 ; 0x9cd0 + 9cc2: 1b 32 cpi r17, 0x2B ; 43 + 9cc4: 21 f4 brne .+8 ; 0x9cce + 9cc6: e5 01 movw r28, r10 + 9cc8: 22 96 adiw r28, 0x02 ; 2 + 9cca: f5 01 movw r30, r10 + 9ccc: 11 81 ldd r17, Z+1 ; 0x01 + 9cce: 00 e0 ldi r16, 0x00 ; 0 + 9cd0: e1 14 cp r14, r1 + 9cd2: f1 04 cpc r15, r1 + 9cd4: 59 f1 breq .+86 ; 0x9d2c + 9cd6: f0 e1 ldi r31, 0x10 ; 16 + 9cd8: ef 16 cp r14, r31 + 9cda: f1 04 cpc r15, r1 + 9cdc: 61 f4 brne .+24 ; 0x9cf6 + 9cde: 10 33 cpi r17, 0x30 ; 48 + 9ce0: e1 f4 brne .+56 ; 0x9d1a + 9ce2: 88 81 ld r24, Y + 9ce4: 8f 7d andi r24, 0xDF ; 223 + 9ce6: 88 35 cpi r24, 0x58 ; 88 + 9ce8: 69 f5 brne .+90 ; 0x9d44 + 9cea: 19 81 ldd r17, Y+1 ; 0x01 + 9cec: 22 96 adiw r28, 0x02 ; 2 + 9cee: 02 60 ori r16, 0x02 ; 2 + 9cf0: 70 e1 ldi r23, 0x10 ; 16 + 9cf2: e7 2e mov r14, r23 + 9cf4: f1 2c mov r15, r1 + 9cf6: 88 e0 ldi r24, 0x08 ; 8 + 9cf8: e8 16 cp r14, r24 + 9cfa: f1 04 cpc r15, r1 + 9cfc: 39 f1 breq .+78 ; 0x9d4c + 9cfe: 2c f4 brge .+10 ; 0x9d0a + 9d00: f2 e0 ldi r31, 0x02 ; 2 + 9d02: ef 16 cp r14, r31 + 9d04: f1 04 cpc r15, r1 + 9d06: c9 f1 breq .+114 ; 0x9d7a + 9d08: 2a c0 rjmp .+84 ; 0x9d5e + 9d0a: 8a e0 ldi r24, 0x0A ; 10 + 9d0c: e8 16 cp r14, r24 + 9d0e: f1 04 cpc r15, r1 + 9d10: 79 f0 breq .+30 ; 0x9d30 + 9d12: e0 e1 ldi r30, 0x10 ; 16 + 9d14: ee 16 cp r14, r30 + 9d16: f1 04 cpc r15, r1 + 9d18: 11 f5 brne .+68 ; 0x9d5e + 9d1a: 50 e1 ldi r21, 0x10 ; 16 + 9d1c: e5 2e mov r14, r21 + 9d1e: f1 2c mov r15, r1 + 9d20: 81 2c mov r8, r1 + 9d22: 91 2c mov r9, r1 + 9d24: a1 2c mov r10, r1 + 9d26: 68 e0 ldi r22, 0x08 ; 8 + 9d28: b6 2e mov r11, r22 + 9d2a: 2c c0 rjmp .+88 ; 0x9d84 + 9d2c: 10 33 cpi r17, 0x30 ; 48 + 9d2e: c9 f2 breq .-78 ; 0x9ce2 + 9d30: 3a e0 ldi r19, 0x0A ; 10 + 9d32: e3 2e mov r14, r19 + 9d34: f1 2c mov r15, r1 + 9d36: 4c ec ldi r20, 0xCC ; 204 + 9d38: 84 2e mov r8, r20 + 9d3a: 98 2c mov r9, r8 + 9d3c: a8 2c mov r10, r8 + 9d3e: 4c e0 ldi r20, 0x0C ; 12 + 9d40: b4 2e mov r11, r20 + 9d42: 20 c0 rjmp .+64 ; 0x9d84 + 9d44: 10 e3 ldi r17, 0x30 ; 48 + 9d46: e1 14 cp r14, r1 + 9d48: f1 04 cpc r15, r1 + 9d4a: a9 f6 brne .-86 ; 0x9cf6 + 9d4c: 98 e0 ldi r25, 0x08 ; 8 + 9d4e: e9 2e mov r14, r25 + 9d50: f1 2c mov r15, r1 + 9d52: 81 2c mov r8, r1 + 9d54: 91 2c mov r9, r1 + 9d56: a1 2c mov r10, r1 + 9d58: 20 e1 ldi r18, 0x10 ; 16 + 9d5a: b2 2e mov r11, r18 + 9d5c: 13 c0 rjmp .+38 ; 0x9d84 + 9d5e: 60 e0 ldi r22, 0x00 ; 0 + 9d60: 70 e0 ldi r23, 0x00 ; 0 + 9d62: 80 e0 ldi r24, 0x00 ; 0 + 9d64: 90 e8 ldi r25, 0x80 ; 128 + 9d66: 97 01 movw r18, r14 + 9d68: 0f 2c mov r0, r15 + 9d6a: 00 0c add r0, r0 + 9d6c: 44 0b sbc r20, r20 + 9d6e: 55 0b sbc r21, r21 + 9d70: 0e 94 9c 53 call 0xa738 ; 0xa738 <__udivmodsi4> + 9d74: 49 01 movw r8, r18 + 9d76: 5a 01 movw r10, r20 + 9d78: 05 c0 rjmp .+10 ; 0x9d84 + 9d7a: 81 2c mov r8, r1 + 9d7c: 91 2c mov r9, r1 + 9d7e: a1 2c mov r10, r1 + 9d80: 80 e4 ldi r24, 0x40 ; 64 + 9d82: b8 2e mov r11, r24 + 9d84: 60 e0 ldi r22, 0x00 ; 0 + 9d86: 20 e0 ldi r18, 0x00 ; 0 + 9d88: 30 e0 ldi r19, 0x00 ; 0 + 9d8a: a9 01 movw r20, r18 + 9d8c: 27 01 movw r4, r14 + 9d8e: 0f 2c mov r0, r15 + 9d90: 00 0c add r0, r0 + 9d92: 66 08 sbc r6, r6 + 9d94: 77 08 sbc r7, r7 + 9d96: 1e 01 movw r2, r28 + 9d98: e0 ed ldi r30, 0xD0 ; 208 + 9d9a: e1 0f add r30, r17 + 9d9c: ea 30 cpi r30, 0x0A ; 10 + 9d9e: 60 f0 brcs .+24 ; 0x9db8 + 9da0: 8f eb ldi r24, 0xBF ; 191 + 9da2: 81 0f add r24, r17 + 9da4: 8a 31 cpi r24, 0x1A ; 26 + 9da6: 10 f4 brcc .+4 ; 0x9dac + 9da8: e9 ec ldi r30, 0xC9 ; 201 + 9daa: 05 c0 rjmp .+10 ; 0x9db6 + 9dac: 8f e9 ldi r24, 0x9F ; 159 + 9dae: 81 0f add r24, r17 + 9db0: 8a 31 cpi r24, 0x1A ; 26 + 9db2: 28 f5 brcc .+74 ; 0x9dfe + 9db4: e9 ea ldi r30, 0xA9 ; 169 + 9db6: e1 0f add r30, r17 + 9db8: 8e 2f mov r24, r30 + 9dba: 90 e0 ldi r25, 0x00 ; 0 + 9dbc: 8e 15 cp r24, r14 + 9dbe: 9f 05 cpc r25, r15 + 9dc0: f4 f4 brge .+60 ; 0x9dfe + 9dc2: 67 fd sbrc r22, 7 + 9dc4: 18 c0 rjmp .+48 ; 0x9df6 + 9dc6: 82 16 cp r8, r18 + 9dc8: 93 06 cpc r9, r19 + 9dca: a4 06 cpc r10, r20 + 9dcc: b5 06 cpc r11, r21 + 9dce: 90 f0 brcs .+36 ; 0x9df4 + 9dd0: c3 01 movw r24, r6 + 9dd2: b2 01 movw r22, r4 + 9dd4: 0e 94 8c 53 call 0xa718 ; 0xa718 <__mulsi3> + 9dd8: 9b 01 movw r18, r22 + 9dda: ac 01 movw r20, r24 + 9ddc: 2e 0f add r18, r30 + 9dde: 31 1d adc r19, r1 + 9de0: 41 1d adc r20, r1 + 9de2: 51 1d adc r21, r1 + 9de4: 21 30 cpi r18, 0x01 ; 1 + 9de6: 31 05 cpc r19, r1 + 9de8: 41 05 cpc r20, r1 + 9dea: f0 e8 ldi r31, 0x80 ; 128 + 9dec: 5f 07 cpc r21, r31 + 9dee: 10 f4 brcc .+4 ; 0x9df4 + 9df0: 61 e0 ldi r22, 0x01 ; 1 + 9df2: 01 c0 rjmp .+2 ; 0x9df6 + 9df4: 6f ef ldi r22, 0xFF ; 255 + 9df6: 21 96 adiw r28, 0x01 ; 1 + 9df8: f1 01 movw r30, r2 + 9dfa: 10 81 ld r17, Z + 9dfc: cc cf rjmp .-104 ; 0x9d96 + 9dfe: 80 2f mov r24, r16 + 9e00: 81 70 andi r24, 0x01 ; 1 + 9e02: c1 14 cp r12, r1 + 9e04: d1 04 cpc r13, r1 + 9e06: 71 f0 breq .+28 ; 0x9e24 + 9e08: 66 23 and r22, r22 + 9e0a: 29 f0 breq .+10 ; 0x9e16 + 9e0c: 21 97 sbiw r28, 0x01 ; 1 + 9e0e: f6 01 movw r30, r12 + 9e10: d1 83 std Z+1, r29 ; 0x01 + 9e12: c0 83 st Z, r28 + 9e14: 07 c0 rjmp .+14 ; 0x9e24 + 9e16: 01 ff sbrs r16, 1 + 9e18: 19 c0 rjmp .+50 ; 0x9e4c + 9e1a: 22 97 sbiw r28, 0x02 ; 2 + 9e1c: f6 01 movw r30, r12 + 9e1e: d1 83 std Z+1, r29 ; 0x01 + 9e20: c0 83 st Z, r28 + 9e22: 14 c0 rjmp .+40 ; 0x9e4c + 9e24: 67 ff sbrs r22, 7 + 9e26: 12 c0 rjmp .+36 ; 0x9e4c + 9e28: 81 11 cpse r24, r1 + 9e2a: 05 c0 rjmp .+10 ; 0x9e36 + 9e2c: 2f ef ldi r18, 0xFF ; 255 + 9e2e: 3f ef ldi r19, 0xFF ; 255 + 9e30: 4f ef ldi r20, 0xFF ; 255 + 9e32: 5f e7 ldi r21, 0x7F ; 127 + 9e34: 04 c0 rjmp .+8 ; 0x9e3e + 9e36: 20 e0 ldi r18, 0x00 ; 0 + 9e38: 30 e0 ldi r19, 0x00 ; 0 + 9e3a: 40 e0 ldi r20, 0x00 ; 0 + 9e3c: 50 e8 ldi r21, 0x80 ; 128 + 9e3e: 82 e2 ldi r24, 0x22 ; 34 + 9e40: 90 e0 ldi r25, 0x00 ; 0 + 9e42: 90 93 e1 0f sts 0x0FE1, r25 + 9e46: 80 93 e0 0f sts 0x0FE0, r24 + 9e4a: 16 c0 rjmp .+44 ; 0x9e78 + 9e4c: 88 23 and r24, r24 + 9e4e: 41 f0 breq .+16 ; 0x9e60 + 9e50: 50 95 com r21 + 9e52: 40 95 com r20 + 9e54: 30 95 com r19 + 9e56: 21 95 neg r18 + 9e58: 3f 4f sbci r19, 0xFF ; 255 + 9e5a: 4f 4f sbci r20, 0xFF ; 255 + 9e5c: 5f 4f sbci r21, 0xFF ; 255 + 9e5e: 0c c0 rjmp .+24 ; 0x9e78 + 9e60: 57 ff sbrs r21, 7 + 9e62: 0a c0 rjmp .+20 ; 0x9e78 + 9e64: 82 e2 ldi r24, 0x22 ; 34 + 9e66: 90 e0 ldi r25, 0x00 ; 0 + 9e68: 90 93 e1 0f sts 0x0FE1, r25 + 9e6c: 80 93 e0 0f sts 0x0FE0, r24 + 9e70: 2f ef ldi r18, 0xFF ; 255 + 9e72: 3f ef ldi r19, 0xFF ; 255 + 9e74: 4f ef ldi r20, 0xFF ; 255 + 9e76: 5f e7 ldi r21, 0x7F ; 127 + 9e78: b9 01 movw r22, r18 + 9e7a: ca 01 movw r24, r20 + 9e7c: 04 c0 rjmp .+8 ; 0x9e86 + 9e7e: 60 e0 ldi r22, 0x00 ; 0 + 9e80: 70 e0 ldi r23, 0x00 ; 0 + 9e82: 80 e0 ldi r24, 0x00 ; 0 + 9e84: 90 e0 ldi r25, 0x00 ; 0 + 9e86: df 91 pop r29 + 9e88: cf 91 pop r28 + 9e8a: 1f 91 pop r17 + 9e8c: 0f 91 pop r16 + 9e8e: ff 90 pop r15 + 9e90: ef 90 pop r14 + 9e92: df 90 pop r13 + 9e94: cf 90 pop r12 + 9e96: bf 90 pop r11 + 9e98: af 90 pop r10 + 9e9a: 9f 90 pop r9 + 9e9c: 8f 90 pop r8 + 9e9e: 7f 90 pop r7 + 9ea0: 6f 90 pop r6 + 9ea2: 5f 90 pop r5 + 9ea4: 4f 90 pop r4 + 9ea6: 3f 90 pop r3 + 9ea8: 2f 90 pop r2 + 9eaa: 08 95 ret + +00009eac : + 9eac: 91 11 cpse r25, r1 + 9eae: 0c 94 c6 52 jmp 0xa58c ; 0xa58c <__ctype_isfalse> + 9eb2: 80 32 cpi r24, 0x20 ; 32 + 9eb4: 19 f0 breq .+6 ; 0x9ebc + 9eb6: 89 50 subi r24, 0x09 ; 9 + 9eb8: 85 50 subi r24, 0x05 ; 5 + 9eba: c8 f7 brcc .-14 ; 0x9eae + 9ebc: 08 95 ret + +00009ebe : + 9ebe: fb 01 movw r30, r22 + 9ec0: dc 01 movw r26, r24 + 9ec2: 02 c0 rjmp .+4 ; 0x9ec8 + 9ec4: 05 90 lpm r0, Z+ + 9ec6: 0d 92 st X+, r0 + 9ec8: 41 50 subi r20, 0x01 ; 1 + 9eca: 50 40 sbci r21, 0x00 ; 0 + 9ecc: d8 f7 brcc .-10 ; 0x9ec4 + 9ece: 08 95 ret + +00009ed0 : + 9ed0: fb 01 movw r30, r22 + 9ed2: dc 01 movw r26, r24 + 9ed4: 41 50 subi r20, 0x01 ; 1 + 9ed6: 50 40 sbci r21, 0x00 ; 0 + 9ed8: 30 f0 brcs .+12 ; 0x9ee6 + 9eda: 8d 91 ld r24, X+ + 9edc: 05 90 lpm r0, Z+ + 9ede: 80 19 sub r24, r0 + 9ee0: 19 f4 brne .+6 ; 0x9ee8 + 9ee2: 00 20 and r0, r0 + 9ee4: b9 f7 brne .-18 ; 0x9ed4 + 9ee6: 88 1b sub r24, r24 + 9ee8: 99 0b sbc r25, r25 + 9eea: 08 95 ret + +00009eec : + 9eec: fb 01 movw r30, r22 + 9eee: dc 01 movw r26, r24 + 9ef0: 02 c0 rjmp .+4 ; 0x9ef6 + 9ef2: 01 90 ld r0, Z+ + 9ef4: 0d 92 st X+, r0 + 9ef6: 41 50 subi r20, 0x01 ; 1 + 9ef8: 50 40 sbci r21, 0x00 ; 0 + 9efa: d8 f7 brcc .-10 ; 0x9ef2 + 9efc: 08 95 ret + +00009efe : + 9efe: dc 01 movw r26, r24 + 9f00: 01 c0 rjmp .+2 ; 0x9f04 + 9f02: 6d 93 st X+, r22 + 9f04: 41 50 subi r20, 0x01 ; 1 + 9f06: 50 40 sbci r21, 0x00 ; 0 + 9f08: e0 f7 brcc .-8 ; 0x9f02 + 9f0a: 08 95 ret + +00009f0c : + 9f0c: fb 01 movw r30, r22 + 9f0e: dc 01 movw r26, r24 + 9f10: 0d 90 ld r0, X+ + 9f12: 00 20 and r0, r0 + 9f14: e9 f7 brne .-6 ; 0x9f10 + 9f16: 11 97 sbiw r26, 0x01 ; 1 + 9f18: 01 90 ld r0, Z+ + 9f1a: 0d 92 st X+, r0 + 9f1c: 00 20 and r0, r0 + 9f1e: e1 f7 brne .-8 ; 0x9f18 + 9f20: 08 95 ret + +00009f22 : + 9f22: fb 01 movw r30, r22 + 9f24: dc 01 movw r26, r24 + 9f26: 01 90 ld r0, Z+ + 9f28: 0d 92 st X+, r0 + 9f2a: 00 20 and r0, r0 + 9f2c: e1 f7 brne .-8 ; 0x9f26 + 9f2e: 08 95 ret + +00009f30 : + 9f30: fb 01 movw r30, r22 + 9f32: dc 01 movw r26, r24 + 9f34: 41 50 subi r20, 0x01 ; 1 + 9f36: 50 40 sbci r21, 0x00 ; 0 + 9f38: 30 f0 brcs .+12 ; 0x9f46 + 9f3a: 8d 91 ld r24, X+ + 9f3c: 01 90 ld r0, Z+ + 9f3e: 80 19 sub r24, r0 + 9f40: 19 f4 brne .+6 ; 0x9f48 + 9f42: 00 20 and r0, r0 + 9f44: b9 f7 brne .-18 ; 0x9f34 + 9f46: 88 1b sub r24, r24 + 9f48: 99 0b sbc r25, r25 + 9f4a: 08 95 ret + +00009f4c : + 9f4c: fb 01 movw r30, r22 + 9f4e: dc 01 movw r26, r24 + 9f50: 41 50 subi r20, 0x01 ; 1 + 9f52: 50 40 sbci r21, 0x00 ; 0 + 9f54: 48 f0 brcs .+18 ; 0x9f68 + 9f56: 01 90 ld r0, Z+ + 9f58: 0d 92 st X+, r0 + 9f5a: 00 20 and r0, r0 + 9f5c: c9 f7 brne .-14 ; 0x9f50 + 9f5e: 01 c0 rjmp .+2 ; 0x9f62 + 9f60: 1d 92 st X+, r1 + 9f62: 41 50 subi r20, 0x01 ; 1 + 9f64: 50 40 sbci r21, 0x00 ; 0 + 9f66: e0 f7 brcc .-8 ; 0x9f60 + 9f68: 08 95 ret + +00009f6a : + 9f6a: fc 01 movw r30, r24 + 9f6c: 23 81 ldd r18, Z+3 ; 0x03 + 9f6e: 27 ff sbrs r18, 7 + 9f70: 10 c0 rjmp .+32 ; 0x9f92 + 9f72: ea ed ldi r30, 0xDA ; 218 + 9f74: ff e0 ldi r31, 0x0F ; 15 + 9f76: 20 81 ld r18, Z + 9f78: 31 81 ldd r19, Z+1 ; 0x01 + 9f7a: 28 17 cp r18, r24 + 9f7c: 39 07 cpc r19, r25 + 9f7e: 11 f4 brne .+4 ; 0x9f84 + 9f80: 11 82 std Z+1, r1 ; 0x01 + 9f82: 10 82 st Z, r1 + 9f84: 32 96 adiw r30, 0x02 ; 2 + 9f86: 2f e0 ldi r18, 0x0F ; 15 + 9f88: e0 3e cpi r30, 0xE0 ; 224 + 9f8a: f2 07 cpc r31, r18 + 9f8c: a1 f7 brne .-24 ; 0x9f76 + 9f8e: 0e 94 93 4d call 0x9b26 ; 0x9b26 + 9f92: 80 e0 ldi r24, 0x00 ; 0 + 9f94: 90 e0 ldi r25, 0x00 ; 0 + 9f96: 08 95 ret + +00009f98 : + 9f98: cf 93 push r28 + 9f9a: df 93 push r29 + 9f9c: ec 01 movw r28, r24 + 9f9e: 2b 81 ldd r18, Y+3 ; 0x03 + 9fa0: 20 ff sbrs r18, 0 + 9fa2: 33 c0 rjmp .+102 ; 0xa00a + 9fa4: 26 ff sbrs r18, 6 + 9fa6: 0a c0 rjmp .+20 ; 0x9fbc + 9fa8: 2f 7b andi r18, 0xBF ; 191 + 9faa: 2b 83 std Y+3, r18 ; 0x03 + 9fac: 8e 81 ldd r24, Y+6 ; 0x06 + 9fae: 9f 81 ldd r25, Y+7 ; 0x07 + 9fb0: 01 96 adiw r24, 0x01 ; 1 + 9fb2: 9f 83 std Y+7, r25 ; 0x07 + 9fb4: 8e 83 std Y+6, r24 ; 0x06 + 9fb6: 8a 81 ldd r24, Y+2 ; 0x02 + 9fb8: 90 e0 ldi r25, 0x00 ; 0 + 9fba: 29 c0 rjmp .+82 ; 0xa00e + 9fbc: 22 ff sbrs r18, 2 + 9fbe: 0f c0 rjmp .+30 ; 0x9fde + 9fc0: e8 81 ld r30, Y + 9fc2: f9 81 ldd r31, Y+1 ; 0x01 + 9fc4: 80 81 ld r24, Z + 9fc6: 08 2e mov r0, r24 + 9fc8: 00 0c add r0, r0 + 9fca: 99 0b sbc r25, r25 + 9fcc: 00 97 sbiw r24, 0x00 ; 0 + 9fce: 19 f4 brne .+6 ; 0x9fd6 + 9fd0: 20 62 ori r18, 0x20 ; 32 + 9fd2: 2b 83 std Y+3, r18 ; 0x03 + 9fd4: 1a c0 rjmp .+52 ; 0xa00a + 9fd6: 31 96 adiw r30, 0x01 ; 1 + 9fd8: f9 83 std Y+1, r31 ; 0x01 + 9fda: e8 83 st Y, r30 + 9fdc: 0e c0 rjmp .+28 ; 0x9ffa + 9fde: ea 85 ldd r30, Y+10 ; 0x0a + 9fe0: fb 85 ldd r31, Y+11 ; 0x0b + 9fe2: 09 95 icall + 9fe4: 97 ff sbrs r25, 7 + 9fe6: 09 c0 rjmp .+18 ; 0x9ffa + 9fe8: 2b 81 ldd r18, Y+3 ; 0x03 + 9fea: 01 96 adiw r24, 0x01 ; 1 + 9fec: 11 f0 breq .+4 ; 0x9ff2 + 9fee: 80 e2 ldi r24, 0x20 ; 32 + 9ff0: 01 c0 rjmp .+2 ; 0x9ff4 + 9ff2: 80 e1 ldi r24, 0x10 ; 16 + 9ff4: 82 2b or r24, r18 + 9ff6: 8b 83 std Y+3, r24 ; 0x03 + 9ff8: 08 c0 rjmp .+16 ; 0xa00a + 9ffa: 2e 81 ldd r18, Y+6 ; 0x06 + 9ffc: 3f 81 ldd r19, Y+7 ; 0x07 + 9ffe: 2f 5f subi r18, 0xFF ; 255 + a000: 3f 4f sbci r19, 0xFF ; 255 + a002: 3f 83 std Y+7, r19 ; 0x07 + a004: 2e 83 std Y+6, r18 ; 0x06 + a006: 99 27 eor r25, r25 + a008: 02 c0 rjmp .+4 ; 0xa00e + a00a: 8f ef ldi r24, 0xFF ; 255 + a00c: 9f ef ldi r25, 0xFF ; 255 + a00e: df 91 pop r29 + a010: cf 91 pop r28 + a012: 08 95 ret + +0000a014 : + a014: cf 93 push r28 + a016: df 93 push r29 + a018: cd b7 in r28, 0x3d ; 61 + a01a: de b7 in r29, 0x3e ; 62 + a01c: ae 01 movw r20, r28 + a01e: 47 5f subi r20, 0xF7 ; 247 + a020: 5f 4f sbci r21, 0xFF ; 255 + a022: 6f 81 ldd r22, Y+7 ; 0x07 + a024: 78 85 ldd r23, Y+8 ; 0x08 + a026: 8d 81 ldd r24, Y+5 ; 0x05 + a028: 9e 81 ldd r25, Y+6 ; 0x06 + a02a: 0e 94 cb 50 call 0xa196 ; 0xa196 + a02e: df 91 pop r29 + a030: cf 91 pop r28 + a032: 08 95 ret + +0000a034 : + a034: 0f 93 push r16 + a036: 1f 93 push r17 + a038: cf 93 push r28 + a03a: df 93 push r29 + a03c: cd b7 in r28, 0x3d ; 61 + a03e: de b7 in r29, 0x3e ; 62 + a040: 0f 81 ldd r16, Y+7 ; 0x07 + a042: 18 85 ldd r17, Y+8 ; 0x08 + a044: f8 01 movw r30, r16 + a046: 83 81 ldd r24, Z+3 ; 0x03 + a048: 88 60 ori r24, 0x08 ; 8 + a04a: 83 83 std Z+3, r24 ; 0x03 + a04c: ae 01 movw r20, r28 + a04e: 45 5f subi r20, 0xF5 ; 245 + a050: 5f 4f sbci r21, 0xFF ; 255 + a052: 69 85 ldd r22, Y+9 ; 0x09 + a054: 7a 85 ldd r23, Y+10 ; 0x0a + a056: c8 01 movw r24, r16 + a058: 0e 94 cb 50 call 0xa196 ; 0xa196 + a05c: f8 01 movw r30, r16 + a05e: 23 81 ldd r18, Z+3 ; 0x03 + a060: 27 7f andi r18, 0xF7 ; 247 + a062: 23 83 std Z+3, r18 ; 0x03 + a064: df 91 pop r29 + a066: cf 91 pop r28 + a068: 1f 91 pop r17 + a06a: 0f 91 pop r16 + a06c: 08 95 ret + +0000a06e : + a06e: 0f 93 push r16 + a070: 1f 93 push r17 + a072: cf 93 push r28 + a074: df 93 push r29 + a076: fb 01 movw r30, r22 + a078: 23 81 ldd r18, Z+3 ; 0x03 + a07a: 21 fd sbrc r18, 1 + a07c: 03 c0 rjmp .+6 ; 0xa084 + a07e: 8f ef ldi r24, 0xFF ; 255 + a080: 9f ef ldi r25, 0xFF ; 255 + a082: 28 c0 rjmp .+80 ; 0xa0d4 + a084: 22 ff sbrs r18, 2 + a086: 16 c0 rjmp .+44 ; 0xa0b4 + a088: 46 81 ldd r20, Z+6 ; 0x06 + a08a: 57 81 ldd r21, Z+7 ; 0x07 + a08c: 24 81 ldd r18, Z+4 ; 0x04 + a08e: 35 81 ldd r19, Z+5 ; 0x05 + a090: 42 17 cp r20, r18 + a092: 53 07 cpc r21, r19 + a094: 44 f4 brge .+16 ; 0xa0a6 + a096: a0 81 ld r26, Z + a098: b1 81 ldd r27, Z+1 ; 0x01 + a09a: 9d 01 movw r18, r26 + a09c: 2f 5f subi r18, 0xFF ; 255 + a09e: 3f 4f sbci r19, 0xFF ; 255 + a0a0: 31 83 std Z+1, r19 ; 0x01 + a0a2: 20 83 st Z, r18 + a0a4: 8c 93 st X, r24 + a0a6: 26 81 ldd r18, Z+6 ; 0x06 + a0a8: 37 81 ldd r19, Z+7 ; 0x07 + a0aa: 2f 5f subi r18, 0xFF ; 255 + a0ac: 3f 4f sbci r19, 0xFF ; 255 + a0ae: 37 83 std Z+7, r19 ; 0x07 + a0b0: 26 83 std Z+6, r18 ; 0x06 + a0b2: 10 c0 rjmp .+32 ; 0xa0d4 + a0b4: eb 01 movw r28, r22 + a0b6: 09 2f mov r16, r25 + a0b8: 18 2f mov r17, r24 + a0ba: 00 84 ldd r0, Z+8 ; 0x08 + a0bc: f1 85 ldd r31, Z+9 ; 0x09 + a0be: e0 2d mov r30, r0 + a0c0: 09 95 icall + a0c2: 89 2b or r24, r25 + a0c4: e1 f6 brne .-72 ; 0xa07e + a0c6: 8e 81 ldd r24, Y+6 ; 0x06 + a0c8: 9f 81 ldd r25, Y+7 ; 0x07 + a0ca: 01 96 adiw r24, 0x01 ; 1 + a0cc: 9f 83 std Y+7, r25 ; 0x07 + a0ce: 8e 83 std Y+6, r24 ; 0x06 + a0d0: 81 2f mov r24, r17 + a0d2: 90 2f mov r25, r16 + a0d4: df 91 pop r29 + a0d6: cf 91 pop r28 + a0d8: 1f 91 pop r17 + a0da: 0f 91 pop r16 + a0dc: 08 95 ret + +0000a0de : + a0de: ef 92 push r14 + a0e0: ff 92 push r15 + a0e2: 0f 93 push r16 + a0e4: 1f 93 push r17 + a0e6: cf 93 push r28 + a0e8: df 93 push r29 + a0ea: db 01 movw r26, r22 + a0ec: 13 96 adiw r26, 0x03 ; 3 + a0ee: 2c 91 ld r18, X + a0f0: 21 ff sbrs r18, 1 + a0f2: 18 c0 rjmp .+48 ; 0xa124 + a0f4: 8b 01 movw r16, r22 + a0f6: 7c 01 movw r14, r24 + a0f8: d0 e0 ldi r29, 0x00 ; 0 + a0fa: c0 e0 ldi r28, 0x00 ; 0 + a0fc: f7 01 movw r30, r14 + a0fe: 81 91 ld r24, Z+ + a100: 7f 01 movw r14, r30 + a102: 88 23 and r24, r24 + a104: 61 f0 breq .+24 ; 0xa11e + a106: d8 01 movw r26, r16 + a108: 18 96 adiw r26, 0x08 ; 8 + a10a: ed 91 ld r30, X+ + a10c: fc 91 ld r31, X + a10e: 19 97 sbiw r26, 0x09 ; 9 + a110: b8 01 movw r22, r16 + a112: 09 95 icall + a114: 89 2b or r24, r25 + a116: 91 f3 breq .-28 ; 0xa0fc + a118: df ef ldi r29, 0xFF ; 255 + a11a: cf ef ldi r28, 0xFF ; 255 + a11c: ef cf rjmp .-34 ; 0xa0fc + a11e: 8d 2f mov r24, r29 + a120: 9c 2f mov r25, r28 + a122: 02 c0 rjmp .+4 ; 0xa128 + a124: 8f ef ldi r24, 0xFF ; 255 + a126: 9f ef ldi r25, 0xFF ; 255 + a128: df 91 pop r29 + a12a: cf 91 pop r28 + a12c: 1f 91 pop r17 + a12e: 0f 91 pop r16 + a130: ff 90 pop r15 + a132: ef 90 pop r14 + a134: 08 95 ret + +0000a136 : + a136: 0f 93 push r16 + a138: 1f 93 push r17 + a13a: cf 93 push r28 + a13c: df 93 push r29 + a13e: cd b7 in r28, 0x3d ; 61 + a140: de b7 in r29, 0x3e ; 62 + a142: 2e 97 sbiw r28, 0x0e ; 14 + a144: 0f b6 in r0, 0x3f ; 63 + a146: f8 94 cli + a148: de bf out 0x3e, r29 ; 62 + a14a: 0f be out 0x3f, r0 ; 63 + a14c: cd bf out 0x3d, r28 ; 61 + a14e: 0d 89 ldd r16, Y+21 ; 0x15 + a150: 1e 89 ldd r17, Y+22 ; 0x16 + a152: 86 e0 ldi r24, 0x06 ; 6 + a154: 8c 83 std Y+4, r24 ; 0x04 + a156: 1a 83 std Y+2, r17 ; 0x02 + a158: 09 83 std Y+1, r16 ; 0x01 + a15a: 8f ef ldi r24, 0xFF ; 255 + a15c: 9f e7 ldi r25, 0x7F ; 127 + a15e: 9e 83 std Y+6, r25 ; 0x06 + a160: 8d 83 std Y+5, r24 ; 0x05 + a162: ae 01 movw r20, r28 + a164: 47 5e subi r20, 0xE7 ; 231 + a166: 5f 4f sbci r21, 0xFF ; 255 + a168: 6f 89 ldd r22, Y+23 ; 0x17 + a16a: 78 8d ldd r23, Y+24 ; 0x18 + a16c: ce 01 movw r24, r28 + a16e: 01 96 adiw r24, 0x01 ; 1 + a170: 0e 94 cb 50 call 0xa196 ; 0xa196 + a174: 2f 81 ldd r18, Y+7 ; 0x07 + a176: 38 85 ldd r19, Y+8 ; 0x08 + a178: f8 01 movw r30, r16 + a17a: e2 0f add r30, r18 + a17c: f3 1f adc r31, r19 + a17e: 10 82 st Z, r1 + a180: 2e 96 adiw r28, 0x0e ; 14 + a182: 0f b6 in r0, 0x3f ; 63 + a184: f8 94 cli + a186: de bf out 0x3e, r29 ; 62 + a188: 0f be out 0x3f, r0 ; 63 + a18a: cd bf out 0x3d, r28 ; 61 + a18c: df 91 pop r29 + a18e: cf 91 pop r28 + a190: 1f 91 pop r17 + a192: 0f 91 pop r16 + a194: 08 95 ret + +0000a196 : + a196: 2f 92 push r2 + a198: 3f 92 push r3 + a19a: 4f 92 push r4 + a19c: 5f 92 push r5 + a19e: 6f 92 push r6 + a1a0: 7f 92 push r7 + a1a2: 8f 92 push r8 + a1a4: 9f 92 push r9 + a1a6: af 92 push r10 + a1a8: bf 92 push r11 + a1aa: cf 92 push r12 + a1ac: df 92 push r13 + a1ae: ef 92 push r14 + a1b0: ff 92 push r15 + a1b2: 0f 93 push r16 + a1b4: 1f 93 push r17 + a1b6: cf 93 push r28 + a1b8: df 93 push r29 + a1ba: cd b7 in r28, 0x3d ; 61 + a1bc: de b7 in r29, 0x3e ; 62 + a1be: 2c 97 sbiw r28, 0x0c ; 12 + a1c0: 0f b6 in r0, 0x3f ; 63 + a1c2: f8 94 cli + a1c4: de bf out 0x3e, r29 ; 62 + a1c6: 0f be out 0x3f, r0 ; 63 + a1c8: cd bf out 0x3d, r28 ; 61 + a1ca: 7c 01 movw r14, r24 + a1cc: 6b 01 movw r12, r22 + a1ce: 8a 01 movw r16, r20 + a1d0: fc 01 movw r30, r24 + a1d2: 17 82 std Z+7, r1 ; 0x07 + a1d4: 16 82 std Z+6, r1 ; 0x06 + a1d6: 83 81 ldd r24, Z+3 ; 0x03 + a1d8: 81 ff sbrs r24, 1 + a1da: bd c1 rjmp .+890 ; 0xa556 + a1dc: ce 01 movw r24, r28 + a1de: 01 96 adiw r24, 0x01 ; 1 + a1e0: 4c 01 movw r8, r24 + a1e2: f7 01 movw r30, r14 + a1e4: 93 81 ldd r25, Z+3 ; 0x03 + a1e6: f6 01 movw r30, r12 + a1e8: 93 fd sbrc r25, 3 + a1ea: 85 91 lpm r24, Z+ + a1ec: 93 ff sbrs r25, 3 + a1ee: 81 91 ld r24, Z+ + a1f0: 6f 01 movw r12, r30 + a1f2: 88 23 and r24, r24 + a1f4: 09 f4 brne .+2 ; 0xa1f8 + a1f6: ab c1 rjmp .+854 ; 0xa54e + a1f8: 85 32 cpi r24, 0x25 ; 37 + a1fa: 39 f4 brne .+14 ; 0xa20a + a1fc: 93 fd sbrc r25, 3 + a1fe: 85 91 lpm r24, Z+ + a200: 93 ff sbrs r25, 3 + a202: 81 91 ld r24, Z+ + a204: 6f 01 movw r12, r30 + a206: 85 32 cpi r24, 0x25 ; 37 + a208: 29 f4 brne .+10 ; 0xa214 + a20a: b7 01 movw r22, r14 + a20c: 90 e0 ldi r25, 0x00 ; 0 + a20e: 0e 94 37 50 call 0xa06e ; 0xa06e + a212: e7 cf rjmp .-50 ; 0xa1e2 + a214: 51 2c mov r5, r1 + a216: 31 2c mov r3, r1 + a218: 20 e0 ldi r18, 0x00 ; 0 + a21a: 20 32 cpi r18, 0x20 ; 32 + a21c: a0 f4 brcc .+40 ; 0xa246 + a21e: 8b 32 cpi r24, 0x2B ; 43 + a220: 69 f0 breq .+26 ; 0xa23c + a222: 30 f4 brcc .+12 ; 0xa230 + a224: 80 32 cpi r24, 0x20 ; 32 + a226: 59 f0 breq .+22 ; 0xa23e + a228: 83 32 cpi r24, 0x23 ; 35 + a22a: 69 f4 brne .+26 ; 0xa246 + a22c: 20 61 ori r18, 0x10 ; 16 + a22e: 2c c0 rjmp .+88 ; 0xa288 + a230: 8d 32 cpi r24, 0x2D ; 45 + a232: 39 f0 breq .+14 ; 0xa242 + a234: 80 33 cpi r24, 0x30 ; 48 + a236: 39 f4 brne .+14 ; 0xa246 + a238: 21 60 ori r18, 0x01 ; 1 + a23a: 26 c0 rjmp .+76 ; 0xa288 + a23c: 22 60 ori r18, 0x02 ; 2 + a23e: 24 60 ori r18, 0x04 ; 4 + a240: 23 c0 rjmp .+70 ; 0xa288 + a242: 28 60 ori r18, 0x08 ; 8 + a244: 21 c0 rjmp .+66 ; 0xa288 + a246: 27 fd sbrc r18, 7 + a248: 27 c0 rjmp .+78 ; 0xa298 + a24a: 30 ed ldi r19, 0xD0 ; 208 + a24c: 38 0f add r19, r24 + a24e: 3a 30 cpi r19, 0x0A ; 10 + a250: 78 f4 brcc .+30 ; 0xa270 + a252: 26 ff sbrs r18, 6 + a254: 06 c0 rjmp .+12 ; 0xa262 + a256: fa e0 ldi r31, 0x0A ; 10 + a258: 5f 9e mul r5, r31 + a25a: 30 0d add r19, r0 + a25c: 11 24 eor r1, r1 + a25e: 53 2e mov r5, r19 + a260: 13 c0 rjmp .+38 ; 0xa288 + a262: 8a e0 ldi r24, 0x0A ; 10 + a264: 38 9e mul r3, r24 + a266: 30 0d add r19, r0 + a268: 11 24 eor r1, r1 + a26a: 33 2e mov r3, r19 + a26c: 20 62 ori r18, 0x20 ; 32 + a26e: 0c c0 rjmp .+24 ; 0xa288 + a270: 8e 32 cpi r24, 0x2E ; 46 + a272: 21 f4 brne .+8 ; 0xa27c + a274: 26 fd sbrc r18, 6 + a276: 6b c1 rjmp .+726 ; 0xa54e + a278: 20 64 ori r18, 0x40 ; 64 + a27a: 06 c0 rjmp .+12 ; 0xa288 + a27c: 8c 36 cpi r24, 0x6C ; 108 + a27e: 11 f4 brne .+4 ; 0xa284 + a280: 20 68 ori r18, 0x80 ; 128 + a282: 02 c0 rjmp .+4 ; 0xa288 + a284: 88 36 cpi r24, 0x68 ; 104 + a286: 41 f4 brne .+16 ; 0xa298 + a288: f6 01 movw r30, r12 + a28a: 93 fd sbrc r25, 3 + a28c: 85 91 lpm r24, Z+ + a28e: 93 ff sbrs r25, 3 + a290: 81 91 ld r24, Z+ + a292: 6f 01 movw r12, r30 + a294: 81 11 cpse r24, r1 + a296: c1 cf rjmp .-126 ; 0xa21a + a298: 98 2f mov r25, r24 + a29a: 9f 7d andi r25, 0xDF ; 223 + a29c: 95 54 subi r25, 0x45 ; 69 + a29e: 93 30 cpi r25, 0x03 ; 3 + a2a0: 28 f4 brcc .+10 ; 0xa2ac + a2a2: 0c 5f subi r16, 0xFC ; 252 + a2a4: 1f 4f sbci r17, 0xFF ; 255 + a2a6: ff e3 ldi r31, 0x3F ; 63 + a2a8: f9 83 std Y+1, r31 ; 0x01 + a2aa: 0d c0 rjmp .+26 ; 0xa2c6 + a2ac: 83 36 cpi r24, 0x63 ; 99 + a2ae: 31 f0 breq .+12 ; 0xa2bc + a2b0: 83 37 cpi r24, 0x73 ; 115 + a2b2: 71 f0 breq .+28 ; 0xa2d0 + a2b4: 83 35 cpi r24, 0x53 ; 83 + a2b6: 09 f0 breq .+2 ; 0xa2ba + a2b8: 5b c0 rjmp .+182 ; 0xa370 + a2ba: 22 c0 rjmp .+68 ; 0xa300 + a2bc: f8 01 movw r30, r16 + a2be: 80 81 ld r24, Z + a2c0: 89 83 std Y+1, r24 ; 0x01 + a2c2: 0e 5f subi r16, 0xFE ; 254 + a2c4: 1f 4f sbci r17, 0xFF ; 255 + a2c6: 44 24 eor r4, r4 + a2c8: 43 94 inc r4 + a2ca: 51 2c mov r5, r1 + a2cc: 54 01 movw r10, r8 + a2ce: 15 c0 rjmp .+42 ; 0xa2fa + a2d0: 38 01 movw r6, r16 + a2d2: f2 e0 ldi r31, 0x02 ; 2 + a2d4: 6f 0e add r6, r31 + a2d6: 71 1c adc r7, r1 + a2d8: f8 01 movw r30, r16 + a2da: a0 80 ld r10, Z + a2dc: b1 80 ldd r11, Z+1 ; 0x01 + a2de: 26 ff sbrs r18, 6 + a2e0: 03 c0 rjmp .+6 ; 0xa2e8 + a2e2: 65 2d mov r22, r5 + a2e4: 70 e0 ldi r23, 0x00 ; 0 + a2e6: 02 c0 rjmp .+4 ; 0xa2ec + a2e8: 6f ef ldi r22, 0xFF ; 255 + a2ea: 7f ef ldi r23, 0xFF ; 255 + a2ec: c5 01 movw r24, r10 + a2ee: 2c 87 std Y+12, r18 ; 0x0c + a2f0: 0e 94 d4 52 call 0xa5a8 ; 0xa5a8 + a2f4: 2c 01 movw r4, r24 + a2f6: 83 01 movw r16, r6 + a2f8: 2c 85 ldd r18, Y+12 ; 0x0c + a2fa: 2f 77 andi r18, 0x7F ; 127 + a2fc: 22 2e mov r2, r18 + a2fe: 17 c0 rjmp .+46 ; 0xa32e + a300: 38 01 movw r6, r16 + a302: f2 e0 ldi r31, 0x02 ; 2 + a304: 6f 0e add r6, r31 + a306: 71 1c adc r7, r1 + a308: f8 01 movw r30, r16 + a30a: a0 80 ld r10, Z + a30c: b1 80 ldd r11, Z+1 ; 0x01 + a30e: 26 ff sbrs r18, 6 + a310: 03 c0 rjmp .+6 ; 0xa318 + a312: 65 2d mov r22, r5 + a314: 70 e0 ldi r23, 0x00 ; 0 + a316: 02 c0 rjmp .+4 ; 0xa31c + a318: 6f ef ldi r22, 0xFF ; 255 + a31a: 7f ef ldi r23, 0xFF ; 255 + a31c: c5 01 movw r24, r10 + a31e: 2c 87 std Y+12, r18 ; 0x0c + a320: 0e 94 c9 52 call 0xa592 ; 0xa592 + a324: 2c 01 movw r4, r24 + a326: 2c 85 ldd r18, Y+12 ; 0x0c + a328: 20 68 ori r18, 0x80 ; 128 + a32a: 22 2e mov r2, r18 + a32c: 83 01 movw r16, r6 + a32e: 23 fc sbrc r2, 3 + a330: 1b c0 rjmp .+54 ; 0xa368 + a332: 83 2d mov r24, r3 + a334: 90 e0 ldi r25, 0x00 ; 0 + a336: 48 16 cp r4, r24 + a338: 59 06 cpc r5, r25 + a33a: b0 f4 brcc .+44 ; 0xa368 + a33c: b7 01 movw r22, r14 + a33e: 80 e2 ldi r24, 0x20 ; 32 + a340: 90 e0 ldi r25, 0x00 ; 0 + a342: 0e 94 37 50 call 0xa06e ; 0xa06e + a346: 3a 94 dec r3 + a348: f4 cf rjmp .-24 ; 0xa332 + a34a: f5 01 movw r30, r10 + a34c: 27 fc sbrc r2, 7 + a34e: 85 91 lpm r24, Z+ + a350: 27 fe sbrs r2, 7 + a352: 81 91 ld r24, Z+ + a354: 5f 01 movw r10, r30 + a356: b7 01 movw r22, r14 + a358: 90 e0 ldi r25, 0x00 ; 0 + a35a: 0e 94 37 50 call 0xa06e ; 0xa06e + a35e: 31 10 cpse r3, r1 + a360: 3a 94 dec r3 + a362: f1 e0 ldi r31, 0x01 ; 1 + a364: 4f 1a sub r4, r31 + a366: 51 08 sbc r5, r1 + a368: 41 14 cp r4, r1 + a36a: 51 04 cpc r5, r1 + a36c: 71 f7 brne .-36 ; 0xa34a + a36e: e5 c0 rjmp .+458 ; 0xa53a + a370: 84 36 cpi r24, 0x64 ; 100 + a372: 11 f0 breq .+4 ; 0xa378 + a374: 89 36 cpi r24, 0x69 ; 105 + a376: 39 f5 brne .+78 ; 0xa3c6 + a378: f8 01 movw r30, r16 + a37a: 27 ff sbrs r18, 7 + a37c: 07 c0 rjmp .+14 ; 0xa38c + a37e: 60 81 ld r22, Z + a380: 71 81 ldd r23, Z+1 ; 0x01 + a382: 82 81 ldd r24, Z+2 ; 0x02 + a384: 93 81 ldd r25, Z+3 ; 0x03 + a386: 0c 5f subi r16, 0xFC ; 252 + a388: 1f 4f sbci r17, 0xFF ; 255 + a38a: 08 c0 rjmp .+16 ; 0xa39c + a38c: 60 81 ld r22, Z + a38e: 71 81 ldd r23, Z+1 ; 0x01 + a390: 07 2e mov r0, r23 + a392: 00 0c add r0, r0 + a394: 88 0b sbc r24, r24 + a396: 99 0b sbc r25, r25 + a398: 0e 5f subi r16, 0xFE ; 254 + a39a: 1f 4f sbci r17, 0xFF ; 255 + a39c: 2f 76 andi r18, 0x6F ; 111 + a39e: 72 2e mov r7, r18 + a3a0: 97 ff sbrs r25, 7 + a3a2: 09 c0 rjmp .+18 ; 0xa3b6 + a3a4: 90 95 com r25 + a3a6: 80 95 com r24 + a3a8: 70 95 com r23 + a3aa: 61 95 neg r22 + a3ac: 7f 4f sbci r23, 0xFF ; 255 + a3ae: 8f 4f sbci r24, 0xFF ; 255 + a3b0: 9f 4f sbci r25, 0xFF ; 255 + a3b2: 20 68 ori r18, 0x80 ; 128 + a3b4: 72 2e mov r7, r18 + a3b6: 2a e0 ldi r18, 0x0A ; 10 + a3b8: 30 e0 ldi r19, 0x00 ; 0 + a3ba: a4 01 movw r20, r8 + a3bc: 0e 94 df 52 call 0xa5be ; 0xa5be <__ultoa_invert> + a3c0: a8 2e mov r10, r24 + a3c2: a8 18 sub r10, r8 + a3c4: 44 c0 rjmp .+136 ; 0xa44e + a3c6: 85 37 cpi r24, 0x75 ; 117 + a3c8: 29 f4 brne .+10 ; 0xa3d4 + a3ca: 2f 7e andi r18, 0xEF ; 239 + a3cc: b2 2e mov r11, r18 + a3ce: 2a e0 ldi r18, 0x0A ; 10 + a3d0: 30 e0 ldi r19, 0x00 ; 0 + a3d2: 25 c0 rjmp .+74 ; 0xa41e + a3d4: f2 2f mov r31, r18 + a3d6: f9 7f andi r31, 0xF9 ; 249 + a3d8: bf 2e mov r11, r31 + a3da: 8f 36 cpi r24, 0x6F ; 111 + a3dc: c1 f0 breq .+48 ; 0xa40e + a3de: 18 f4 brcc .+6 ; 0xa3e6 + a3e0: 88 35 cpi r24, 0x58 ; 88 + a3e2: 79 f0 breq .+30 ; 0xa402 + a3e4: b4 c0 rjmp .+360 ; 0xa54e + a3e6: 80 37 cpi r24, 0x70 ; 112 + a3e8: 19 f0 breq .+6 ; 0xa3f0 + a3ea: 88 37 cpi r24, 0x78 ; 120 + a3ec: 21 f0 breq .+8 ; 0xa3f6 + a3ee: af c0 rjmp .+350 ; 0xa54e + a3f0: 2f 2f mov r18, r31 + a3f2: 20 61 ori r18, 0x10 ; 16 + a3f4: b2 2e mov r11, r18 + a3f6: b4 fe sbrs r11, 4 + a3f8: 0d c0 rjmp .+26 ; 0xa414 + a3fa: 8b 2d mov r24, r11 + a3fc: 84 60 ori r24, 0x04 ; 4 + a3fe: b8 2e mov r11, r24 + a400: 09 c0 rjmp .+18 ; 0xa414 + a402: 24 ff sbrs r18, 4 + a404: 0a c0 rjmp .+20 ; 0xa41a + a406: 9f 2f mov r25, r31 + a408: 96 60 ori r25, 0x06 ; 6 + a40a: b9 2e mov r11, r25 + a40c: 06 c0 rjmp .+12 ; 0xa41a + a40e: 28 e0 ldi r18, 0x08 ; 8 + a410: 30 e0 ldi r19, 0x00 ; 0 + a412: 05 c0 rjmp .+10 ; 0xa41e + a414: 20 e1 ldi r18, 0x10 ; 16 + a416: 30 e0 ldi r19, 0x00 ; 0 + a418: 02 c0 rjmp .+4 ; 0xa41e + a41a: 20 e1 ldi r18, 0x10 ; 16 + a41c: 32 e0 ldi r19, 0x02 ; 2 + a41e: f8 01 movw r30, r16 + a420: b7 fe sbrs r11, 7 + a422: 07 c0 rjmp .+14 ; 0xa432 + a424: 60 81 ld r22, Z + a426: 71 81 ldd r23, Z+1 ; 0x01 + a428: 82 81 ldd r24, Z+2 ; 0x02 + a42a: 93 81 ldd r25, Z+3 ; 0x03 + a42c: 0c 5f subi r16, 0xFC ; 252 + a42e: 1f 4f sbci r17, 0xFF ; 255 + a430: 06 c0 rjmp .+12 ; 0xa43e + a432: 60 81 ld r22, Z + a434: 71 81 ldd r23, Z+1 ; 0x01 + a436: 80 e0 ldi r24, 0x00 ; 0 + a438: 90 e0 ldi r25, 0x00 ; 0 + a43a: 0e 5f subi r16, 0xFE ; 254 + a43c: 1f 4f sbci r17, 0xFF ; 255 + a43e: a4 01 movw r20, r8 + a440: 0e 94 df 52 call 0xa5be ; 0xa5be <__ultoa_invert> + a444: a8 2e mov r10, r24 + a446: a8 18 sub r10, r8 + a448: fb 2d mov r31, r11 + a44a: ff 77 andi r31, 0x7F ; 127 + a44c: 7f 2e mov r7, r31 + a44e: 76 fe sbrs r7, 6 + a450: 0b c0 rjmp .+22 ; 0xa468 + a452: 37 2d mov r19, r7 + a454: 3e 7f andi r19, 0xFE ; 254 + a456: a5 14 cp r10, r5 + a458: 50 f4 brcc .+20 ; 0xa46e + a45a: 74 fe sbrs r7, 4 + a45c: 0a c0 rjmp .+20 ; 0xa472 + a45e: 72 fc sbrc r7, 2 + a460: 08 c0 rjmp .+16 ; 0xa472 + a462: 37 2d mov r19, r7 + a464: 3e 7e andi r19, 0xEE ; 238 + a466: 05 c0 rjmp .+10 ; 0xa472 + a468: ba 2c mov r11, r10 + a46a: 37 2d mov r19, r7 + a46c: 03 c0 rjmp .+6 ; 0xa474 + a46e: ba 2c mov r11, r10 + a470: 01 c0 rjmp .+2 ; 0xa474 + a472: b5 2c mov r11, r5 + a474: 34 ff sbrs r19, 4 + a476: 0d c0 rjmp .+26 ; 0xa492 + a478: fe 01 movw r30, r28 + a47a: ea 0d add r30, r10 + a47c: f1 1d adc r31, r1 + a47e: 80 81 ld r24, Z + a480: 80 33 cpi r24, 0x30 ; 48 + a482: 11 f4 brne .+4 ; 0xa488 + a484: 39 7e andi r19, 0xE9 ; 233 + a486: 09 c0 rjmp .+18 ; 0xa49a + a488: 32 ff sbrs r19, 2 + a48a: 06 c0 rjmp .+12 ; 0xa498 + a48c: b3 94 inc r11 + a48e: b3 94 inc r11 + a490: 04 c0 rjmp .+8 ; 0xa49a + a492: 83 2f mov r24, r19 + a494: 86 78 andi r24, 0x86 ; 134 + a496: 09 f0 breq .+2 ; 0xa49a + a498: b3 94 inc r11 + a49a: 33 fd sbrc r19, 3 + a49c: 13 c0 rjmp .+38 ; 0xa4c4 + a49e: 30 ff sbrs r19, 0 + a4a0: 06 c0 rjmp .+12 ; 0xa4ae + a4a2: 5a 2c mov r5, r10 + a4a4: b3 14 cp r11, r3 + a4a6: 18 f4 brcc .+6 ; 0xa4ae + a4a8: 53 0c add r5, r3 + a4aa: 5b 18 sub r5, r11 + a4ac: b3 2c mov r11, r3 + a4ae: b3 14 cp r11, r3 + a4b0: 68 f4 brcc .+26 ; 0xa4cc + a4b2: b7 01 movw r22, r14 + a4b4: 80 e2 ldi r24, 0x20 ; 32 + a4b6: 90 e0 ldi r25, 0x00 ; 0 + a4b8: 3c 87 std Y+12, r19 ; 0x0c + a4ba: 0e 94 37 50 call 0xa06e ; 0xa06e + a4be: b3 94 inc r11 + a4c0: 3c 85 ldd r19, Y+12 ; 0x0c + a4c2: f5 cf rjmp .-22 ; 0xa4ae + a4c4: b3 14 cp r11, r3 + a4c6: 10 f4 brcc .+4 ; 0xa4cc + a4c8: 3b 18 sub r3, r11 + a4ca: 01 c0 rjmp .+2 ; 0xa4ce + a4cc: 31 2c mov r3, r1 + a4ce: 34 ff sbrs r19, 4 + a4d0: 12 c0 rjmp .+36 ; 0xa4f6 + a4d2: b7 01 movw r22, r14 + a4d4: 80 e3 ldi r24, 0x30 ; 48 + a4d6: 90 e0 ldi r25, 0x00 ; 0 + a4d8: 3c 87 std Y+12, r19 ; 0x0c + a4da: 0e 94 37 50 call 0xa06e ; 0xa06e + a4de: 3c 85 ldd r19, Y+12 ; 0x0c + a4e0: 32 ff sbrs r19, 2 + a4e2: 17 c0 rjmp .+46 ; 0xa512 + a4e4: 31 fd sbrc r19, 1 + a4e6: 03 c0 rjmp .+6 ; 0xa4ee + a4e8: 88 e7 ldi r24, 0x78 ; 120 + a4ea: 90 e0 ldi r25, 0x00 ; 0 + a4ec: 02 c0 rjmp .+4 ; 0xa4f2 + a4ee: 88 e5 ldi r24, 0x58 ; 88 + a4f0: 90 e0 ldi r25, 0x00 ; 0 + a4f2: b7 01 movw r22, r14 + a4f4: 0c c0 rjmp .+24 ; 0xa50e + a4f6: 83 2f mov r24, r19 + a4f8: 86 78 andi r24, 0x86 ; 134 + a4fa: 59 f0 breq .+22 ; 0xa512 + a4fc: 31 ff sbrs r19, 1 + a4fe: 02 c0 rjmp .+4 ; 0xa504 + a500: 8b e2 ldi r24, 0x2B ; 43 + a502: 01 c0 rjmp .+2 ; 0xa506 + a504: 80 e2 ldi r24, 0x20 ; 32 + a506: 37 fd sbrc r19, 7 + a508: 8d e2 ldi r24, 0x2D ; 45 + a50a: b7 01 movw r22, r14 + a50c: 90 e0 ldi r25, 0x00 ; 0 + a50e: 0e 94 37 50 call 0xa06e ; 0xa06e + a512: a5 14 cp r10, r5 + a514: 38 f4 brcc .+14 ; 0xa524 + a516: b7 01 movw r22, r14 + a518: 80 e3 ldi r24, 0x30 ; 48 + a51a: 90 e0 ldi r25, 0x00 ; 0 + a51c: 0e 94 37 50 call 0xa06e ; 0xa06e + a520: 5a 94 dec r5 + a522: f7 cf rjmp .-18 ; 0xa512 + a524: aa 94 dec r10 + a526: f4 01 movw r30, r8 + a528: ea 0d add r30, r10 + a52a: f1 1d adc r31, r1 + a52c: 80 81 ld r24, Z + a52e: b7 01 movw r22, r14 + a530: 90 e0 ldi r25, 0x00 ; 0 + a532: 0e 94 37 50 call 0xa06e ; 0xa06e + a536: a1 10 cpse r10, r1 + a538: f5 cf rjmp .-22 ; 0xa524 + a53a: 33 20 and r3, r3 + a53c: 09 f4 brne .+2 ; 0xa540 + a53e: 51 ce rjmp .-862 ; 0xa1e2 + a540: b7 01 movw r22, r14 + a542: 80 e2 ldi r24, 0x20 ; 32 + a544: 90 e0 ldi r25, 0x00 ; 0 + a546: 0e 94 37 50 call 0xa06e ; 0xa06e + a54a: 3a 94 dec r3 + a54c: f6 cf rjmp .-20 ; 0xa53a + a54e: f7 01 movw r30, r14 + a550: 86 81 ldd r24, Z+6 ; 0x06 + a552: 97 81 ldd r25, Z+7 ; 0x07 + a554: 02 c0 rjmp .+4 ; 0xa55a + a556: 8f ef ldi r24, 0xFF ; 255 + a558: 9f ef ldi r25, 0xFF ; 255 + a55a: 2c 96 adiw r28, 0x0c ; 12 + a55c: 0f b6 in r0, 0x3f ; 63 + a55e: f8 94 cli + a560: de bf out 0x3e, r29 ; 62 + a562: 0f be out 0x3f, r0 ; 63 + a564: cd bf out 0x3d, r28 ; 61 + a566: df 91 pop r29 + a568: cf 91 pop r28 + a56a: 1f 91 pop r17 + a56c: 0f 91 pop r16 + a56e: ff 90 pop r15 + a570: ef 90 pop r14 + a572: df 90 pop r13 + a574: cf 90 pop r12 + a576: bf 90 pop r11 + a578: af 90 pop r10 + a57a: 9f 90 pop r9 + a57c: 8f 90 pop r8 + a57e: 7f 90 pop r7 + a580: 6f 90 pop r6 + a582: 5f 90 pop r5 + a584: 4f 90 pop r4 + a586: 3f 90 pop r3 + a588: 2f 90 pop r2 + a58a: 08 95 ret + +0000a58c <__ctype_isfalse>: + a58c: 99 27 eor r25, r25 + a58e: 88 27 eor r24, r24 + +0000a590 <__ctype_istrue>: + a590: 08 95 ret + +0000a592 : + a592: fc 01 movw r30, r24 + a594: 05 90 lpm r0, Z+ + a596: 61 50 subi r22, 0x01 ; 1 + a598: 70 40 sbci r23, 0x00 ; 0 + a59a: 01 10 cpse r0, r1 + a59c: d8 f7 brcc .-10 ; 0xa594 + a59e: 80 95 com r24 + a5a0: 90 95 com r25 + a5a2: 8e 0f add r24, r30 + a5a4: 9f 1f adc r25, r31 + a5a6: 08 95 ret + +0000a5a8 : + a5a8: fc 01 movw r30, r24 + a5aa: 61 50 subi r22, 0x01 ; 1 + a5ac: 70 40 sbci r23, 0x00 ; 0 + a5ae: 01 90 ld r0, Z+ + a5b0: 01 10 cpse r0, r1 + a5b2: d8 f7 brcc .-10 ; 0xa5aa + a5b4: 80 95 com r24 + a5b6: 90 95 com r25 + a5b8: 8e 0f add r24, r30 + a5ba: 9f 1f adc r25, r31 + a5bc: 08 95 ret + +0000a5be <__ultoa_invert>: + a5be: fa 01 movw r30, r20 + a5c0: aa 27 eor r26, r26 + a5c2: 28 30 cpi r18, 0x08 ; 8 + a5c4: 51 f1 breq .+84 ; 0xa61a <__ultoa_invert+0x5c> + a5c6: 20 31 cpi r18, 0x10 ; 16 + a5c8: 81 f1 breq .+96 ; 0xa62a <__ultoa_invert+0x6c> + a5ca: e8 94 clt + a5cc: 6f 93 push r22 + a5ce: 6e 7f andi r22, 0xFE ; 254 + a5d0: 6e 5f subi r22, 0xFE ; 254 + a5d2: 7f 4f sbci r23, 0xFF ; 255 + a5d4: 8f 4f sbci r24, 0xFF ; 255 + a5d6: 9f 4f sbci r25, 0xFF ; 255 + a5d8: af 4f sbci r26, 0xFF ; 255 + a5da: b1 e0 ldi r27, 0x01 ; 1 + a5dc: 3e d0 rcall .+124 ; 0xa65a <__ultoa_invert+0x9c> + a5de: b4 e0 ldi r27, 0x04 ; 4 + a5e0: 3c d0 rcall .+120 ; 0xa65a <__ultoa_invert+0x9c> + a5e2: 67 0f add r22, r23 + a5e4: 78 1f adc r23, r24 + a5e6: 89 1f adc r24, r25 + a5e8: 9a 1f adc r25, r26 + a5ea: a1 1d adc r26, r1 + a5ec: 68 0f add r22, r24 + a5ee: 79 1f adc r23, r25 + a5f0: 8a 1f adc r24, r26 + a5f2: 91 1d adc r25, r1 + a5f4: a1 1d adc r26, r1 + a5f6: 6a 0f add r22, r26 + a5f8: 71 1d adc r23, r1 + a5fa: 81 1d adc r24, r1 + a5fc: 91 1d adc r25, r1 + a5fe: a1 1d adc r26, r1 + a600: 20 d0 rcall .+64 ; 0xa642 <__ultoa_invert+0x84> + a602: 09 f4 brne .+2 ; 0xa606 <__ultoa_invert+0x48> + a604: 68 94 set + a606: 3f 91 pop r19 + a608: 2a e0 ldi r18, 0x0A ; 10 + a60a: 26 9f mul r18, r22 + a60c: 11 24 eor r1, r1 + a60e: 30 19 sub r19, r0 + a610: 30 5d subi r19, 0xD0 ; 208 + a612: 31 93 st Z+, r19 + a614: de f6 brtc .-74 ; 0xa5cc <__ultoa_invert+0xe> + a616: cf 01 movw r24, r30 + a618: 08 95 ret + a61a: 46 2f mov r20, r22 + a61c: 47 70 andi r20, 0x07 ; 7 + a61e: 40 5d subi r20, 0xD0 ; 208 + a620: 41 93 st Z+, r20 + a622: b3 e0 ldi r27, 0x03 ; 3 + a624: 0f d0 rcall .+30 ; 0xa644 <__ultoa_invert+0x86> + a626: c9 f7 brne .-14 ; 0xa61a <__ultoa_invert+0x5c> + a628: f6 cf rjmp .-20 ; 0xa616 <__ultoa_invert+0x58> + a62a: 46 2f mov r20, r22 + a62c: 4f 70 andi r20, 0x0F ; 15 + a62e: 40 5d subi r20, 0xD0 ; 208 + a630: 4a 33 cpi r20, 0x3A ; 58 + a632: 18 f0 brcs .+6 ; 0xa63a <__ultoa_invert+0x7c> + a634: 49 5d subi r20, 0xD9 ; 217 + a636: 31 fd sbrc r19, 1 + a638: 40 52 subi r20, 0x20 ; 32 + a63a: 41 93 st Z+, r20 + a63c: 02 d0 rcall .+4 ; 0xa642 <__ultoa_invert+0x84> + a63e: a9 f7 brne .-22 ; 0xa62a <__ultoa_invert+0x6c> + a640: ea cf rjmp .-44 ; 0xa616 <__ultoa_invert+0x58> + a642: b4 e0 ldi r27, 0x04 ; 4 + a644: a6 95 lsr r26 + a646: 97 95 ror r25 + a648: 87 95 ror r24 + a64a: 77 95 ror r23 + a64c: 67 95 ror r22 + a64e: ba 95 dec r27 + a650: c9 f7 brne .-14 ; 0xa644 <__ultoa_invert+0x86> + a652: 00 97 sbiw r24, 0x00 ; 0 + a654: 61 05 cpc r22, r1 + a656: 71 05 cpc r23, r1 + a658: 08 95 ret + a65a: 9b 01 movw r18, r22 + a65c: ac 01 movw r20, r24 + a65e: 0a 2e mov r0, r26 + a660: 06 94 lsr r0 + a662: 57 95 ror r21 + a664: 47 95 ror r20 + a666: 37 95 ror r19 + a668: 27 95 ror r18 + a66a: ba 95 dec r27 + a66c: c9 f7 brne .-14 ; 0xa660 <__ultoa_invert+0xa2> + a66e: 62 0f add r22, r18 + a670: 73 1f adc r23, r19 + a672: 84 1f adc r24, r20 + a674: 95 1f adc r25, r21 + a676: a0 1d adc r26, r0 + a678: 08 95 ret + +0000a67a : + a67a: dc 01 movw r26, r24 + a67c: cb 01 movw r24, r22 + +0000a67e : + a67e: fc 01 movw r30, r24 + a680: e1 99 sbic 0x1c, 1 ; 28 + a682: fe cf rjmp .-4 ; 0xa680 + a684: 06 c0 rjmp .+12 ; 0xa692 + a686: ff bb out 0x1f, r31 ; 31 + a688: ee bb out 0x1e, r30 ; 30 + a68a: e0 9a sbi 0x1c, 0 ; 28 + a68c: 31 96 adiw r30, 0x01 ; 1 + a68e: 0d b2 in r0, 0x1d ; 29 + a690: 0d 92 st X+, r0 + a692: 41 50 subi r20, 0x01 ; 1 + a694: 50 40 sbci r21, 0x00 ; 0 + a696: b8 f7 brcc .-18 ; 0xa686 + a698: 08 95 ret + +0000a69a : + a69a: a6 e1 ldi r26, 0x16 ; 22 + a69c: b0 e0 ldi r27, 0x00 ; 0 + a69e: 44 e0 ldi r20, 0x04 ; 4 + a6a0: 50 e0 ldi r21, 0x00 ; 0 + a6a2: 0c 94 3f 53 jmp 0xa67e ; 0xa67e + +0000a6a6 : + a6a6: a8 e1 ldi r26, 0x18 ; 24 + a6a8: b0 e0 ldi r27, 0x00 ; 0 + a6aa: 42 e0 ldi r20, 0x02 ; 2 + a6ac: 50 e0 ldi r21, 0x00 ; 0 + a6ae: 0c 94 3f 53 jmp 0xa67e ; 0xa67e + +0000a6b2 : + a6b2: dc 01 movw r26, r24 + a6b4: a4 0f add r26, r20 + a6b6: b5 1f adc r27, r21 + a6b8: 41 50 subi r20, 0x01 ; 1 + a6ba: 50 40 sbci r21, 0x00 ; 0 + a6bc: 48 f0 brcs .+18 ; 0xa6d0 + a6be: cb 01 movw r24, r22 + a6c0: 84 0f add r24, r20 + a6c2: 95 1f adc r25, r21 + a6c4: 2e 91 ld r18, -X + a6c6: 0e 94 6a 53 call 0xa6d4 ; 0xa6d4 + a6ca: 41 50 subi r20, 0x01 ; 1 + a6cc: 50 40 sbci r21, 0x00 ; 0 + a6ce: d0 f7 brcc .-12 ; 0xa6c4 + a6d0: 08 95 ret + +0000a6d2 : + a6d2: 26 2f mov r18, r22 + +0000a6d4 : + a6d4: e1 99 sbic 0x1c, 1 ; 28 + a6d6: fe cf rjmp .-4 ; 0xa6d4 + a6d8: 9f bb out 0x1f, r25 ; 31 + a6da: 8e bb out 0x1e, r24 ; 30 + a6dc: e0 9a sbi 0x1c, 0 ; 28 + a6de: 01 97 sbiw r24, 0x01 ; 1 + a6e0: 0d b2 in r0, 0x1d ; 29 + a6e2: 02 16 cp r0, r18 + a6e4: 31 f0 breq .+12 ; 0xa6f2 + a6e6: 2d bb out 0x1d, r18 ; 29 + a6e8: 0f b6 in r0, 0x3f ; 63 + a6ea: f8 94 cli + a6ec: e2 9a sbi 0x1c, 2 ; 28 + a6ee: e1 9a sbi 0x1c, 1 ; 28 + a6f0: 0f be out 0x3f, r0 ; 63 + a6f2: 08 95 ret + +0000a6f4 : + a6f4: 03 96 adiw r24, 0x03 ; 3 + a6f6: 27 2f mov r18, r23 + a6f8: 0e 94 6a 53 call 0xa6d4 ; 0xa6d4 + a6fc: 0e 94 69 53 call 0xa6d2 ; 0xa6d2 + a700: 25 2f mov r18, r21 + a702: 0e 94 6a 53 call 0xa6d4 ; 0xa6d4 + a706: 24 2f mov r18, r20 + a708: 0c 94 6a 53 jmp 0xa6d4 ; 0xa6d4 + +0000a70c : + a70c: 01 96 adiw r24, 0x01 ; 1 + a70e: 27 2f mov r18, r23 + a710: 0e 94 6a 53 call 0xa6d4 ; 0xa6d4 + a714: 0c 94 69 53 jmp 0xa6d2 ; 0xa6d2 + +0000a718 <__mulsi3>: + a718: db 01 movw r26, r22 + a71a: 8f 93 push r24 + a71c: 9f 93 push r25 + a71e: 0e 94 be 53 call 0xa77c ; 0xa77c <__muluhisi3> + a722: bf 91 pop r27 + a724: af 91 pop r26 + a726: a2 9f mul r26, r18 + a728: 80 0d add r24, r0 + a72a: 91 1d adc r25, r1 + a72c: a3 9f mul r26, r19 + a72e: 90 0d add r25, r0 + a730: b2 9f mul r27, r18 + a732: 90 0d add r25, r0 + a734: 11 24 eor r1, r1 + a736: 08 95 ret + +0000a738 <__udivmodsi4>: + a738: a1 e2 ldi r26, 0x21 ; 33 + a73a: 1a 2e mov r1, r26 + a73c: aa 1b sub r26, r26 + a73e: bb 1b sub r27, r27 + a740: fd 01 movw r30, r26 + a742: 0d c0 rjmp .+26 ; 0xa75e <__udivmodsi4_ep> + +0000a744 <__udivmodsi4_loop>: + a744: aa 1f adc r26, r26 + a746: bb 1f adc r27, r27 + a748: ee 1f adc r30, r30 + a74a: ff 1f adc r31, r31 + a74c: a2 17 cp r26, r18 + a74e: b3 07 cpc r27, r19 + a750: e4 07 cpc r30, r20 + a752: f5 07 cpc r31, r21 + a754: 20 f0 brcs .+8 ; 0xa75e <__udivmodsi4_ep> + a756: a2 1b sub r26, r18 + a758: b3 0b sbc r27, r19 + a75a: e4 0b sbc r30, r20 + a75c: f5 0b sbc r31, r21 + +0000a75e <__udivmodsi4_ep>: + a75e: 66 1f adc r22, r22 + a760: 77 1f adc r23, r23 + a762: 88 1f adc r24, r24 + a764: 99 1f adc r25, r25 + a766: 1a 94 dec r1 + a768: 69 f7 brne .-38 ; 0xa744 <__udivmodsi4_loop> + a76a: 60 95 com r22 + a76c: 70 95 com r23 + a76e: 80 95 com r24 + a770: 90 95 com r25 + a772: 9b 01 movw r18, r22 + a774: ac 01 movw r20, r24 + a776: bd 01 movw r22, r26 + a778: cf 01 movw r24, r30 + a77a: 08 95 ret + +0000a77c <__muluhisi3>: + a77c: 0e 94 c9 53 call 0xa792 ; 0xa792 <__umulhisi3> + a780: a5 9f mul r26, r21 + a782: 90 0d add r25, r0 + a784: b4 9f mul r27, r20 + a786: 90 0d add r25, r0 + a788: a4 9f mul r26, r20 + a78a: 80 0d add r24, r0 + a78c: 91 1d adc r25, r1 + a78e: 11 24 eor r1, r1 + a790: 08 95 ret + +0000a792 <__umulhisi3>: + a792: a2 9f mul r26, r18 + a794: b0 01 movw r22, r0 + a796: b3 9f mul r27, r19 + a798: c0 01 movw r24, r0 + a79a: a3 9f mul r26, r19 + a79c: 70 0d add r23, r0 + a79e: 81 1d adc r24, r1 + a7a0: 11 24 eor r1, r1 + a7a2: 91 1d adc r25, r1 + a7a4: b2 9f mul r27, r18 + a7a6: 70 0d add r23, r0 + a7a8: 81 1d adc r24, r1 + a7aa: 11 24 eor r1, r1 + a7ac: 91 1d adc r25, r1 + a7ae: 08 95 ret + +0000a7b0 <_exit>: + a7b0: f8 94 cli + +0000a7b2 <__stop_program>: + a7b2: ff cf rjmp .-2 ; 0xa7b2 <__stop_program> diff --git a/Projects/DidacticSystem/Adam/MainController/firmware.sym b/Projects/DidacticSystem/Adam/MainController/firmware.sym new file mode 100644 index 0000000..f8864d4 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/firmware.sym @@ -0,0 +1,1047 @@ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 W __vector_default +00000000 T __vectors +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003b a __RAMPZ__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000008c T statusLockerSensAdditionalDescStr +0000008c T __trampolines_end +0000008c T __trampolines_start +000000ab T statusLockerCloseStr +000000b4 T statusLockerOpenStr +000000bd T statusLockerSensDescStr +000000c8 t __c.3634 +000000cb t __c.3632 +000000ce t __c.3630 +000000d1 t __c.3628 +000000d4 t __c.3625 +00000106 t __c.3674 +0000010a t __c.3672 +0000010e t __c.3670 +00000113 t __c.3668 +00000116 t __c.3666 +0000011a t __c.3664 +0000011e t __c.3662 +00000122 t __c.3660 +00000127 t __c.3658 +0000012a t __c.3656 +0000012e t __c.3768 +0000014e t __c.3718 +00000171 t __c.3649 +0000018a T cmdListConfigure +000001d8 T cmdListEnable +0000027a T cmdListNormal +000002b0 T errorStrings +000002c8 T BladBuforaPozostaloBajtowStr +000002f2 T nlStr +000002f5 T okStr +000002fa T cmd_help_zapiszMW +0000031d T cmd_zapiszMW +00000323 T cmd_help_ustawMW +00000340 T cmd_ustawMW +00000345 T cmd_help_ustawR +00000362 T cmd_ustawR +00000367 T cmd_help_conf_save +0000037a T cmd_conf_save +0000037f T cmd_help_conf_mac +000003ad T cmd_conf_mac +000003b1 T cmd_conf_ip_gw_help +000003d9 T cmd_conf_ip_gw +000003dc T cmd_conf_ip_mask_help +000003ec T cmd_conf_ip_mask +000003f1 T cmd_help_conf_udp +0000043f T cmd_conf_udp +00000443 T cmd_help_conf_ip +00000466 T cmd_conf_ip +00000469 T cmd_help_configure +00000478 T cmd_configure +0000047f T cmd_help_disable +00000489 T cmd_disable +00000491 T cmd_help_enable +0000049d T cmd_enable +000004a4 T cmd_help_ac +000004c4 T cmd_ac +000004c7 T cmd_help_settime +000004e9 T cmd_settime +000004f1 T cmd_help_spb +00000504 T cmd_spb +00000508 T cmd_help_spa +0000051b T cmd_spa +0000051f T cmd_help_down +00000547 T cmd_down +0000054c T cmd_help_up +00000572 T cmd_up +00000575 T cmd_help_read_rf +0000059f T cmd_read_rf +000005a6 T cmd_help_edit_rf +000005d0 T cmd_edit_rf +000005d7 T cmd_help_erase_rf +000005fc T cmd_erase_rf +00000604 T cmd_help_create_rf +00000620 T cmd_create_rf +00000624 T cmd_help_dir_rf +00000638 T cmd_dir_rf +0000063e T cmd_help_xflash +00000676 T cmd_xflash +0000067d T cmd_help_xSend +000006a0 T cmd_xSend +000006a6 T cmd_help_xRec +000006cc T cmd_xRec +000006d1 T cmd_help_ping +00000702 T cmd_ping +00000707 T cmd_help_rping +0000072d T cmd_rping +00000733 T cmd_help_net_dbg +0000077c T cmd_net_dbg +00000782 T cmd_help_time +0000078d T cmd_time +00000792 T cmd_help_enc_stat +000007ac T cmd_enc_stat +000007b4 T cmd_help_status +000007eb T cmd_status +000007f2 T cmd_help_help +00000804 T cmd_help +00000809 T debugDisabledInfoStr +0000081d T debugEnabledInfoStr +00000830 T movingCurtainPosStr +00000840 T movingCurtainDownStr +00000873 T movingCurtainUpStr +000008a6 T xwyslijStartStr +000008c3 T readRamFIleLenStr +000008d5 T editRamFileIntroStr +000008fd T statusLockerSensorsDisStr +00000919 T statusLockerSensorsStr +00000932 T statusNoRs485Dev +0000094c T statusRs485listStr +00000967 T statusIpGwStr +0000097c T statusIpMaskStr +00000991 T statusIpStr +000009a6 T statusMacStr +000009bb T systemRamConfigStr +000009ce T statusVoltageStr +000009e9 T statusTemperatureStr +00000a04 T statusRamDiskStateStr +00000a31 T statusDynamicHeapStateStr +00000a5b T statusStaticHeapStateStr +00000a85 T statusNumberOfTasksStr +00000a9e T systemStateStr +00000aae T errorOpenFile +00000ac3 T errorBootloaderNotResponding +00000ae2 T errorNoRemoteDevice +00000b05 T errorxModemUnknownResponse +00000b24 T errorxModemRemoteSideCan +00000b4b T errorxModemFrameCrc +00000b5e T errorxModemFrameFrameNoCorrectionNotMatch +00000b61 T errorxModemWrongFrameNo +00000b64 T errorxModemByteSendTimeout +00000b67 T errorxModemFrameStartTimeout +00000b6a T errorNoFile +00000b74 T errorOK +00000b7d t __c.3427 +00000b8e t __c.2010 +00000b98 t __c.3649 +00000b9b t __c.3647 +00000b9d t __c.3559 +00000bb5 t __c.3556 +00000bc8 t __c.3553 +00000bcb t __c.3551 +00000bcd t __c.3549 +00000be1 t __c.3545 +00000be6 T CmdlineCmdNotFound +00000beb T CmdlineNotice +00000bf5 T CmdlinePromptConfigure +00000bfc T CmdlinePromptEnable +00000c03 T CmdlinePromptNormal +00000c0a t __c.3558 +00000c19 t __c.3556 +00000c28 t __c.3554 +00000c37 t __c.3552 +00000c46 t __c.3550 +00000c55 t __c.3548 +00000c64 t __c.3546 +00000c7f t __c.2141 +00000c9e t __c.2004 +00000ca1 t __c.2002 +00000ca6 t __c.2000 +00000cab t __c.1998 +00000cb0 t __c.1996 +00000cb5 t __c.1994 +00000cba t __c.1992 +00000cbf t __c.1990 +00000cca t __c.1988 +00000cdb t __c.1986 +00000cea t __c.1984 +00000cf9 t __c.1982 +00000d08 t __c.1980 +00000d15 t __c.1974 +00000d18 t __c.1972 +00000d23 t __c.1970 +00000d26 t __c.1968 +00000d31 t __c.1966 +00000d40 t __c.1964 +00000d50 t __c.1962 +00000d60 t __c.1960 +00000d71 t __c.1958 +00000d80 t __c.1956 +00000d8f t __c.1954 +00000d9b t __c.1948 +00000da2 t __c.1946 +00000da8 t __c.1944 +00000dbe t __c.1938 +00000dca t __c.1932 +00000de8 t __c.2542 +00000deb t __c.2540 +00000df6 t __c.2538 +00000df9 t __c.2536 +00000e04 t __c.2534 +00000e07 t __c.2532 +00000e12 t __c.2526 +00000e51 t __c.2524 +00000e7f t __c.2522 +00000e9e t __c.2520 +00000ebf t __c.2492 +00000edb t __c.2490 +00000ef3 t __c.2488 +00000f0c t __c.2514 +00000f1c t __c.2512 +00000f2b t __c.2510 +00000f2e t __c.2508 +00000f3a t __c.2506 +00000f3d t __c.2504 +00000f49 t __c.2502 +00000f58 t __c.2491 +00000f6c t __c.2488 +00000f84 t __c.2483 +00000fad t __c.2574 +00000fb0 t __c.2572 +00000fb3 t __c.2570 +00000fb9 t __c.2567 +00000fbc t __c.2565 +00000fbf t __c.2563 +00000fc5 t __c.2561 +00000feb t __c.2559 +00001010 t __c.2553 +00001013 t __c.2551 +00001022 t __c.2549 +00001025 t __c.2547 +00001034 t __c.2545 +00001037 t __c.2543 +00001046 t __c.2541 +00001049 t __c.2539 +00001058 t __c.2537 +0000105b t __c.2535 +00001063 t __c.2533 +00001069 t __c.2531 +00001071 t __c.2529 +00001080 t __c.2527 +0000108e t __c.2499 +00001091 t __c.2497 +00001097 t __c.2495 +000010a7 t __c.2490 +000010bb t __c.2488 +000010d2 t __c.2723 +000010e9 t __c.2692 +000010ff W __stack +00001113 t __c.2687 +00001139 t __c.2682 +00001155 t __c.2707 +00001189 t __c.2705 +000011d1 t __c.2703 +00001205 t __c.2701 +00001247 t __c.2535 +0000124c t __c.2533 +00001252 t __c.2531 +00001279 t __c.2529 +0000128c t __c.2527 +00001298 t __c.2511 +000012b7 t __c.2509 +000012ba t __c.2504 +000012cf t __c.2502 +000012d6 t __c.2500 +000012e9 t __c.2497 +00001307 t __c.2495 +00001329 t __c.2488 +0000133b t __c.2486 +00001361 t __c.3530 +0000138b t __c.3528 +000013b8 t __c.3526 +000013c9 T statusRollerDescStr2 +000013d9 T statusRollerDescStrConf +000013e4 T statusRollerDescStr +00001422 T __ctors_end +00001422 T __ctors_start +00001422 T __dtors_end +00001422 T __dtors_start +00001422 W __init +0000142e T initExternalMem +0000167a T __do_copy_data +00001694 T __do_clear_bss +0000169c t .do_clear_bss_loop +0000169e t .do_clear_bss_start +000016ac T __bad_interrupt +000016ac W __vector_1 +000016ac W __vector_10 +000016ac W __vector_11 +000016ac W __vector_13 +000016ac W __vector_14 +000016ac W __vector_15 +000016ac W __vector_16 +000016ac W __vector_2 +000016ac W __vector_21 +000016ac W __vector_22 +000016ac W __vector_23 +000016ac W __vector_24 +000016ac W __vector_25 +000016ac W __vector_26 +000016ac W __vector_27 +000016ac W __vector_28 +000016ac W __vector_29 +000016ac W __vector_3 +000016ac W __vector_32 +000016ac W __vector_33 +000016ac W __vector_34 +000016ac W __vector_4 +000016ac W __vector_5 +000016ac W __vector_6 +000016ac W __vector_7 +000016ac W __vector_8 +000016ac W __vector_9 +000016b0 T vApplicationIdleHook +000016b6 T vApplicationTickHook +000016ce T loadConfiguration +000016e2 T saveConfiguration +000016ea T VtyGetChar +00001722 T initQueueStreamUSB +0000173e T xSerialPortInitMinimal +000017d0 T __vector_18 +00001856 W uartRs485SendByte +00001884 W rs485Receive +00001898 T __vector_19 +0000191e T __vector_20 +00001944 W flushRs485RecBuffer +0000197e W takeRs485 +00001994 W releaseRs485 +000019aa T InterruptVtyOn +000019b6 T __vector_30 +00001a3e T uartVtySendByte +00001a74 T VtyPutChar +00001a7e T __vector_31 +00001b04 T hardwareInit +00001b3c T LockersMemInit +00001b4e T printLockers +00001c46 T checkLockerSensors +00001dc4 W spiSend +00001df2 T spiSendENC +00001e20 W spiSendSpinBlock +00001e30 T spiSendENCSpinBlock +00001e40 T disableAllSpiDevices +00001e56 W spiEnableEnc28j60 +00001e5a W spiDisableEnc28j60 +00001e5e T enableSpiSd +00001e6a T disableSpiSd +00001e76 W enableSpiMPC23S17 +00001e7a W disableSpiMPC23S17 +00001e7e W enableSpiMCP3008 +00001e88 W disableSpiMCP3008 +00001e92 T enableSpiMCP4150 +00001e9c T disableSpiMCP4150 +00001ea6 W spiEnableDS1305 +00001eb0 W spiDisableDS1305 +00001eba T __vector_17 +00001f2c T sensorsTaskInit +00001f34 T sensorsTask +00001fa6 t enableFunction +00001fc6 t disableFunction +00001fde t configureModeFunction +00001ffe t pingFunction +00002012 t readRamFIleFunction +0000210a t writeRamFileFunction +0000211a t pokazCzasFunction +000021b6 t helpFunction +000021c0 t czytajAC_Function +0000221a t setTimeFunction +000022ee t ustawPortExtBFunction +00002312 t ustawPortExtAFunction +00002336 t curtainDownFunction +000023e8 t statusEncFunction +000023f8 t saveConfigFunction +00002402 t goXmodemWyslijFunction +00002474 t zapiszModWykFunction +00002496 t ustawModWykFunction +000024d0 t ustawPortRezystor +000024f2 t curtainUpFunction +000025be t editRamFileFunction +00002688 t goXmodemOdbierzFunction +000029ee t debugFunction +00002b94 t setMacAddrFunction +00002c02 t setUdpFunction +00002ce8 t setIpGwFunction +00002d86 t setIpMaskFunction +00002dc6 t setIpFunction +00002e64 T VtyInit +00002e86 T printErrorInfo +00002edc t rpingFunction +00002f3a t eraseRamFileFunction +00002f66 t dodajRamPlikFunction +00002fa0 t flashExModuleFunction +00003050 T printStatus +00003280 t statusFunction +00003326 T encTask +000033b4 T vTaskVTYusb +00003412 T vTaskVTYsocket +0000342a T spiInit +00003460 T spiSetCPHA +00003464 T spiClearCPHA +00003468 T spiSetCPOL +0000346c T spiClearCPOL +00003470 T spiTake +00003486 T spiGive +000034a4 T xmalloc +000034c0 T xmallocAvailable +000034d8 t uaktualnijRozmiarPliku +0000351c t nastepnyKlaster +00003568 t znajdzKlasterN +00003594 t znajdzPlik +0000364e t znajdzWolnyKlaster +0000368c T ramDyskInit +000036b0 T ramDyskUtworzPlik +0000377a T ramDyskOtworzPlik +000037a6 T ramDyskUsunPlik +000037e8 T ramDyskZamknijPlik +0000380a T ramDyskCzyscPlik +0000385c T ramDyskZapiszBajtDoPliku +000038d8 t putSTD +000038e8 T ramDyskCzytajBajtZPliku +0000395a t getSTD +0000398a T ramDyskZapiszBlokDoPliku +00003a9e T ramDyskCzytajBlokZPliku +00003be8 T ramDyskUstawWskaznik +00003c74 T ramDyskUstawWskaznikNaKoniec +00003cc6 T ramDyskDodajBlokXmodem +00003d7c T ramDyskDir +00003e90 T ramDyskLiczbaWolnychKlastrow +00003eaa T ramDyskOtworzPlikStdIo +00003ef4 T ramDyskZamknijPlikStdIo +00003f20 t cmdlinePrintPrompt +00003f6e t cmdlineRepaint +00003ff6 t cmdHistoryCopy +0000403e T cmdStateConfigure +000040b8 T cmdlineInputFunc +00004696 T cmdLineGetLastArgIdx +000046c0 T cmdlineMainLoop +000047c2 T cmdlineGetArgStr +0000480e T cmdlineGetArgInt +00004834 T cmdlineGetArgHex +0000485a T cmdPrintHelp +00004936 T vt100Init +00004956 T vt100ClearScreen +00004976 T vt100SetAttr +0000499e T vt100SetCursorMode +000049c8 T vt100SetCursorPos +000049fc T readTimeBCD +00004a34 T readTimeDecoded +00004a38 T readTime +00004a3c T setTimeBCD +00004a76 T setTimeDecoded +00004a7a T setTime +00004a7e T ds1305start +00004a9a T ds1305writeMem +00004b04 T ds1305readMem +00004b74 T MPC23s17SetDirA +00004ba8 T MPC23s17SetDirB +00004bdc T MPC23s17SetPortA +00004c24 T MPC23s17SetBitsOnPortA +00004c5e T MPC23s17ClearBitsOnPortA +00004c9a T MPC23s17SetPortB +00004cce T MPC23s17SetBitsOnPortB +00004d08 T MPC23s17ClearBitsOnPortB +00004d44 T MPC23s17ReadPortA +00004d88 T MPC23s17ReadPortB +00004dd0 T MCP3008_getSampleDiff +00004e10 T MCP3008_getSampleSingle +00004e56 T MCP4150_setValue +00004e7c t enc28j60WriteOp +00004eb4 t enc28j60SetBank +00004ef8 t enc28j60Write +00004f1e t enc28j60ReadOp +00004f60 t enc28j60Read +00004f80 t enc28j60PhyWrite +00004fc8 T enc28j60getrev +00004fce T enc28j60hasRxPkt +00004fe0 T enc28j60linkup +0000501c W nicSend +000050ca W nicPoll +000051f2 W nicSetMacAddress +0000522c W nicMacInit +00005350 W nicGetMacAddress +0000538c W nicRegDump +00005460 t streamQueueInputFun +00005498 t streamQueueOutputFun +000054ce T initQueueStream +000054fe T nicLoadConfig +0000550e T nicSaveConfig +0000551e T nicInit +0000558e T ntohs +00005596 T htons +0000559e T htonl +000055a4 T ntohl +000055aa T netChecksum +0000560a T netPrintEthAddr +00005652 T netPrintIPAddr +000056a6 T netPrintEthHeader +0000571e T netPrintIpHeader +0000586a T netPrintTcpHeader +00005a1c T ipInit +00005a1e T ipLoadConfig +00005a62 T ipSaveConfig +00005a9e T netstackIPv4Process +00005bba T setIpDebug +00005bd4 T ipSetConfig +00005c02 T ipSetConfigIp +00005c14 T ipSetConfigMask +00005c26 T ipSetConfigGw +00005c38 T ipGetConfig +00005c3e T ipSend +00005dec T ipPrintConfig +00005ea2 T icmpInit +00005eb0 T setIcmpDebug +00005ebe T icmpPrintHeader +00005f8e T icmpEchoRequest +00006096 T icmpIpIn +000060d6 T setArpDebug +000060f0 T arpInit +00006108 T arpTimer +00006122 T arpMatchIp +0000615c T arpIpIn +000062a4 T arpIpOut +0000633c T arpPrintHeader +000064ba T arpArpIn +0000662e T arpPrintTable +0000676a T socketInit +00006802 T calculateTcpChecksun +00006824 T processTcpPacket +00006c36 T sendTcpBuffer +00006c3a T netstackTCPIPProcess +00006c8c T setTcpDebug +00006c9a T flushTcpQueues +00006c9c T httpProcess +00006c9e T udpLoadConfig +00006cd8 T udpInit_0 +00006d28 T setUdpDebug +00006d36 T udpSend +00006e26 T netstackUDPIPProcess +0000703a T flushUdpQueues +000070a0 T udpSaveConfig +000070e0 T udpPrintStatus +000071a6 t _crc_xmodem_update +000071e8 T rollersMemInit +00007204 T printRs485devices +000072b2 T rs485ping +00007482 T rs485rollerHello +000076da T rs485xModemFlash +00007b14 T rs485curtainUp +00007bb6 T rs485Led +00007c3c T sendSettings +00007cc2 T saveSettings +00007d32 T rs485curtainDown +00007dd4 t prvIdleTask +00007dda t prvListTaskWithinSingleList +00007f28 T xTaskGenericCreate +0000810c T uxTaskPriorityGet +00008128 T vTaskPrioritySet +000081e4 T vTaskSuspend +0000825e T xTaskIsTaskSuspended +00008282 T vTaskResume +000082fa T xTaskResumeFromISR +00008378 T vTaskStartScheduler +000083dc T vTaskEndScheduler +000083e6 T vTaskSuspendAll +000083f2 T xTaskGetTickCount +00008406 T uxTaskGetNumberOfTasks +0000840c T vTaskStartTrace +0000843e T ulTaskEndTrace +0000846a T vTaskIncrementTick +0000856a T xTaskResumeAll +0000864c T vTaskDelayUntil +00008702 T vTaskDelay +0000877a T vTaskList +00008818 T vTaskSwitchContext +0000894e T vTaskPlaceOnEventList +000089ea T xTaskRemoveFromEventList +00008a70 T vTaskSetTimeOutState +00008a86 T xTaskCheckForTimeOut +00008af2 T vTaskMissedYield +00008afa t prvCopyDataToQueue +00008b7a t prvCopyDataFromQueue +00008bae t prvUnlockQueue +00008c2a T xQueueCreate +00008cc0 T xQueueCreateExternal +00008d44 T xQueueGenericSend +00008e6c T xQueueGenericSendFromISR +00008ebc T xQueueGenericReceive +00009004 T xQueueReceiveFromISR +00009056 T uxQueueMessagesWaiting +00009066 T uxQueueMessagesWaitingFromISR +0000906c T vQueueDelete +00009084 T xQueueIsQueueEmptyFromISR +00009090 T xQueueIsQueueFullFromISR +0000909e T vListInitialise +000090ba T vListInitialiseItem +000090c2 T vListInsertEnd +00009108 T vListInsert +00009176 T vListRemove +000091be T xCoRoutineCreate +0000928c T vCoRoutineAddToDelayedList +00009310 T vCoRoutineSchedule +000094fc T xCoRoutineRemoveFromEventList +00009552 T pvPortMalloc +0000959e T vPortFree +000095a0 T vPortInitialiseBlocks +000095aa T xPortGetFreeHeapSize +000095bc T pxPortInitialiseStack +00009694 T xPortStartScheduler +00009700 T vPortEndScheduler +00009702 T vPortYield +000097b4 T vPortYieldFromTick +0000986a T __vector_12 +000098ba T main +000099ae T __udivmodqi4 +000099b4 t __udivmodqi4_loop +000099bc t __udivmodqi4_ep +000099c6 T __udivmodhi4 +000099ce t __udivmodhi4_loop +000099dc t __udivmodhi4_ep +000099ee T __bswapsi2 +000099fc T malloc +00009b26 T free +00009c56 T strtol +00009eac T isspace +00009ebe T memcpy_P +00009ed0 T strncmp_P +00009eec T memcpy +00009efe T memset +00009f0c T strcat +00009f22 T strcpy +00009f30 T strncmp +00009f4c T strncpy +00009f6a T fclose +00009f98 T fgetc +0000a014 T fprintf +0000a034 T fprintf_P +0000a06e T fputc +0000a0de T fputs +0000a136 T sprintf +0000a196 T vfprintf +0000a58c T __ctype_isfalse +0000a590 T __ctype_istrue +0000a592 T strnlen_P +0000a5a8 T strnlen +0000a5be T __ultoa_invert +0000a67a T eeprom_read_block +0000a67e T eeprom_read_blraw +0000a69a T eeprom_read_dword +0000a69a T eeprom_read_float +0000a6a6 T eeprom_read_word +0000a6b2 T eeprom_update_block +0000a6d2 T eeprom_update_byte +0000a6d4 T eeprom_update_r18 +0000a6f4 T eeprom_update_dword +0000a6f4 T eeprom_update_float +0000a70c T eeprom_update_word +0000a718 T __mulsi3 +0000a738 T __udivmodsi4 +0000a744 t __udivmodsi4_loop +0000a75e t __udivmodsi4_ep +0000a77c T __muluhisi3 +0000a792 T __umulhisi3 +0000a7b0 W exit +0000a7b0 T _exit +0000a7b2 t __stop_program +0000a7b4 A __data_load_start +0000a7b4 T _etext +0000a83c A __data_load_end +00800100 D __data_start +00800100 d tickCntr.3566 +00800101 d xHigherPriorityTaskWoken.3440 +00800102 D heapEnd +00800104 d uxPreviousTask +00800105 D __malloc_heap_end +00800107 D __malloc_heap_start +00800109 D __malloc_margin +00800188 B __bss_start +00800188 D __data_end +00800188 D _edata +00800188 B timer100Hz +00800189 b xHigherPriorityTaskWoken.3497 +0080018a b data.3498 +0080018b b xHigherPriorityTaskWoken.3486 +0080018c b xHigherPriorityTaskWoken.3455 +0080018d b data.3456 +0080018e b xHigherPriorityTaskWoken.3497 +0080018f b data.3498 +00800190 b gNextPacketPtr +00800192 b Enc28j60Bank +00800193 B pxCurrentTCB +00800195 b pcStatusString +008001c7 b xTracing +008001c8 b pcTraceBufferEnd +008001ca b pcTraceBufferStart +008001cc b pcTraceBuffer +008001ce b uxTaskNumber +008001cf b xNumOfOverflows +008001d0 b xMissedYield +008001d1 b uxMissedTicks +008001d2 b uxSchedulerSuspended +008001d3 b xSchedulerRunning +008001d4 b uxTopReadyPriority +008001d5 b uxTopUsedPriority +008001d6 b xTickCount +008001d8 b uxCurrentNumberOfTasks +008001d9 b xSuspendedTaskList +008001e2 b xPendingReadyList +008001eb b pxOverflowDelayedTaskList +008001ed b pxDelayedTaskList +008001ef b xDelayedTaskList2 +008001f8 b xDelayedTaskList1 +00800201 b pxReadyTasksLists +0080021c B pxCurrentCoRoutine +0080021e b xPassedTicks +00800220 b xLastTickCount +00800222 b xCoRoutineTickCount +00800224 b uxTopCoRoutineReadyPriority +00800225 b xPendingReadyCoRoutineList +0080022e b pxOverflowDelayedCoRoutineList +00800230 b pxDelayedCoRoutineList +00800232 b xDelayedCoRoutineList2 +0080023b b xDelayedCoRoutineList1 +00800244 b pxReadyCoRoutineLists +0080024d b xNextFreeByte +0080024f b xHeap +00800e6b B usbStream +00800e79 B portB +00800e7a B wwwport +00800e7b B xVtyTx +00800e7d B udpDbgLevel +00800e7e B nicState +00800e8c B arpDebug +00800e8e B udpStream +00800e9c B xRs485Rec +00800e9e B CLIStateSerialUsb +00800ea0 B lockSensors +00800ea2 B udpSocket +00800ea4 B temperature +00800ea5 B tcpDebugLevel +00800ea6 B xHandleSensors +00800ea8 B rollers +00800eaa B icmpDebug +00800eac B xVtyRec +00800eae B voltage +00800eaf B xSemaphoreRs485 +00800eb1 B xHandleVTY_UDP +00800eb3 B czasRtc +00800eba B xHandleVTY_USB +00800ebc B sockets +00800ebe B xSemaphoreSpiSS +00800ec0 B udpDbgStream +00800ec2 B portA +00800ec3 B xRs485Tx +00800ec5 B udpBuffers +00800ec9 B klastry +00800f49 B xHandleEnc +00800f4b B icmpDebugLevel +00800f4c B tcpDebugStream +00800f4e B IpMyConfig +00800f5d B arpDebugLevel +00800f5e B CLIStateSerialUdp +00800f60 B xSpiRx +00800f62 B fdVty +00800f68 B ArpTable +00800fd6 B __brkval +00800fd8 B __flp +00800fda B __iob +00800fe0 B errno +00800fe2 B __bss_end +00800fe2 B _end +00801100 A __heap_start +008027ff A __heap_end +00810000 D udpPortSrcEep +00810002 D udpPortDstEep +00810004 D udpIpDst_eep +00810008 d lockerSensorsEEP +00810020 d mymac_eep +00810026 d defGw_eep +0081002a d mask_eep +0081002e d myip_eep +00810032 D __eeprom_end diff --git a/Projects/DidacticSystem/Adam/MainController/flash.sh b/Projects/DidacticSystem/Adam/MainController/flash.sh new file mode 100755 index 0000000..4282698 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/flash.sh @@ -0,0 +1,20 @@ +#!/usr/bin/expect -f + +system "hex2bin firmware.hex" +system "echo To_jest_wypelnienie_poniewaz_bootloader_ma_jeszcze_buga_i_nie_wgrywa_ostatniego_bloku_256_bajtow._Zatem_tutaj_jest_jakis_zbedny_tekst_ktory_bedzie_widzany_w_obrazie_firmware_procka._Chyba_juz_starcz_tego_tekstu >> firmware.bin" + + +set dev "/dev/atmega128eval" +set file "./firmware.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" + +send "flash" +expect "C" +send_user "\nStarting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" diff --git a/Projects/DidacticSystem/Adam/MainController/hardware.c b/Projects/DidacticSystem/Adam/MainController/hardware.c new file mode 100644 index 0000000..ef33082 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/hardware.c @@ -0,0 +1,383 @@ +#include "hardware.h" + +#if LANG_EN +#include "hardware_en.h" +#endif + +#if LANG_PL +#include "hardware_pl.h" +#endif + +xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję do czasu zakończenia wysyłania poprzedniego bajtu + +void hardwareInit(void) +{ + //DDRA = 0x00; //External Memory + portENTER_CRITICAL(); + xSpiRx = xQueueCreate(1, 1); + portEXIT_CRITICAL(); + + DDRB = 0xF7; + PORTB = 0xD1; + /* + 0 - Sl_RST + 1 - SCK + 2 - MOSI + 3 - MISO + 4 - External SPI ASR 4 + 5 - External SPI ASR 5 (DS1305) 0 - off; 1 - on + 6 - External SPI ASR 6 (MCP3008) 0 - on; 1 - off + 7 - External SPI ASR 7 (MPC23S17) 0 - on; 1 - off + */ + + //DDRC = 0x00; //External Memory + + DDRD = 0x00; + /* + 0 - SCL + 1 - SDA + 2 - RxD USB + 3 - TxD USB + 4 - External SPI ASR 0 + 5 - External SPI ASR 1 + 6 - External SPI ASR 2 + 7 - External SPI ASR 3 + */ + + DDRE = 0x0E; + PORTE = 0x0C; + /* + 0 - RxD Rs485 + 1 - TxD Rs485 + 2 - ENC RST + 3 - ENC CS + 4 - INT 4 + 5 - INT 5 + 6 - INT 6 + 7 - INT Enc28j60 + */ + DDRF = 0x00; //JTAG and A/C + DDRG = 0x1F; + /* + 0 - WR + 1 - RD + 2 - ALE + 3 - SD CS + 4 - RS485 TxEn + 5 - + 6 - + 7 - + */ +} + +void LockersMemInit(void) +{ + lockSensors = xmalloc(4 * sizeof(struct lockerSensor)); +} + +uint8_t printLockers(FILE *stream) +{ + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + { + if (tmpLock->enabled) + { + fprintf_P(stream, statusLockerSensDescStr, i); + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + else + fprintf_P(stream, statusLockerCloseStr); + fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + result++; + } + tmpLock++; + } + return result; +} + +void checkLockerSensors(void) +{ + if (lockSensors[0].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + vTaskDelay(30); + lockSensors[0].acVal = MCP3008_getSampleSingle(LOCK_SENS_1_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + lockSensors[0].locked = (lockSensors[0].acVal > lockSensors[0].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[1].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + vTaskDelay(30); + lockSensors[1].acVal = MCP3008_getSampleSingle(LOCK_SENS_2_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + lockSensors[1].locked = (lockSensors[1].acVal > lockSensors[1].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[2].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + vTaskDelay(30); + lockSensors[2].acVal = MCP3008_getSampleSingle(LOCK_SENS_3_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + lockSensors[2].locked = (lockSensors[2].acVal > lockSensors[2].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[3].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + vTaskDelay(30); + lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + vTaskDelay(10); + } +} + + +uint8_t spiSend(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendENC(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendSpinBlock(uint8_t data) +{ + SPDR = data; + SPCR &= ~(1< +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "mpc23s17.h" +#include "mcp3008.h" +#include "spi.h" + +#define Rs485TxStart() (PORTG |= 0x10) +#define Rs485TxStop() (PORTG &= 0xEF) + +#define ENC_RST_ON PORTE &= ~0x04; +#define ENC_RST_OFF PORTE |= 0x04; + +struct lockerSensor +{ + uint8_t enabled; + uint16_t threshold; + uint16_t acVal; + uint8_t locked; +}; + + +struct lockerSensor *lockSensors; + + +/** + * Hardware initialize + */ +void hardwareInit(void); + +/** + * Initialization of memory for lockers state structs + */ +void LockersMemInit(void); + +// ************************ Printing hardware info ********************* +/** + * Prints lockers + * @param stream - output stream + * @return number of printed lockers + */ +uint8_t printLockers(FILE *stream); + +// ************************ I/O module ********************************* +/** + * Checks locker sensors + */ +void checkLockerSensors(void); + + +// ************************ Obsługa Rs485 ****************************** +void takeRs485(void); +void releaseRs485(void); +void rs485Send(uint8_t c); +uint8_t rs485Receive(uint8_t *c, uint8_t timeout); + +// ************************ Obsługa SPI ******************************** +uint8_t spiSend(uint8_t data); +uint8_t spiSendENC(uint8_t data); +uint8_t spiSendSpinBlock(uint8_t data); +uint8_t spiSendENCSpinBlock(uint8_t data); + +void disableAllSpiDevices(void); + +void spiEnableEnc28j60(void); +void spiDisableEnc28j60(void); + +void enableSpiSd(void); +void disableSpiSd(void); + +void enableSpiMPC23S17(void); +void disableSpiMPC23S17(void); + +void enableSpiMCP3008(void); +void disableSpiMCP3008(void); + +void spiEnableDS1305(void); +void spiDisableDS1305(void); + +void enableSpiMCP4150(void); +void disableSpiMCP4150(void); + +#endif + diff --git a/Projects/DidacticSystem/Adam/MainController/hardware.lst b/Projects/DidacticSystem/Adam/MainController/hardware.lst new file mode 100644 index 0000000..3d3e04f --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/hardware.lst @@ -0,0 +1,1371 @@ + 1 .file "hardware.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 273 .global hardwareInit + 275 hardwareInit: + 276 .stabd 46,0,0 + 1:hardware.c **** #include "hardware.h" + 2:hardware.c **** + 3:hardware.c **** #if LANG_EN + 4:hardware.c **** #include "hardware_en.h" + 5:hardware.c **** #endif + 6:hardware.c **** + 7:hardware.c **** #if LANG_PL + 8:hardware.c **** #include "hardware_pl.h" + 9:hardware.c **** #endif + 10:hardware.c **** + 11:hardware.c **** xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję d + 12:hardware.c **** + 13:hardware.c **** void hardwareInit(void) + 14:hardware.c **** { + 278 .LM0: + 279 .LFBB1: + 280 /* prologue: function */ + 281 /* frame size = 0 */ + 282 /* stack size = 0 */ + 283 .L__stack_usage = 0 + 15:hardware.c **** //DDRA = 0x00; //External Memory + 16:hardware.c **** portENTER_CRITICAL(); + 285 .LM1: + 286 /* #APP */ + 287 ; 16 "hardware.c" 1 + 288 0000 0FB6 in __tmp_reg__, __SREG__ + 289 ; 0 "" 2 + 290 ; 16 "hardware.c" 1 + 291 0002 F894 cli + 292 ; 0 "" 2 + 293 ; 16 "hardware.c" 1 + 294 0004 0F92 push __tmp_reg__ + 295 ; 0 "" 2 + 17:hardware.c **** xSpiRx = xQueueCreate(1, 1); + 297 .LM2: + 298 /* #NOAPP */ + 299 0006 61E0 ldi r22,lo8(1) + 300 0008 81E0 ldi r24,lo8(1) + 301 000a 0E94 0000 call xQueueCreate + 302 000e 9093 0000 sts xSpiRx+1,r25 + 303 0012 8093 0000 sts xSpiRx,r24 + 18:hardware.c **** portEXIT_CRITICAL(); + 305 .LM3: + 306 /* #APP */ + 307 ; 18 "hardware.c" 1 + 308 0016 0F90 pop __tmp_reg__ + 309 ; 0 "" 2 + 310 ; 18 "hardware.c" 1 + 311 0018 0FBE out __SREG__, __tmp_reg__ + 312 ; 0 "" 2 + 19:hardware.c **** + 20:hardware.c **** DDRB = 0xF7; + 314 .LM4: + 315 /* #NOAPP */ + 316 001a 87EF ldi r24,lo8(-9) + 317 001c 87BB out 0x17,r24 + 21:hardware.c **** PORTB = 0xD1; + 319 .LM5: + 320 001e 81ED ldi r24,lo8(-47) + 321 0020 88BB out 0x18,r24 + 22:hardware.c **** /* + 23:hardware.c **** 0 - Sl_RST + 24:hardware.c **** 1 - SCK + 25:hardware.c **** 2 - MOSI + 26:hardware.c **** 3 - MISO + 27:hardware.c **** 4 - External SPI ASR 4 + 28:hardware.c **** 5 - External SPI ASR 5 (DS1305) 0 - off; 1 - on + 29:hardware.c **** 6 - External SPI ASR 6 (MCP3008) 0 - on; 1 - off + 30:hardware.c **** 7 - External SPI ASR 7 (MPC23S17) 0 - on; 1 - off + 31:hardware.c **** */ + 32:hardware.c **** + 33:hardware.c **** //DDRC = 0x00; //External Memory + 34:hardware.c **** + 35:hardware.c **** DDRD = 0x00; + 323 .LM6: + 324 0022 11BA out 0x11,__zero_reg__ + 36:hardware.c **** /* + 37:hardware.c **** 0 - SCL + 38:hardware.c **** 1 - SDA + 39:hardware.c **** 2 - RxD USB + 40:hardware.c **** 3 - TxD USB + 41:hardware.c **** 4 - External SPI ASR 0 + 42:hardware.c **** 5 - External SPI ASR 1 + 43:hardware.c **** 6 - External SPI ASR 2 + 44:hardware.c **** 7 - External SPI ASR 3 + 45:hardware.c **** */ + 46:hardware.c **** + 47:hardware.c **** DDRE = 0x0E; + 326 .LM7: + 327 0024 8EE0 ldi r24,lo8(14) + 328 0026 82B9 out 0x2,r24 + 48:hardware.c **** PORTE = 0x0C; + 330 .LM8: + 331 0028 8CE0 ldi r24,lo8(12) + 332 002a 83B9 out 0x3,r24 + 49:hardware.c **** /* + 50:hardware.c **** 0 - RxD Rs485 + 51:hardware.c **** 1 - TxD Rs485 + 52:hardware.c **** 2 - ENC RST + 53:hardware.c **** 3 - ENC CS + 54:hardware.c **** 4 - INT 4 + 55:hardware.c **** 5 - INT 5 + 56:hardware.c **** 6 - INT 6 + 57:hardware.c **** 7 - INT Enc28j60 + 58:hardware.c **** */ + 59:hardware.c **** DDRF = 0x00; //JTAG and A/C + 334 .LM9: + 335 002c 1092 6100 sts 97,__zero_reg__ + 60:hardware.c **** DDRG = 0x1F; + 337 .LM10: + 338 0030 8FE1 ldi r24,lo8(31) + 339 0032 8093 6400 sts 100,r24 + 340 0036 0895 ret + 342 .Lscope1: + 344 .stabd 78,0,0 + 346 .global LockersMemInit + 348 LockersMemInit: + 349 .stabd 46,0,0 + 61:hardware.c **** /* + 62:hardware.c **** 0 - WR + 63:hardware.c **** 1 - RD + 64:hardware.c **** 2 - ALE + 65:hardware.c **** 3 - SD CS + 66:hardware.c **** 4 - RS485 TxEn + 67:hardware.c **** 5 - + 68:hardware.c **** 6 - + 69:hardware.c **** 7 - + 70:hardware.c **** */ + 71:hardware.c **** } + 72:hardware.c **** + 73:hardware.c **** void LockersMemInit(void) + 74:hardware.c **** { + 351 .LM11: + 352 .LFBB2: + 353 /* prologue: function */ + 354 /* frame size = 0 */ + 355 /* stack size = 0 */ + 356 .L__stack_usage = 0 + 75:hardware.c **** lockSensors = xmalloc(4 * sizeof(struct lockerSensor)); + 358 .LM12: + 359 0038 88E1 ldi r24,lo8(24) + 360 003a 90E0 ldi r25,0 + 361 003c 0E94 0000 call xmalloc + 362 0040 9093 0000 sts lockSensors+1,r25 + 363 0044 8093 0000 sts lockSensors,r24 + 364 0048 0895 ret + 366 .Lscope2: + 368 .stabd 78,0,0 + 370 .global printLockers + 372 printLockers: + 373 .stabd 46,0,0 + 76:hardware.c **** } + 77:hardware.c **** + 78:hardware.c **** uint8_t printLockers(FILE *stream) + 79:hardware.c **** { + 375 .LM13: + 376 .LFBB3: + 377 004a 5F92 push r5 + 378 004c 6F92 push r6 + 379 004e 7F92 push r7 + 380 0050 8F92 push r8 + 381 0052 9F92 push r9 + 382 0054 AF92 push r10 + 383 0056 BF92 push r11 + 384 0058 CF92 push r12 + 385 005a DF92 push r13 + 386 005c EF92 push r14 + 387 005e FF92 push r15 + 388 0060 0F93 push r16 + 389 0062 1F93 push r17 + 390 0064 CF93 push r28 + 391 0066 DF93 push r29 + 392 /* prologue: function */ + 393 /* frame size = 0 */ + 394 /* stack size = 15 */ + 395 .L__stack_usage = 15 + 396 0068 782E mov r7,r24 + 397 006a 692E mov r6,r25 + 80:hardware.c **** uint8_t i; + 81:hardware.c **** uint8_t result = 0; + 82:hardware.c **** struct lockerSensor *tmpLock = lockSensors; + 399 .LM14: + 400 006c C091 0000 lds r28,lockSensors + 401 0070 D091 0000 lds r29,lockSensors+1 + 402 0074 01E0 ldi r16,lo8(1) + 403 0076 10E0 ldi r17,0 + 81:hardware.c **** struct lockerSensor *tmpLock = lockSensors; + 405 .LM15: + 406 0078 512C mov r5,__zero_reg__ + 83:hardware.c **** for (i=1; i<=4; i++) + 84:hardware.c **** { + 85:hardware.c **** if (tmpLock->enabled) + 86:hardware.c **** { + 87:hardware.c **** fprintf_P(stream, statusLockerSensDescStr, i); + 408 .LM16: + 409 007a 80E0 ldi r24,lo8(statusLockerSensDescStr) + 410 007c E82E mov r14,r24 + 411 007e 80E0 ldi r24,hi8(statusLockerSensDescStr) + 412 0080 F82E mov r15,r24 + 88:hardware.c **** if (tmpLock->threshold > tmpLock->acVal) + 89:hardware.c **** fprintf_P(stream, statusLockerOpenStr); + 90:hardware.c **** else + 91:hardware.c **** fprintf_P(stream, statusLockerCloseStr); + 92:hardware.c **** fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + 414 .LM17: + 415 0082 90E0 ldi r25,lo8(statusLockerSensAdditionalDescStr) + 416 0084 C92E mov r12,r25 + 417 0086 90E0 ldi r25,hi8(statusLockerSensAdditionalDescStr) + 418 0088 D92E mov r13,r25 + 91:hardware.c **** fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + 420 .LM18: + 421 008a 20E0 ldi r18,lo8(statusLockerCloseStr) + 422 008c A22E mov r10,r18 + 423 008e 20E0 ldi r18,hi8(statusLockerCloseStr) + 424 0090 B22E mov r11,r18 + 89:hardware.c **** else + 426 .LM19: + 427 0092 30E0 ldi r19,lo8(statusLockerOpenStr) + 428 0094 832E mov r8,r19 + 429 0096 30E0 ldi r19,hi8(statusLockerOpenStr) + 430 0098 932E mov r9,r19 + 431 .L7: + 85:hardware.c **** { + 433 .LM20: + 434 009a 8881 ld r24,Y + 435 009c 8823 tst r24 + 436 009e 01F0 breq .L4 + 87:hardware.c **** if (tmpLock->threshold > tmpLock->acVal) + 438 .LM21: + 439 00a0 1F93 push r17 + 440 00a2 0F93 push r16 + 441 00a4 FF92 push r15 + 442 00a6 EF92 push r14 + 443 00a8 6F92 push r6 + 444 00aa 7F92 push r7 + 445 00ac 0E94 0000 call fprintf_P + 88:hardware.c **** fprintf_P(stream, statusLockerOpenStr); + 447 .LM22: + 448 00b0 0F90 pop __tmp_reg__ + 449 00b2 0F90 pop __tmp_reg__ + 450 00b4 0F90 pop __tmp_reg__ + 451 00b6 0F90 pop __tmp_reg__ + 452 00b8 0F90 pop __tmp_reg__ + 453 00ba 0F90 pop __tmp_reg__ + 454 00bc 2981 ldd r18,Y+1 + 455 00be 3A81 ldd r19,Y+2 + 456 00c0 8B81 ldd r24,Y+3 + 457 00c2 9C81 ldd r25,Y+4 + 458 00c4 8217 cp r24,r18 + 459 00c6 9307 cpc r25,r19 + 460 00c8 00F4 brsh .L5 + 89:hardware.c **** else + 462 .LM23: + 463 00ca 9F92 push r9 + 464 00cc 8F92 push r8 + 465 00ce 00C0 rjmp .L12 + 466 .L5: + 91:hardware.c **** fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + 468 .LM24: + 469 00d0 BF92 push r11 + 470 00d2 AF92 push r10 + 471 .L12: + 472 00d4 6F92 push r6 + 473 00d6 7F92 push r7 + 474 00d8 0E94 0000 call fprintf_P + 475 00dc 0F90 pop __tmp_reg__ + 476 00de 0F90 pop __tmp_reg__ + 477 00e0 0F90 pop __tmp_reg__ + 478 00e2 0F90 pop __tmp_reg__ + 480 .LM25: + 481 00e4 8C81 ldd r24,Y+4 + 482 00e6 8F93 push r24 + 483 00e8 8B81 ldd r24,Y+3 + 484 00ea 8F93 push r24 + 485 00ec 8A81 ldd r24,Y+2 + 486 00ee 8F93 push r24 + 487 00f0 8981 ldd r24,Y+1 + 488 00f2 8F93 push r24 + 489 00f4 DF92 push r13 + 490 00f6 CF92 push r12 + 491 00f8 6F92 push r6 + 492 00fa 7F92 push r7 + 493 00fc 0E94 0000 call fprintf_P + 93:hardware.c **** result++; + 495 .LM26: + 496 0100 5394 inc r5 + 497 0102 8DB7 in r24,__SP_L__ + 498 0104 9EB7 in r25,__SP_H__ + 499 0106 0896 adiw r24,8 + 500 0108 0FB6 in __tmp_reg__,__SREG__ + 501 010a F894 cli + 502 010c 9EBF out __SP_H__,r25 + 503 010e 0FBE out __SREG__,__tmp_reg__ + 504 0110 8DBF out __SP_L__,r24 + 505 .L4: + 94:hardware.c **** } + 95:hardware.c **** tmpLock++; + 507 .LM27: + 508 0112 2696 adiw r28,6 + 509 0114 0F5F subi r16,-1 + 510 0116 1F4F sbci r17,-1 + 83:hardware.c **** { + 512 .LM28: + 513 0118 0530 cpi r16,5 + 514 011a 1105 cpc r17,__zero_reg__ + 515 011c 01F0 breq .+2 + 516 011e 00C0 rjmp .L7 + 96:hardware.c **** } + 97:hardware.c **** return result; + 98:hardware.c **** } + 518 .LM29: + 519 0120 852D mov r24,r5 + 520 /* epilogue start */ + 521 0122 DF91 pop r29 + 522 0124 CF91 pop r28 + 523 0126 1F91 pop r17 + 524 0128 0F91 pop r16 + 525 012a FF90 pop r15 + 526 012c EF90 pop r14 + 527 012e DF90 pop r13 + 528 0130 CF90 pop r12 + 529 0132 BF90 pop r11 + 530 0134 AF90 pop r10 + 531 0136 9F90 pop r9 + 532 0138 8F90 pop r8 + 533 013a 7F90 pop r7 + 534 013c 6F90 pop r6 + 535 013e 5F90 pop r5 + 536 0140 0895 ret + 542 .Lscope3: + 544 .stabd 78,0,0 + 546 .global checkLockerSensors + 548 checkLockerSensors: + 549 .stabd 46,0,0 + 99:hardware.c **** + 100:hardware.c **** void checkLockerSensors(void) + 101:hardware.c **** { + 551 .LM30: + 552 .LFBB4: + 553 0142 CF93 push r28 + 554 0144 DF93 push r29 + 555 /* prologue: function */ + 556 /* frame size = 0 */ + 557 /* stack size = 2 */ + 558 .L__stack_usage = 2 + 102:hardware.c **** if (lockSensors[0].enabled) + 560 .LM31: + 561 0146 E091 0000 lds r30,lockSensors + 562 014a F091 0000 lds r31,lockSensors+1 + 563 014e 8081 ld r24,Z + 564 0150 8823 tst r24 + 565 0152 01F0 breq .L15 + 103:hardware.c **** { + 104:hardware.c **** MPC23s17SetBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + 567 .LM32: + 568 0154 60E0 ldi r22,0 + 569 0156 80E4 ldi r24,lo8(64) + 570 0158 0E94 0000 call MPC23s17SetBitsOnPortA + 105:hardware.c **** vTaskDelay(30); + 572 .LM33: + 573 015c 8EE1 ldi r24,lo8(30) + 574 015e 90E0 ldi r25,0 + 575 0160 0E94 0000 call vTaskDelay + 106:hardware.c **** lockSensors[0].acVal = MCP3008_getSampleSingle(LOCK_SENS_1_AC_IN); + 577 .LM34: + 578 0164 C091 0000 lds r28,lockSensors + 579 0168 D091 0000 lds r29,lockSensors+1 + 580 016c 84E0 ldi r24,lo8(4) + 581 016e 0E94 0000 call MCP3008_getSampleSingle + 582 0172 9C83 std Y+4,r25 + 583 0174 8B83 std Y+3,r24 + 107:hardware.c **** MPC23s17ClearBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + 585 .LM35: + 586 0176 60E0 ldi r22,0 + 587 0178 80E4 ldi r24,lo8(64) + 588 017a 0E94 0000 call MPC23s17ClearBitsOnPortA + 108:hardware.c **** lockSensors[0].locked = (lockSensors[0].acVal > lockSensors[0].threshold) ? 1 : 0; + 590 .LM36: + 591 017e E091 0000 lds r30,lockSensors + 592 0182 F091 0000 lds r31,lockSensors+1 + 593 0186 81E0 ldi r24,lo8(1) + 594 0188 4381 ldd r20,Z+3 + 595 018a 5481 ldd r21,Z+4 + 596 018c 2181 ldd r18,Z+1 + 597 018e 3281 ldd r19,Z+2 + 598 0190 2417 cp r18,r20 + 599 0192 3507 cpc r19,r21 + 600 0194 00F0 brlo .L16 + 601 0196 80E0 ldi r24,0 + 602 .L16: + 603 0198 8583 std Z+5,r24 + 109:hardware.c **** vTaskDelay(10); + 605 .LM37: + 606 019a 8AE0 ldi r24,lo8(10) + 607 019c 90E0 ldi r25,0 + 608 019e 0E94 0000 call vTaskDelay + 609 .L15: + 110:hardware.c **** } + 111:hardware.c **** + 112:hardware.c **** if (lockSensors[1].enabled) + 611 .LM38: + 612 01a2 E091 0000 lds r30,lockSensors + 613 01a6 F091 0000 lds r31,lockSensors+1 + 614 01aa 8681 ldd r24,Z+6 + 615 01ac 8823 tst r24 + 616 01ae 01F0 breq .L17 + 113:hardware.c **** { + 114:hardware.c **** MPC23s17SetBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + 618 .LM39: + 619 01b0 60E0 ldi r22,0 + 620 01b2 80E2 ldi r24,lo8(32) + 621 01b4 0E94 0000 call MPC23s17SetBitsOnPortA + 115:hardware.c **** vTaskDelay(30); + 623 .LM40: + 624 01b8 8EE1 ldi r24,lo8(30) + 625 01ba 90E0 ldi r25,0 + 626 01bc 0E94 0000 call vTaskDelay + 116:hardware.c **** lockSensors[1].acVal = MCP3008_getSampleSingle(LOCK_SENS_2_AC_IN); + 628 .LM41: + 629 01c0 C091 0000 lds r28,lockSensors + 630 01c4 D091 0000 lds r29,lockSensors+1 + 631 01c8 85E0 ldi r24,lo8(5) + 632 01ca 0E94 0000 call MCP3008_getSampleSingle + 633 01ce 9A87 std Y+10,r25 + 634 01d0 8987 std Y+9,r24 + 117:hardware.c **** MPC23s17ClearBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + 636 .LM42: + 637 01d2 60E0 ldi r22,0 + 638 01d4 80E2 ldi r24,lo8(32) + 639 01d6 0E94 0000 call MPC23s17ClearBitsOnPortA + 118:hardware.c **** lockSensors[1].locked = (lockSensors[1].acVal > lockSensors[1].threshold) ? 1 : 0; + 641 .LM43: + 642 01da E091 0000 lds r30,lockSensors + 643 01de F091 0000 lds r31,lockSensors+1 + 644 01e2 81E0 ldi r24,lo8(1) + 645 01e4 4185 ldd r20,Z+9 + 646 01e6 5285 ldd r21,Z+10 + 647 01e8 2781 ldd r18,Z+7 + 648 01ea 3085 ldd r19,Z+8 + 649 01ec 2417 cp r18,r20 + 650 01ee 3507 cpc r19,r21 + 651 01f0 00F0 brlo .L18 + 652 01f2 80E0 ldi r24,0 + 653 .L18: + 654 01f4 8387 std Z+11,r24 + 119:hardware.c **** vTaskDelay(10); + 656 .LM44: + 657 01f6 8AE0 ldi r24,lo8(10) + 658 01f8 90E0 ldi r25,0 + 659 01fa 0E94 0000 call vTaskDelay + 660 .L17: + 120:hardware.c **** } + 121:hardware.c **** + 122:hardware.c **** if (lockSensors[2].enabled) + 662 .LM45: + 663 01fe E091 0000 lds r30,lockSensors + 664 0202 F091 0000 lds r31,lockSensors+1 + 665 0206 8485 ldd r24,Z+12 + 666 0208 8823 tst r24 + 667 020a 01F0 breq .L19 + 123:hardware.c **** { + 124:hardware.c **** MPC23s17SetBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + 669 .LM46: + 670 020c 60E0 ldi r22,0 + 671 020e 80E1 ldi r24,lo8(16) + 672 0210 0E94 0000 call MPC23s17SetBitsOnPortA + 125:hardware.c **** vTaskDelay(30); + 674 .LM47: + 675 0214 8EE1 ldi r24,lo8(30) + 676 0216 90E0 ldi r25,0 + 677 0218 0E94 0000 call vTaskDelay + 126:hardware.c **** lockSensors[2].acVal = MCP3008_getSampleSingle(LOCK_SENS_3_AC_IN); + 679 .LM48: + 680 021c C091 0000 lds r28,lockSensors + 681 0220 D091 0000 lds r29,lockSensors+1 + 682 0224 86E0 ldi r24,lo8(6) + 683 0226 0E94 0000 call MCP3008_getSampleSingle + 684 022a 988B std Y+16,r25 + 685 022c 8F87 std Y+15,r24 + 127:hardware.c **** MPC23s17ClearBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + 687 .LM49: + 688 022e 60E0 ldi r22,0 + 689 0230 80E1 ldi r24,lo8(16) + 690 0232 0E94 0000 call MPC23s17ClearBitsOnPortA + 128:hardware.c **** lockSensors[2].locked = (lockSensors[2].acVal > lockSensors[2].threshold) ? 1 : 0; + 692 .LM50: + 693 0236 E091 0000 lds r30,lockSensors + 694 023a F091 0000 lds r31,lockSensors+1 + 695 023e 81E0 ldi r24,lo8(1) + 696 0240 4785 ldd r20,Z+15 + 697 0242 5089 ldd r21,Z+16 + 698 0244 2585 ldd r18,Z+13 + 699 0246 3685 ldd r19,Z+14 + 700 0248 2417 cp r18,r20 + 701 024a 3507 cpc r19,r21 + 702 024c 00F0 brlo .L20 + 703 024e 80E0 ldi r24,0 + 704 .L20: + 705 0250 818B std Z+17,r24 + 129:hardware.c **** vTaskDelay(10); + 707 .LM51: + 708 0252 8AE0 ldi r24,lo8(10) + 709 0254 90E0 ldi r25,0 + 710 0256 0E94 0000 call vTaskDelay + 711 .L19: + 130:hardware.c **** } + 131:hardware.c **** + 132:hardware.c **** if (lockSensors[3].enabled) + 713 .LM52: + 714 025a E091 0000 lds r30,lockSensors + 715 025e F091 0000 lds r31,lockSensors+1 + 716 0262 8289 ldd r24,Z+18 + 717 0264 8823 tst r24 + 718 0266 01F0 breq .L14 + 133:hardware.c **** { + 134:hardware.c **** MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + 720 .LM53: + 721 0268 60E0 ldi r22,0 + 722 026a 88E0 ldi r24,lo8(8) + 723 026c 0E94 0000 call MPC23s17SetBitsOnPortA + 135:hardware.c **** vTaskDelay(30); + 725 .LM54: + 726 0270 8EE1 ldi r24,lo8(30) + 727 0272 90E0 ldi r25,0 + 728 0274 0E94 0000 call vTaskDelay + 136:hardware.c **** lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + 730 .LM55: + 731 0278 C091 0000 lds r28,lockSensors + 732 027c D091 0000 lds r29,lockSensors+1 + 733 0280 87E0 ldi r24,lo8(7) + 734 0282 0E94 0000 call MCP3008_getSampleSingle + 735 0286 9E8B std Y+22,r25 + 736 0288 8D8B std Y+21,r24 + 137:hardware.c **** MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + 738 .LM56: + 739 028a 60E0 ldi r22,0 + 740 028c 88E0 ldi r24,lo8(8) + 741 028e 0E94 0000 call MPC23s17ClearBitsOnPortA + 138:hardware.c **** lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + 743 .LM57: + 744 0292 E091 0000 lds r30,lockSensors + 745 0296 F091 0000 lds r31,lockSensors+1 + 746 029a 81E0 ldi r24,lo8(1) + 747 029c 4589 ldd r20,Z+21 + 748 029e 5689 ldd r21,Z+22 + 749 02a0 2389 ldd r18,Z+19 + 750 02a2 3489 ldd r19,Z+20 + 751 02a4 2417 cp r18,r20 + 752 02a6 3507 cpc r19,r21 + 753 02a8 00F0 brlo .L22 + 754 02aa 80E0 ldi r24,0 + 755 .L22: + 756 02ac 878B std Z+23,r24 + 139:hardware.c **** vTaskDelay(10); + 758 .LM58: + 759 02ae 8AE0 ldi r24,lo8(10) + 760 02b0 90E0 ldi r25,0 + 761 /* epilogue start */ + 140:hardware.c **** } + 141:hardware.c **** } + 763 .LM59: + 764 02b2 DF91 pop r29 + 765 02b4 CF91 pop r28 + 139:hardware.c **** vTaskDelay(10); + 767 .LM60: + 768 02b6 0C94 0000 jmp vTaskDelay + 769 .L14: + 770 /* epilogue start */ + 772 .LM61: + 773 02ba DF91 pop r29 + 774 02bc CF91 pop r28 + 775 02be 0895 ret + 777 .Lscope4: + 779 .stabd 78,0,0 + 782 .weak spiSend + 784 spiSend: + 785 .stabd 46,0,0 + 142:hardware.c **** + 143:hardware.c **** + 144:hardware.c **** uint8_t spiSend(uint8_t data) + 145:hardware.c **** { + 787 .LM62: + 788 .LFBB5: + 789 02c0 CF93 push r28 + 790 02c2 DF93 push r29 + 791 02c4 1F92 push __zero_reg__ + 792 02c6 CDB7 in r28,__SP_L__ + 793 02c8 DEB7 in r29,__SP_H__ + 794 /* prologue: function */ + 795 /* frame size = 1 */ + 796 /* stack size = 3 */ + 797 .L__stack_usage = 3 + 146:hardware.c **** uint8_t result; + 147:hardware.c **** SPDR = data; + 799 .LM63: + 800 02ca 8FB9 out 0xf,r24 + 148:hardware.c **** xQueueReceive(xSpiRx, &result, 10); + 802 .LM64: + 803 02cc 20E0 ldi r18,0 + 804 02ce 4AE0 ldi r20,lo8(10) + 805 02d0 50E0 ldi r21,0 + 806 02d2 BE01 movw r22,r28 + 807 02d4 6F5F subi r22,-1 + 808 02d6 7F4F sbci r23,-1 + 809 02d8 8091 0000 lds r24,xSpiRx + 810 02dc 9091 0000 lds r25,xSpiRx+1 + 811 02e0 0E94 0000 call xQueueGenericReceive + 149:hardware.c **** return result; + 150:hardware.c **** } + 813 .LM65: + 814 02e4 8981 ldd r24,Y+1 + 815 /* epilogue start */ + 816 02e6 0F90 pop __tmp_reg__ + 817 02e8 DF91 pop r29 + 818 02ea CF91 pop r28 + 819 02ec 0895 ret + 824 .Lscope5: + 826 .stabd 78,0,0 + 829 .global spiSendENC + 831 spiSendENC: + 832 .stabd 46,0,0 + 151:hardware.c **** + 152:hardware.c **** uint8_t spiSendENC(uint8_t data) + 153:hardware.c **** { + 834 .LM66: + 835 .LFBB6: + 836 02ee CF93 push r28 + 837 02f0 DF93 push r29 + 838 02f2 1F92 push __zero_reg__ + 839 02f4 CDB7 in r28,__SP_L__ + 840 02f6 DEB7 in r29,__SP_H__ + 841 /* prologue: function */ + 842 /* frame size = 1 */ + 843 /* stack size = 3 */ + 844 .L__stack_usage = 3 + 154:hardware.c **** uint8_t result; + 155:hardware.c **** SPDR = data; + 846 .LM67: + 847 02f8 8FB9 out 0xf,r24 + 156:hardware.c **** xQueueReceive(xSpiRx, &result, 10); + 849 .LM68: + 850 02fa 20E0 ldi r18,0 + 851 02fc 4AE0 ldi r20,lo8(10) + 852 02fe 50E0 ldi r21,0 + 853 0300 BE01 movw r22,r28 + 854 0302 6F5F subi r22,-1 + 855 0304 7F4F sbci r23,-1 + 856 0306 8091 0000 lds r24,xSpiRx + 857 030a 9091 0000 lds r25,xSpiRx+1 + 858 030e 0E94 0000 call xQueueGenericReceive + 157:hardware.c **** return result; + 158:hardware.c **** } + 860 .LM69: + 861 0312 8981 ldd r24,Y+1 + 862 /* epilogue start */ + 863 0314 0F90 pop __tmp_reg__ + 864 0316 DF91 pop r29 + 865 0318 CF91 pop r28 + 866 031a 0895 ret + 871 .Lscope6: + 873 .stabd 78,0,0 + 876 .weak spiSendSpinBlock + 878 spiSendSpinBlock: + 879 .stabd 46,0,0 + 159:hardware.c **** + 160:hardware.c **** uint8_t spiSendSpinBlock(uint8_t data) + 161:hardware.c **** { + 881 .LM70: + 882 .LFBB7: + 883 /* prologue: function */ + 884 /* frame size = 0 */ + 885 /* stack size = 0 */ + 886 .L__stack_usage = 0 + 162:hardware.c **** SPDR = data; + 888 .LM71: + 889 031c 8FB9 out 0xf,r24 + 163:hardware.c **** SPCR &= ~(1< +const char statusLockerSensDescStr[] PROGMEM = " locker %d"; +const char statusLockerOpenStr[] PROGMEM = " open "; +const char statusLockerCloseStr[] PROGMEM = " locked "; +const char statusLockerSensAdditionalDescStr[] PROGMEM = " (threshold %d, AC value %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/hardware_pl.h b/Projects/DidacticSystem/Adam/MainController/hardware_pl.h new file mode 100644 index 0000000..9bf0733 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/hardware_pl.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE PL + +prog_char statusLockerSensDescStr[] = " rygiel %d"; +prog_char statusLockerOpenStr[] = " otwarty "; +prog_char statusLockerCloseStr[] = " zamkniety"; +prog_char statusLockerSensAdditionalDescStr[] = " (granica %d, wartosc AC %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/main.c b/Projects/DidacticSystem/Adam/MainController/main.c new file mode 100644 index 0000000..09fdcd3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/main.c @@ -0,0 +1,177 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + +uint8_t timer100Hz = 0; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; + +xQueueHandle xRs485Tx; +xQueueHandle xRs485Rec; + + +volatile uint8_t temperature; +volatile uint8_t voltage; + + +void vApplicationIdleHook( void ); + +/** + * RTC clock support + */ +void vApplicationTickHook( void ); + +xTaskHandle xHandleVTY_USB; +xTaskHandle xHandleVTY_UDP; +xTaskHandle xHandleEnc; +xTaskHandle xHandleSensors; + +void initExternalMem(void) +{ + MCUCR |= _BV(SRE); //Włączenie pamięci zewnętrznej + MCUCR |= 0x0E; + +#define testZewPamiec 1 +#if testZewPamiec == 1 +#define SND(DTA) UDR1=DTA; \ + while( ! (UCSR1A & (1<>4 & 0x0F); + uint8_t znLo = (hiAddr & 0x0F); + + znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + + SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + + uint16_t addr; + uint16_t startAddr = hiAddr<<8; + uint16_t stopAddr = startAddr + 0xFF; + + for (addr = startAddr; addr <= stopAddr; addr++) + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + } + SND ('\r') SND ('\n') +#undef SND +#endif +} + +cmdState_t *CLIStateSerialUsb; +cmdState_t *CLIStateSerialUdp; +FILE usbStream; +FILE udpStream; + +streamBuffers_t udpBuffers; + +portSHORT main( void ) +{ + ramDyskInit(); //Inicjalizacja Ram dysku + hardwareInit(); + spiInit(disableAllSpiDevices); + +// VTY on serial + xSerialPortInitMinimal(); + CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + + +// cmdStateClear(newCmdState); + + sensorsTaskInit(); + loadConfiguration(); + + initQueueStreamUSB(&usbStream); + VtyInit(CLIStateSerialUsb, &usbStream); + + udpInit_0(); + socketInit(); + initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + VtyInit(CLIStateSerialUdp, &udpStream); + +//xTaskCreate(encTask, NULL /*"ENC" */, STACK_SIZE_ENC, (void *)CLIStateSerialUsb->myStdInOut, 0, &xHandleEnc); + xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb), 1, &xHandleVTY_USB); +//xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp), 1, &xHandleVTY_UDP); + xTaskCreate(sensorsTask, NULL /*"Sensors"*/, STACK_SIZE_SENSORS, NULL, 1, &xHandleSensors); + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + arpTimer(); + } +} diff --git a/Projects/DidacticSystem/Adam/MainController/main.h b/Projects/DidacticSystem/Adam/MainController/main.h new file mode 100644 index 0000000..fde6c62 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/main.h @@ -0,0 +1,66 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + +#include "memory_x.h" +#include "Rs485_prot.h" + +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "queueStream.h" +#include "cli_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" +#include "spi.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "enc28j60.h" + +#include "ramdysk.h" +#include "ff.h" +#include "sd_diskio.h" +#include "rtc.h" + +#include "sensors_task.h" +#include "netstack_task.h" + + +#include "cmdline.h" +#include "vty.h" + +#include "../../Lib/net/include/arp.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" + + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.31" + + + + +volatile timeDecoded_t czasRtc; + +void initExternalMem(void) __attribute__ ((naked)) __attribute__ ((section (".init4"))); + +extern UdpSocket_t *udpSocket; + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/main.lst b/Projects/DidacticSystem/Adam/MainController/main.lst new file mode 100644 index 0000000..a94c751 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/main.lst @@ -0,0 +1,890 @@ + 1 .file "main.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 272 .section .init4,"ax",@progbits + 274 .global initExternalMem + 276 initExternalMem: + 277 .stabd 46,0,0 + 1:main.c **** /* + 2:main.c **** + 3:main.c **** FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + 4:main.c **** This file is part of the FreeRTOS.org distribution. + 5:main.c **** FreeRTOS.org is free software; you can redistribute it and/or modify it + 6:main.c **** under the terms of the GNU General Public License (version 2) as published + 7:main.c **** by the Free Software Foundation and modified by the FreeRTOS exception. + 8:main.c **** FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + 9:main.c **** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + 10:main.c **** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + 11:main.c **** more details. + 12:main.c **** + 13:main.c **** You should have received a copy of the GNU General Public License along + 14:main.c **** with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + 15:main.c **** Temple Place, Suite 330, Boston, MA 02111-1307 USA. + 16:main.c **** + 17:main.c **** A special exception to the GPL is included to allow you to distribute a + 18:main.c **** combined work that includes FreeRTOS.org without being obliged to provide + 19:main.c **** the source code for any proprietary components. See the licensing section + 20:main.c **** of http://www.FreeRTOS.org for full details. + 21:main.c **** *************************************************************************** + 22:main.c **** * * + 23:main.c **** * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + 24:main.c **** * * + 25:main.c **** * This is a concise, step by step, 'hands on' guide that describes both * + 26:main.c **** * general multitasking concepts and FreeRTOS specifics. It presents and * + 27:main.c **** * explains numerous examples that are written using the FreeRTOS API. * + 28:main.c **** * Full source code for all the examples is provided in an accompanying * + 29:main.c **** * .zip file. * + 30:main.c **** * * + 31:main.c **** *************************************************************************** + 32:main.c **** 1 tab == 4 spaces! + 33:main.c **** Please ensure to read the configuration and relevant port sections of the + 34:main.c **** online documentation. + 35:main.c **** + 36:main.c **** http://www.FreeRTOS.org - Documentation, latest information, license and + 37:main.c **** contact details. + 38:main.c **** + 39:main.c **** http://www.SafeRTOS.com - A version that is certified for use in safety + 40:main.c **** critical systems. + 41:main.c **** + 42:main.c **** http://www.OpenRTOS.com - Commercial support, development, porting, + 43:main.c **** licensing and training services. + 44:main.c **** */ + 45:main.c **** + 46:main.c **** #include "main.h" + 47:main.c **** + 48:main.c **** uint8_t timer100Hz = 0; + 49:main.c **** + 50:main.c **** xQueueHandle xVtyTx; + 51:main.c **** xQueueHandle xVtyRec; + 52:main.c **** + 53:main.c **** xQueueHandle xRs485Tx; + 54:main.c **** xQueueHandle xRs485Rec; + 55:main.c **** + 56:main.c **** + 57:main.c **** volatile uint8_t temperature; + 58:main.c **** volatile uint8_t voltage; + 59:main.c **** + 60:main.c **** + 61:main.c **** void vApplicationIdleHook( void ); + 62:main.c **** + 63:main.c **** /** + 64:main.c **** * RTC clock support + 65:main.c **** */ + 66:main.c **** void vApplicationTickHook( void ); + 67:main.c **** + 68:main.c **** xTaskHandle xHandleVTY_USB; + 69:main.c **** xTaskHandle xHandleVTY_UDP; + 70:main.c **** xTaskHandle xHandleEnc; + 71:main.c **** xTaskHandle xHandleSensors; + 72:main.c **** + 73:main.c **** void initExternalMem(void) + 74:main.c **** { + 279 .LM0: + 280 .LFBB1: + 281 /* prologue: naked */ + 282 /* frame size = 0 */ + 283 /* stack size = 0 */ + 284 .L__stack_usage = 0 + 75:main.c **** MCUCR |= _BV(SRE); //Włączenie pamięci zewnętrznej + 286 .LM1: + 287 0000 85B7 in r24,0x35 + 288 0002 8068 ori r24,lo8(-128) + 289 0004 85BF out 0x35,r24 + 76:main.c **** MCUCR |= 0x0E; + 291 .LM2: + 292 0006 85B7 in r24,0x35 + 293 0008 8E60 ori r24,lo8(14) + 294 000a 85BF out 0x35,r24 + 77:main.c **** + 78:main.c **** #define testZewPamiec 1 + 79:main.c **** #if testZewPamiec == 1 + 80:main.c **** #define SND(DTA) UDR1=DTA; \ + 81:main.c **** while( ! (UCSR1A & (1<>4 & 0x0F); + 93:main.c **** uint8_t znLo = (hiAddr & 0x0F); + 94:main.c **** + 95:main.c **** znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + 96:main.c **** znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + 97:main.c **** + 98:main.c **** SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + 450 .LM34: + 451 00e4 6DE0 ldi r22,lo8(13) + 452 00e6 70E3 ldi r23,lo8(48) + 453 00e8 C8E7 ldi r28,lo8(120) + 454 00ea 4AE2 ldi r20,lo8(42) + 455 00ec D0E2 ldi r29,lo8(32) + 99:main.c **** + 100:main.c **** uint16_t addr; + 101:main.c **** uint16_t startAddr = hiAddr<<8; + 102:main.c **** uint16_t stopAddr = startAddr + 0xFF; + 103:main.c **** + 104:main.c **** for (addr = startAddr; addr <= stopAddr; addr++) + 105:main.c **** *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + 106:main.c **** + 107:main.c **** uint8_t isOK=1; + 108:main.c **** for (addr = startAddr; addr <= stopAddr; addr++) + 109:main.c **** if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + 110:main.c **** isOK = 0; + 111:main.c **** + 112:main.c **** if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + 113:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 457 .LM35: + 458 00ee 16E4 ldi r17,lo8(70) + 459 00f0 01E4 ldi r16,lo8(65) + 460 00f2 39E4 ldi r19,lo8(73) + 461 00f4 D32E mov r13,r19 + 462 00f6 5CE4 ldi r21,lo8(76) + 463 00f8 C52E mov r12,r21 + 464 00fa 5AE0 ldi r21,lo8(10) + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 466 .LM36: + 467 00fc EFE4 ldi r30,lo8(79) + 468 00fe BE2E mov r11,r30 + 469 0100 FBE4 ldi r31,lo8(75) + 470 0102 AF2E mov r10,r31 + 471 .L37: + 92:main.c **** uint8_t znLo = (hiAddr & 0x0F); + 473 .LM37: + 474 0104 382F mov r19,r24 + 475 0106 3295 swap r19 + 476 0108 3F70 andi r19,lo8(15) + 93:main.c **** + 478 .LM38: + 479 010a 282F mov r18,r24 + 480 010c 2F70 andi r18,lo8(15) + 95:main.c **** znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + 482 .LM39: + 483 010e 3A30 cpi r19,lo8(10) + 484 0110 00F4 brsh .L16 + 95:main.c **** znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + 486 .LM40: + 487 0112 305D subi r19,lo8(-(48)) + 488 0114 00C0 rjmp .L17 + 489 .L16: + 95:main.c **** znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + 491 .LM41: + 492 0116 395C subi r19,lo8(-(55)) + 493 .L17: + 96:main.c **** + 495 .LM42: + 496 0118 2A30 cpi r18,lo8(10) + 497 011a 00F4 brsh .L18 + 96:main.c **** + 499 .LM43: + 500 011c 205D subi r18,lo8(-(48)) + 501 011e 00C0 rjmp .L19 + 502 .L18: + 96:main.c **** + 504 .LM44: + 505 0120 295C subi r18,lo8(-(55)) + 506 .L19: + 98:main.c **** + 508 .LM45: + 509 0122 6093 9C00 sts 156,r22 + 510 .L20: + 98:main.c **** + 512 .LM46: + 513 0126 E091 9B00 lds r30,155 + 514 012a E5FF sbrs r30,5 + 515 012c 00C0 rjmp .L20 + 98:main.c **** + 517 .LM47: + 518 012e 7093 9C00 sts 156,r23 + 519 .L21: + 98:main.c **** + 521 .LM48: + 522 0132 E091 9B00 lds r30,155 + 523 0136 E5FF sbrs r30,5 + 524 0138 00C0 rjmp .L21 + 98:main.c **** + 526 .LM49: + 527 013a C093 9C00 sts 156,r28 + 528 .L22: + 98:main.c **** + 530 .LM50: + 531 013e E091 9B00 lds r30,155 + 532 0142 E5FF sbrs r30,5 + 533 0144 00C0 rjmp .L22 + 98:main.c **** + 535 .LM51: + 536 0146 3093 9C00 sts 156,r19 + 537 .L23: + 98:main.c **** + 539 .LM52: + 540 014a 3091 9B00 lds r19,155 + 541 014e 35FF sbrs r19,5 + 542 0150 00C0 rjmp .L23 + 98:main.c **** + 544 .LM53: + 545 0152 2093 9C00 sts 156,r18 + 546 .L24: + 98:main.c **** + 548 .LM54: + 549 0156 2091 9B00 lds r18,155 + 550 015a 25FF sbrs r18,5 + 551 015c 00C0 rjmp .L24 + 98:main.c **** + 553 .LM55: + 554 015e 4093 9C00 sts 156,r20 + 555 .L25: + 98:main.c **** + 557 .LM56: + 558 0162 2091 9B00 lds r18,155 + 559 0166 25FF sbrs r18,5 + 560 0168 00C0 rjmp .L25 + 98:main.c **** + 562 .LM57: + 563 016a 4093 9C00 sts 156,r20 + 564 .L26: + 98:main.c **** + 566 .LM58: + 567 016e 2091 9B00 lds r18,155 + 568 0172 25FF sbrs r18,5 + 569 0174 00C0 rjmp .L26 + 98:main.c **** + 571 .LM59: + 572 0176 D093 9C00 sts 156,r29 + 573 .L27: + 98:main.c **** + 575 .LM60: + 576 017a 2091 9B00 lds r18,155 + 577 017e 25FF sbrs r18,5 + 578 0180 00C0 rjmp .L27 + 101:main.c **** uint16_t stopAddr = startAddr + 0xFF; + 580 .LM61: + 581 0182 F82F mov r31,r24 + 582 0184 EE27 clr r30 + 102:main.c **** + 584 .LM62: + 585 0186 9F01 movw r18,r30 + 586 0188 2150 subi r18,1 + 587 018a 3F4F sbci r19,-1 + 104:main.c **** *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + 589 .LM63: + 590 018c DF01 movw r26,r30 + 591 018e 00C0 rjmp .L28 + 592 .L29: + 105:main.c **** + 594 .LM64: + 595 0190 7D01 movw r14,r26 + 596 0192 F694 lsr r15 + 597 0194 E794 ror r14 + 598 0196 ED92 st X+,r14 + 599 .L28: + 104:main.c **** *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + 601 .LM65: + 602 0198 2A17 cp r18,r26 + 603 019a 3B07 cpc r19,r27 + 604 019c 00F4 brsh .L29 + 605 019e 9924 clr r9 + 606 01a0 9394 inc r9 + 607 01a2 00C0 rjmp .L30 + 608 .L32: + 609 01a4 DF01 movw r26,r30 + 610 01a6 1196 adiw r26,1 + 109:main.c **** isOK = 0; + 612 .LM66: + 613 01a8 7F01 movw r14,r30 + 614 01aa F694 lsr r15 + 615 01ac E794 ror r14 + 616 01ae E081 ld r30,Z + 617 01b0 EE11 cpse r30,r14 + 110:main.c **** + 619 .LM67: + 620 01b2 912C mov r9,__zero_reg__ + 621 .L31: + 622 01b4 FD01 movw r30,r26 + 623 .L30: + 108:main.c **** if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + 625 .LM68: + 626 01b6 2E17 cp r18,r30 + 627 01b8 3F07 cpc r19,r31 + 628 01ba 00F4 brsh .L32 + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 630 .LM69: + 631 01bc 21E0 ldi r18,lo8(1) + 632 01be 9212 cpse r9,r18 + 633 01c0 00C0 rjmp .L33 + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 635 .LM70: + 636 01c2 B092 9C00 sts 156,r11 + 637 .L34: + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 639 .LM71: + 640 01c6 2091 9B00 lds r18,155 + 641 01ca 25FF sbrs r18,5 + 642 01cc 00C0 rjmp .L34 + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 644 .LM72: + 645 01ce A092 9C00 sts 156,r10 + 646 .L35: + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 648 .LM73: + 649 01d2 2091 9B00 lds r18,155 + 650 01d6 25FF sbrs r18,5 + 651 01d8 00C0 rjmp .L35 + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 653 .LM74: + 654 01da 5093 9C00 sts 156,r21 + 655 .L36: + 112:main.c **** else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + 657 .LM75: + 658 01de 2091 9B00 lds r18,155 + 659 01e2 25FF sbrs r18,5 + 660 01e4 00C0 rjmp .L36 + 661 .L44: + 662 01e6 0196 adiw r24,1 + 663 .LBE2: + 90:main.c **** { + 665 .LM76: + 666 01e8 8F3F cpi r24,-1 + 667 01ea 9105 cpc r25,__zero_reg__ + 668 01ec 01F0 breq .+2 + 669 01ee 00C0 rjmp .L37 + 670 01f0 00C0 rjmp .L112 + 671 .L33: + 672 .LBB3: + 674 .LM77: + 675 01f2 1093 9C00 sts 156,r17 + 676 .L39: + 678 .LM78: + 679 01f6 2091 9B00 lds r18,155 + 680 01fa 25FF sbrs r18,5 + 681 01fc 00C0 rjmp .L39 + 683 .LM79: + 684 01fe 0093 9C00 sts 156,r16 + 685 .L40: + 687 .LM80: + 688 0202 2091 9B00 lds r18,155 + 689 0206 25FF sbrs r18,5 + 690 0208 00C0 rjmp .L40 + 692 .LM81: + 693 020a D092 9C00 sts 156,r13 + 694 .L41: + 696 .LM82: + 697 020e 2091 9B00 lds r18,155 + 698 0212 25FF sbrs r18,5 + 699 0214 00C0 rjmp .L41 + 701 .LM83: + 702 0216 C092 9C00 sts 156,r12 + 703 .L42: + 705 .LM84: + 706 021a 2091 9B00 lds r18,155 + 707 021e 25FF sbrs r18,5 + 708 0220 00C0 rjmp .L42 + 710 .LM85: + 711 0222 5093 9C00 sts 156,r21 + 712 .L43: + 714 .LM86: + 715 0226 2091 9B00 lds r18,155 + 716 022a 25FF sbrs r18,5 + 717 022c 00C0 rjmp .L43 + 718 022e 00C0 rjmp .L44 + 719 .L112: + 720 .LBE3: + 114:main.c **** } + 115:main.c **** SND ('\r') SND ('\n') + 722 .LM87: + 723 0230 8DE0 ldi r24,lo8(13) + 724 0232 8093 9C00 sts 156,r24 + 725 .L45: + 727 .LM88: + 728 0236 8091 9B00 lds r24,155 + 729 023a 85FF sbrs r24,5 + 730 023c 00C0 rjmp .L45 + 732 .LM89: + 733 023e 8AE0 ldi r24,lo8(10) + 734 0240 8093 9C00 sts 156,r24 + 735 .L46: + 737 .LM90: + 738 0244 8091 9B00 lds r24,155 + 739 0248 85FF sbrs r24,5 + 740 024a 00C0 rjmp .L46 + 741 /* epilogue start */ + 116:main.c **** #undef SND + 117:main.c **** #endif + 118:main.c **** } + 743 .LM91: + 753 .Lscope1: + 755 .stabd 78,0,0 + 756 .section .text.startup,"ax",@progbits + 758 .global main + 760 main: + 761 .stabd 46,0,0 + 119:main.c **** + 120:main.c **** cmdState_t *CLIStateSerialUsb; + 121:main.c **** cmdState_t *CLIStateSerialUdp; + 122:main.c **** FILE usbStream; + 123:main.c **** FILE udpStream; + 124:main.c **** + 125:main.c **** streamBuffers_t udpBuffers; + 126:main.c **** + 127:main.c **** portSHORT main( void ) + 128:main.c **** { + 763 .LM92: + 764 .LFBB2: + 765 0000 AF92 push r10 + 766 0002 BF92 push r11 + 767 0004 CF92 push r12 + 768 0006 DF92 push r13 + 769 0008 EF92 push r14 + 770 000a FF92 push r15 + 771 000c 0F93 push r16 + 772 /* prologue: function */ + 773 /* frame size = 0 */ + 774 /* stack size = 7 */ + 775 .L__stack_usage = 7 + 129:main.c **** ramDyskInit(); //Inicjalizacja Ram dysku + 777 .LM93: + 778 000e 0E94 0000 call ramDyskInit + 130:main.c **** hardwareInit(); + 780 .LM94: + 781 0012 0E94 0000 call hardwareInit + 131:main.c **** spiInit(disableAllSpiDevices); + 783 .LM95: + 784 0016 80E0 ldi r24,lo8(gs(disableAllSpiDevices)) + 785 0018 90E0 ldi r25,hi8(gs(disableAllSpiDevices)) + 786 001a 0E94 0000 call spiInit + 132:main.c **** + 133:main.c **** // VTY on serial + 134:main.c **** xSerialPortInitMinimal(); + 788 .LM96: + 789 001e 0E94 0000 call xSerialPortInitMinimal + 135:main.c **** CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + 791 .LM97: + 792 0022 83E2 ldi r24,lo8(35) + 793 0024 90E0 ldi r25,0 + 794 0026 0E94 0000 call xmalloc + 795 002a 9093 0000 sts CLIStateSerialUsb+1,r25 + 796 002e 8093 0000 sts CLIStateSerialUsb,r24 + 136:main.c **** CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + 798 .LM98: + 799 0032 83E2 ldi r24,lo8(35) + 800 0034 90E0 ldi r25,0 + 801 0036 0E94 0000 call xmalloc + 802 003a 9093 0000 sts CLIStateSerialUdp+1,r25 + 803 003e 8093 0000 sts CLIStateSerialUdp,r24 + 137:main.c **** + 138:main.c **** + 139:main.c **** // cmdStateClear(newCmdState); + 140:main.c **** + 141:main.c **** sensorsTaskInit(); + 805 .LM99: + 806 0042 0E94 0000 call sensorsTaskInit + 142:main.c **** loadConfiguration(); + 808 .LM100: + 809 0046 0E94 0000 call loadConfiguration + 143:main.c **** + 144:main.c **** initQueueStreamUSB(&usbStream); + 811 .LM101: + 812 004a 80E0 ldi r24,lo8(usbStream) + 813 004c 90E0 ldi r25,hi8(usbStream) + 814 004e 0E94 0000 call initQueueStreamUSB + 145:main.c **** VtyInit(CLIStateSerialUsb, &usbStream); + 816 .LM102: + 817 0052 60E0 ldi r22,lo8(usbStream) + 818 0054 70E0 ldi r23,hi8(usbStream) + 819 0056 8091 0000 lds r24,CLIStateSerialUsb + 820 005a 9091 0000 lds r25,CLIStateSerialUsb+1 + 821 005e 0E94 0000 call VtyInit + 146:main.c **** + 147:main.c **** udpInit_0(); + 823 .LM103: + 824 0062 0E94 0000 call udpInit_0 + 148:main.c **** socketInit(); + 826 .LM104: + 827 0066 0E94 0000 call socketInit + 149:main.c **** initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + 829 .LM105: + 830 006a E091 0000 lds r30,udpSocket + 831 006e F091 0000 lds r31,udpSocket+1 + 832 0072 2485 ldd r18,Z+12 + 833 0074 3585 ldd r19,Z+13 + 834 0076 4285 ldd r20,Z+10 + 835 0078 5385 ldd r21,Z+11 + 836 007a 60E0 ldi r22,lo8(udpBuffers) + 837 007c 70E0 ldi r23,hi8(udpBuffers) + 838 007e 80E0 ldi r24,lo8(udpStream) + 839 0080 90E0 ldi r25,hi8(udpStream) + 840 0082 0E94 0000 call initQueueStream + 150:main.c **** VtyInit(CLIStateSerialUdp, &udpStream); + 842 .LM106: + 843 0086 60E0 ldi r22,lo8(udpStream) + 844 0088 70E0 ldi r23,hi8(udpStream) + 845 008a 8091 0000 lds r24,CLIStateSerialUdp + 846 008e 9091 0000 lds r25,CLIStateSerialUdp+1 + 847 0092 0E94 0000 call VtyInit + 151:main.c **** + 152:main.c **** //xTaskCreate(encTask, NULL /*"ENC" */, STACK_SIZE_ENC, (void *)CLIStateSerialUsb-> + 153:main.c **** xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb) + 849 .LM107: + 850 0096 2091 0000 lds r18,CLIStateSerialUsb + 851 009a 3091 0000 lds r19,CLIStateSerialUsb+1 + 852 009e A12C mov r10,__zero_reg__ + 853 00a0 B12C mov r11,__zero_reg__ + 854 00a2 C12C mov r12,__zero_reg__ + 855 00a4 D12C mov r13,__zero_reg__ + 856 00a6 80E0 ldi r24,lo8(xHandleVTY_USB) + 857 00a8 E82E mov r14,r24 + 858 00aa 80E0 ldi r24,hi8(xHandleVTY_USB) + 859 00ac F82E mov r15,r24 + 860 00ae 01E0 ldi r16,lo8(1) + 861 00b0 4CEB ldi r20,lo8(-68) + 862 00b2 52E0 ldi r21,lo8(2) + 863 00b4 60E0 ldi r22,0 + 864 00b6 70E0 ldi r23,0 + 865 00b8 80E0 ldi r24,lo8(gs(vTaskVTYusb)) + 866 00ba 90E0 ldi r25,hi8(gs(vTaskVTYusb)) + 867 00bc 0E94 0000 call xTaskGenericCreate + 154:main.c **** //xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp) + 155:main.c **** xTaskCreate(sensorsTask, NULL /*"Sensors"*/, STACK_SIZE_SENSORS, NULL, + 869 .LM108: + 870 00c0 90E0 ldi r25,lo8(xHandleSensors) + 871 00c2 E92E mov r14,r25 + 872 00c4 90E0 ldi r25,hi8(xHandleSensors) + 873 00c6 F92E mov r15,r25 + 874 00c8 20E0 ldi r18,0 + 875 00ca 30E0 ldi r19,0 + 876 00cc 44EF ldi r20,lo8(-12) + 877 00ce 51E0 ldi r21,lo8(1) + 878 00d0 60E0 ldi r22,0 + 879 00d2 70E0 ldi r23,0 + 880 00d4 80E0 ldi r24,lo8(gs(sensorsTask)) + 881 00d6 90E0 ldi r25,hi8(gs(sensorsTask)) + 882 00d8 0E94 0000 call xTaskGenericCreate + 156:main.c **** vTaskStartScheduler(); + 884 .LM109: + 885 00dc 0E94 0000 call vTaskStartScheduler + 157:main.c **** return 0; + 158:main.c **** } + 887 .LM110: + 888 00e0 80E0 ldi r24,0 + 889 00e2 90E0 ldi r25,0 + 890 /* epilogue start */ + 891 00e4 0F91 pop r16 + 892 00e6 FF90 pop r15 + 893 00e8 EF90 pop r14 + 894 00ea DF90 pop r13 + 895 00ec CF90 pop r12 + 896 00ee BF90 pop r11 + 897 00f0 AF90 pop r10 + 898 00f2 0895 ret + 900 .Lscope2: + 902 .stabd 78,0,0 + 903 .text + 905 .global vApplicationIdleHook + 907 vApplicationIdleHook: + 908 .stabd 46,0,0 + 159:main.c **** /*-----------------------------------------------------------*/ + 160:main.c **** + 161:main.c **** void vApplicationIdleHook( void ) + 162:main.c **** { + 910 .LM111: + 911 .LFBB3: + 912 /* prologue: function */ + 913 /* frame size = 0 */ + 914 /* stack size = 0 */ + 915 .L__stack_usage = 0 + 916 .L115: + 163:main.c **** for( ;; ) + 164:main.c **** { + 165:main.c **** vCoRoutineSchedule(); + 918 .LM112: + 919 0000 0E94 0000 call vCoRoutineSchedule + 166:main.c **** } + 921 .LM113: + 922 0004 00C0 rjmp .L115 + 924 .Lscope3: + 926 .stabd 78,0,0 + 928 .global vApplicationTickHook + 930 vApplicationTickHook: + 931 .stabd 46,0,0 + 167:main.c **** } + 168:main.c **** + 169:main.c **** void vApplicationTickHook( void ) + 170:main.c **** { + 933 .LM114: + 934 .LFBB4: + 935 /* prologue: function */ + 936 /* frame size = 0 */ + 937 /* stack size = 0 */ + 938 .L__stack_usage = 0 + 171:main.c **** static uint8_t tickCntr = configTICK_RATE_HZ; + 172:main.c **** if (--tickCntr == 0) + 940 .LM115: + 941 0006 8091 0000 lds r24,tickCntr.3566 + 942 000a 8150 subi r24,lo8(-(-1)) + 943 000c 01F0 breq .L117 + 944 000e 8093 0000 sts tickCntr.3566,r24 + 945 0012 0895 ret + 946 .L117: + 173:main.c **** { + 174:main.c **** tickCntr = configTICK_RATE_HZ; + 948 .LM116: + 949 0014 84E6 ldi r24,lo8(100) + 950 0016 8093 0000 sts tickCntr.3566,r24 + 175:main.c **** arpTimer(); + 952 .LM117: + 953 001a 0C94 0000 jmp arpTimer + 958 .Lscope4: + 960 .stabd 78,0,0 + 961 .data + 964 tickCntr.3566: + 965 0000 64 .byte 100 + 966 .comm udpBuffers,4,1 + 967 .comm udpStream,14,1 + 968 .comm usbStream,14,1 + 969 .comm CLIStateSerialUdp,2,1 + 970 .comm CLIStateSerialUsb,2,1 + 971 .comm xHandleSensors,2,1 + 972 .comm xHandleEnc,2,1 + 973 .comm xHandleVTY_UDP,2,1 + 974 .comm xHandleVTY_USB,2,1 + 975 .comm voltage,1,1 + 976 .comm temperature,1,1 + 977 .comm xRs485Rec,2,1 + 978 .comm xRs485Tx,2,1 + 979 .comm xVtyRec,2,1 + 980 .comm xVtyTx,2,1 + 981 .global timer100Hz + 982 .section .bss + 985 timer100Hz: + 986 0000 00 .zero 1 + 987 .comm czasRtc,7,1 + 988 .comm sockets,2,1 + 989 .comm tcpDebugLevel,1,1 + 990 .comm tcpDebugStream,2,1 + 991 .comm IpMyConfig,15,1 + 992 .comm udpDbgLevel,1,1 + 993 .comm udpDbgStream,2,1 + 994 .comm udpSocket,2,1 + 995 .comm icmpDebugLevel,1,1 + 996 .comm icmpDebug,2,1 + 997 .comm arpDebugLevel,1,1 + 998 .comm arpDebug,2,1 + 999 .comm nicState,14,1 + 1000 .comm xSemaphoreRs485,2,1 + 1001 .comm lockSensors,2,1 + 1002 .comm portB,1,1 + 1003 .comm portA,1,1 + 1004 .comm xSemaphoreSpiSS,2,1 + 1005 .comm rollers,2,1 + 1006 .comm wwwport,1,1 + 1007 .comm klastry,128,1 + 1045 .text + 1047 .Letext0: + 1048 .ident "GCC: (GNU) 4.9.2" + 1049 .global __do_copy_data + 1050 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 main.c + /tmp/ccwA9pJ9.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccwA9pJ9.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccwA9pJ9.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccwA9pJ9.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccwA9pJ9.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccwA9pJ9.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccwA9pJ9.s:276 .init4:0000000000000000 initExternalMem + /tmp/ccwA9pJ9.s:760 .text.startup:0000000000000000 main + *COM*:0000000000000002 CLIStateSerialUsb + *COM*:0000000000000002 CLIStateSerialUdp + *COM*:000000000000000e usbStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000004 udpBuffers + *COM*:000000000000000e udpStream + *COM*:0000000000000002 xHandleVTY_USB + *COM*:0000000000000002 xHandleSensors + /tmp/ccwA9pJ9.s:907 .text:0000000000000000 vApplicationIdleHook + /tmp/ccwA9pJ9.s:930 .text:0000000000000006 vApplicationTickHook + /tmp/ccwA9pJ9.s:964 .data:0000000000000000 tickCntr.3566 + *COM*:0000000000000002 xHandleEnc + *COM*:0000000000000002 xHandleVTY_UDP + *COM*:0000000000000001 voltage + *COM*:0000000000000001 temperature + *COM*:0000000000000002 xRs485Rec + *COM*:0000000000000002 xRs485Tx + *COM*:0000000000000002 xVtyRec + *COM*:0000000000000002 xVtyTx + /tmp/ccwA9pJ9.s:985 .bss:0000000000000000 timer100Hz + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +ramDyskInit +hardwareInit +disableAllSpiDevices +spiInit +xSerialPortInitMinimal +xmalloc +sensorsTaskInit +loadConfiguration +initQueueStreamUSB +VtyInit +udpInit_0 +socketInit +initQueueStream +vTaskVTYusb +xTaskGenericCreate +sensorsTask +vTaskStartScheduler +vCoRoutineSchedule +arpTimer +__do_copy_data +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/netstack_task.c b/Projects/DidacticSystem/Adam/MainController/netstack_task.c new file mode 100644 index 0000000..d648e7a --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/netstack_task.c @@ -0,0 +1,157 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include "netstack_task.h" + + +/*uint16_t printHTMLstatus(char *buf, uint16_t pos, uint16_t maxPos) +{*/ +/* char *tmpPtr; + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "

Status

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

"SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), temperature); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp, L_KLASTROW); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Temperatura%d C
Napięcie na magistrali%d V
Liczba wolnych klastrów%d / %d

")); + + tmpPtr = getBufPosToWrite(buf, pos); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Czujniki rygli

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + for (tmp = 0; tmp < 4; tmp++) + { + if (lockSensors[tmp].enabled) + { + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp+1); + if (lockSensors[tmp].locked) + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + else + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), lockSensors[tmp].acVal, lockSensors[tmp].threshold); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + } + } + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Czujnik nrPołożenie ryglaOdczyt z przetwornika ACWart graniczna
%dzamkniętyotwarty%d%d

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Moduły wykonawcze

")); + return pos;*/ +// return 0; +// } + + +void encTask ( void *pvParameters ) +{ + FILE *netstackDebug = (FILE *) pvParameters; + uint16_t plen; + + nicInit(); + ipInit(); + arpInit(); + icmpInit(); + + + //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + + + for ( ; ; ) + { + vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebrzeniu przerwania od ENC + + // get the next new packet: + plen = nicPoll(); + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + { + flushUdpQueues(); + flushTcpQueues(); + //flush HTTP long file queue + continue; + } + + if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + { + arpIpIn(); + netstackIPv4Process(); + } + else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + { + arpArpIn(); + } + else + { + if (netstackDebug != NULL) + { + fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + } + } + + continue; + } +} + +#if 0 +// uint16_t dat_p; +// uint8_t cmd_pos=0; +// int8_t cmd; +// uint8_t payloadlen=0; +// char str[30]; +// char cmdval; + + + // arp is broadcast if unknown but a host may also + // verify the mac address by sending it to + // a unicast address. + if ( eth_type_is_arp_and_my_ip(Enc28j60_global.buf, plen)) + { + make_arp_answer_from_request(Enc28j60_global.buf); + continue; + } + + // IP - check if ip packets are for us: + if ( eth_type_is_ip_and_my_ip ( Enc28j60_global.buf,plen ) ==0 ) + continue; + + // PING + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_ICMP && Enc28j60_global.buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V ) + { + // a ping packet, let's send pong + make_echo_reply_from_request (Enc28j60_global.buf, plen); + continue; + } + + } + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_H_P]==MYTELNETPOERT_H + && (Enc28j60_global.buf[TCP_DST_PORT_L_P]>=MYTELNETPOERT_L || Enc28j60_global.buf[TCP_DST_PORT_L_P]<=MYTELNETPOERT_L + 20)) + { + processIpPacket(Enc28j60_global.buf); + continue; + } +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/netstack_task.h b/Projects/DidacticSystem/Adam/MainController/netstack_task.h new file mode 100644 index 0000000..a79a3a6 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/netstack_task.h @@ -0,0 +1,51 @@ +#ifndef ENC_TASK_H +#define ENC_TASK_H 1 + +#include +#include +#include +#include +#include + +#include "enc28j60.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" +#include "icmp.h" +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +//TODO add new task: http server +typedef enum +{ + URLramDysk, + URLsdDysk, + URLstatus, + URLerror +} urlSource_t; + + +extern struct lockerSensor *lockSensors; + +uint8_t verify_password(char *str); + +/** + * takes a string of url address and process it + * @param str - part of URL string + * @param [out] - filename or command + * @return http source (SD, RamDysk, status) + */ +urlSource_t analyse_get_url (const char *str, char *fname); + +/** + * Enc28j60 task + */ +void encTask(void *pvParameters); + +extern nicState_t nicState; +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/netstack_task.lst b/Projects/DidacticSystem/Adam/MainController/netstack_task.lst new file mode 100644 index 0000000..4e7a27a --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/netstack_task.lst @@ -0,0 +1,299 @@ + 1 .file "netstack_task.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 274 .global encTask + 276 encTask: + 277 .stabd 46,0,0 + 1:netstack_task.c **** /********************************************* + 2:netstack_task.c **** * vim:sw=8:ts=8:si:et + 3:netstack_task.c **** * To use the above modeline in vim you must have "set modeline" in your .vimrc + 4:netstack_task.c **** * Author: Guido Socher + 5:netstack_task.c **** * Copyright: GPL V2 + 6:netstack_task.c **** * See http://www.gnu.org/licenses/gpl.html + 7:netstack_task.c **** * + 8:netstack_task.c **** * Ethernet remote device and sensor + 9:netstack_task.c **** * UDP and HTTP interface + 10:netstack_task.c **** url looks like this http://baseurl/password/command + 11:netstack_task.c **** or http://baseurl/password/ + 12:netstack_task.c **** * + 13:netstack_task.c **** * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + 14:netstack_task.c **** * Note: there is a version number in the text. Search for tuxgraphics + 15:netstack_task.c **** *********************************************/ + 16:netstack_task.c **** #include "netstack_task.h" + 17:netstack_task.c **** + 18:netstack_task.c **** + 19:netstack_task.c **** /*uint16_t printHTMLstatus(char *buf, uint16_t pos, uint16_t maxPos) + 20:netstack_task.c **** {*/ + 21:netstack_task.c **** /* char *tmpPtr; + 22:netstack_task.c **** + 23:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "Status")); + 25:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

"SYSTEM_NAME" ver "S_VERSION" buil + 26:netstack_task.c **** + 27:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + 28:netstack_task.c **** + 29:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 30:netstack_task.c **** pos +=sprintf_P(tmpPtr, PSTR(""), temperature); + 31:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 32:netstack_task.c **** pos +=sprintf_P(tmpPtr, PSTR(""), voltage); + 33:netstack_task.c **** + 34:netstack_task.c **** uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + 35:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 36:netstack_task.c **** pos +=sprintf_P(tmpPtr, PSTR(""), tmp, + 37:netstack_task.c **** + 38:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Temperatura%d C
Napięcie na magistrali%d V
Liczba wolnych klastrów%d / %d

")); + 39:netstack_task.c **** + 40:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 41:netstack_task.c **** + 42:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Czujniki rygli

")); + 43:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + 44:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR (""), tmp+1); + 51:netstack_task.c **** if (lockSensors[tmp].locked) + 52:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + 53:netstack_task.c **** else + 54:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + 55:netstack_task.c **** + 56:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 57:netstack_task.c **** pos +=sprintf_P(tmpPtr, PSTR(""), lockSensors[tmp].acVal, lockSensors[t + 58:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + 59:netstack_task.c **** } + 60:netstack_task.c **** } + 61:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Czujnik nrPołożenie rygla + 45:netstack_task.c **** for (tmp = 0; tmp < 4; tmp++) + 46:netstack_task.c **** { + 47:netstack_task.c **** if (lockSensors[tmp].enabled) + 48:netstack_task.c **** { + 49:netstack_task.c **** tmpPtr = getBufPosToWrite(buf, pos); + 50:netstack_task.c **** pos +=sprintf_P(tmpPtr, PSTR("
%dzamkniętyotwarty%d%d

")); + 62:netstack_task.c **** + 63:netstack_task.c **** pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Moduły wykonawcze

")); + 64:netstack_task.c **** return pos;*/ + 65:netstack_task.c **** // return 0; + 66:netstack_task.c **** // } + 67:netstack_task.c **** + 68:netstack_task.c **** + 69:netstack_task.c **** void encTask ( void *pvParameters ) + 70:netstack_task.c **** { + 279 .LM0: + 280 .LFBB1: + 281 /* prologue: function */ + 282 /* frame size = 0 */ + 283 /* stack size = 0 */ + 284 .L__stack_usage = 0 + 285 0000 EC01 movw r28,r24 + 71:netstack_task.c **** FILE *netstackDebug = (FILE *) pvParameters; + 72:netstack_task.c **** uint16_t plen; + 73:netstack_task.c **** + 74:netstack_task.c **** nicInit(); + 287 .LM1: + 288 0002 0E94 0000 call nicInit + 75:netstack_task.c **** ipInit(); + 290 .LM2: + 291 0006 0E94 0000 call ipInit + 76:netstack_task.c **** arpInit(); + 293 .LM3: + 294 000a 0E94 0000 call arpInit + 77:netstack_task.c **** icmpInit(); + 296 .LM4: + 297 000e 0E94 0000 call icmpInit + 78:netstack_task.c **** + 79:netstack_task.c **** + 80:netstack_task.c **** //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + 81:netstack_task.c **** + 82:netstack_task.c **** + 83:netstack_task.c **** for ( ; ; ) + 84:netstack_task.c **** { + 85:netstack_task.c **** vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwo + 86:netstack_task.c **** + 87:netstack_task.c **** // get the next new packet: + 88:netstack_task.c **** plen = nicPoll(); + 89:netstack_task.c **** /*plen will ne unequal to zero if there is a valid + 90:netstack_task.c **** * packet (without crc error) */ + 91:netstack_task.c **** if ( plen==0 ) + 92:netstack_task.c **** { + 93:netstack_task.c **** flushUdpQueues(); + 94:netstack_task.c **** flushTcpQueues(); + 95:netstack_task.c **** //flush HTTP long file queue + 96:netstack_task.c **** continue; + 97:netstack_task.c **** } + 98:netstack_task.c **** + 99:netstack_task.c **** if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + 100:netstack_task.c **** { + 101:netstack_task.c **** arpIpIn(); + 102:netstack_task.c **** netstackIPv4Process(); + 103:netstack_task.c **** } + 104:netstack_task.c **** else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + 105:netstack_task.c **** { + 106:netstack_task.c **** arpArpIn(); + 107:netstack_task.c **** } + 108:netstack_task.c **** else + 109:netstack_task.c **** { + 110:netstack_task.c **** if (netstackDebug != NULL) + 111:netstack_task.c **** { + 112:netstack_task.c **** fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + 299 .LM5: + 300 0012 00E0 ldi r16,lo8(__c.3427) + 301 0014 10E0 ldi r17,hi8(__c.3427) + 302 .L2: + 85:netstack_task.c **** + 304 .LM6: + 305 0016 80E0 ldi r24,0 + 306 0018 90E0 ldi r25,0 + 307 001a 0E94 0000 call vTaskDelay + 88:netstack_task.c **** /*plen will ne unequal to zero if there is a valid + 309 .LM7: + 310 001e 0E94 0000 call nicPoll + 91:netstack_task.c **** { + 312 .LM8: + 313 0022 892B or r24,r25 + 314 0024 01F4 brne .L3 + 93:netstack_task.c **** flushTcpQueues(); + 316 .LM9: + 317 0026 0E94 0000 call flushUdpQueues + 94:netstack_task.c **** //flush HTTP long file queue + 319 .LM10: + 320 002a 0E94 0000 call flushTcpQueues + 96:netstack_task.c **** } + 322 .LM11: + 323 002e 00C0 rjmp .L2 + 324 .L3: + 99:netstack_task.c **** { + 326 .LM12: + 327 0030 E091 0000 lds r30,nicState+8 + 328 0034 F091 0000 lds r31,nicState+8+1 + 329 0038 E484 ldd r14,Z+12 + 330 003a F584 ldd r15,Z+13 + 331 003c 80E0 ldi r24,0 + 332 003e 98E0 ldi r25,lo8(8) + 333 0040 0E94 0000 call htons + 334 0044 E816 cp r14,r24 + 335 0046 F906 cpc r15,r25 + 336 0048 01F4 brne .L5 + 101:netstack_task.c **** netstackIPv4Process(); + 338 .LM13: + 339 004a 0E94 0000 call arpIpIn + 102:netstack_task.c **** } + 341 .LM14: + 342 004e 0E94 0000 call netstackIPv4Process + 343 0052 00C0 rjmp .L2 + 344 .L5: + 104:netstack_task.c **** { + 346 .LM15: + 347 0054 E091 0000 lds r30,nicState+8 + 348 0058 F091 0000 lds r31,nicState+8+1 + 349 005c E484 ldd r14,Z+12 + 350 005e F584 ldd r15,Z+13 + 351 0060 86E0 ldi r24,lo8(6) + 352 0062 98E0 ldi r25,lo8(8) + 353 0064 0E94 0000 call htons + 354 0068 E816 cp r14,r24 + 355 006a F906 cpc r15,r25 + 356 006c 01F4 brne .L6 + 106:netstack_task.c **** } + 358 .LM16: + 359 006e 0E94 0000 call arpArpIn + 360 0072 00C0 rjmp .L2 + 361 .L6: + 110:netstack_task.c **** { + 363 .LM17: + 364 0074 2097 sbiw r28,0 + 365 0076 01F0 breq .L2 + 367 .LM18: + 368 0078 1F93 push r17 + 369 007a 0F93 push r16 + 370 007c DF93 push r29 + 371 007e CF93 push r28 + 372 0080 0E94 0000 call fprintf_P + 373 0084 0F90 pop __tmp_reg__ + 374 0086 0F90 pop __tmp_reg__ + 375 0088 0F90 pop __tmp_reg__ + 376 008a 0F90 pop __tmp_reg__ + 377 008c 00C0 rjmp .L2 + 379 .Lscope1: + 381 .stabd 78,0,0 + 382 .section .progmem.data,"a",@progbits + 385 __c.3427: + 386 0000 556E 6B6E .string "Unknown packet\r\n" + 386 6F77 6E20 + 386 7061 636B + 386 6574 0D0A + 386 00 + 387 .comm czasRtc,7,1 + 388 .comm sockets,2,1 + 389 .comm tcpDebugLevel,1,1 + 390 .comm tcpDebugStream,2,1 + 391 .comm IpMyConfig,15,1 + 392 .comm udpDbgLevel,1,1 + 393 .comm udpDbgStream,2,1 + 394 .comm udpSocket,2,1 + 395 .comm icmpDebugLevel,1,1 + 396 .comm icmpDebug,2,1 + 397 .comm arpDebugLevel,1,1 + 398 .comm arpDebug,2,1 + 399 .comm nicState,14,1 + 400 .comm xSemaphoreRs485,2,1 + 401 .comm lockSensors,2,1 + 402 .comm portB,1,1 + 403 .comm portA,1,1 + 404 .comm xSemaphoreSpiSS,2,1 + 405 .comm rollers,2,1 + 406 .comm wwwport,1,1 + 407 .comm klastry,128,1 + 429 .weak nicPoll + 430 .text + 432 .Letext0: + 433 .ident "GCC: (GNU) 4.9.2" + 434 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 netstack_task.c + /tmp/ccc7lghF.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccc7lghF.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccc7lghF.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccc7lghF.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/ccc7lghF.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccc7lghF.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccc7lghF.s:276 .text:0000000000000000 encTask + /tmp/ccc7lghF.s:385 .progmem.data:0000000000000000 __c.3427 + *COM*:000000000000000e nicState + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +nicInit +ipInit +arpInit +icmpInit +vTaskDelay +nicPoll +flushUdpQueues +flushTcpQueues +htons +arpIpIn +netstackIPv4Process +arpArpIn +fprintf_P +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/rtc.c b/Projects/DidacticSystem/Adam/MainController/rtc.c new file mode 100644 index 0000000..bf54760 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/rtc.c @@ -0,0 +1,259 @@ +/*--------------------------------------------------------------------------*/ +/* RTC controls */ + +#include +#include +#include "rtc.h" + + + +#define SCL_LOW() DDRE |= 0x04 /* SCL = LOW */ +#define SCL_HIGH() DDRE &= 0xFB /* SCL = High-Z */ +#define SCL_VAL ((PINE & 0x04) ? 1 : 0) /* SCL input level */ +#define SDA_LOW() DDRE |= 0x08 /* SDA = LOW */ +#define SDA_HIGH() DDRE &= 0xF7 /* SDA = High-Z */ +#define SDA_VAL ((PINE & 0x08) ? 1 : 0) /* SDA input level */ + + + +/*-------------------------------------------------*/ +/* I2C bus protocol */ + + +static +void iic_delay (void) +{ + int n; + + for (n = 4; n; n--) PINB; +} + + +/* Generate start condition on the IIC bus */ +static +void iic_start (void) +{ + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_LOW(); + iic_delay(); + SCL_LOW(); + iic_delay(); +} + + +/* Generate stop condition on the IIC bus */ +static +void iic_stop (void) +{ + SDA_LOW(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_HIGH(); + iic_delay(); +} + + +/* Send a byte to the IIC bus */ +static +int iic_send (BYTE dat) +{ + BYTE b = 0x80; + int ack; + + + do { + if (dat & b) { /* SDA = Z/L */ + SDA_HIGH(); + } else { + SDA_LOW(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (b >>= 1); + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + ack = SDA_VAL ? 0 : 1; /* Sample ACK */ + iic_delay(); + SCL_LOW(); + iic_delay(); + return ack; +} + + +/* Receive a byte from the IIC bus */ +static +BYTE iic_rcvr (int ack) +{ + UINT d = 1; + + + do { + d <<= 1; + SCL_HIGH(); + if (SDA_VAL) d++; + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (d < 0x100); + if (ack) { /* SDA = ACK */ + SDA_LOW(); + } else { + SDA_HIGH(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + SDA_HIGH(); + iic_delay(); + + return (BYTE)d; +} + + + +/*-------------------------------------------------*/ +/* I2C block read/write controls */ + + +int iic_read ( + BYTE dev, /* Device address */ + UINT adr, /* Read start address */ + UINT cnt, /* Read byte count */ + void* buff /* Read data buffer */ +) +{ + BYTE *rbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + iic_start(); /* Reselect device in read mode */ + if (iic_send(dev | 1)) { + do { /* Receive data */ + cnt--; + *rbuff++ = iic_rcvr(cnt ? 1 : 0); + } while (cnt); + } + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +int iic_write ( + BYTE dev, /* Device address */ + UINT adr, /* Write start address */ + UINT cnt, /* Write byte count */ + const void* buff /* Data to be written */ +) +{ + const BYTE *wbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + do { /* Send data */ + if (!iic_send(*wbuff++)) break; + } while (--cnt); + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +/*-------------------------------------------------*/ +/* RTC functions */ + + +int rtc_gettime (RTC *rtc) +{ + BYTE buf[8]; + + + if (!iic_read(0xD0, 0, 7, buf)) return 0; + + rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10; + rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10; + rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10; + rtc->wday = (buf[2] & 0x07); + rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10; + rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10; + rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10; + + return 1; +} + + + + +int rtc_settime (const RTC *rtc) +{ + + BYTE buf[8]; + + + buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10; + buf[1] = rtc->min / 10 * 16 + rtc->min % 10; + buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10; + buf[3] = rtc->wday & 7; + buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10; + buf[5] = rtc->month / 10 * 16 + rtc->month % 10; + buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10; + return iic_write(0xD0, 0, 7, buf); +} + + + + +int rtc_init (void) +{ + BYTE buf[8]; /* RTC R/W buffer */ + UINT adr; + + + /* Read RTC registers */ + if (!iic_read(0xD0, 0, 8, buf)) return 0; /* IIC error */ + + if (buf[7] & 0x20) { /* When data has been volatiled, set default time */ + /* Clear nv-ram. Reg[8..63] */ + memset(buf, 0, 8); + for (adr = 8; adr < 64; adr += 8) + iic_write(0x0D, adr, 8, buf); + /* Reset time to Jan 1, '08. Reg[0..7] */ + buf[4] = 1; buf[5] = 1; buf[6] = 8; + iic_write(0x0D, 0, 8, buf); + } + return 1; +} + diff --git a/Projects/DidacticSystem/Adam/MainController/rtc.h b/Projects/DidacticSystem/Adam/MainController/rtc.h new file mode 100644 index 0000000..4642685 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/rtc.h @@ -0,0 +1,19 @@ +#include "integer.h" + +typedef struct { + WORD year; /* 2000..2099 */ + BYTE month; /* 1..12 */ + BYTE mday; /* 1.. 31 */ + BYTE wday; /* 1..7 */ + BYTE hour; /* 0..23 */ + BYTE min; /* 0..59 */ + BYTE sec; /* 0..59 */ +} RTC; + +int iic_write (BYTE, UINT, UINT, const void*); /* Write to IIC device */ +int iic_read (BYTE, UINT, UINT, void*); /* Read from IIC device */ + +int rtc_init (void); /* Initialize RTC */ +int rtc_gettime (RTC*); /* Get time */ +int rtc_settime (const RTC*); /* Set time */ + diff --git a/Projects/DidacticSystem/Adam/MainController/sensors_task.c b/Projects/DidacticSystem/Adam/MainController/sensors_task.c new file mode 100644 index 0000000..602b879 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/sensors_task.c @@ -0,0 +1,81 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include +#include +#include "sensors_task.h" +#include "memory_x.h" +#include "main.h" +#include "Rs485_prot.h" +#include "protocol1.h" +#include "mpc23s17.h" + + + +void sensorsTaskInit(void) +{ + LockersMemInit(); + rollersMemInit(); +} + +void sensorsTask(void* pvParameters) +{ + (void) pvParameters; + uint8_t addr = 255; +// uint8_t i; + + MPC23s17SetDirA(0x00, 0); + + MPC23s17SetDirB(0x00, 0); + + for( ; ; ) + { + uint16_t tmp; + //Read power suply voltage + tmp = MCP3008_getSampleSingle(0); + voltage = (uint8_t)(tmp>>5); + vTaskDelay(10); + + //Read temperature inside chasis + tmp = MCP3008_getSampleSingle(1); + tmp *=10; + temperature = (uint8_t)(tmp / 24); + vTaskDelay(10); + + //read lock + checkLockerSensors(); + + for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + { + rs485rollerHello(addr); + vTaskDelay(10); + } + + for (addr = FIRST_LIGHT_DRIVER_ADDR; addr <= LAST_LIGHT_DRIVER_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + + for (addr = FIRST_SENSOR_ADDR; addr <= LAST_SENSOR_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + } +} diff --git a/Projects/DidacticSystem/Adam/MainController/sensors_task.h b/Projects/DidacticSystem/Adam/MainController/sensors_task.h new file mode 100644 index 0000000..05b0780 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/sensors_task.h @@ -0,0 +1,51 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include + +#include "main.h" +#include "memory_x.h" +#include "Rs485_prot.h" + +#ifndef SENSORS_TASK_H +#define SENSORS_TASK_H + + + + +#define NOT_DETECTED 0x01 +#define BOOTLOADER_MODE 0x02 +#define NEW_STATE 0x04 +#define RESERVED 0x08 +#define ROLLER1_UP 0x10 +#define ROLLER1_DOWN 0x20 +#define ROLLER2_UP 0x40 +#define ROLLER2_DOWN 0x80 + + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + + + + +void sensorsTaskInit(void); + +void sensorsTask(void *pvParameters); + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/sensors_task.lst b/Projects/DidacticSystem/Adam/MainController/sensors_task.lst new file mode 100644 index 0000000..9fba2fa --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/sensors_task.lst @@ -0,0 +1,242 @@ + 1 .file "sensors_task.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 271 .global sensorsTaskInit + 273 sensorsTaskInit: + 274 .stabd 46,0,0 + 1:sensors_task.c **** /********************************************* + 2:sensors_task.c **** * vim:sw=8:ts=8:si:et + 3:sensors_task.c **** * To use the above modeline in vim you must have "set modeline" in your .vimrc + 4:sensors_task.c **** * Author: Guido Socher + 5:sensors_task.c **** * Copyright: GPL V2 + 6:sensors_task.c **** * See http://www.gnu.org/licenses/gpl.html + 7:sensors_task.c **** * + 8:sensors_task.c **** * Ethernet remote device and sensor + 9:sensors_task.c **** * UDP and HTTP interface + 10:sensors_task.c **** url looks like this http://baseurl/password/command + 11:sensors_task.c **** or http://baseurl/password/ + 12:sensors_task.c **** * + 13:sensors_task.c **** * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + 14:sensors_task.c **** * Note: there is a version number in the text. Search for tuxgraphics + 15:sensors_task.c **** *********************************************/ + 16:sensors_task.c **** #include + 17:sensors_task.c **** #include + 18:sensors_task.c **** #include + 19:sensors_task.c **** #include + 20:sensors_task.c **** #include + 21:sensors_task.c **** #include "sensors_task.h" + 22:sensors_task.c **** #include "memory_x.h" + 23:sensors_task.c **** #include "main.h" + 24:sensors_task.c **** #include "Rs485_prot.h" + 25:sensors_task.c **** #include "protocol1.h" + 26:sensors_task.c **** #include "mpc23s17.h" + 27:sensors_task.c **** + 28:sensors_task.c **** + 29:sensors_task.c **** + 30:sensors_task.c **** void sensorsTaskInit(void) + 31:sensors_task.c **** { + 276 .LM0: + 277 .LFBB1: + 278 /* prologue: function */ + 279 /* frame size = 0 */ + 280 /* stack size = 0 */ + 281 .L__stack_usage = 0 + 32:sensors_task.c **** LockersMemInit(); + 283 .LM1: + 284 0000 0E94 0000 call LockersMemInit + 33:sensors_task.c **** rollersMemInit(); + 286 .LM2: + 287 0004 0C94 0000 jmp rollersMemInit + 289 .Lscope1: + 291 .stabd 78,0,0 + 294 .global sensorsTask + 296 sensorsTask: + 297 .stabd 46,0,0 + 34:sensors_task.c **** } + 35:sensors_task.c **** + 36:sensors_task.c **** void sensorsTask(void* pvParameters) + 37:sensors_task.c **** { + 299 .LM3: + 300 .LFBB2: + 301 /* prologue: function */ + 302 /* frame size = 0 */ + 303 /* stack size = 0 */ + 304 .L__stack_usage = 0 + 38:sensors_task.c **** (void) pvParameters; + 39:sensors_task.c **** uint8_t addr = 255; + 40:sensors_task.c **** // uint8_t i; + 41:sensors_task.c **** + 42:sensors_task.c **** MPC23s17SetDirA(0x00, 0); + 306 .LM4: + 307 0008 60E0 ldi r22,0 + 308 000a 80E0 ldi r24,0 + 309 000c 0E94 0000 call MPC23s17SetDirA + 43:sensors_task.c **** + 44:sensors_task.c **** MPC23s17SetDirB(0x00, 0); + 311 .LM5: + 312 0010 60E0 ldi r22,0 + 313 0012 80E0 ldi r24,0 + 314 0014 0E94 0000 call MPC23s17SetDirB + 315 .LBB2: + 45:sensors_task.c **** + 46:sensors_task.c **** for( ; ; ) + 47:sensors_task.c **** { + 48:sensors_task.c **** uint16_t tmp; + 49:sensors_task.c **** //Read power suply voltage + 50:sensors_task.c **** tmp = MCP3008_getSampleSingle(0); + 51:sensors_task.c **** voltage = (uint8_t)(tmp>>5); + 52:sensors_task.c **** vTaskDelay(10); + 53:sensors_task.c **** + 54:sensors_task.c **** //Read temperature inside chasis + 55:sensors_task.c **** tmp = MCP3008_getSampleSingle(1); + 56:sensors_task.c **** tmp *=10; + 317 .LM6: + 318 0018 DAE0 ldi r29,lo8(10) + 57:sensors_task.c **** temperature = (uint8_t)(tmp / 24); + 320 .LM7: + 321 001a 08E1 ldi r16,lo8(24) + 322 001c 10E0 ldi r17,0 + 323 .L4: + 50:sensors_task.c **** voltage = (uint8_t)(tmp>>5); + 325 .LM8: + 326 001e 80E0 ldi r24,0 + 327 0020 0E94 0000 call MCP3008_getSampleSingle + 51:sensors_task.c **** vTaskDelay(10); + 329 .LM9: + 330 0024 25E0 ldi r18,5 + 331 1: + 332 0026 9695 lsr r25 + 333 0028 8795 ror r24 + 334 002a 2A95 dec r18 + 335 002c 01F4 brne 1b + 336 002e 8093 0000 sts voltage,r24 + 52:sensors_task.c **** + 338 .LM10: + 339 0032 8AE0 ldi r24,lo8(10) + 340 0034 90E0 ldi r25,0 + 341 0036 0E94 0000 call vTaskDelay + 55:sensors_task.c **** tmp *=10; + 343 .LM11: + 344 003a 81E0 ldi r24,lo8(1) + 345 003c 0E94 0000 call MCP3008_getSampleSingle + 56:sensors_task.c **** temperature = (uint8_t)(tmp / 24); + 347 .LM12: + 348 0040 9C01 movw r18,r24 + 349 0042 D29F mul r29,r18 + 350 0044 C001 movw r24,r0 + 351 0046 D39F mul r29,r19 + 352 0048 900D add r25,r0 + 353 004a 1124 clr __zero_reg__ + 355 .LM13: + 356 004c B801 movw r22,r16 + 357 004e 0E94 0000 call __udivmodhi4 + 358 0052 6093 0000 sts temperature,r22 + 58:sensors_task.c **** vTaskDelay(10); + 360 .LM14: + 361 0056 8AE0 ldi r24,lo8(10) + 362 0058 90E0 ldi r25,0 + 363 005a 0E94 0000 call vTaskDelay + 59:sensors_task.c **** + 60:sensors_task.c **** //read lock + 61:sensors_task.c **** checkLockerSensors(); + 365 .LM15: + 366 005e 0E94 0000 call checkLockerSensors + 62:sensors_task.c **** + 63:sensors_task.c **** for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + 368 .LM16: + 369 0062 C1E0 ldi r28,lo8(1) + 370 .L3: + 64:sensors_task.c **** { + 65:sensors_task.c **** rs485rollerHello(addr); + 372 .LM17: + 373 0064 8C2F mov r24,r28 + 374 0066 0E94 0000 call rs485rollerHello + 66:sensors_task.c **** vTaskDelay(10); + 376 .LM18: + 377 006a 8AE0 ldi r24,lo8(10) + 378 006c 90E0 ldi r25,0 + 379 006e 0E94 0000 call vTaskDelay + 63:sensors_task.c **** { + 381 .LM19: + 382 0072 CF5F subi r28,lo8(-(1)) + 383 0074 C032 cpi r28,lo8(32) + 384 0076 01F4 brne .L3 + 385 0078 00C0 rjmp .L4 + 386 .LBE2: + 391 .Lscope2: + 393 .stabd 78,0,0 + 394 .comm czasRtc,7,1 + 395 .comm sockets,2,1 + 396 .comm tcpDebugLevel,1,1 + 397 .comm tcpDebugStream,2,1 + 398 .comm IpMyConfig,15,1 + 399 .comm udpDbgLevel,1,1 + 400 .comm udpDbgStream,2,1 + 401 .comm udpSocket,2,1 + 402 .comm icmpDebugLevel,1,1 + 403 .comm icmpDebug,2,1 + 404 .comm arpDebugLevel,1,1 + 405 .comm arpDebug,2,1 + 406 .comm nicState,14,1 + 407 .comm xSemaphoreRs485,2,1 + 408 .comm lockSensors,2,1 + 409 .comm portB,1,1 + 410 .comm portA,1,1 + 411 .comm xSemaphoreSpiSS,2,1 + 412 .comm rollers,2,1 + 413 .comm wwwport,1,1 + 414 .comm klastry,128,1 + 437 .Letext0: + 438 .ident "GCC: (GNU) 4.9.2" + 439 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 sensors_task.c + /tmp/cc4MDYtp.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cc4MDYtp.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cc4MDYtp.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cc4MDYtp.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cc4MDYtp.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cc4MDYtp.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cc4MDYtp.s:273 .text:0000000000000000 sensorsTaskInit + /tmp/cc4MDYtp.s:296 .text:0000000000000008 sensorsTask + *COM*:0000000000000007 czasRtc + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000002 udpSocket + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:000000000000000e nicState + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +LockersMemInit +rollersMemInit +MPC23s17SetDirA +MPC23s17SetDirB +MCP3008_getSampleSingle +voltage +vTaskDelay +__udivmodhi4 +temperature +checkLockerSensors +rs485rollerHello +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/serial.c b/Projects/DidacticSystem/Adam/MainController/serial.c new file mode 100644 index 0000000..f143608 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/serial.c @@ -0,0 +1,186 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + return 0; +} + +void xSerialPortInitMinimal(void) +{ + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xRs485Rec = xQueueCreate( 16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xRs485Tx = xQueueCreate( 4, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + vSemaphoreCreateBinary(xSemaphoreRs485); + } + portEXIT_CRITICAL(); + + UBRR0L = 7; + UBRR0H = 0; + + UBRR1L = 7; + UBRR1H = 0; + + UCSR0B = ((1< + 2:serial.c **** #include + 3:serial.c **** #include "FreeRTOS.h" + 4:serial.c **** #include "queue.h" + 5:serial.c **** #include "task.h" + 6:serial.c **** #include "serial.h" + 7:serial.c **** #include "hardware.h" + 8:serial.c **** + 9:serial.c **** #define debug 1 + 10:serial.c **** + 11:serial.c **** /*-----------------------------------------------------------*/ + 12:serial.c **** + 13:serial.c **** void initQueueStreamUSB(FILE *stream) + 14:serial.c **** { + 15:serial.c **** fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + 16:serial.c **** fdev_set_udata(stream, NULL); + 17:serial.c **** return; + 18:serial.c **** } + 19:serial.c **** + 20:serial.c **** int VtyGetChar(FILE *stream) + 21:serial.c **** { + 281 .LM0: + 282 .LFBB1: + 283 0000 CF93 push r28 + 284 0002 DF93 push r29 + 285 0004 1F92 push __zero_reg__ + 286 0006 CDB7 in r28,__SP_L__ + 287 0008 DEB7 in r29,__SP_H__ + 288 /* prologue: function */ + 289 /* frame size = 1 */ + 290 /* stack size = 3 */ + 291 .L__stack_usage = 3 + 22:serial.c **** (void) stream; + 23:serial.c **** uint8_t c; + 24:serial.c **** if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + 293 .LM1: + 294 000a 20E0 ldi r18,0 + 295 000c 4FEF ldi r20,lo8(-1) + 296 000e 5FEF ldi r21,lo8(-1) + 297 0010 BE01 movw r22,r28 + 298 0012 6F5F subi r22,-1 + 299 0014 7F4F sbci r23,-1 + 300 0016 8091 0000 lds r24,xVtyRec + 301 001a 9091 0000 lds r25,xVtyRec+1 + 302 001e 0E94 0000 call xQueueGenericReceive + 303 0022 8823 tst r24 + 304 0024 01F0 breq .L3 + 25:serial.c **** return EOF; + 26:serial.c **** return c; + 306 .LM2: + 307 0026 8981 ldd r24,Y+1 + 308 0028 90E0 ldi r25,0 + 309 002a 00C0 rjmp .L2 + 310 .L3: + 25:serial.c **** return EOF; + 312 .LM3: + 313 002c 8FEF ldi r24,lo8(-1) + 314 002e 9FEF ldi r25,lo8(-1) + 315 .L2: + 316 /* epilogue start */ + 27:serial.c **** } + 318 .LM4: + 319 0030 0F90 pop __tmp_reg__ + 320 0032 DF91 pop r29 + 321 0034 CF91 pop r28 + 322 0036 0895 ret + 327 .Lscope1: + 329 .stabd 78,0,0 + 332 .global initQueueStreamUSB + 334 initQueueStreamUSB: + 335 .stabd 46,0,0 + 14:serial.c **** fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + 337 .LM5: + 338 .LFBB2: + 339 /* prologue: function */ + 340 /* frame size = 0 */ + 341 /* stack size = 0 */ + 342 .L__stack_usage = 0 + 343 0038 FC01 movw r30,r24 + 15:serial.c **** fdev_set_udata(stream, NULL); + 345 .LM6: + 346 003a 80E0 ldi r24,lo8(gs(VtyPutChar)) + 347 003c 90E0 ldi r25,hi8(gs(VtyPutChar)) + 348 003e 9187 std Z+9,r25 + 349 0040 8087 std Z+8,r24 + 350 0042 80E0 ldi r24,lo8(gs(VtyGetChar)) + 351 0044 90E0 ldi r25,hi8(gs(VtyGetChar)) + 352 0046 9387 std Z+11,r25 + 353 0048 8287 std Z+10,r24 + 354 004a 83E0 ldi r24,lo8(3) + 355 004c 8383 std Z+3,r24 + 356 004e 1586 std Z+13,__zero_reg__ + 357 0050 1486 std Z+12,__zero_reg__ + 358 0052 0895 ret + 360 .Lscope2: + 362 .stabd 78,0,0 + 364 .global xSerialPortInitMinimal + 366 xSerialPortInitMinimal: + 367 .stabd 46,0,0 + 28:serial.c **** + 29:serial.c **** int VtyPutChar(char c, FILE *stream) + 30:serial.c **** { + 31:serial.c **** (void) stream; + 32:serial.c **** uartVtySendByte(c); + 33:serial.c **** return 0; + 34:serial.c **** } + 35:serial.c **** + 36:serial.c **** void xSerialPortInitMinimal(void) + 37:serial.c **** { + 369 .LM7: + 370 .LFBB3: + 371 /* prologue: function */ + 372 /* frame size = 0 */ + 373 /* stack size = 0 */ + 374 .L__stack_usage = 0 + 38:serial.c **** portENTER_CRITICAL(); + 376 .LM8: + 377 /* #APP */ + 378 ; 38 "serial.c" 1 + 379 0054 0FB6 in __tmp_reg__, __SREG__ + 380 ; 0 "" 2 + 381 ; 38 "serial.c" 1 + 382 0056 F894 cli + 383 ; 0 "" 2 + 384 ; 38 "serial.c" 1 + 385 0058 0F92 push __tmp_reg__ + 386 ; 0 "" 2 + 39:serial.c **** { + 40:serial.c **** xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + 388 .LM9: + 389 /* #NOAPP */ + 390 005a 61E0 ldi r22,lo8(1) + 391 005c 80E4 ldi r24,lo8(64) + 392 005e 0E94 0000 call xQueueCreate + 393 0062 9093 0000 sts xVtyRec+1,r25 + 394 0066 8093 0000 sts xVtyRec,r24 + 41:serial.c **** xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + 396 .LM10: + 397 006a 61E0 ldi r22,lo8(1) + 398 006c 80E2 ldi r24,lo8(32) + 399 006e 0E94 0000 call xQueueCreate + 400 0072 9093 0000 sts xVtyTx+1,r25 + 401 0076 8093 0000 sts xVtyTx,r24 + 42:serial.c **** xRs485Rec = xQueueCreate( 16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + 403 .LM11: + 404 007a 61E0 ldi r22,lo8(1) + 405 007c 80E1 ldi r24,lo8(16) + 406 007e 0E94 0000 call xQueueCreate + 407 0082 9093 0000 sts xRs485Rec+1,r25 + 408 0086 8093 0000 sts xRs485Rec,r24 + 43:serial.c **** xRs485Tx = xQueueCreate( 4, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + 410 .LM12: + 411 008a 61E0 ldi r22,lo8(1) + 412 008c 84E0 ldi r24,lo8(4) + 413 008e 0E94 0000 call xQueueCreate + 414 0092 9093 0000 sts xRs485Tx+1,r25 + 415 0096 8093 0000 sts xRs485Tx,r24 + 44:serial.c **** + 45:serial.c **** vSemaphoreCreateBinary(xSemaphoreRs485); + 417 .LM13: + 418 009a 60E0 ldi r22,0 + 419 009c 81E0 ldi r24,lo8(1) + 420 009e 0E94 0000 call xQueueCreate + 421 00a2 9093 0000 sts xSemaphoreRs485+1,r25 + 422 00a6 8093 0000 sts xSemaphoreRs485,r24 + 423 00aa 0097 sbiw r24,0 + 424 00ac 01F0 breq .L7 + 426 .LM14: + 427 00ae 20E0 ldi r18,0 + 428 00b0 40E0 ldi r20,0 + 429 00b2 50E0 ldi r21,0 + 430 00b4 60E0 ldi r22,0 + 431 00b6 70E0 ldi r23,0 + 432 00b8 0E94 0000 call xQueueGenericSend + 433 .L7: + 46:serial.c **** } + 47:serial.c **** portEXIT_CRITICAL(); + 435 .LM15: + 436 /* #APP */ + 437 ; 47 "serial.c" 1 + 438 00bc 0F90 pop __tmp_reg__ + 439 ; 0 "" 2 + 440 ; 47 "serial.c" 1 + 441 00be 0FBE out __SREG__, __tmp_reg__ + 442 ; 0 "" 2 + 48:serial.c **** + 49:serial.c **** UBRR0L = 7; + 444 .LM16: + 445 /* #NOAPP */ + 446 00c0 87E0 ldi r24,lo8(7) + 447 00c2 89B9 out 0x9,r24 + 50:serial.c **** UBRR0H = 0; + 449 .LM17: + 450 00c4 1092 9000 sts 144,__zero_reg__ + 51:serial.c **** + 52:serial.c **** UBRR1L = 7; + 452 .LM18: + 453 00c8 8093 9900 sts 153,r24 + 53:serial.c **** UBRR1H = 0; + 455 .LM19: + 456 00cc 1092 9800 sts 152,__zero_reg__ + 54:serial.c **** + 55:serial.c **** UCSR0B = ((1< + +/* ************ Debug options ***************************************** */ +#define UDP_DEBUG 1 +#define IP_DEBUG 1 +#define ARP_DEBUG 1 +#define ICMP_DEBUG 1 +#define TCP_DEBUG 1 + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +#define MAX_NUMBER_OF_ROLLERS 10 + + +/* maximum number of TCP connections */ +#define NUMBER_OF_SOCKETS 20 + +/* CLI */ +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + +/* Telnet */ +#define MYTELNETPOERT 25000 + + +uint8_t wwwport; // 80 is just a default value. Gets overwritten during init +//int16_t info_hdr_len=0; +//int16_t info_data_len=0; + + +#define SEQNUM 0xFA000000; // my initial tcp sequence number + +#define ARP_TABLE_SIZE 10 +#define ARP_CACHE_TIME_TO_LIVE 128 + + +#define MYWWWPORT 80 +#define MYTELNETPORT 23 +#define MYUDPPORT 1200 + +#define MY_IP1 192 +#define MY_IP2 168 +#define MY_IP3 0 +#define MY_IP4 2 + +#define MY_GW1 192 +#define MY_GW2 168 +#define MY_GW3 0 +#define MY_GW4 1 + +#define MY_MASK1 255 +#define MY_MASK2 255 +#define MY_MASK3 255 +#define MY_MASK4 0 + +#define UDP_SRC_PORT 3000 +#define UDP_DST_PORT 0 + +#define UDP_DST_IP1 192 +#define UDP_DST_IP2 168 +#define UDP_DST_IP3 0 +#define UDP_DST_IP4 1 + +#define MAC_ADR1 0x12 +#define MAC_ADR2 0x34 +#define MAC_ADR3 0x56 +#define MAC_ADR4 0x78 +#define MAC_ADR5 0x9A +#define MAC_ADR6 0xBC + + + +//#define NUMBER_OF_UDP_SOCK + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/sterownikGlowny.cbp b/Projects/DidacticSystem/Adam/MainController/sterownikGlowny.cbp new file mode 100644 index 0000000..2866a41 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/sterownikGlowny.cbp @@ -0,0 +1,136 @@ + + + + + + diff --git a/Projects/DidacticSystem/Adam/MainController/vty.c b/Projects/DidacticSystem/Adam/MainController/vty.c new file mode 100644 index 0000000..2856573 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/vty.c @@ -0,0 +1,985 @@ +#include "main.h" +#include "vty.h" +#include "ramdysk.h" +#include "protocol1.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "softwareConfig.h" +#include "mcp4150.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t statusEncFunction (cmdState_t *state); +static cliExRes_t curtainDownFunction (cmdState_t *state); +static cliExRes_t curtainUpFunction (cmdState_t *state); +static cliExRes_t rpingFunction (cmdState_t *state); +static cliExRes_t pingFunction (cmdState_t *state); +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state); +static cliExRes_t goXmodemWyslijFunction (cmdState_t *state); +static cliExRes_t dodajRamPlikFunction (cmdState_t *state); +static cliExRes_t eraseRamFileFunction (cmdState_t *state); +static cliExRes_t flashExModuleFunction (cmdState_t *state); +static cliExRes_t writeRamFileFunction (cmdState_t *state); +static cliExRes_t editRamFileFunction (cmdState_t *state); +static cliExRes_t readRamFIleFunction (cmdState_t *state); + +static cliExRes_t ustawPortExtAFunction (cmdState_t *state); +static cliExRes_t ustawPortExtBFunction (cmdState_t *state); +static cliExRes_t ustawPortRezystor (cmdState_t *state); + +static cliExRes_t ustawModWykFunction (cmdState_t *state); +static cliExRes_t zapiszModWykFunction (cmdState_t *state); + +static cliExRes_t pokazCzasFunction (cmdState_t *state); +static cliExRes_t debugFunction (cmdState_t *state); +static cliExRes_t czytajAC_Function (cmdState_t *state); + +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +static cliExRes_t setIpFunction(cmdState_t *state); +static cliExRes_t setIpMaskFunction(cmdState_t *state); +static cliExRes_t setIpGwFunction(cmdState_t *state); +static cliExRes_t setUdpFunction(cmdState_t *state); + +static cliExRes_t setMacAddrFunction (cmdState_t *state); +static cliExRes_t setTimeFunction (cmdState_t *state); + +static cliExRes_t saveConfigFunction (cmdState_t *state); + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction (cmdState_t *state); +#endif + +struct ramPlikFd fdVty; //TODO move it to CLI struct + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; +const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + + +const char * const errorStrings[] PROGMEM = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enc_stat, cmd_help_enc_stat, statusEncFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_net_dbg, cmd_help_net_dbg, debugFunction}, + + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_xRec, cmd_help_xRec, goXmodemOdbierzFunction}, + {cmd_xSend, cmd_help_xSend, goXmodemWyslijFunction}, + {cmd_xflash, cmd_help_xflash, flashExModuleFunction}, +#ifdef testZewPamiec + {cmd_rtest, cmd_help_rtest, testPamZewFunction}, +#endif + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_create_rf, cmd_help_create_rf, dodajRamPlikFunction}, + {cmd_erase_rf, cmd_help_erase_rf, eraseRamFileFunction}, + {cmd_edit_rf, cmd_help_edit_rf, editRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + + {cmd_up, cmd_help_up, curtainUpFunction}, + {cmd_down, cmd_help_down, curtainDownFunction}, + + {cmd_spa, cmd_help_spa, ustawPortExtAFunction}, + {cmd_spb, cmd_help_spb, ustawPortExtBFunction}, + {cmd_ustawR, cmd_help_ustawR, ustawPortRezystor}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_ac, cmd_help_ac, czytajAC_Function}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {cmd_ustawMW, cmd_help_ustawMW, ustawModWykFunction}, + {cmd_zapiszMW, cmd_help_zapiszMW, zapiszModWykFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_conf_ip, cmd_help_conf_ip, setIpFunction}, + {cmd_conf_ip_mask, cmd_conf_ip_mask_help, setIpMaskFunction}, + {cmd_conf_ip_gw, cmd_conf_ip_gw_help, setIpGwFunction}, + {cmd_conf_udp, cmd_help_conf_udp, setUdpFunction}, + {cmd_conf_mac, cmd_help_conf_mac, setMacAddrFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + fprintf_P(stream, statusTemperatureStr, temperature); + fprintf_P(stream, statusVoltageStr, voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); +// printErrorInfo(state); //TODO fix and uncomment + + //Print system configuration + fprintf_P(stream, systemRamConfigStr); + + fprintf_P(stream, statusMacStr); + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpStr); + netPrintIPAddr(stream, ipGetConfig()->ip); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpMaskStr); + netPrintIPAddr(stream, ipGetConfig()->netmask); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpGwStr); + netPrintIPAddr(stream, ipGetConfig()->gateway); + fprintf_P(stream, PSTR("\r\n")); + + //Print Rs485 Execitive modules + fprintf_P(stream, statusRs485listStr); +// tmp = printRs485devices(stream); +// if (tmp == 0) +// fprintf_P(stream, statusNoRs485Dev); + + //Print locker sensors + fprintf_P(stream, statusLockerSensorsStr); + tmp = printLockers(stream); + if (tmp == 0) + fprintf_P(stream, statusLockerSensorsDisStr); + + //Print time FIXME deadlock problem +/* readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + + udpPrintStatus(stream); +// arpPrintTable(stream); +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + if (state->argc < 1) + { + printStatus(state->myStdInOut); + return OK_SILENT; + } + + FILE stream; + if (ramDyskOtworzPlikStdIo(cmdlineGetArgStr(1, state), &fdVty, &stream, __SWR | __SRD) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + printStatus(&stream); + ramDyskZamknijPlikStdIo(&stream); + return OK_SILENT; +} + +static cliExRes_t statusEncFunction(cmdState_t *state) +{ + nicRegDump(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + return OK_SILENT; +} + +static cliExRes_t debugFunction (cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t level = cmdlineGetArgInt(2, state); + const char *str = (const char*)cmdlineGetArgStr(1, state); + if (level == 0) + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + + } + else //level > 0 + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + } + + return SYNTAX_ERROR; +} + + +static cliExRes_t setTimeFunction(cmdState_t *state) +{ + uint8_t godzina = cmdlineGetArgInt(1, state); + uint8_t minuta = cmdlineGetArgInt(2, state); + uint8_t sekunda = cmdlineGetArgInt(3, state); + + ds1305start(); + + uint8_t cDzies = godzina/10; + uint8_t cJedn = godzina - cDzies*10; + czasRtc.hours.syst24.cDzies = cDzies; + czasRtc.hours.syst24.cJedn = cJedn; + + cDzies = minuta/10; + cJedn = minuta - cDzies * 10; + czasRtc.minutes.cDzies = cDzies; + czasRtc.minutes.cJedn = cJedn; + + cDzies = sekunda/10; + cJedn = sekunda - cDzies * 10; + czasRtc.seconds.cDzies = cDzies; + czasRtc.seconds.cJedn = cJedn; + + setTimeDecoded((timeDecoded_t *)(&czasRtc)); + return OK_SILENT; +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + return OK_SILENT; +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + udpSocket->dstIp = ip; + + uint16_t port = cmdlineGetArgInt(5, state); + udpSocket->srcPort = htons(port); + + if (state->argc > 5) + { + port = cmdlineGetArgInt(6, state); + udpSocket->dstPort = htons(port); + } + return OK_SILENT; +} + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + + ipSetConfigMask(mask); + return OK_SILENT; +} + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + return OK_SILENT; +} + +static cliExRes_t ustawModWykFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + uint8_t wartosc = cmdlineGetArgHex(2, state); + + sendSettings(adres, wartosc); + + return OK_SILENT; +} +static cliExRes_t zapiszModWykFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + saveSettings(adres); + return OK_SILENT; +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + if (state->argc < 6) + return SYNTAX_ERROR; + + nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + +static cliExRes_t czytajAC_Function(cmdState_t *state) +{ + uint8_t nrWejscia = cmdlineGetArgInt(1, state); + uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t curtainDownFunction(cmdState_t *state) +{ + uint8_t nrRolety; + uint8_t nrSterownika; + uint8_t wartosc; + + nrSterownika = cmdlineGetArgInt(1, state); + nrRolety = cmdlineGetArgInt(2, state); + nrRolety &= 0x01; + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut,movingCurtainDownStr, nrSterownika, nrRolety+1); + + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t curtainUpFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + uint8_t wartosc = 255; + if (state->argc > 2) + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut, movingCurtainUpStr, nrSterownika, nrRolety+1); + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t ustawPortExtAFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirA(0x00, 0); + MPC23s17SetPortA(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortExtBFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirB(0x00, 0); + MPC23s17SetPortB(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortRezystor(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t wartosc = cmdlineGetArgInt(1, state); + + MCP4150_setValue(wartosc); + + return OK_SILENT; +} + +static cliExRes_t rpingFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + if ((state->err2 = rs485ping(nrSterownika)) == 0) + return OK_INFORM; + + state->errno = noRemoteDevice; + state->err1 = nrSterownika; + printErrorInfo(state); + return OK_SILENT; +} + +static cliExRes_t pingFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + //uint8_t ip[4]; + //ip[0] = (uint8_t)(cmdlineGetArgInt(1, state)); + //ip[1] = (uint8_t)(cmdlineGetArgInt(2, state)); + //ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + //ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + //Ipv4Ping(*((uint32_t *)(ip))); + + return OK_SILENT; +} + + +static cliExRes_t flashExModuleFunction(cmdState_t *state) +{ + if (state->argc != 2) + return SYNTAX_ERROR; + + uint8_t nrUrzadzenia = cmdlineGetArgInt(1, state); + char *nazwaPliku = cmdlineGetArgStr(2, state); + uint8_t blad; + + // Sprawdzanie, czy moduł wykonawczy odpowiada + if (rs485ping(nrUrzadzenia) != 0) + { + state->errno = noRemoteDevice; + printErrorInfo(state); + return ERROR_INFORM; + } + + //Sprawdzanie, czy istnieje odpowiedni plik z firmware + if (ramDyskOtworzPlik(nazwaPliku, &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, nazwaPliku); + return ERROR_INFORM; + } + + blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + + ramDyskZamknijPlik(&fdVty); + + if (blad != 0) + return ERROR_INFORM; + + return OK_SILENT; +} + +static cliExRes_t goXmodemWyslijFunction(cmdState_t *state) // TODO add code in xModem +{ + fprintf_P(state->myStdInOut, xwyslijStartStr); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + return OK_SILENT; +} + +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state) //TODO move to xmodem +{ + fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + uint8_t i = 25; + + uint8_t temp1; +// uint8_t temp2; + + uint8_t c; + uint8_t liczbaProb; + uint8_t *zapPtr; + uint8_t *zapPtrKopia; + + uint16_t crcLokalne; + uint8_t nrBloku; + + uint8_t nrBlokuZdalny; + uint8_t nrBlokuZdalnyNeg; + + uint8_t crcHi; + uint8_t crcLo; + + state->err1=0; + state->err2=0; + liczbaProb = 20; + for ( ; ; ) + { + fputc('C' , state->myStdInOut); + while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + + if(xQueueReceive(xVtyRec, &c, 100)) + if (c == SOH) + break; //Rozpoczynamy transmisje + + liczbaProb--; + if (liczbaProb == 0) + { + ramDyskZamknijPlik(&fdVty); + state->errno = (uint8_t)(AllOK); + return ERROR_INFORM; + } + } + + nrBloku = 1; + liczbaProb = 10; + + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + for ( ; ; ) + { + if (!xQueueReceive(xVtyRec, &nrBlokuZdalny, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (!xQueueReceive(xVtyRec, &nrBlokuZdalnyNeg, 1)) + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + + //1 Sprawdzanie, czy pasuje numer bloku z numerem bloku w usupełnieniu bitowym do 1 + c = 255-nrBlokuZdalnyNeg; + if (nrBlokuZdalny != c) + { + state->errno = (uint8_t)(xModemFrameFrameNoCorrectionNotMatch); + state->err1 = nrBlokuZdalny; + state->err2 = nrBlokuZdalnyNeg; + break; + } + + //Sprawdzenie, czy nie jest wznowiona transmisja poprzedniego bloku lub nie zaczęła się od bloku 0 + c = nrBloku-1; + if (nrBlokuZdalny == c) + { + nrBloku = c; //Cofnięcie nr aktualnego bloku o 1 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + } + + //2 Sprawdzanie, czy pasuje numer bloku + if (nrBlokuZdalny != nrBloku) + { + state->errno = (uint8_t)(xModemWrongFrameNo); + state->err1 = nrBlokuZdalnyNeg; + state->err2 = nrBloku; + break; + } + + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + { + if(xQueueReceive(xVtyRec, &c, 10)) + *(zapPtr++) = c; + else + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + } + if (!xQueueReceive(xVtyRec, &crcHi, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 2; + break; + } + if (!xQueueReceive(xVtyRec, &crcLo, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 1; + break; + } + + //3 Zerowanie CRC + crcLokalne=0; + + //4 Obliczanie CRC + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + + //5 Srawdzanie CRC + if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + { + liczbaProb = 10; + uartVtySendByte(ACK); + } + else + { + liczbaProb--; + nrBloku--; + uartVtySendByte(NAK); + } + + if (liczbaProb == 0) + { + state->err1 = nrBlokuZdalny; + state->err2 = nrBloku; + state->errno = (uint8_t)(xModemWrongFrameNo); + break; + } + + if (!xQueueReceive(xVtyRec, &temp1, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (temp1 == SOH) + { + nrBloku++; + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + state->errno = (uint8_t)(AllOK); + continue; + } + + if (temp1 == CAN) + { + state->err1 = nrBloku; + state->errno = (uint8_t)(xModemRemoteSideCan); + break; + } + if (temp1 == EOT) + { + uartVtySendByte(NAK); + if (xQueueReceive(xVtyRec, &temp1, 10)) + { + if (temp1 == EOT) + uartVtySendByte(ACK); + } + state->errno = (uint8_t)(AllOK); + break; + } + state->errno = (uint8_t)(xModemUnknownResponse); + state->err1 = temp1; + break; + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t eraseRamFileFunction(cmdState_t *state) +{ + if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + return OK_INFORM; + + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t dodajRamPlikFunction(cmdState_t *state) +{ + if (state->argc != 1) + return SYNTAX_ERROR; + + if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + { + return OK_INFORM; + } + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t writeRamFileFunction(cmdState_t *state) +{ + ramDyskDir(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t editRamFileFunction(cmdState_t *state) +{ + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + ramDyskUstawWskaznikNaKoniec(&fdVty); + uint8_t znak = 0; + fprintf_P(state->myStdInOut, editRamFileIntroStr); + while(1) + { + if(!xQueueReceive( xVtyRec, &znak, portMAX_DELAY)) + continue; + + if (znak == 0x03) // ^C + break; + + uartVtySendByte(znak); //Echo + ramDyskZapiszBajtDoPliku(&fdVty, znak); + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t readRamFIleFunction(cmdState_t *state) //TODO move this code to fat8 +{ + uint8_t rezultat; + uint8_t znak = ' '; + if ((rezultat = ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty)) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + while (rezultat == 0) + { + rezultat = ramDyskCzytajBajtZPliku(&fdVty, &znak); + + uartVtySendByte(znak); + if (znak == '\r') + uartVtySendByte('\n'); + } + fprintf_P(state->myStdInOut, nlStr); + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction(cmdState_t *state) +{ + state = NULL; + uint8_t *ptr; + ptr= 0x4000; + uint8_t tmp; + for (tmp=0; tmp <255; tmp++) + { + *(ptr) = tmp; + ptr++; + } + ptr= 0x4000; + uint8_t tmp2; + for (tmp=0; tmp <4; tmp++) + { + uartVtySendByte('\r'); + uartVtySendByte('\n'); + for (tmp2=0; tmp2<64; tmp2++) + { + uartVtySendByte(*(ptr)); + ptr++; + } + } + return OK_SILENT; +} +#endif + + diff --git a/Projects/DidacticSystem/Adam/MainController/vty.h b/Projects/DidacticSystem/Adam/MainController/vty.h new file mode 100644 index 0000000..e4251f4 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/vty.h @@ -0,0 +1,81 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include +#include + +#include "ds1305.h" +#include "enc28j60.h" +#include "memory_x.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "sensors_task.h" +#include "nic.h" +#include "ip.h" +#include "net.h" +#include "arp.h" +#include "cmdline.h" +#include "udp.h" + + +// Znaki kontrolne w protokole Xmodem +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +// xmodem timeout/retry parameters +#define XMODEM_RETRY_LIMIT 16 + +// error return codes +#define XMODEM_ERROR_REMOTECANCEL 1 +#define XMODEM_ERROR_OUTOFSYNC 2 +#define XMODEM_ERROR_RETRYEXCEED 3 + +#define XMODEM_BUFFER_SIZE 128 + + +extern nicState_t nicState; +extern UdpSocket_t *udpSocket; + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + +extern xQueueHandle xRs485Rec; +extern xQueueHandle xRs485Tx; + +extern volatile timeDecoded_t czasRtc; +extern struct Enc28j60_config Enc28j60_global; + +extern struct sterRolet *rollers; + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/DidacticSystem/Adam/MainController/vty.lst b/Projects/DidacticSystem/Adam/MainController/vty.lst new file mode 100644 index 0000000..7a3e052 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/vty.lst @@ -0,0 +1,5890 @@ + 1 .file "vty.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __RAMPZ__ = 0x3b + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 10 .text + 11 .Ltext0: + 275 enableFunction: + 276 .stabd 46,0,0 + 1:vty.c **** #include "main.h" + 2:vty.c **** #include "vty.h" + 3:vty.c **** #include "ramdysk.h" + 4:vty.c **** #include "protocol1.h" + 5:vty.c **** #include "mpc23s17.h" + 6:vty.c **** #include "mcp3008.h" + 7:vty.c **** #include "ds1305.h" + 8:vty.c **** #include "hardwareConfig.h" + 9:vty.c **** #include "configuration.h" + 10:vty.c **** #include "Rs485_prot.h" + 11:vty.c **** #include "net.h" + 12:vty.c **** #include "ip.h" + 13:vty.c **** #include "arp.h" + 14:vty.c **** #include "softwareConfig.h" + 15:vty.c **** #include "mcp4150.h" + 16:vty.c **** + 17:vty.c **** #if LANG_EN + 18:vty.c **** #include "vty_en.h" + 19:vty.c **** #endif + 20:vty.c **** + 21:vty.c **** #if LANG_PL + 22:vty.c **** #include "vty_pl.h" + 23:vty.c **** #endif + 24:vty.c **** + 25:vty.c **** #ifndef LANG_VTY + 26:vty.c **** #error "Vty Language not defined" + 27:vty.c **** #endif + 28:vty.c **** + 29:vty.c **** + 30:vty.c **** static cliExRes_t helpFunction (cmdState_t *state); + 31:vty.c **** static cliExRes_t statusFunction (cmdState_t *state); + 32:vty.c **** static cliExRes_t statusEncFunction (cmdState_t *state); + 33:vty.c **** static cliExRes_t curtainDownFunction (cmdState_t *state); + 34:vty.c **** static cliExRes_t curtainUpFunction (cmdState_t *state); + 35:vty.c **** static cliExRes_t rpingFunction (cmdState_t *state); + 36:vty.c **** static cliExRes_t pingFunction (cmdState_t *state); + 37:vty.c **** static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state); + 38:vty.c **** static cliExRes_t goXmodemWyslijFunction (cmdState_t *state); + 39:vty.c **** static cliExRes_t dodajRamPlikFunction (cmdState_t *state); + 40:vty.c **** static cliExRes_t eraseRamFileFunction (cmdState_t *state); + 41:vty.c **** static cliExRes_t flashExModuleFunction (cmdState_t *state); + 42:vty.c **** static cliExRes_t writeRamFileFunction (cmdState_t *state); + 43:vty.c **** static cliExRes_t editRamFileFunction (cmdState_t *state); + 44:vty.c **** static cliExRes_t readRamFIleFunction (cmdState_t *state); + 45:vty.c **** + 46:vty.c **** static cliExRes_t ustawPortExtAFunction (cmdState_t *state); + 47:vty.c **** static cliExRes_t ustawPortExtBFunction (cmdState_t *state); + 48:vty.c **** static cliExRes_t ustawPortRezystor (cmdState_t *state); + 49:vty.c **** + 50:vty.c **** static cliExRes_t ustawModWykFunction (cmdState_t *state); + 51:vty.c **** static cliExRes_t zapiszModWykFunction (cmdState_t *state); + 52:vty.c **** + 53:vty.c **** static cliExRes_t pokazCzasFunction (cmdState_t *state); + 54:vty.c **** static cliExRes_t debugFunction (cmdState_t *state); + 55:vty.c **** static cliExRes_t czytajAC_Function (cmdState_t *state); + 56:vty.c **** + 57:vty.c **** static cliExRes_t enableFunction (cmdState_t *state); + 58:vty.c **** static cliExRes_t disableFunction (cmdState_t *state); + 59:vty.c **** static cliExRes_t configureModeFunction (cmdState_t *state); + 60:vty.c **** + 61:vty.c **** static cliExRes_t setIpFunction(cmdState_t *state); + 62:vty.c **** static cliExRes_t setIpMaskFunction(cmdState_t *state); + 63:vty.c **** static cliExRes_t setIpGwFunction(cmdState_t *state); + 64:vty.c **** static cliExRes_t setUdpFunction(cmdState_t *state); + 65:vty.c **** + 66:vty.c **** static cliExRes_t setMacAddrFunction (cmdState_t *state); + 67:vty.c **** static cliExRes_t setTimeFunction (cmdState_t *state); + 68:vty.c **** + 69:vty.c **** static cliExRes_t saveConfigFunction (cmdState_t *state); + 70:vty.c **** + 71:vty.c **** #ifdef testZewPamiec + 72:vty.c **** static cliExRes_t testPamZewFunction (cmdState_t *state); + 73:vty.c **** #endif + 74:vty.c **** + 75:vty.c **** struct ramPlikFd fdVty; //TODO move it to CLI struct + 76:vty.c **** + 77:vty.c **** const char okStr[] PROGMEM = "OK\r\n"; + 78:vty.c **** const char nlStr[] PROGMEM = "\r\n"; + 79:vty.c **** const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + 80:vty.c **** + 81:vty.c **** + 82:vty.c **** const char * const errorStrings[] PROGMEM = { + 83:vty.c **** errorOK, + 84:vty.c **** errorNoFile, + 85:vty.c **** errorxModemFrameStartTimeout, + 86:vty.c **** errorxModemByteSendTimeout, + 87:vty.c **** errorxModemWrongFrameNo, + 88:vty.c **** errorxModemFrameFrameNoCorrectionNotMatch, + 89:vty.c **** errorxModemFrameCrc, + 90:vty.c **** errorxModemRemoteSideCan, + 91:vty.c **** errorxModemUnknownResponse, + 92:vty.c **** errorNoRemoteDevice, + 93:vty.c **** errorBootloaderNotResponding, + 94:vty.c **** errorOpenFile + 95:vty.c **** }; + 96:vty.c **** + 97:vty.c **** const command_t cmdListNormal[] PROGMEM = + 98:vty.c **** { + 99:vty.c **** {cmd_help, cmd_help_help, helpFunction}, + 100:vty.c **** {cmd_status, cmd_help_status, statusFunction}, + 101:vty.c **** {cmd_time, cmd_help_time, pokazCzasFunction}, + 102:vty.c **** {cmd_rping, cmd_help_rping, rpingFunction}, + 103:vty.c **** {cmd_ping, cmd_help_ping, pingFunction}, + 104:vty.c **** {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + 105:vty.c **** {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + 106:vty.c **** {cmd_enable, cmd_help_enable, enableFunction}, + 107:vty.c **** {NULL, NULL, NULL} + 108:vty.c **** }; + 109:vty.c **** + 110:vty.c **** const command_t cmdListEnable[] PROGMEM = + 111:vty.c **** { + 112:vty.c **** {cmd_help, cmd_help_help, helpFunction}, + 113:vty.c **** {cmd_status, cmd_help_status, statusFunction}, + 114:vty.c **** {cmd_enc_stat, cmd_help_enc_stat, statusEncFunction}, + 115:vty.c **** {cmd_time, cmd_help_time, pokazCzasFunction}, + 116:vty.c **** {cmd_net_dbg, cmd_help_net_dbg, debugFunction}, + 117:vty.c **** + 118:vty.c **** {cmd_rping, cmd_help_rping, rpingFunction}, + 119:vty.c **** {cmd_ping, cmd_help_ping, pingFunction}, + 120:vty.c **** {cmd_xRec, cmd_help_xRec, goXmodemOdbierzFunction}, + 121:vty.c **** {cmd_xSend, cmd_help_xSend, goXmodemWyslijFunction}, + 122:vty.c **** {cmd_xflash, cmd_help_xflash, flashExModuleFunction}, + 123:vty.c **** #ifdef testZewPamiec + 124:vty.c **** {cmd_rtest, cmd_help_rtest, testPamZewFunction}, + 125:vty.c **** #endif + 126:vty.c **** {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + 127:vty.c **** {cmd_create_rf, cmd_help_create_rf, dodajRamPlikFunction}, + 128:vty.c **** {cmd_erase_rf, cmd_help_erase_rf, eraseRamFileFunction}, + 129:vty.c **** {cmd_edit_rf, cmd_help_edit_rf, editRamFileFunction}, + 130:vty.c **** {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + 131:vty.c **** + 132:vty.c **** {cmd_up, cmd_help_up, curtainUpFunction}, + 133:vty.c **** {cmd_down, cmd_help_down, curtainDownFunction}, + 134:vty.c **** + 135:vty.c **** {cmd_spa, cmd_help_spa, ustawPortExtAFunction}, + 136:vty.c **** {cmd_spb, cmd_help_spb, ustawPortExtBFunction}, + 137:vty.c **** {cmd_ustawR, cmd_help_ustawR, ustawPortRezystor}, + 138:vty.c **** {cmd_settime, cmd_help_settime, setTimeFunction}, + 139:vty.c **** {cmd_ac, cmd_help_ac, czytajAC_Function}, + 140:vty.c **** {cmd_disable, cmd_help_disable, disableFunction}, + 141:vty.c **** {cmd_configure, cmd_help_configure, configureModeFunction}, + 142:vty.c **** {cmd_ustawMW, cmd_help_ustawMW, ustawModWykFunction}, + 143:vty.c **** {cmd_zapiszMW, cmd_help_zapiszMW, zapiszModWykFunction}, + 144:vty.c **** {NULL, NULL, NULL} + 145:vty.c **** }; + 146:vty.c **** + 147:vty.c **** const command_t cmdListConfigure[] PROGMEM = + 148:vty.c **** { + 149:vty.c **** {cmd_help, cmd_help_help, helpFunction}, + 150:vty.c **** {cmd_status, cmd_help_status, statusFunction}, + 151:vty.c **** {cmd_time, cmd_help_time, pokazCzasFunction}, + 152:vty.c **** {cmd_settime, cmd_help_settime, setTimeFunction}, + 153:vty.c **** {cmd_conf_ip, cmd_help_conf_ip, setIpFunction}, + 154:vty.c **** {cmd_conf_ip_mask, cmd_conf_ip_mask_help, setIpMaskFunction}, + 155:vty.c **** {cmd_conf_ip_gw, cmd_conf_ip_gw_help, setIpGwFunction}, + 156:vty.c **** {cmd_conf_udp, cmd_help_conf_udp, setUdpFunction}, + 157:vty.c **** {cmd_conf_mac, cmd_help_conf_mac, setMacAddrFunction}, + 158:vty.c **** {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + 159:vty.c **** {cmd_enable, cmd_help_enable, enableFunction}, + 160:vty.c **** {cmd_disable, cmd_help_disable, disableFunction}, + 161:vty.c **** {NULL, NULL, NULL} + 162:vty.c **** }; + 163:vty.c **** + 164:vty.c **** void VtyInit(cmdState_t* state, FILE *stream) + 165:vty.c **** { + 166:vty.c **** cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR + 167:vty.c **** } + 168:vty.c **** + 169:vty.c **** void printErrorInfo(cmdState_t *state) + 170:vty.c **** { + 171:vty.c **** if (state->errno != 0) + 172:vty.c **** { + 173:vty.c **** fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state-> + 174:vty.c **** } + 175:vty.c **** state->errno = 0; + 176:vty.c **** state->err1 = 0; + 177:vty.c **** state->err2 = 0; + 178:vty.c **** } + 179:vty.c **** + 180:vty.c **** static cliExRes_t enableFunction(cmdState_t *state) + 181:vty.c **** { + 278 .LM0: + 279 .LFBB1: + 280 /* prologue: function */ + 281 /* frame size = 0 */ + 282 /* stack size = 0 */ + 283 .L__stack_usage = 0 + 284 0000 FC01 movw r30,r24 + 182:vty.c **** if (state->cliMode != RESTRICTED_NORMAL) + 286 .LM1: + 287 0002 80A1 ldd r24,Z+32 + 288 0004 8330 cpi r24,lo8(3) + 289 0006 01F0 breq .L3 + 183:vty.c **** { + 184:vty.c **** state->cmdList = cmdListEnable; + 291 .LM2: + 292 0008 80E0 ldi r24,lo8(cmdListEnable) + 293 000a 90E0 ldi r25,hi8(cmdListEnable) + 294 000c 92A3 std Z+34,r25 + 295 000e 81A3 std Z+33,r24 + 185:vty.c **** state->cliMode = NR_ENABLE; + 297 .LM3: + 298 0010 81E0 ldi r24,lo8(1) + 299 0012 80A3 std Z+32,r24 + 186:vty.c **** return OK_SILENT; + 301 .LM4: + 302 0014 80E0 ldi r24,0 + 303 0016 90E0 ldi r25,0 + 304 0018 0895 ret + 305 .L3: + 187:vty.c **** } + 188:vty.c **** return ERROR_OPERATION_NOT_ALLOWED; + 307 .LM5: + 308 001a 85E0 ldi r24,lo8(5) + 309 001c 90E0 ldi r25,0 + 189:vty.c **** } + 311 .LM6: + 312 001e 0895 ret + 314 .Lscope1: + 316 .stabd 78,0,0 + 320 disableFunction: + 321 .stabd 46,0,0 + 190:vty.c **** static cliExRes_t disableFunction(cmdState_t *state) + 191:vty.c **** { + 323 .LM7: + 324 .LFBB2: + 325 /* prologue: function */ + 326 /* frame size = 0 */ + 327 /* stack size = 0 */ + 328 .L__stack_usage = 0 + 329 0020 FC01 movw r30,r24 + 192:vty.c **** state->cmdList = cmdListNormal; + 331 .LM8: + 332 0022 80E0 ldi r24,lo8(cmdListNormal) + 333 0024 90E0 ldi r25,hi8(cmdListNormal) + 334 0026 92A3 std Z+34,r25 + 335 0028 81A3 std Z+33,r24 + 193:vty.c **** if (state->cliMode != RESTRICTED_NORMAL) + 337 .LM9: + 338 002a 80A1 ldd r24,Z+32 + 339 002c 8330 cpi r24,lo8(3) + 340 002e 01F0 breq .L6 + 194:vty.c **** { + 195:vty.c **** state->cliMode = NR_NORMAL; + 342 .LM10: + 343 0030 10A2 std Z+32,__zero_reg__ + 344 .L6: + 196:vty.c **** } + 197:vty.c **** return OK_SILENT; + 198:vty.c **** } + 346 .LM11: + 347 0032 80E0 ldi r24,0 + 348 0034 90E0 ldi r25,0 + 349 0036 0895 ret + 351 .Lscope2: + 353 .stabd 78,0,0 + 357 configureModeFunction: + 358 .stabd 46,0,0 + 199:vty.c **** static cliExRes_t configureModeFunction(cmdState_t *state) + 200:vty.c **** { + 360 .LM12: + 361 .LFBB3: + 362 /* prologue: function */ + 363 /* frame size = 0 */ + 364 /* stack size = 0 */ + 365 .L__stack_usage = 0 + 366 0038 FC01 movw r30,r24 + 201:vty.c **** if (state->cliMode == NR_ENABLE) + 368 .LM13: + 369 003a 80A1 ldd r24,Z+32 + 370 003c 8130 cpi r24,lo8(1) + 371 003e 01F4 brne .L12 + 202:vty.c **** { + 203:vty.c **** state->cmdList = cmdListConfigure; + 373 .LM14: + 374 0040 80E0 ldi r24,lo8(cmdListConfigure) + 375 0042 90E0 ldi r25,hi8(cmdListConfigure) + 376 0044 92A3 std Z+34,r25 + 377 0046 81A3 std Z+33,r24 + 204:vty.c **** state->cliMode = NR_CONFIGURE; + 379 .LM15: + 380 0048 82E0 ldi r24,lo8(2) + 381 004a 80A3 std Z+32,r24 + 205:vty.c **** return OK_SILENT; + 383 .LM16: + 384 004c 80E0 ldi r24,0 + 385 004e 90E0 ldi r25,0 + 386 0050 0895 ret + 387 .L12: + 206:vty.c **** } + 207:vty.c **** return ERROR_OPERATION_NOT_ALLOWED; + 389 .LM17: + 390 0052 85E0 ldi r24,lo8(5) + 391 0054 90E0 ldi r25,0 + 208:vty.c **** } + 393 .LM18: + 394 0056 0895 ret + 396 .Lscope3: + 398 .stabd 78,0,0 + 402 pingFunction: + 403 .stabd 46,0,0 + 209:vty.c **** + 210:vty.c **** // ************************** VTY API ************************************************************* + 211:vty.c **** void printStatus(FILE *stream) + 212:vty.c **** { + 213:vty.c **** fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + 214:vty.c **** //Print system state + 215:vty.c **** fprintf_P(stream, systemStateStr); + 216:vty.c **** fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + 217:vty.c **** fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + 218:vty.c **** fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + 219:vty.c **** fprintf_P(stream, statusTemperatureStr, temperature); + 220:vty.c **** fprintf_P(stream, statusVoltageStr, voltage); + 221:vty.c **** + 222:vty.c **** uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + 223:vty.c **** fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); + 224:vty.c **** // printErrorInfo(state); //TODO fix and uncomment + 225:vty.c **** + 226:vty.c **** //Print system configuration + 227:vty.c **** fprintf_P(stream, systemRamConfigStr); + 228:vty.c **** + 229:vty.c **** fprintf_P(stream, statusMacStr); + 230:vty.c **** netPrintEthAddr(stream, &nicState.mac); + 231:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 232:vty.c **** + 233:vty.c **** fprintf_P(stream, statusIpStr); + 234:vty.c **** netPrintIPAddr(stream, ipGetConfig()->ip); + 235:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 236:vty.c **** + 237:vty.c **** fprintf_P(stream, statusIpMaskStr); + 238:vty.c **** netPrintIPAddr(stream, ipGetConfig()->netmask); + 239:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 240:vty.c **** + 241:vty.c **** fprintf_P(stream, statusIpGwStr); + 242:vty.c **** netPrintIPAddr(stream, ipGetConfig()->gateway); + 243:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 244:vty.c **** + 245:vty.c **** //Print Rs485 Execitive modules + 246:vty.c **** fprintf_P(stream, statusRs485listStr); + 247:vty.c **** // tmp = printRs485devices(stream); + 248:vty.c **** // if (tmp == 0) + 249:vty.c **** // fprintf_P(stream, statusNoRs485Dev); + 250:vty.c **** + 251:vty.c **** //Print locker sensors + 252:vty.c **** fprintf_P(stream, statusLockerSensorsStr); + 253:vty.c **** tmp = printLockers(stream); + 254:vty.c **** if (tmp == 0) + 255:vty.c **** fprintf_P(stream, statusLockerSensorsDisStr); + 256:vty.c **** + 257:vty.c **** //Print time FIXME deadlock problem + 258:vty.c **** /* readTimeDecoded((timeDecoded_t *)(&czasRtc)); + 259:vty.c **** uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + 260:vty.c **** uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 261:vty.c **** uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + 262:vty.c **** fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + 263:vty.c **** + 264:vty.c **** udpPrintStatus(stream); + 265:vty.c **** // arpPrintTable(stream); + 266:vty.c **** } + 267:vty.c **** + 268:vty.c **** + 269:vty.c **** // ************************** CLI Functions ******************************************************* + 270:vty.c **** + 271:vty.c **** static cliExRes_t statusFunction(cmdState_t *state) + 272:vty.c **** { + 273:vty.c **** if (state->argc < 1) + 274:vty.c **** { + 275:vty.c **** printStatus(state->myStdInOut); + 276:vty.c **** return OK_SILENT; + 277:vty.c **** } + 278:vty.c **** + 279:vty.c **** FILE stream; + 280:vty.c **** if (ramDyskOtworzPlikStdIo(cmdlineGetArgStr(1, state), &fdVty, &stream, __SWR | __SRD) != 0) + 281:vty.c **** { + 282:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 283:vty.c **** return ERROR_INFORM; + 284:vty.c **** } + 285:vty.c **** + 286:vty.c **** printStatus(&stream); + 287:vty.c **** ramDyskZamknijPlikStdIo(&stream); + 288:vty.c **** return OK_SILENT; + 289:vty.c **** } + 290:vty.c **** + 291:vty.c **** static cliExRes_t statusEncFunction(cmdState_t *state) + 292:vty.c **** { + 293:vty.c **** nicRegDump(state->myStdInOut); + 294:vty.c **** return OK_SILENT; + 295:vty.c **** } + 296:vty.c **** + 297:vty.c **** static cliExRes_t pokazCzasFunction(cmdState_t *state) + 298:vty.c **** { + 299:vty.c **** readTimeDecoded((timeDecoded_t *)(&czasRtc)); + 300:vty.c **** uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + 301:vty.c **** uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 302:vty.c **** uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + 303:vty.c **** fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + 304:vty.c **** return OK_SILENT; + 305:vty.c **** } + 306:vty.c **** + 307:vty.c **** static cliExRes_t debugFunction (cmdState_t *state) + 308:vty.c **** { + 309:vty.c **** if (state->argc < 2) + 310:vty.c **** return SYNTAX_ERROR; + 311:vty.c **** + 312:vty.c **** uint8_t level = cmdlineGetArgInt(2, state); + 313:vty.c **** const char *str = (const char*)cmdlineGetArgStr(1, state); + 314:vty.c **** if (level == 0) + 315:vty.c **** { + 316:vty.c **** if (strncmp_P(str, PSTR("arp"), 3) == 0) + 317:vty.c **** { + 318:vty.c **** setArpDebug(NULL, 0); + 319:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 320:vty.c **** return OK_SILENT; + 321:vty.c **** } + 322:vty.c **** + 323:vty.c **** if (strncmp_P(str, PSTR("ip"), 2) == 0) + 324:vty.c **** { + 325:vty.c **** setIpDebug(NULL, 0); + 326:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 327:vty.c **** return OK_SILENT; + 328:vty.c **** } + 329:vty.c **** + 330:vty.c **** if (strncmp_P(str, PSTR("icmp"), 2) == 0) + 331:vty.c **** { + 332:vty.c **** setIcmpDebug(NULL, 0); + 333:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 334:vty.c **** return OK_SILENT; + 335:vty.c **** } + 336:vty.c **** + 337:vty.c **** if (strncmp_P(str, PSTR("tcp"), 2) == 0) + 338:vty.c **** { + 339:vty.c **** setTcpDebug(NULL, 0); + 340:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 341:vty.c **** return OK_SILENT; + 342:vty.c **** } + 343:vty.c **** + 344:vty.c **** if (strncmp_P(str, PSTR("udp"), 2) == 0) + 345:vty.c **** { + 346:vty.c **** setUdpDebug(NULL, 0); + 347:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 348:vty.c **** return OK_SILENT; + 349:vty.c **** } + 350:vty.c **** + 351:vty.c **** + 352:vty.c **** } + 353:vty.c **** else //level > 0 + 354:vty.c **** { + 355:vty.c **** if (strncmp_P(str, PSTR("arp"), 3) == 0) + 356:vty.c **** { + 357:vty.c **** setArpDebug(state->myStdInOut, level); + 358:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 359:vty.c **** return OK_SILENT; + 360:vty.c **** } + 361:vty.c **** + 362:vty.c **** if (strncmp_P(str, PSTR("ip"), 2) == 0) + 363:vty.c **** { + 364:vty.c **** setIpDebug(state->myStdInOut, level); + 365:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 366:vty.c **** return OK_SILENT; + 367:vty.c **** } + 368:vty.c **** + 369:vty.c **** if (strncmp_P(str, PSTR("icmp"), 2) == 0) + 370:vty.c **** { + 371:vty.c **** setIcmpDebug(state->myStdInOut, level); + 372:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 373:vty.c **** return OK_SILENT; + 374:vty.c **** } + 375:vty.c **** + 376:vty.c **** if (strncmp_P(str, PSTR("tcp"), 2) == 0) + 377:vty.c **** { + 378:vty.c **** setTcpDebug(state->myStdInOut, level); + 379:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 380:vty.c **** return OK_SILENT; + 381:vty.c **** } + 382:vty.c **** + 383:vty.c **** if (strncmp_P(str, PSTR("udp"), 2) == 0) + 384:vty.c **** { + 385:vty.c **** setUdpDebug(state->myStdInOut, level); + 386:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 387:vty.c **** return OK_SILENT; + 388:vty.c **** } + 389:vty.c **** } + 390:vty.c **** + 391:vty.c **** return SYNTAX_ERROR; + 392:vty.c **** } + 393:vty.c **** + 394:vty.c **** + 395:vty.c **** static cliExRes_t setTimeFunction(cmdState_t *state) + 396:vty.c **** { + 397:vty.c **** uint8_t godzina = cmdlineGetArgInt(1, state); + 398:vty.c **** uint8_t minuta = cmdlineGetArgInt(2, state); + 399:vty.c **** uint8_t sekunda = cmdlineGetArgInt(3, state); + 400:vty.c **** + 401:vty.c **** ds1305start(); + 402:vty.c **** + 403:vty.c **** uint8_t cDzies = godzina/10; + 404:vty.c **** uint8_t cJedn = godzina - cDzies*10; + 405:vty.c **** czasRtc.hours.syst24.cDzies = cDzies; + 406:vty.c **** czasRtc.hours.syst24.cJedn = cJedn; + 407:vty.c **** + 408:vty.c **** cDzies = minuta/10; + 409:vty.c **** cJedn = minuta - cDzies * 10; + 410:vty.c **** czasRtc.minutes.cDzies = cDzies; + 411:vty.c **** czasRtc.minutes.cJedn = cJedn; + 412:vty.c **** + 413:vty.c **** cDzies = sekunda/10; + 414:vty.c **** cJedn = sekunda - cDzies * 10; + 415:vty.c **** czasRtc.seconds.cDzies = cDzies; + 416:vty.c **** czasRtc.seconds.cJedn = cJedn; + 417:vty.c **** + 418:vty.c **** setTimeDecoded((timeDecoded_t *)(&czasRtc)); + 419:vty.c **** return OK_SILENT; + 420:vty.c **** } + 421:vty.c **** + 422:vty.c **** static cliExRes_t setIpFunction(cmdState_t *state) + 423:vty.c **** { + 424:vty.c **** if (state->argc < 4) + 425:vty.c **** return SYNTAX_ERROR; + 426:vty.c **** + 427:vty.c **** uint32_t ip = cmdlineGetArgInt(1, state) + + 428:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 429:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 430:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 431:vty.c **** + 432:vty.c **** ipSetConfigIp(ip); + 433:vty.c **** return OK_SILENT; + 434:vty.c **** } + 435:vty.c **** + 436:vty.c **** static cliExRes_t setUdpFunction(cmdState_t *state) + 437:vty.c **** { + 438:vty.c **** if (state->argc < 5) + 439:vty.c **** return SYNTAX_ERROR; + 440:vty.c **** + 441:vty.c **** uint32_t ip = cmdlineGetArgInt(1, state) + + 442:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 443:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 444:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 445:vty.c **** udpSocket->dstIp = ip; + 446:vty.c **** + 447:vty.c **** uint16_t port = cmdlineGetArgInt(5, state); + 448:vty.c **** udpSocket->srcPort = htons(port); + 449:vty.c **** + 450:vty.c **** if (state->argc > 5) + 451:vty.c **** { + 452:vty.c **** port = cmdlineGetArgInt(6, state); + 453:vty.c **** udpSocket->dstPort = htons(port); + 454:vty.c **** } + 455:vty.c **** return OK_SILENT; + 456:vty.c **** } + 457:vty.c **** + 458:vty.c **** + 459:vty.c **** static cliExRes_t setIpMaskFunction(cmdState_t *state) + 460:vty.c **** { + 461:vty.c **** if (state->argc < 1) + 462:vty.c **** return SYNTAX_ERROR; + 463:vty.c **** + 464:vty.c **** uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + 465:vty.c **** + 466:vty.c **** ipSetConfigMask(mask); + 467:vty.c **** return OK_SILENT; + 468:vty.c **** } + 469:vty.c **** + 470:vty.c **** + 471:vty.c **** static cliExRes_t setIpGwFunction(cmdState_t *state) + 472:vty.c **** { + 473:vty.c **** if (state->argc < 4) + 474:vty.c **** return SYNTAX_ERROR; + 475:vty.c **** + 476:vty.c **** uint32_t gw = cmdlineGetArgInt(1, state) + + 477:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 478:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 479:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 480:vty.c **** ipSetConfigGw(gw); + 481:vty.c **** return OK_SILENT; + 482:vty.c **** } + 483:vty.c **** + 484:vty.c **** static cliExRes_t ustawModWykFunction(cmdState_t *state) + 485:vty.c **** { + 486:vty.c **** if (state->argc < 2) + 487:vty.c **** return SYNTAX_ERROR; + 488:vty.c **** + 489:vty.c **** uint8_t adres = cmdlineGetArgInt(1, state); + 490:vty.c **** uint8_t wartosc = cmdlineGetArgHex(2, state); + 491:vty.c **** + 492:vty.c **** sendSettings(adres, wartosc); + 493:vty.c **** + 494:vty.c **** return OK_SILENT; + 495:vty.c **** } + 496:vty.c **** static cliExRes_t zapiszModWykFunction(cmdState_t *state) + 497:vty.c **** { + 498:vty.c **** if (state->argc < 1) + 499:vty.c **** return SYNTAX_ERROR; + 500:vty.c **** + 501:vty.c **** uint8_t adres = cmdlineGetArgInt(1, state); + 502:vty.c **** saveSettings(adres); + 503:vty.c **** return OK_SILENT; + 504:vty.c **** } + 505:vty.c **** + 506:vty.c **** static cliExRes_t setMacAddrFunction(cmdState_t *state) + 507:vty.c **** { + 508:vty.c **** if (state->argc < 6) + 509:vty.c **** return SYNTAX_ERROR; + 510:vty.c **** + 511:vty.c **** nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + 512:vty.c **** nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + 513:vty.c **** nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + 514:vty.c **** nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + 515:vty.c **** nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + 516:vty.c **** nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + 517:vty.c **** nicSetMacAddress(nicState.mac.addr); + 518:vty.c **** return OK_SILENT; + 519:vty.c **** } + 520:vty.c **** + 521:vty.c **** static cliExRes_t czytajAC_Function(cmdState_t *state) + 522:vty.c **** { + 523:vty.c **** uint8_t nrWejscia = cmdlineGetArgInt(1, state); + 524:vty.c **** uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + 525:vty.c **** fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + 526:vty.c **** return OK_SILENT; + 527:vty.c **** } + 528:vty.c **** + 529:vty.c **** static cliExRes_t helpFunction(cmdState_t *state) + 530:vty.c **** { + 531:vty.c **** cmdPrintHelp(state); + 532:vty.c **** return OK_SILENT; + 533:vty.c **** } + 534:vty.c **** + 535:vty.c **** static cliExRes_t curtainDownFunction(cmdState_t *state) + 536:vty.c **** { + 537:vty.c **** uint8_t nrRolety; + 538:vty.c **** uint8_t nrSterownika; + 539:vty.c **** uint8_t wartosc; + 540:vty.c **** + 541:vty.c **** nrSterownika = cmdlineGetArgInt(1, state); + 542:vty.c **** nrRolety = cmdlineGetArgInt(2, state); + 543:vty.c **** nrRolety &= 0x01; + 544:vty.c **** wartosc = cmdlineGetArgInt(3, state); + 545:vty.c **** + 546:vty.c **** fprintf_P(state->myStdInOut,movingCurtainDownStr, nrSterownika, nrRolety+1); + 547:vty.c **** + 548:vty.c **** if ((wartosc > 0) && (wartosc <=100)) + 549:vty.c **** fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 550:vty.c **** + 551:vty.c **** uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + 552:vty.c **** + 553:vty.c **** if (result == 0) + 554:vty.c **** return OK_INFORM; + 555:vty.c **** + 556:vty.c **** return ERROR_SILENT; + 557:vty.c **** } + 558:vty.c **** + 559:vty.c **** static cliExRes_t curtainUpFunction(cmdState_t *state) + 560:vty.c **** { + 561:vty.c **** if (state->argc < 2) + 562:vty.c **** return SYNTAX_ERROR; + 563:vty.c **** + 564:vty.c **** uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + 565:vty.c **** uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + 566:vty.c **** uint8_t wartosc = 255; + 567:vty.c **** if (state->argc > 2) + 568:vty.c **** wartosc = cmdlineGetArgInt(3, state); + 569:vty.c **** + 570:vty.c **** fprintf_P(state->myStdInOut, movingCurtainUpStr, nrSterownika, nrRolety+1); + 571:vty.c **** if ((wartosc > 0) && (wartosc <=100)) + 572:vty.c **** fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 573:vty.c **** + 574:vty.c **** uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + 575:vty.c **** + 576:vty.c **** if (result == 0) + 577:vty.c **** return OK_INFORM; + 578:vty.c **** + 579:vty.c **** return ERROR_SILENT; + 580:vty.c **** } + 581:vty.c **** + 582:vty.c **** static cliExRes_t ustawPortExtAFunction(cmdState_t *state) + 583:vty.c **** { + 584:vty.c **** uint8_t wyjscie = cmdlineGetArgInt(1, state); + 585:vty.c **** MPC23s17SetDirA(0x00, 0); + 586:vty.c **** MPC23s17SetPortA(wyjscie, 0); + 587:vty.c **** return OK_SILENT; + 588:vty.c **** } + 589:vty.c **** + 590:vty.c **** static cliExRes_t ustawPortExtBFunction(cmdState_t *state) + 591:vty.c **** { + 592:vty.c **** uint8_t wyjscie = cmdlineGetArgInt(1, state); + 593:vty.c **** MPC23s17SetDirB(0x00, 0); + 594:vty.c **** MPC23s17SetPortB(wyjscie, 0); + 595:vty.c **** return OK_SILENT; + 596:vty.c **** } + 597:vty.c **** + 598:vty.c **** static cliExRes_t ustawPortRezystor(cmdState_t *state) + 599:vty.c **** { + 600:vty.c **** if (state->argc < 1) + 601:vty.c **** return SYNTAX_ERROR; + 602:vty.c **** + 603:vty.c **** uint8_t wartosc = cmdlineGetArgInt(1, state); + 604:vty.c **** + 605:vty.c **** MCP4150_setValue(wartosc); + 606:vty.c **** + 607:vty.c **** return OK_SILENT; + 608:vty.c **** } + 609:vty.c **** + 610:vty.c **** static cliExRes_t rpingFunction(cmdState_t *state) + 611:vty.c **** { + 612:vty.c **** if (state->argc < 1) + 613:vty.c **** return SYNTAX_ERROR; + 614:vty.c **** + 615:vty.c **** uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + 616:vty.c **** if ((state->err2 = rs485ping(nrSterownika)) == 0) + 617:vty.c **** return OK_INFORM; + 618:vty.c **** + 619:vty.c **** state->errno = noRemoteDevice; + 620:vty.c **** state->err1 = nrSterownika; + 621:vty.c **** printErrorInfo(state); + 622:vty.c **** return OK_SILENT; + 623:vty.c **** } + 624:vty.c **** + 625:vty.c **** static cliExRes_t pingFunction(cmdState_t *state) + 626:vty.c **** { + 405 .LM19: + 406 .LFBB4: + 407 /* prologue: function */ + 408 /* frame size = 0 */ + 409 /* stack size = 0 */ + 410 .L__stack_usage = 0 + 627:vty.c **** if (state->argc < 4) + 412 .LM20: + 413 0058 FC01 movw r30,r24 + 414 005a 818D ldd r24,Z+25 + 415 005c 8430 cpi r24,lo8(4) + 416 005e 00F0 brlo .L15 + 628:vty.c **** return SYNTAX_ERROR; + 629:vty.c **** + 630:vty.c **** //uint8_t ip[4]; + 631:vty.c **** //ip[0] = (uint8_t)(cmdlineGetArgInt(1, state)); + 632:vty.c **** //ip[1] = (uint8_t)(cmdlineGetArgInt(2, state)); + 633:vty.c **** //ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + 634:vty.c **** //ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + 635:vty.c **** //Ipv4Ping(*((uint32_t *)(ip))); + 636:vty.c **** + 637:vty.c **** return OK_SILENT; + 418 .LM21: + 419 0060 80E0 ldi r24,0 + 420 0062 90E0 ldi r25,0 + 421 0064 0895 ret + 422 .L15: + 628:vty.c **** return SYNTAX_ERROR; + 424 .LM22: + 425 0066 82E0 ldi r24,lo8(2) + 426 0068 90E0 ldi r25,0 + 638:vty.c **** } + 428 .LM23: + 429 006a 0895 ret + 431 .Lscope4: + 433 .stabd 78,0,0 + 437 readRamFIleFunction: + 438 .stabd 46,0,0 + 639:vty.c **** + 640:vty.c **** + 641:vty.c **** static cliExRes_t flashExModuleFunction(cmdState_t *state) + 642:vty.c **** { + 643:vty.c **** if (state->argc != 2) + 644:vty.c **** return SYNTAX_ERROR; + 645:vty.c **** + 646:vty.c **** uint8_t nrUrzadzenia = cmdlineGetArgInt(1, state); + 647:vty.c **** char *nazwaPliku = cmdlineGetArgStr(2, state); + 648:vty.c **** uint8_t blad; + 649:vty.c **** + 650:vty.c **** // Sprawdzanie, czy moduł wykonawczy odpowiada + 651:vty.c **** if (rs485ping(nrUrzadzenia) != 0) + 652:vty.c **** { + 653:vty.c **** state->errno = noRemoteDevice; + 654:vty.c **** printErrorInfo(state); + 655:vty.c **** return ERROR_INFORM; + 656:vty.c **** } + 657:vty.c **** + 658:vty.c **** //Sprawdzanie, czy istnieje odpowiedni plik z firmware + 659:vty.c **** if (ramDyskOtworzPlik(nazwaPliku, &fdVty) != 0) + 660:vty.c **** { + 661:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, nazwaPliku); + 662:vty.c **** return ERROR_INFORM; + 663:vty.c **** } + 664:vty.c **** + 665:vty.c **** blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + 666:vty.c **** + 667:vty.c **** ramDyskZamknijPlik(&fdVty); + 668:vty.c **** + 669:vty.c **** if (blad != 0) + 670:vty.c **** return ERROR_INFORM; + 671:vty.c **** + 672:vty.c **** return OK_SILENT; + 673:vty.c **** } + 674:vty.c **** + 675:vty.c **** static cliExRes_t goXmodemWyslijFunction(cmdState_t *state) // TODO add code in xModem + 676:vty.c **** { + 677:vty.c **** fprintf_P(state->myStdInOut, xwyslijStartStr); + 678:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 679:vty.c **** { + 680:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 681:vty.c **** return ERROR_INFORM; + 682:vty.c **** } + 683:vty.c **** return OK_SILENT; + 684:vty.c **** } + 685:vty.c **** + 686:vty.c **** static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state) //TODO move to xmodem + 687:vty.c **** { + 688:vty.c **** fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + 689:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 690:vty.c **** { + 691:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 692:vty.c **** return ERROR_INFORM; + 693:vty.c **** } + 694:vty.c **** + 695:vty.c **** uint8_t i = 25; + 696:vty.c **** + 697:vty.c **** uint8_t temp1; + 698:vty.c **** // uint8_t temp2; + 699:vty.c **** + 700:vty.c **** uint8_t c; + 701:vty.c **** uint8_t liczbaProb; + 702:vty.c **** uint8_t *zapPtr; + 703:vty.c **** uint8_t *zapPtrKopia; + 704:vty.c **** + 705:vty.c **** uint16_t crcLokalne; + 706:vty.c **** uint8_t nrBloku; + 707:vty.c **** + 708:vty.c **** uint8_t nrBlokuZdalny; + 709:vty.c **** uint8_t nrBlokuZdalnyNeg; + 710:vty.c **** + 711:vty.c **** uint8_t crcHi; + 712:vty.c **** uint8_t crcLo; + 713:vty.c **** + 714:vty.c **** state->err1=0; + 715:vty.c **** state->err2=0; + 716:vty.c **** liczbaProb = 20; + 717:vty.c **** for ( ; ; ) + 718:vty.c **** { + 719:vty.c **** fputc('C' , state->myStdInOut); + 720:vty.c **** while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + 721:vty.c **** + 722:vty.c **** if(xQueueReceive(xVtyRec, &c, 100)) + 723:vty.c **** if (c == SOH) + 724:vty.c **** break; //Rozpoczynamy transmisje + 725:vty.c **** + 726:vty.c **** liczbaProb--; + 727:vty.c **** if (liczbaProb == 0) + 728:vty.c **** { + 729:vty.c **** ramDyskZamknijPlik(&fdVty); + 730:vty.c **** state->errno = (uint8_t)(AllOK); + 731:vty.c **** return ERROR_INFORM; + 732:vty.c **** } + 733:vty.c **** } + 734:vty.c **** + 735:vty.c **** nrBloku = 1; + 736:vty.c **** liczbaProb = 10; + 737:vty.c **** + 738:vty.c **** zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 739:vty.c **** zapPtrKopia = zapPtr; + 740:vty.c **** for ( ; ; ) + 741:vty.c **** { + 742:vty.c **** if (!xQueueReceive(xVtyRec, &nrBlokuZdalny, 100)) + 743:vty.c **** { + 744:vty.c **** state->errno = (uint8_t)(xModemFrameStartTimeout); + 745:vty.c **** break; + 746:vty.c **** } + 747:vty.c **** + 748:vty.c **** if (!xQueueReceive(xVtyRec, &nrBlokuZdalnyNeg, 1)) + 749:vty.c **** { + 750:vty.c **** state->errno = (uint8_t)(xModemByteSendTimeout); + 751:vty.c **** break; + 752:vty.c **** } + 753:vty.c **** + 754:vty.c **** //1 Sprawdzanie, czy pasuje numer bloku z numerem bloku w usupełnieniu bitowym do 1 + 755:vty.c **** c = 255-nrBlokuZdalnyNeg; + 756:vty.c **** if (nrBlokuZdalny != c) + 757:vty.c **** { + 758:vty.c **** state->errno = (uint8_t)(xModemFrameFrameNoCorrectionNotMatch); + 759:vty.c **** state->err1 = nrBlokuZdalny; + 760:vty.c **** state->err2 = nrBlokuZdalnyNeg; + 761:vty.c **** break; + 762:vty.c **** } + 763:vty.c **** + 764:vty.c **** //Sprawdzenie, czy nie jest wznowiona transmisja poprzedniego bloku lub nie zaczęła się od b + 765:vty.c **** c = nrBloku-1; + 766:vty.c **** if (nrBlokuZdalny == c) + 767:vty.c **** { + 768:vty.c **** nrBloku = c; //Cofnięcie nr aktualnego bloku o 1 + 769:vty.c **** zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 770:vty.c **** zapPtrKopia = zapPtr; + 771:vty.c **** } + 772:vty.c **** + 773:vty.c **** //2 Sprawdzanie, czy pasuje numer bloku + 774:vty.c **** if (nrBlokuZdalny != nrBloku) + 775:vty.c **** { + 776:vty.c **** state->errno = (uint8_t)(xModemWrongFrameNo); + 777:vty.c **** state->err1 = nrBlokuZdalnyNeg; + 778:vty.c **** state->err2 = nrBloku; + 779:vty.c **** break; + 780:vty.c **** } + 781:vty.c **** + 782:vty.c **** for (i=0; i < XMODEM_BUFFER_SIZE; i++) + 783:vty.c **** { + 784:vty.c **** if(xQueueReceive(xVtyRec, &c, 10)) + 785:vty.c **** *(zapPtr++) = c; + 786:vty.c **** else + 787:vty.c **** { + 788:vty.c **** state->errno = (uint8_t)(xModemByteSendTimeout); + 789:vty.c **** break; + 790:vty.c **** } + 791:vty.c **** } + 792:vty.c **** if (!xQueueReceive(xVtyRec, &crcHi, 10)) + 793:vty.c **** { + 794:vty.c **** state->errno = (uint8_t)(xModemFrameCrc); + 795:vty.c **** state->err1 = 2; + 796:vty.c **** break; + 797:vty.c **** } + 798:vty.c **** if (!xQueueReceive(xVtyRec, &crcLo, 10)) + 799:vty.c **** { + 800:vty.c **** state->errno = (uint8_t)(xModemFrameCrc); + 801:vty.c **** state->err1 = 1; + 802:vty.c **** break; + 803:vty.c **** } + 804:vty.c **** + 805:vty.c **** //3 Zerowanie CRC + 806:vty.c **** crcLokalne=0; + 807:vty.c **** + 808:vty.c **** //4 Obliczanie CRC + 809:vty.c **** for (i=0; i < XMODEM_BUFFER_SIZE; i++) + 810:vty.c **** crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + 811:vty.c **** + 812:vty.c **** //5 Srawdzanie CRC + 813:vty.c **** if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + 814:vty.c **** { + 815:vty.c **** liczbaProb = 10; + 816:vty.c **** uartVtySendByte(ACK); + 817:vty.c **** } + 818:vty.c **** else + 819:vty.c **** { + 820:vty.c **** liczbaProb--; + 821:vty.c **** nrBloku--; + 822:vty.c **** uartVtySendByte(NAK); + 823:vty.c **** } + 824:vty.c **** + 825:vty.c **** if (liczbaProb == 0) + 826:vty.c **** { + 827:vty.c **** state->err1 = nrBlokuZdalny; + 828:vty.c **** state->err2 = nrBloku; + 829:vty.c **** state->errno = (uint8_t)(xModemWrongFrameNo); + 830:vty.c **** break; + 831:vty.c **** } + 832:vty.c **** + 833:vty.c **** if (!xQueueReceive(xVtyRec, &temp1, 100)) + 834:vty.c **** { + 835:vty.c **** state->errno = (uint8_t)(xModemFrameStartTimeout); + 836:vty.c **** break; + 837:vty.c **** } + 838:vty.c **** + 839:vty.c **** if (temp1 == SOH) + 840:vty.c **** { + 841:vty.c **** nrBloku++; + 842:vty.c **** zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 843:vty.c **** zapPtrKopia = zapPtr; + 844:vty.c **** state->errno = (uint8_t)(AllOK); + 845:vty.c **** continue; + 846:vty.c **** } + 847:vty.c **** + 848:vty.c **** if (temp1 == CAN) + 849:vty.c **** { + 850:vty.c **** state->err1 = nrBloku; + 851:vty.c **** state->errno = (uint8_t)(xModemRemoteSideCan); + 852:vty.c **** break; + 853:vty.c **** } + 854:vty.c **** if (temp1 == EOT) + 855:vty.c **** { + 856:vty.c **** uartVtySendByte(NAK); + 857:vty.c **** if (xQueueReceive(xVtyRec, &temp1, 10)) + 858:vty.c **** { + 859:vty.c **** if (temp1 == EOT) + 860:vty.c **** uartVtySendByte(ACK); + 861:vty.c **** } + 862:vty.c **** state->errno = (uint8_t)(AllOK); + 863:vty.c **** break; + 864:vty.c **** } + 865:vty.c **** state->errno = (uint8_t)(xModemUnknownResponse); + 866:vty.c **** state->err1 = temp1; + 867:vty.c **** break; + 868:vty.c **** } + 869:vty.c **** ramDyskZamknijPlik(&fdVty); + 870:vty.c **** return OK_SILENT; + 871:vty.c **** } + 872:vty.c **** + 873:vty.c **** static cliExRes_t eraseRamFileFunction(cmdState_t *state) + 874:vty.c **** { + 875:vty.c **** if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + 876:vty.c **** return OK_INFORM; + 877:vty.c **** + 878:vty.c **** printErrorInfo(state); + 879:vty.c **** return ERROR_INFORM; + 880:vty.c **** } + 881:vty.c **** + 882:vty.c **** static cliExRes_t dodajRamPlikFunction(cmdState_t *state) + 883:vty.c **** { + 884:vty.c **** if (state->argc != 1) + 885:vty.c **** return SYNTAX_ERROR; + 886:vty.c **** + 887:vty.c **** if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + 888:vty.c **** { + 889:vty.c **** return OK_INFORM; + 890:vty.c **** } + 891:vty.c **** printErrorInfo(state); + 892:vty.c **** return ERROR_INFORM; + 893:vty.c **** } + 894:vty.c **** + 895:vty.c **** static cliExRes_t writeRamFileFunction(cmdState_t *state) + 896:vty.c **** { + 897:vty.c **** ramDyskDir(state->myStdInOut); + 898:vty.c **** return OK_SILENT; + 899:vty.c **** } + 900:vty.c **** + 901:vty.c **** static cliExRes_t editRamFileFunction(cmdState_t *state) + 902:vty.c **** { + 903:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 904:vty.c **** { + 905:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 906:vty.c **** return ERROR_INFORM; + 907:vty.c **** } + 908:vty.c **** ramDyskUstawWskaznikNaKoniec(&fdVty); + 909:vty.c **** uint8_t znak = 0; + 910:vty.c **** fprintf_P(state->myStdInOut, editRamFileIntroStr); + 911:vty.c **** while(1) + 912:vty.c **** { + 913:vty.c **** if(!xQueueReceive( xVtyRec, &znak, portMAX_DELAY)) + 914:vty.c **** continue; + 915:vty.c **** + 916:vty.c **** if (znak == 0x03) // ^C + 917:vty.c **** break; + 918:vty.c **** + 919:vty.c **** uartVtySendByte(znak); //Echo + 920:vty.c **** ramDyskZapiszBajtDoPliku(&fdVty, znak); + 921:vty.c **** } + 922:vty.c **** ramDyskZamknijPlik(&fdVty); + 923:vty.c **** return OK_SILENT; + 924:vty.c **** } + 925:vty.c **** + 926:vty.c **** static cliExRes_t readRamFIleFunction(cmdState_t *state) //TODO move this code to fat8 + 927:vty.c **** { + 440 .LM24: + 441 .LFBB5: + 442 006c FF92 push r15 + 443 006e 0F93 push r16 + 444 0070 1F93 push r17 + 445 0072 CF93 push r28 + 446 0074 DF93 push r29 + 447 0076 1F92 push __zero_reg__ + 448 0078 CDB7 in r28,__SP_L__ + 449 007a DEB7 in r29,__SP_H__ + 450 /* prologue: function */ + 451 /* frame size = 1 */ + 452 /* stack size = 6 */ + 453 .L__stack_usage = 6 + 454 007c 8C01 movw r16,r24 + 928:vty.c **** uint8_t rezultat; + 929:vty.c **** uint8_t znak = ' '; + 456 .LM25: + 457 007e 80E2 ldi r24,lo8(32) + 458 0080 8983 std Y+1,r24 + 930:vty.c **** if ((rezultat = ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty)) != 0) + 460 .LM26: + 461 0082 B801 movw r22,r16 + 462 0084 81E0 ldi r24,lo8(1) + 463 0086 0E94 0000 call cmdlineGetArgStr + 464 008a 60E0 ldi r22,lo8(fdVty) + 465 008c 70E0 ldi r23,hi8(fdVty) + 466 008e 0E94 0000 call ramDyskOtworzPlik + 467 0092 8823 tst r24 + 468 0094 01F0 breq .L17 + 931:vty.c **** { + 932:vty.c **** fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + 470 .LM27: + 471 0096 B801 movw r22,r16 + 472 0098 81E0 ldi r24,lo8(1) + 473 009a 0E94 0000 call cmdlineGetArgStr + 474 009e 9F93 push r25 + 475 00a0 8F93 push r24 + 476 00a2 80E0 ldi r24,lo8(errorOpenFile) + 477 00a4 90E0 ldi r25,hi8(errorOpenFile) + 478 00a6 9F93 push r25 + 479 00a8 8F93 push r24 + 480 00aa F801 movw r30,r16 + 481 00ac 838D ldd r24,Z+27 + 482 00ae 8F93 push r24 + 483 00b0 828D ldd r24,Z+26 + 484 00b2 8F93 push r24 + 485 00b4 0E94 0000 call fprintf_P + 933:vty.c **** return ERROR_INFORM; + 487 .LM28: + 488 00b8 0F90 pop __tmp_reg__ + 489 00ba 0F90 pop __tmp_reg__ + 490 00bc 0F90 pop __tmp_reg__ + 491 00be 0F90 pop __tmp_reg__ + 492 00c0 0F90 pop __tmp_reg__ + 493 00c2 0F90 pop __tmp_reg__ + 494 00c4 84E0 ldi r24,lo8(4) + 495 00c6 90E0 ldi r25,0 + 496 00c8 00C0 rjmp .L18 + 497 .L17: + 934:vty.c **** } + 935:vty.c **** uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + 499 .LM29: + 500 00ca E091 0000 lds r30,fdVty+4 + 501 00ce F091 0000 lds r31,fdVty+4+1 + 502 00d2 8281 ldd r24,Z+2 + 503 00d4 90E0 ldi r25,0 + 504 00d6 982F mov r25,r24 + 505 00d8 8827 clr r24 + 506 00da 2181 ldd r18,Z+1 + 507 00dc 820F add r24,r18 + 508 00de 911D adc r25,__zero_reg__ + 936:vty.c **** fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + 510 .LM30: + 511 00e0 9F93 push r25 + 512 00e2 8F93 push r24 + 513 00e4 80E0 ldi r24,lo8(readRamFIleLenStr) + 514 00e6 90E0 ldi r25,hi8(readRamFIleLenStr) + 515 00e8 9F93 push r25 + 516 00ea 8F93 push r24 + 517 00ec F801 movw r30,r16 + 518 00ee 838D ldd r24,Z+27 + 519 00f0 8F93 push r24 + 520 00f2 828D ldd r24,Z+26 + 521 00f4 8F93 push r24 + 522 00f6 0E94 0000 call fprintf_P + 523 00fa 0F90 pop __tmp_reg__ + 524 00fc 0F90 pop __tmp_reg__ + 525 00fe 0F90 pop __tmp_reg__ + 526 0100 0F90 pop __tmp_reg__ + 527 0102 0F90 pop __tmp_reg__ + 528 0104 0F90 pop __tmp_reg__ + 529 .L20: + 937:vty.c **** while (rezultat == 0) + 938:vty.c **** { + 939:vty.c **** rezultat = ramDyskCzytajBajtZPliku(&fdVty, &znak); + 531 .LM31: + 532 0106 BE01 movw r22,r28 + 533 0108 6F5F subi r22,-1 + 534 010a 7F4F sbci r23,-1 + 535 010c 80E0 ldi r24,lo8(fdVty) + 536 010e 90E0 ldi r25,hi8(fdVty) + 537 0110 0E94 0000 call ramDyskCzytajBajtZPliku + 538 0114 F82E mov r15,r24 + 940:vty.c **** + 941:vty.c **** uartVtySendByte(znak); + 540 .LM32: + 541 0116 8981 ldd r24,Y+1 + 542 0118 0E94 0000 call uartVtySendByte + 942:vty.c **** if (znak == '\r') + 544 .LM33: + 545 011c 8981 ldd r24,Y+1 + 546 011e 8D30 cpi r24,lo8(13) + 547 0120 01F4 brne .L19 + 943:vty.c **** uartVtySendByte('\n'); + 549 .LM34: + 550 0122 8AE0 ldi r24,lo8(10) + 551 0124 0E94 0000 call uartVtySendByte + 552 .L19: + 937:vty.c **** { + 554 .LM35: + 555 0128 FF20 tst r15 + 556 012a 01F0 breq .L20 + 944:vty.c **** } + 945:vty.c **** fprintf_P(state->myStdInOut, nlStr); + 558 .LM36: + 559 012c 80E0 ldi r24,lo8(nlStr) + 560 012e 90E0 ldi r25,hi8(nlStr) + 561 0130 9F93 push r25 + 562 0132 8F93 push r24 + 563 0134 F801 movw r30,r16 + 564 0136 838D ldd r24,Z+27 + 565 0138 8F93 push r24 + 566 013a 828D ldd r24,Z+26 + 567 013c 8F93 push r24 + 568 013e 0E94 0000 call fprintf_P + 946:vty.c **** ramDyskZamknijPlik(&fdVty); + 570 .LM37: + 571 0142 80E0 ldi r24,lo8(fdVty) + 572 0144 90E0 ldi r25,hi8(fdVty) + 573 0146 0E94 0000 call ramDyskZamknijPlik + 947:vty.c **** return OK_SILENT; + 575 .LM38: + 576 014a 0F90 pop __tmp_reg__ + 577 014c 0F90 pop __tmp_reg__ + 578 014e 0F90 pop __tmp_reg__ + 579 0150 0F90 pop __tmp_reg__ + 580 0152 80E0 ldi r24,0 + 581 0154 90E0 ldi r25,0 + 582 .L18: + 583 /* epilogue start */ + 948:vty.c **** } + 585 .LM39: + 586 0156 0F90 pop __tmp_reg__ + 587 0158 DF91 pop r29 + 588 015a CF91 pop r28 + 589 015c 1F91 pop r17 + 590 015e 0F91 pop r16 + 591 0160 FF90 pop r15 + 592 0162 0895 ret + 597 .Lscope5: + 599 .stabd 78,0,0 + 603 writeRamFileFunction: + 604 .stabd 46,0,0 + 896:vty.c **** ramDyskDir(state->myStdInOut); + 606 .LM40: + 607 .LFBB6: + 608 /* prologue: function */ + 609 /* frame size = 0 */ + 610 /* stack size = 0 */ + 611 .L__stack_usage = 0 + 897:vty.c **** return OK_SILENT; + 613 .LM41: + 614 0164 FC01 movw r30,r24 + 615 0166 828D ldd r24,Z+26 + 616 0168 938D ldd r25,Z+27 + 617 016a 0E94 0000 call ramDyskDir + 899:vty.c **** + 619 .LM42: + 620 016e 80E0 ldi r24,0 + 621 0170 90E0 ldi r25,0 + 622 0172 0895 ret + 624 .Lscope6: + 626 .stabd 78,0,0 + 630 pokazCzasFunction: + 631 .stabd 46,0,0 + 298:vty.c **** readTimeDecoded((timeDecoded_t *)(&czasRtc)); + 633 .LM43: + 634 .LFBB7: + 635 0174 CF93 push r28 + 636 0176 DF93 push r29 + 637 /* prologue: function */ + 638 /* frame size = 0 */ + 639 /* stack size = 2 */ + 640 .L__stack_usage = 2 + 641 0178 EC01 movw r28,r24 + 299:vty.c **** uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + 643 .LM44: + 644 017a 80E0 ldi r24,lo8(czasRtc) + 645 017c 90E0 ldi r25,hi8(czasRtc) + 646 017e 0E94 0000 call readTimeDecoded + 300:vty.c **** uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 648 .LM45: + 649 0182 E0E0 ldi r30,lo8(czasRtc+2) + 650 0184 F0E0 ldi r31,hi8(czasRtc+2) + 651 0186 9081 ld r25,Z + 652 0188 9695 lsr r25 + 653 018a 9695 lsr r25 + 654 018c 9695 lsr r25 + 655 018e 8081 ld r24,Z + 656 0190 8F70 andi r24,lo8(15) + 301:vty.c **** uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + 658 .LM46: + 659 0192 E0E0 ldi r30,lo8(czasRtc+1) + 660 0194 F0E0 ldi r31,hi8(czasRtc+1) + 661 0196 2081 ld r18,Z + 662 0198 2695 lsr r18 + 663 019a 2695 lsr r18 + 664 019c 2695 lsr r18 + 665 019e 4081 ld r20,Z + 666 01a0 4F70 andi r20,lo8(15) + 302:vty.c **** fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + 668 .LM47: + 669 01a2 E0E0 ldi r30,lo8(czasRtc) + 670 01a4 F0E0 ldi r31,hi8(czasRtc) + 671 01a6 3081 ld r19,Z + 672 01a8 3695 lsr r19 + 673 01aa 3695 lsr r19 + 674 01ac 3695 lsr r19 + 675 01ae 5081 ld r21,Z + 676 01b0 5F70 andi r21,lo8(15) + 677 01b2 3E70 andi r19,lo8(14) + 678 01b4 632F mov r22,r19 + 679 01b6 660F lsl r22 + 680 01b8 660F lsl r22 + 681 01ba 360F add r19,r22 + 682 01bc 350F add r19,r21 + 303:vty.c **** return OK_SILENT; + 684 .LM48: + 685 01be 1F92 push __zero_reg__ + 686 01c0 3F93 push r19 + 301:vty.c **** uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + 688 .LM49: + 689 01c2 2E70 andi r18,lo8(14) + 690 01c4 322F mov r19,r18 + 691 01c6 330F lsl r19 + 692 01c8 330F lsl r19 + 693 01ca 230F add r18,r19 + 694 01cc 240F add r18,r20 + 303:vty.c **** return OK_SILENT; + 696 .LM50: + 697 01ce 1F92 push __zero_reg__ + 698 01d0 2F93 push r18 + 300:vty.c **** uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + 700 .LM51: + 701 01d2 9670 andi r25,lo8(6) + 702 01d4 292F mov r18,r25 + 703 01d6 220F lsl r18 + 704 01d8 220F lsl r18 + 705 01da 920F add r25,r18 + 706 01dc 980F add r25,r24 + 303:vty.c **** return OK_SILENT; + 708 .LM52: + 709 01de 1F92 push __zero_reg__ + 710 01e0 9F93 push r25 + 711 01e2 80E0 ldi r24,lo8(__c.3649) + 712 01e4 90E0 ldi r25,hi8(__c.3649) + 713 01e6 9F93 push r25 + 714 01e8 8F93 push r24 + 715 01ea 8B8D ldd r24,Y+27 + 716 01ec 8F93 push r24 + 717 01ee 8A8D ldd r24,Y+26 + 718 01f0 8F93 push r24 + 719 01f2 0E94 0000 call fprintf_P + 304:vty.c **** } + 721 .LM53: + 722 01f6 8DB7 in r24,__SP_L__ + 723 01f8 9EB7 in r25,__SP_H__ + 724 01fa 0A96 adiw r24,10 + 725 01fc 0FB6 in __tmp_reg__,__SREG__ + 726 01fe F894 cli + 727 0200 9EBF out __SP_H__,r25 + 728 0202 0FBE out __SREG__,__tmp_reg__ + 729 0204 8DBF out __SP_L__,r24 + 305:vty.c **** + 731 .LM54: + 732 0206 80E0 ldi r24,0 + 733 0208 90E0 ldi r25,0 + 734 /* epilogue start */ + 735 020a DF91 pop r29 + 736 020c CF91 pop r28 + 737 020e 0895 ret + 739 .Lscope7: + 741 .stabd 78,0,0 + 745 helpFunction: + 746 .stabd 46,0,0 + 530:vty.c **** cmdPrintHelp(state); + 748 .LM55: + 749 .LFBB8: + 750 /* prologue: function */ + 751 /* frame size = 0 */ + 752 /* stack size = 0 */ + 753 .L__stack_usage = 0 + 531:vty.c **** return OK_SILENT; + 755 .LM56: + 756 0210 0E94 0000 call cmdPrintHelp + 533:vty.c **** + 758 .LM57: + 759 0214 80E0 ldi r24,0 + 760 0216 90E0 ldi r25,0 + 761 0218 0895 ret + 763 .Lscope8: + 765 .stabd 78,0,0 + 769 czytajAC_Function: + 770 .stabd 46,0,0 + 522:vty.c **** uint8_t nrWejscia = cmdlineGetArgInt(1, state); + 772 .LM58: + 773 .LFBB9: + 774 021a 0F93 push r16 + 775 021c 1F93 push r17 + 776 021e CF93 push r28 + 777 0220 DF93 push r29 + 778 0222 1F92 push __zero_reg__ + 779 0224 CDB7 in r28,__SP_L__ + 780 0226 DEB7 in r29,__SP_H__ + 781 /* prologue: function */ + 782 /* frame size = 1 */ + 783 /* stack size = 5 */ + 784 .L__stack_usage = 5 + 785 0228 8C01 movw r16,r24 + 523:vty.c **** uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + 787 .LM59: + 788 022a BC01 movw r22,r24 + 789 022c 81E0 ldi r24,lo8(1) + 790 022e 0E94 0000 call cmdlineGetArgInt + 524:vty.c **** fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + 792 .LM60: + 793 0232 862F mov r24,r22 + 794 0234 6983 std Y+1,r22 + 795 0236 0E94 0000 call MCP3008_getSampleSingle + 525:vty.c **** return OK_SILENT; + 797 .LM61: + 798 023a 9F93 push r25 + 799 023c 8F93 push r24 + 800 023e 1F92 push __zero_reg__ + 801 0240 6981 ldd r22,Y+1 + 802 0242 6F93 push r22 + 803 0244 80E0 ldi r24,lo8(__c.3718) + 804 0246 90E0 ldi r25,hi8(__c.3718) + 805 0248 9F93 push r25 + 806 024a 8F93 push r24 + 807 024c F801 movw r30,r16 + 808 024e 838D ldd r24,Z+27 + 809 0250 8F93 push r24 + 810 0252 828D ldd r24,Z+26 + 811 0254 8F93 push r24 + 812 0256 0E94 0000 call fprintf_P + 526:vty.c **** } + 814 .LM62: + 815 025a 0FB6 in __tmp_reg__,__SREG__ + 816 025c F894 cli + 817 025e DEBF out __SP_H__,r29 + 818 0260 0FBE out __SREG__,__tmp_reg__ + 819 0262 CDBF out __SP_L__,r28 + 527:vty.c **** + 821 .LM63: + 822 0264 80E0 ldi r24,0 + 823 0266 90E0 ldi r25,0 + 824 /* epilogue start */ + 825 0268 0F90 pop __tmp_reg__ + 826 026a DF91 pop r29 + 827 026c CF91 pop r28 + 828 026e 1F91 pop r17 + 829 0270 0F91 pop r16 + 830 0272 0895 ret + 832 .Lscope9: + 834 .stabd 78,0,0 + 838 setTimeFunction: + 839 .stabd 46,0,0 + 396:vty.c **** uint8_t godzina = cmdlineGetArgInt(1, state); + 841 .LM64: + 842 .LFBB10: + 843 0274 EF92 push r14 + 844 0276 FF92 push r15 + 845 0278 1F93 push r17 + 846 027a CF93 push r28 + 847 027c DF93 push r29 + 848 /* prologue: function */ + 849 /* frame size = 0 */ + 850 /* stack size = 5 */ + 851 .L__stack_usage = 5 + 852 027e 7C01 movw r14,r24 + 397:vty.c **** uint8_t minuta = cmdlineGetArgInt(2, state); + 854 .LM65: + 855 0280 BC01 movw r22,r24 + 856 0282 81E0 ldi r24,lo8(1) + 857 0284 0E94 0000 call cmdlineGetArgInt + 858 0288 162F mov r17,r22 + 398:vty.c **** uint8_t sekunda = cmdlineGetArgInt(3, state); + 860 .LM66: + 861 028a B701 movw r22,r14 + 862 028c 82E0 ldi r24,lo8(2) + 863 028e 0E94 0000 call cmdlineGetArgInt + 864 0292 D62F mov r29,r22 + 399:vty.c **** + 866 .LM67: + 867 0294 B701 movw r22,r14 + 868 0296 83E0 ldi r24,lo8(3) + 869 0298 0E94 0000 call cmdlineGetArgInt + 870 029c C62F mov r28,r22 + 401:vty.c **** + 872 .LM68: + 873 029e 0E94 0000 call ds1305start + 403:vty.c **** uint8_t cJedn = godzina - cDzies*10; + 875 .LM69: + 876 02a2 4AE0 ldi r20,lo8(10) + 877 02a4 812F mov r24,r17 + 878 02a6 642F mov r22,r20 + 879 02a8 0E94 0000 call __udivmodqi4 + 405:vty.c **** czasRtc.hours.syst24.cJedn = cJedn; + 881 .LM70: + 882 02ac 982F mov r25,r24 + 883 02ae 9370 andi r25,lo8(3) + 884 02b0 E0E0 ldi r30,lo8(czasRtc+2) + 885 02b2 F0E0 ldi r31,hi8(czasRtc+2) + 886 02b4 292F mov r18,r25 + 887 02b6 2295 swap r18 + 888 02b8 207F andi r18,lo8(-16) + 889 02ba 9081 ld r25,Z + 890 02bc 9F7C andi r25,lo8(-49) + 891 02be 922B or r25,r18 + 892 02c0 9083 st Z,r25 + 404:vty.c **** czasRtc.hours.syst24.cDzies = cDzies; + 894 .LM71: + 895 02c2 36EF ldi r19,lo8(-10) + 896 02c4 839F mul r24,r19 + 897 02c6 100D add r17,r0 + 898 02c8 1124 clr __zero_reg__ + 406:vty.c **** + 900 .LM72: + 901 02ca 812F mov r24,r17 + 902 02cc 8F70 andi r24,lo8(15) + 903 02ce 1081 ld r17,Z + 904 02d0 107F andi r17,lo8(-16) + 905 02d2 182B or r17,r24 + 906 02d4 1083 st Z,r17 + 408:vty.c **** cJedn = minuta - cDzies * 10; + 908 .LM73: + 909 02d6 8D2F mov r24,r29 + 910 02d8 0E94 0000 call __udivmodqi4 + 410:vty.c **** czasRtc.minutes.cJedn = cJedn; + 912 .LM74: + 913 02dc 982F mov r25,r24 + 914 02de 9770 andi r25,lo8(7) + 915 02e0 E0E0 ldi r30,lo8(czasRtc+1) + 916 02e2 F0E0 ldi r31,hi8(czasRtc+1) + 917 02e4 292F mov r18,r25 + 918 02e6 2295 swap r18 + 919 02e8 207F andi r18,lo8(-16) + 920 02ea 9081 ld r25,Z + 921 02ec 9F78 andi r25,lo8(-113) + 922 02ee 922B or r25,r18 + 923 02f0 9083 st Z,r25 + 409:vty.c **** czasRtc.minutes.cDzies = cDzies; + 925 .LM75: + 926 02f2 839F mul r24,r19 + 927 02f4 D00D add r29,r0 + 928 02f6 1124 clr __zero_reg__ + 411:vty.c **** + 930 .LM76: + 931 02f8 8D2F mov r24,r29 + 932 02fa 8F70 andi r24,lo8(15) + 933 02fc D081 ld r29,Z + 934 02fe D07F andi r29,lo8(-16) + 935 0300 D82B or r29,r24 + 936 0302 D083 st Z,r29 + 413:vty.c **** cJedn = sekunda - cDzies * 10; + 938 .LM77: + 939 0304 8C2F mov r24,r28 + 940 0306 0E94 0000 call __udivmodqi4 + 415:vty.c **** czasRtc.seconds.cJedn = cJedn; + 942 .LM78: + 943 030a 982F mov r25,r24 + 944 030c 9770 andi r25,lo8(7) + 945 030e E0E0 ldi r30,lo8(czasRtc) + 946 0310 F0E0 ldi r31,hi8(czasRtc) + 947 0312 292F mov r18,r25 + 948 0314 2295 swap r18 + 949 0316 207F andi r18,lo8(-16) + 950 0318 9081 ld r25,Z + 951 031a 9F78 andi r25,lo8(-113) + 952 031c 922B or r25,r18 + 953 031e 9083 st Z,r25 + 414:vty.c **** czasRtc.seconds.cDzies = cDzies; + 955 .LM79: + 956 0320 839F mul r24,r19 + 957 0322 C00D add r28,r0 + 958 0324 1124 clr __zero_reg__ + 416:vty.c **** + 960 .LM80: + 961 0326 8C2F mov r24,r28 + 962 0328 8F70 andi r24,lo8(15) + 963 032a C081 ld r28,Z + 964 032c C07F andi r28,lo8(-16) + 965 032e C82B or r28,r24 + 966 0330 C083 st Z,r28 + 418:vty.c **** return OK_SILENT; + 968 .LM81: + 969 0332 CF01 movw r24,r30 + 970 0334 0E94 0000 call setTimeDecoded + 420:vty.c **** + 972 .LM82: + 973 0338 80E0 ldi r24,0 + 974 033a 90E0 ldi r25,0 + 975 /* epilogue start */ + 976 033c DF91 pop r29 + 977 033e CF91 pop r28 + 978 0340 1F91 pop r17 + 979 0342 FF90 pop r15 + 980 0344 EF90 pop r14 + 981 0346 0895 ret + 983 .Lscope10: + 985 .stabd 78,0,0 + 989 ustawPortExtBFunction: + 990 .stabd 46,0,0 + 591:vty.c **** uint8_t wyjscie = cmdlineGetArgInt(1, state); + 992 .LM83: + 993 .LFBB11: + 994 0348 CF93 push r28 + 995 /* prologue: function */ + 996 /* frame size = 0 */ + 997 /* stack size = 1 */ + 998 .L__stack_usage = 1 + 592:vty.c **** MPC23s17SetDirB(0x00, 0); + 1000 .LM84: + 1001 034a BC01 movw r22,r24 + 1002 034c 81E0 ldi r24,lo8(1) + 1003 034e 0E94 0000 call cmdlineGetArgInt + 1004 0352 C62F mov r28,r22 + 593:vty.c **** MPC23s17SetPortB(wyjscie, 0); + 1006 .LM85: + 1007 0354 60E0 ldi r22,0 + 1008 0356 80E0 ldi r24,0 + 1009 0358 0E94 0000 call MPC23s17SetDirB + 594:vty.c **** return OK_SILENT; + 1011 .LM86: + 1012 035c 60E0 ldi r22,0 + 1013 035e 8C2F mov r24,r28 + 1014 0360 0E94 0000 call MPC23s17SetPortB + 596:vty.c **** + 1016 .LM87: + 1017 0364 80E0 ldi r24,0 + 1018 0366 90E0 ldi r25,0 + 1019 /* epilogue start */ + 1020 0368 CF91 pop r28 + 1021 036a 0895 ret + 1023 .Lscope11: + 1025 .stabd 78,0,0 + 1029 ustawPortExtAFunction: + 1030 .stabd 46,0,0 + 583:vty.c **** uint8_t wyjscie = cmdlineGetArgInt(1, state); + 1032 .LM88: + 1033 .LFBB12: + 1034 036c CF93 push r28 + 1035 /* prologue: function */ + 1036 /* frame size = 0 */ + 1037 /* stack size = 1 */ + 1038 .L__stack_usage = 1 + 584:vty.c **** MPC23s17SetDirA(0x00, 0); + 1040 .LM89: + 1041 036e BC01 movw r22,r24 + 1042 0370 81E0 ldi r24,lo8(1) + 1043 0372 0E94 0000 call cmdlineGetArgInt + 1044 0376 C62F mov r28,r22 + 585:vty.c **** MPC23s17SetPortA(wyjscie, 0); + 1046 .LM90: + 1047 0378 60E0 ldi r22,0 + 1048 037a 80E0 ldi r24,0 + 1049 037c 0E94 0000 call MPC23s17SetDirA + 586:vty.c **** return OK_SILENT; + 1051 .LM91: + 1052 0380 60E0 ldi r22,0 + 1053 0382 8C2F mov r24,r28 + 1054 0384 0E94 0000 call MPC23s17SetPortA + 588:vty.c **** + 1056 .LM92: + 1057 0388 80E0 ldi r24,0 + 1058 038a 90E0 ldi r25,0 + 1059 /* epilogue start */ + 1060 038c CF91 pop r28 + 1061 038e 0895 ret + 1063 .Lscope12: + 1065 .stabd 78,0,0 + 1069 curtainDownFunction: + 1070 .stabd 46,0,0 + 536:vty.c **** uint8_t nrRolety; + 1072 .LM93: + 1073 .LFBB13: + 1074 0390 FF92 push r15 + 1075 0392 0F93 push r16 + 1076 0394 1F93 push r17 + 1077 0396 CF93 push r28 + 1078 0398 DF93 push r29 + 1079 /* prologue: function */ + 1080 /* frame size = 0 */ + 1081 /* stack size = 5 */ + 1082 .L__stack_usage = 5 + 1083 039a EC01 movw r28,r24 + 541:vty.c **** nrRolety = cmdlineGetArgInt(2, state); + 1085 .LM94: + 1086 039c BC01 movw r22,r24 + 1087 039e 81E0 ldi r24,lo8(1) + 1088 03a0 0E94 0000 call cmdlineGetArgInt + 1089 03a4 F62E mov r15,r22 + 542:vty.c **** nrRolety &= 0x01; + 1091 .LM95: + 1092 03a6 BE01 movw r22,r28 + 1093 03a8 82E0 ldi r24,lo8(2) + 1094 03aa 0E94 0000 call cmdlineGetArgInt + 543:vty.c **** wartosc = cmdlineGetArgInt(3, state); + 1096 .LM96: + 1097 03ae 162F mov r17,r22 + 1098 03b0 1170 andi r17,lo8(1) + 544:vty.c **** + 1100 .LM97: + 1101 03b2 BE01 movw r22,r28 + 1102 03b4 83E0 ldi r24,lo8(3) + 1103 03b6 0E94 0000 call cmdlineGetArgInt + 1104 03ba 062F mov r16,r22 + 546:vty.c **** + 1106 .LM98: + 1107 03bc 212F mov r18,r17 + 1108 03be 30E0 ldi r19,0 + 1109 03c0 2F5F subi r18,-1 + 1110 03c2 3F4F sbci r19,-1 + 1111 03c4 3F93 push r19 + 1112 03c6 2F93 push r18 + 1113 03c8 1F92 push __zero_reg__ + 1114 03ca FF92 push r15 + 1115 03cc 80E0 ldi r24,lo8(movingCurtainDownStr) + 1116 03ce 90E0 ldi r25,hi8(movingCurtainDownStr) + 1117 03d0 9F93 push r25 + 1118 03d2 8F93 push r24 + 1119 03d4 8B8D ldd r24,Y+27 + 1120 03d6 8F93 push r24 + 1121 03d8 8A8D ldd r24,Y+26 + 1122 03da 8F93 push r24 + 1123 03dc 0E94 0000 call fprintf_P + 548:vty.c **** fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 1125 .LM99: + 1126 03e0 8FEF ldi r24,lo8(-1) + 1127 03e2 800F add r24,r16 + 1128 03e4 2DB7 in r18,__SP_L__ + 1129 03e6 3EB7 in r19,__SP_H__ + 1130 03e8 285F subi r18,-8 + 1131 03ea 3F4F sbci r19,-1 + 1132 03ec 0FB6 in __tmp_reg__,__SREG__ + 1133 03ee F894 cli + 1134 03f0 3EBF out __SP_H__,r19 + 1135 03f2 0FBE out __SREG__,__tmp_reg__ + 1136 03f4 2DBF out __SP_L__,r18 + 1137 03f6 8436 cpi r24,lo8(100) + 1138 03f8 00F4 brsh .L31 + 549:vty.c **** + 1140 .LM100: + 1141 03fa 1F92 push __zero_reg__ + 1142 03fc 0F93 push r16 + 1143 03fe 80E0 ldi r24,lo8(movingCurtainPosStr) + 1144 0400 90E0 ldi r25,hi8(movingCurtainPosStr) + 1145 0402 9F93 push r25 + 1146 0404 8F93 push r24 + 1147 0406 8B8D ldd r24,Y+27 + 1148 0408 8F93 push r24 + 1149 040a 8A8D ldd r24,Y+26 + 1150 040c 8F93 push r24 + 1151 040e 0E94 0000 call fprintf_P + 1152 0412 0F90 pop __tmp_reg__ + 1153 0414 0F90 pop __tmp_reg__ + 1154 0416 0F90 pop __tmp_reg__ + 1155 0418 0F90 pop __tmp_reg__ + 1156 041a 0F90 pop __tmp_reg__ + 1157 041c 0F90 pop __tmp_reg__ + 1158 .L31: + 551:vty.c **** + 1160 .LM101: + 1161 041e 402F mov r20,r16 + 1162 0420 612F mov r22,r17 + 1163 0422 8F2D mov r24,r15 + 1164 0424 0E94 0000 call rs485curtainDown + 553:vty.c **** return OK_INFORM; + 1166 .LM102: + 1167 0428 8823 tst r24 + 1168 042a 01F0 breq .L33 + 556:vty.c **** } + 1170 .LM103: + 1171 042c 83E0 ldi r24,lo8(3) + 1172 042e 90E0 ldi r25,0 + 1173 0430 00C0 rjmp .L32 + 1174 .L33: + 554:vty.c **** + 1176 .LM104: + 1177 0432 81E0 ldi r24,lo8(1) + 1178 0434 90E0 ldi r25,0 + 1179 .L32: + 1180 /* epilogue start */ + 557:vty.c **** + 1182 .LM105: + 1183 0436 DF91 pop r29 + 1184 0438 CF91 pop r28 + 1185 043a 1F91 pop r17 + 1186 043c 0F91 pop r16 + 1187 043e FF90 pop r15 + 1188 0440 0895 ret + 1194 .Lscope13: + 1196 .stabd 78,0,0 + 1200 statusEncFunction: + 1201 .stabd 46,0,0 + 292:vty.c **** nicRegDump(state->myStdInOut); + 1203 .LM106: + 1204 .LFBB14: + 1205 /* prologue: function */ + 1206 /* frame size = 0 */ + 1207 /* stack size = 0 */ + 1208 .L__stack_usage = 0 + 293:vty.c **** return OK_SILENT; + 1210 .LM107: + 1211 0442 FC01 movw r30,r24 + 1212 0444 828D ldd r24,Z+26 + 1213 0446 938D ldd r25,Z+27 + 1214 0448 0E94 0000 call nicRegDump + 295:vty.c **** + 1216 .LM108: + 1217 044c 80E0 ldi r24,0 + 1218 044e 90E0 ldi r25,0 + 1219 0450 0895 ret + 1221 .Lscope14: + 1223 .stabd 78,0,0 + 1227 saveConfigFunction: + 1228 .stabd 46,0,0 + 949:vty.c **** + 950:vty.c **** static cliExRes_t saveConfigFunction(cmdState_t *state) + 951:vty.c **** { + 1230 .LM109: + 1231 .LFBB15: + 1232 /* prologue: function */ + 1233 /* frame size = 0 */ + 1234 /* stack size = 0 */ + 1235 .L__stack_usage = 0 + 952:vty.c **** (void) state; + 953:vty.c **** saveConfiguration(); + 1237 .LM110: + 1238 0452 0E94 0000 call saveConfiguration + 954:vty.c **** return OK_SILENT; + 955:vty.c **** } + 1240 .LM111: + 1241 0456 80E0 ldi r24,0 + 1242 0458 90E0 ldi r25,0 + 1243 045a 0895 ret + 1245 .Lscope15: + 1247 .stabd 78,0,0 + 1251 goXmodemWyslijFunction: + 1252 .stabd 46,0,0 + 676:vty.c **** fprintf_P(state->myStdInOut, xwyslijStartStr); + 1254 .LM112: + 1255 .LFBB16: + 1256 045c CF93 push r28 + 1257 045e DF93 push r29 + 1258 /* prologue: function */ + 1259 /* frame size = 0 */ + 1260 /* stack size = 2 */ + 1261 .L__stack_usage = 2 + 1262 0460 EC01 movw r28,r24 + 677:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 1264 .LM113: + 1265 0462 80E0 ldi r24,lo8(xwyslijStartStr) + 1266 0464 90E0 ldi r25,hi8(xwyslijStartStr) + 1267 0466 9F93 push r25 + 1268 0468 8F93 push r24 + 1269 046a 8B8D ldd r24,Y+27 + 1270 046c 8F93 push r24 + 1271 046e 8A8D ldd r24,Y+26 + 1272 0470 8F93 push r24 + 1273 0472 0E94 0000 call fprintf_P + 678:vty.c **** { + 1275 .LM114: + 1276 0476 BE01 movw r22,r28 + 1277 0478 81E0 ldi r24,lo8(1) + 1278 047a 0E94 0000 call cmdlineGetArgStr + 1279 047e 60E0 ldi r22,lo8(fdVty) + 1280 0480 70E0 ldi r23,hi8(fdVty) + 1281 0482 0E94 0000 call ramDyskOtworzPlik + 1282 0486 0F90 pop __tmp_reg__ + 1283 0488 0F90 pop __tmp_reg__ + 1284 048a 0F90 pop __tmp_reg__ + 1285 048c 0F90 pop __tmp_reg__ + 1286 048e 8823 tst r24 + 1287 0490 01F0 breq .L38 + 1288 .LBB15: + 1289 .LBB16: + 680:vty.c **** return ERROR_INFORM; + 1291 .LM115: + 1292 0492 BE01 movw r22,r28 + 1293 0494 81E0 ldi r24,lo8(1) + 1294 0496 0E94 0000 call cmdlineGetArgStr + 1295 049a 9F93 push r25 + 1296 049c 8F93 push r24 + 1297 049e 80E0 ldi r24,lo8(errorOpenFile) + 1298 04a0 90E0 ldi r25,hi8(errorOpenFile) + 1299 04a2 9F93 push r25 + 1300 04a4 8F93 push r24 + 1301 04a6 8B8D ldd r24,Y+27 + 1302 04a8 8F93 push r24 + 1303 04aa 8A8D ldd r24,Y+26 + 1304 04ac 8F93 push r24 + 1305 04ae 0E94 0000 call fprintf_P + 1306 04b2 0F90 pop __tmp_reg__ + 1307 04b4 0F90 pop __tmp_reg__ + 1308 04b6 0F90 pop __tmp_reg__ + 1309 04b8 0F90 pop __tmp_reg__ + 1310 04ba 0F90 pop __tmp_reg__ + 1311 04bc 0F90 pop __tmp_reg__ + 1312 04be 84E0 ldi r24,lo8(4) + 1313 04c0 90E0 ldi r25,0 + 1314 04c2 00C0 rjmp .L37 + 1315 .L38: + 1316 .LBE16: + 1317 .LBE15: + 683:vty.c **** } + 1319 .LM116: + 1320 04c4 80E0 ldi r24,0 + 1321 04c6 90E0 ldi r25,0 + 1322 .L37: + 1323 /* epilogue start */ + 684:vty.c **** + 1325 .LM117: + 1326 04c8 DF91 pop r29 + 1327 04ca CF91 pop r28 + 1328 04cc 0895 ret + 1330 .Lscope16: + 1332 .stabd 78,0,0 + 1336 zapiszModWykFunction: + 1337 .stabd 46,0,0 + 497:vty.c **** if (state->argc < 1) + 1339 .LM118: + 1340 .LFBB17: + 1341 /* prologue: function */ + 1342 /* frame size = 0 */ + 1343 /* stack size = 0 */ + 1344 .L__stack_usage = 0 + 498:vty.c **** return SYNTAX_ERROR; + 1346 .LM119: + 1347 04ce FC01 movw r30,r24 + 1348 04d0 218D ldd r18,Z+25 + 1349 04d2 2223 tst r18 + 1350 04d4 01F0 breq .L41 + 1351 04d6 BC01 movw r22,r24 + 1352 .LBB19: + 1353 .LBB20: + 501:vty.c **** saveSettings(adres); + 1355 .LM120: + 1356 04d8 81E0 ldi r24,lo8(1) + 1357 04da 0E94 0000 call cmdlineGetArgInt + 1358 04de 862F mov r24,r22 + 502:vty.c **** return OK_SILENT; + 1360 .LM121: + 1361 04e0 0E94 0000 call saveSettings + 1362 04e4 80E0 ldi r24,0 + 1363 04e6 90E0 ldi r25,0 + 1364 04e8 0895 ret + 1365 .L41: + 1366 .LBE20: + 1367 .LBE19: + 499:vty.c **** + 1369 .LM122: + 1370 04ea 82E0 ldi r24,lo8(2) + 1371 04ec 90E0 ldi r25,0 + 504:vty.c **** + 1373 .LM123: + 1374 04ee 0895 ret + 1376 .Lscope17: + 1378 .stabd 78,0,0 + 1382 ustawModWykFunction: + 1383 .stabd 46,0,0 + 485:vty.c **** if (state->argc < 2) + 1385 .LM124: + 1386 .LFBB18: + 1387 04f0 1F93 push r17 + 1388 04f2 CF93 push r28 + 1389 04f4 DF93 push r29 + 1390 /* prologue: function */ + 1391 /* frame size = 0 */ + 1392 /* stack size = 3 */ + 1393 .L__stack_usage = 3 + 486:vty.c **** return SYNTAX_ERROR; + 1395 .LM125: + 1396 04f6 FC01 movw r30,r24 + 1397 04f8 218D ldd r18,Z+25 + 1398 04fa 2230 cpi r18,lo8(2) + 1399 04fc 00F0 brlo .L44 + 1400 04fe EC01 movw r28,r24 + 1401 .LBB23: + 1402 .LBB24: + 489:vty.c **** uint8_t wartosc = cmdlineGetArgHex(2, state); + 1404 .LM126: + 1405 0500 BC01 movw r22,r24 + 1406 0502 81E0 ldi r24,lo8(1) + 1407 0504 0E94 0000 call cmdlineGetArgInt + 1408 0508 162F mov r17,r22 + 490:vty.c **** + 1410 .LM127: + 1411 050a BE01 movw r22,r28 + 1412 050c 82E0 ldi r24,lo8(2) + 1413 050e 0E94 0000 call cmdlineGetArgHex + 492:vty.c **** + 1415 .LM128: + 1416 0512 812F mov r24,r17 + 1417 0514 0E94 0000 call sendSettings + 1418 0518 80E0 ldi r24,0 + 1419 051a 90E0 ldi r25,0 + 1420 051c 00C0 rjmp .L43 + 1421 .L44: + 1422 .LBE24: + 1423 .LBE23: + 487:vty.c **** + 1425 .LM129: + 1426 051e 82E0 ldi r24,lo8(2) + 1427 0520 90E0 ldi r25,0 + 1428 .L43: + 1429 /* epilogue start */ + 495:vty.c **** static cliExRes_t zapiszModWykFunction(cmdState_t *state) + 1431 .LM130: + 1432 0522 DF91 pop r29 + 1433 0524 CF91 pop r28 + 1434 0526 1F91 pop r17 + 1435 0528 0895 ret + 1437 .Lscope18: + 1439 .stabd 78,0,0 + 1443 ustawPortRezystor: + 1444 .stabd 46,0,0 + 599:vty.c **** if (state->argc < 1) + 1446 .LM131: + 1447 .LFBB19: + 1448 /* prologue: function */ + 1449 /* frame size = 0 */ + 1450 /* stack size = 0 */ + 1451 .L__stack_usage = 0 + 600:vty.c **** return SYNTAX_ERROR; + 1453 .LM132: + 1454 052a FC01 movw r30,r24 + 1455 052c 218D ldd r18,Z+25 + 1456 052e 2223 tst r18 + 1457 0530 01F0 breq .L47 + 1458 0532 BC01 movw r22,r24 + 1459 .LBB27: + 1460 .LBB28: + 603:vty.c **** + 1462 .LM133: + 1463 0534 81E0 ldi r24,lo8(1) + 1464 0536 0E94 0000 call cmdlineGetArgInt + 1465 053a 862F mov r24,r22 + 605:vty.c **** + 1467 .LM134: + 1468 053c 0E94 0000 call MCP4150_setValue + 1469 0540 80E0 ldi r24,0 + 1470 0542 90E0 ldi r25,0 + 1471 0544 0895 ret + 1472 .L47: + 1473 .LBE28: + 1474 .LBE27: + 601:vty.c **** + 1476 .LM135: + 1477 0546 82E0 ldi r24,lo8(2) + 1478 0548 90E0 ldi r25,0 + 608:vty.c **** + 1480 .LM136: + 1481 054a 0895 ret + 1483 .Lscope19: + 1485 .stabd 78,0,0 + 1489 curtainUpFunction: + 1490 .stabd 46,0,0 + 560:vty.c **** if (state->argc < 2) + 1492 .LM137: + 1493 .LFBB20: + 1494 054c FF92 push r15 + 1495 054e 0F93 push r16 + 1496 0550 1F93 push r17 + 1497 0552 CF93 push r28 + 1498 0554 DF93 push r29 + 1499 /* prologue: function */ + 1500 /* frame size = 0 */ + 1501 /* stack size = 5 */ + 1502 .L__stack_usage = 5 + 561:vty.c **** return SYNTAX_ERROR; + 1504 .LM138: + 1505 0556 FC01 movw r30,r24 + 1506 0558 218D ldd r18,Z+25 + 1507 055a 2230 cpi r18,lo8(2) + 1508 055c 00F4 brsh .+2 + 1509 055e 00C0 rjmp .L52 + 1510 0560 EC01 movw r28,r24 + 1511 .LBB31: + 1512 .LBB32: + 564:vty.c **** uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + 1514 .LM139: + 1515 0562 BC01 movw r22,r24 + 1516 0564 81E0 ldi r24,lo8(1) + 1517 0566 0E94 0000 call cmdlineGetArgInt + 1518 056a 162F mov r17,r22 + 1519 056c 1F73 andi r17,lo8(63) + 565:vty.c **** uint8_t wartosc = 255; + 1521 .LM140: + 1522 056e BE01 movw r22,r28 + 1523 0570 82E0 ldi r24,lo8(2) + 1524 0572 0E94 0000 call cmdlineGetArgInt + 1525 0576 062F mov r16,r22 + 1526 0578 0170 andi r16,lo8(1) + 567:vty.c **** wartosc = cmdlineGetArgInt(3, state); + 1528 .LM141: + 1529 057a 898D ldd r24,Y+25 + 1530 057c 8330 cpi r24,lo8(3) + 1531 057e 00F0 brlo .L53 + 568:vty.c **** + 1533 .LM142: + 1534 0580 BE01 movw r22,r28 + 1535 0582 83E0 ldi r24,lo8(3) + 1536 0584 0E94 0000 call cmdlineGetArgInt + 1537 0588 F62E mov r15,r22 + 1538 058a 00C0 rjmp .L50 + 1539 .L53: + 566:vty.c **** if (state->argc > 2) + 1541 .LM143: + 1542 058c FF24 clr r15 + 1543 058e FA94 dec r15 + 1544 .L50: + 570:vty.c **** if ((wartosc > 0) && (wartosc <=100)) + 1546 .LM144: + 1547 0590 802F mov r24,r16 + 1548 0592 90E0 ldi r25,0 + 1549 0594 0196 adiw r24,1 + 1550 0596 9F93 push r25 + 1551 0598 8F93 push r24 + 1552 059a 1F92 push __zero_reg__ + 1553 059c 1F93 push r17 + 1554 059e 80E0 ldi r24,lo8(movingCurtainUpStr) + 1555 05a0 90E0 ldi r25,hi8(movingCurtainUpStr) + 1556 05a2 9F93 push r25 + 1557 05a4 8F93 push r24 + 1558 05a6 8B8D ldd r24,Y+27 + 1559 05a8 8F93 push r24 + 1560 05aa 8A8D ldd r24,Y+26 + 1561 05ac 8F93 push r24 + 1562 05ae 0E94 0000 call fprintf_P + 571:vty.c **** fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + 1564 .LM145: + 1565 05b2 8DB7 in r24,__SP_L__ + 1566 05b4 9EB7 in r25,__SP_H__ + 1567 05b6 0896 adiw r24,8 + 1568 05b8 0FB6 in __tmp_reg__,__SREG__ + 1569 05ba F894 cli + 1570 05bc 9EBF out __SP_H__,r25 + 1571 05be 0FBE out __SREG__,__tmp_reg__ + 1572 05c0 8DBF out __SP_L__,r24 + 1573 05c2 8FEF ldi r24,lo8(-1) + 1574 05c4 8F0D add r24,r15 + 1575 05c6 8436 cpi r24,lo8(100) + 1576 05c8 00F4 brsh .L51 + 572:vty.c **** + 1578 .LM146: + 1579 05ca 1F92 push __zero_reg__ + 1580 05cc FF92 push r15 + 1581 05ce 80E0 ldi r24,lo8(movingCurtainPosStr) + 1582 05d0 90E0 ldi r25,hi8(movingCurtainPosStr) + 1583 05d2 9F93 push r25 + 1584 05d4 8F93 push r24 + 1585 05d6 8B8D ldd r24,Y+27 + 1586 05d8 8F93 push r24 + 1587 05da 8A8D ldd r24,Y+26 + 1588 05dc 8F93 push r24 + 1589 05de 0E94 0000 call fprintf_P + 1590 05e2 0F90 pop __tmp_reg__ + 1591 05e4 0F90 pop __tmp_reg__ + 1592 05e6 0F90 pop __tmp_reg__ + 1593 05e8 0F90 pop __tmp_reg__ + 1594 05ea 0F90 pop __tmp_reg__ + 1595 05ec 0F90 pop __tmp_reg__ + 1596 .L51: + 574:vty.c **** + 1598 .LM147: + 1599 05ee 4F2D mov r20,r15 + 1600 05f0 602F mov r22,r16 + 1601 05f2 812F mov r24,r17 + 1602 05f4 0E94 0000 call rs485curtainUp + 576:vty.c **** return OK_INFORM; + 1604 .LM148: + 1605 05f8 8823 tst r24 + 1606 05fa 01F0 breq .L54 + 579:vty.c **** } + 1608 .LM149: + 1609 05fc 83E0 ldi r24,lo8(3) + 1610 05fe 90E0 ldi r25,0 + 1611 0600 00C0 rjmp .L49 + 1612 .L52: + 1613 .LBE32: + 1614 .LBE31: + 562:vty.c **** + 1616 .LM150: + 1617 0602 82E0 ldi r24,lo8(2) + 1618 0604 90E0 ldi r25,0 + 1619 0606 00C0 rjmp .L49 + 1620 .L54: + 1621 .LBB34: + 1622 .LBB33: + 577:vty.c **** + 1624 .LM151: + 1625 0608 81E0 ldi r24,lo8(1) + 1626 060a 90E0 ldi r25,0 + 1627 .L49: + 1628 /* epilogue start */ + 1629 .LBE33: + 1630 .LBE34: + 580:vty.c **** + 1632 .LM152: + 1633 060c DF91 pop r29 + 1634 060e CF91 pop r28 + 1635 0610 1F91 pop r17 + 1636 0612 0F91 pop r16 + 1637 0614 FF90 pop r15 + 1638 0616 0895 ret + 1650 .Lscope20: + 1652 .stabd 78,0,0 + 1656 editRamFileFunction: + 1657 .stabd 46,0,0 + 902:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 1659 .LM153: + 1660 .LFBB21: + 1661 0618 0F93 push r16 + 1662 061a 1F93 push r17 + 1663 061c CF93 push r28 + 1664 061e DF93 push r29 + 1665 0620 1F92 push __zero_reg__ + 1666 0622 CDB7 in r28,__SP_L__ + 1667 0624 DEB7 in r29,__SP_H__ + 1668 /* prologue: function */ + 1669 /* frame size = 1 */ + 1670 /* stack size = 5 */ + 1671 .L__stack_usage = 5 + 1672 0626 8C01 movw r16,r24 + 903:vty.c **** { + 1674 .LM154: + 1675 0628 BC01 movw r22,r24 + 1676 062a 81E0 ldi r24,lo8(1) + 1677 062c 0E94 0000 call cmdlineGetArgStr + 1678 0630 60E0 ldi r22,lo8(fdVty) + 1679 0632 70E0 ldi r23,hi8(fdVty) + 1680 0634 0E94 0000 call ramDyskOtworzPlik + 1681 0638 8823 tst r24 + 1682 063a 01F0 breq .L56 + 905:vty.c **** return ERROR_INFORM; + 1684 .LM155: + 1685 063c B801 movw r22,r16 + 1686 063e 81E0 ldi r24,lo8(1) + 1687 0640 0E94 0000 call cmdlineGetArgStr + 1688 0644 9F93 push r25 + 1689 0646 8F93 push r24 + 1690 0648 80E0 ldi r24,lo8(errorOpenFile) + 1691 064a 90E0 ldi r25,hi8(errorOpenFile) + 1692 064c 9F93 push r25 + 1693 064e 8F93 push r24 + 1694 0650 F801 movw r30,r16 + 1695 0652 838D ldd r24,Z+27 + 1696 0654 8F93 push r24 + 1697 0656 828D ldd r24,Z+26 + 1698 0658 8F93 push r24 + 1699 065a 0E94 0000 call fprintf_P + 906:vty.c **** } + 1701 .LM156: + 1702 065e 0F90 pop __tmp_reg__ + 1703 0660 0F90 pop __tmp_reg__ + 1704 0662 0F90 pop __tmp_reg__ + 1705 0664 0F90 pop __tmp_reg__ + 1706 0666 0F90 pop __tmp_reg__ + 1707 0668 0F90 pop __tmp_reg__ + 1708 066a 84E0 ldi r24,lo8(4) + 1709 066c 90E0 ldi r25,0 + 1710 066e 00C0 rjmp .L57 + 1711 .L56: + 1712 .LBB37: + 1713 .LBB38: + 908:vty.c **** uint8_t znak = 0; + 1715 .LM157: + 1716 0670 80E0 ldi r24,lo8(fdVty) + 1717 0672 90E0 ldi r25,hi8(fdVty) + 1718 0674 0E94 0000 call ramDyskUstawWskaznikNaKoniec + 909:vty.c **** fprintf_P(state->myStdInOut, editRamFileIntroStr); + 1720 .LM158: + 1721 0678 1982 std Y+1,__zero_reg__ + 910:vty.c **** while(1) + 1723 .LM159: + 1724 067a 80E0 ldi r24,lo8(editRamFileIntroStr) + 1725 067c 90E0 ldi r25,hi8(editRamFileIntroStr) + 1726 067e 9F93 push r25 + 1727 0680 8F93 push r24 + 1728 0682 F801 movw r30,r16 + 1729 0684 838D ldd r24,Z+27 + 1730 0686 8F93 push r24 + 1731 0688 828D ldd r24,Z+26 + 1732 068a 8F93 push r24 + 1733 068c 0E94 0000 call fprintf_P + 1734 0690 0F90 pop __tmp_reg__ + 1735 0692 0F90 pop __tmp_reg__ + 1736 0694 0F90 pop __tmp_reg__ + 1737 0696 0F90 pop __tmp_reg__ + 1738 .L58: + 913:vty.c **** continue; + 1740 .LM160: + 1741 0698 20E0 ldi r18,0 + 1742 069a 4FEF ldi r20,lo8(-1) + 1743 069c 5FEF ldi r21,lo8(-1) + 1744 069e BE01 movw r22,r28 + 1745 06a0 6F5F subi r22,-1 + 1746 06a2 7F4F sbci r23,-1 + 1747 06a4 8091 0000 lds r24,xVtyRec + 1748 06a8 9091 0000 lds r25,xVtyRec+1 + 1749 06ac 0E94 0000 call xQueueGenericReceive + 1750 06b0 8823 tst r24 + 1751 06b2 01F0 breq .L58 + 916:vty.c **** break; + 1753 .LM161: + 1754 06b4 8981 ldd r24,Y+1 + 1755 06b6 8330 cpi r24,lo8(3) + 1756 06b8 01F0 breq .L59 + 919:vty.c **** ramDyskZapiszBajtDoPliku(&fdVty, znak); + 1758 .LM162: + 1759 06ba 0E94 0000 call uartVtySendByte + 920:vty.c **** } + 1761 .LM163: + 1762 06be 6981 ldd r22,Y+1 + 1763 06c0 80E0 ldi r24,lo8(fdVty) + 1764 06c2 90E0 ldi r25,hi8(fdVty) + 1765 06c4 0E94 0000 call ramDyskZapiszBajtDoPliku + 1766 06c8 00C0 rjmp .L58 + 1767 .L59: + 922:vty.c **** return OK_SILENT; + 1769 .LM164: + 1770 06ca 80E0 ldi r24,lo8(fdVty) + 1771 06cc 90E0 ldi r25,hi8(fdVty) + 1772 06ce 0E94 0000 call ramDyskZamknijPlik + 1773 06d2 80E0 ldi r24,0 + 1774 06d4 90E0 ldi r25,0 + 1775 .L57: + 1776 /* epilogue start */ + 1777 .LBE38: + 1778 .LBE37: + 924:vty.c **** + 1780 .LM165: + 1781 06d6 0F90 pop __tmp_reg__ + 1782 06d8 DF91 pop r29 + 1783 06da CF91 pop r28 + 1784 06dc 1F91 pop r17 + 1785 06de 0F91 pop r16 + 1786 06e0 0895 ret + 1791 .Lscope21: + 1793 .stabd 78,0,0 + 1797 goXmodemOdbierzFunction: + 1798 .stabd 46,0,0 + 687:vty.c **** fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + 1800 .LM166: + 1801 .LFBB22: + 1802 06e2 8F92 push r8 + 1803 06e4 9F92 push r9 + 1804 06e6 AF92 push r10 + 1805 06e8 BF92 push r11 + 1806 06ea CF92 push r12 + 1807 06ec DF92 push r13 + 1808 06ee EF92 push r14 + 1809 06f0 FF92 push r15 + 1810 06f2 0F93 push r16 + 1811 06f4 1F93 push r17 + 1812 06f6 CF93 push r28 + 1813 06f8 DF93 push r29 + 1814 06fa 00D0 rcall . + 1815 06fc 00D0 rcall . + 1816 06fe 00D0 rcall . + 1817 0700 CDB7 in r28,__SP_L__ + 1818 0702 DEB7 in r29,__SP_H__ + 1819 /* prologue: function */ + 1820 /* frame size = 6 */ + 1821 /* stack size = 18 */ + 1822 .L__stack_usage = 18 + 1823 0704 8C01 movw r16,r24 + 688:vty.c **** if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + 1825 .LM167: + 1826 0706 80E0 ldi r24,lo8(__c.3768) + 1827 0708 90E0 ldi r25,hi8(__c.3768) + 1828 070a 9F93 push r25 + 1829 070c 8F93 push r24 + 1830 070e F801 movw r30,r16 + 1831 0710 838D ldd r24,Z+27 + 1832 0712 8F93 push r24 + 1833 0714 828D ldd r24,Z+26 + 1834 0716 8F93 push r24 + 1835 0718 0E94 0000 call fprintf_P + 689:vty.c **** { + 1837 .LM168: + 1838 071c B801 movw r22,r16 + 1839 071e 81E0 ldi r24,lo8(1) + 1840 0720 0E94 0000 call cmdlineGetArgStr + 1841 0724 60E0 ldi r22,lo8(fdVty) + 1842 0726 70E0 ldi r23,hi8(fdVty) + 1843 0728 0E94 0000 call ramDyskOtworzPlik + 1844 072c 0F90 pop __tmp_reg__ + 1845 072e 0F90 pop __tmp_reg__ + 1846 0730 0F90 pop __tmp_reg__ + 1847 0732 0F90 pop __tmp_reg__ + 1848 0734 8823 tst r24 + 1849 0736 01F0 breq .L64 + 691:vty.c **** return ERROR_INFORM; + 1851 .LM169: + 1852 0738 B801 movw r22,r16 + 1853 073a 81E0 ldi r24,lo8(1) + 1854 073c 0E94 0000 call cmdlineGetArgStr + 1855 0740 9F93 push r25 + 1856 0742 8F93 push r24 + 1857 0744 80E0 ldi r24,lo8(errorOpenFile) + 1858 0746 90E0 ldi r25,hi8(errorOpenFile) + 1859 0748 9F93 push r25 + 1860 074a 8F93 push r24 + 1861 074c F801 movw r30,r16 + 1862 074e 838D ldd r24,Z+27 + 1863 0750 8F93 push r24 + 1864 0752 828D ldd r24,Z+26 + 1865 0754 8F93 push r24 + 1866 0756 0E94 0000 call fprintf_P + 692:vty.c **** } + 1868 .LM170: + 1869 075a 0F90 pop __tmp_reg__ + 1870 075c 0F90 pop __tmp_reg__ + 1871 075e 0F90 pop __tmp_reg__ + 1872 0760 0F90 pop __tmp_reg__ + 1873 0762 0F90 pop __tmp_reg__ + 1874 0764 0F90 pop __tmp_reg__ + 1875 0766 00C0 rjmp .L107 + 1876 .L64: + 1877 .LBB45: + 1878 .LBB46: + 714:vty.c **** state->err2=0; + 1880 .LM171: + 1881 0768 F801 movw r30,r16 + 1882 076a 168E std Z+30,__zero_reg__ + 1883 076c 158E std Z+29,__zero_reg__ + 715:vty.c **** liczbaProb = 20; + 1885 .LM172: + 1886 076e 178E std Z+31,__zero_reg__ + 1887 0770 74E1 ldi r23,lo8(20) + 1888 0772 F72E mov r15,r23 + 1889 .L69: + 719:vty.c **** while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + 1891 .LM173: + 1892 0774 F801 movw r30,r16 + 1893 0776 628D ldd r22,Z+26 + 1894 0778 738D ldd r23,Z+27 + 1895 077a 83E4 ldi r24,lo8(67) + 1896 077c 90E0 ldi r25,0 + 1897 077e 0E94 0000 call fputc + 1898 .L66: + 720:vty.c **** + 1900 .LM174: + 1901 0782 8091 9B00 lds r24,155 + 1902 0786 86FF sbrs r24,6 + 1903 0788 00C0 rjmp .L66 + 722:vty.c **** if (c == SOH) + 1905 .LM175: + 1906 078a 20E0 ldi r18,0 + 1907 078c 44E6 ldi r20,lo8(100) + 1908 078e 50E0 ldi r21,0 + 1909 0790 BE01 movw r22,r28 + 1910 0792 6B5F subi r22,-5 + 1911 0794 7F4F sbci r23,-1 + 1912 0796 8091 0000 lds r24,xVtyRec + 1913 079a 9091 0000 lds r25,xVtyRec+1 + 1914 079e 0E94 0000 call xQueueGenericReceive + 1915 07a2 8823 tst r24 + 1916 07a4 01F0 breq .L67 + 723:vty.c **** break; //Rozpoczynamy transmisje + 1918 .LM176: + 1919 07a6 8D81 ldd r24,Y+5 + 1920 07a8 8130 cpi r24,lo8(1) + 1921 07aa 01F0 breq .L68 + 1922 .L67: + 1923 07ac FA94 dec r15 + 727:vty.c **** { + 1925 .LM177: + 1926 07ae F110 cpse r15,__zero_reg__ + 1927 07b0 00C0 rjmp .L69 + 729:vty.c **** state->errno = (uint8_t)(AllOK); + 1929 .LM178: + 1930 07b2 80E0 ldi r24,lo8(fdVty) + 1931 07b4 90E0 ldi r25,hi8(fdVty) + 1932 07b6 0E94 0000 call ramDyskZamknijPlik + 730:vty.c **** return ERROR_INFORM; + 1934 .LM179: + 1935 07ba F801 movw r30,r16 + 1936 07bc 148E std Z+28,__zero_reg__ + 1937 .L107: + 731:vty.c **** } + 1939 .LM180: + 1940 07be 84E0 ldi r24,lo8(4) + 1941 07c0 90E0 ldi r25,0 + 1942 07c2 00C0 rjmp .L65 + 1943 .L68: + 738:vty.c **** zapPtrKopia = zapPtr; + 1945 .LM181: + 1946 07c4 61E0 ldi r22,lo8(1) + 1947 07c6 70E0 ldi r23,0 + 1948 07c8 80E0 ldi r24,lo8(fdVty) + 1949 07ca 90E0 ldi r25,hi8(fdVty) + 1950 07cc 0E94 0000 call ramDyskDodajBlokXmodem + 1951 07d0 4C01 movw r8,r24 + 735:vty.c **** liczbaProb = 10; + 1953 .LM182: + 1954 07d2 EE24 clr r14 + 1955 07d4 E394 inc r14 + 736:vty.c **** + 1957 .LM183: + 1958 07d6 5AE0 ldi r21,lo8(10) + 1959 07d8 B52E mov r11,r21 + 788:vty.c **** break; + 1961 .LM184: + 1962 07da 63E0 ldi r22,lo8(3) + 1963 07dc A62E mov r10,r22 + 1964 .L86: + 742:vty.c **** { + 1966 .LM185: + 1967 07de 20E0 ldi r18,0 + 1968 07e0 44E6 ldi r20,lo8(100) + 1969 07e2 50E0 ldi r21,0 + 1970 07e4 BE01 movw r22,r28 + 1971 07e6 6C5F subi r22,-4 + 1972 07e8 7F4F sbci r23,-1 + 1973 07ea 8091 0000 lds r24,xVtyRec + 1974 07ee 9091 0000 lds r25,xVtyRec+1 + 1975 07f2 0E94 0000 call xQueueGenericReceive + 1976 07f6 8111 cpse r24,__zero_reg__ + 1977 07f8 00C0 rjmp .L71 + 1978 .L84: + 744:vty.c **** break; + 1980 .LM186: + 1981 07fa 82E0 ldi r24,lo8(2) + 1982 07fc 00C0 rjmp .L108 + 1983 .L71: + 748:vty.c **** { + 1985 .LM187: + 1986 07fe 20E0 ldi r18,0 + 1987 0800 41E0 ldi r20,lo8(1) + 1988 0802 50E0 ldi r21,0 + 1989 0804 BE01 movw r22,r28 + 1990 0806 6D5F subi r22,-3 + 1991 0808 7F4F sbci r23,-1 + 1992 080a 8091 0000 lds r24,xVtyRec + 1993 080e 9091 0000 lds r25,xVtyRec+1 + 1994 0812 0E94 0000 call xQueueGenericReceive + 1995 0816 8111 cpse r24,__zero_reg__ + 1996 0818 00C0 rjmp .L73 + 750:vty.c **** break; + 1998 .LM188: + 1999 081a 83E0 ldi r24,lo8(3) + 2000 .L108: + 2001 081c F801 movw r30,r16 + 2002 081e 00C0 rjmp .L105 + 2003 .L73: + 755:vty.c **** if (nrBlokuZdalny != c) + 2005 .LM189: + 2006 0820 2B81 ldd r18,Y+3 + 2007 0822 822F mov r24,r18 + 2008 0824 8095 com r24 + 2009 0826 8D83 std Y+5,r24 + 756:vty.c **** { + 2011 .LM190: + 2012 0828 FC80 ldd r15,Y+4 + 2013 082a F816 cp r15,r24 + 2014 082c 01F0 breq .L74 + 758:vty.c **** state->err1 = nrBlokuZdalny; + 2016 .LM191: + 2017 082e 85E0 ldi r24,lo8(5) + 2018 0830 F801 movw r30,r16 + 2019 0832 848F std Z+28,r24 + 759:vty.c **** state->err2 = nrBlokuZdalnyNeg; + 2021 .LM192: + 2022 0834 8F2D mov r24,r15 + 2023 0836 90E0 ldi r25,0 + 2024 0838 968F std Z+30,r25 + 2025 083a 858F std Z+29,r24 + 760:vty.c **** break; + 2027 .LM193: + 2028 083c 278F std Z+31,r18 + 2029 083e 00C0 rjmp .L72 + 2030 .L74: + 765:vty.c **** if (nrBlokuZdalny == c) + 2032 .LM194: + 2033 0840 8FEF ldi r24,lo8(-1) + 2034 0842 8E0D add r24,r14 + 2035 0844 8D83 std Y+5,r24 + 766:vty.c **** { + 2037 .LM195: + 2038 0846 F812 cpse r15,r24 + 2039 0848 00C0 rjmp .L75 + 769:vty.c **** zapPtrKopia = zapPtr; + 2041 .LM196: + 2042 084a 6F2D mov r22,r15 + 2043 084c 70E0 ldi r23,0 + 2044 084e 80E0 ldi r24,lo8(fdVty) + 2045 0850 90E0 ldi r25,hi8(fdVty) + 2046 0852 0E94 0000 call ramDyskDodajBlokXmodem + 2047 0856 4C01 movw r8,r24 + 2048 0858 EF2C mov r14,r15 + 2049 .L75: + 774:vty.c **** { + 2051 .LM197: + 2052 085a FC80 ldd r15,Y+4 + 2053 085c FE14 cp r15,r14 + 2054 085e 01F0 breq .L76 + 776:vty.c **** state->err1 = nrBlokuZdalnyNeg; + 2056 .LM198: + 2057 0860 84E0 ldi r24,lo8(4) + 2058 0862 F801 movw r30,r16 + 2059 0864 848F std Z+28,r24 + 777:vty.c **** state->err2 = nrBloku; + 2061 .LM199: + 2062 0866 8B81 ldd r24,Y+3 + 2063 0868 90E0 ldi r25,0 + 2064 086a 968F std Z+30,r25 + 2065 086c 858F std Z+29,r24 + 778:vty.c **** break; + 2067 .LM200: + 2068 086e E78E std Z+31,r14 + 2069 0870 00C0 rjmp .L72 + 2070 .L76: + 2071 0872 6401 movw r12,r8 + 774:vty.c **** { + 2073 .LM201: + 2074 0874 E12C mov r14,__zero_reg__ + 2075 .L78: + 784:vty.c **** *(zapPtr++) = c; + 2077 .LM202: + 2078 0876 20E0 ldi r18,0 + 2079 0878 4AE0 ldi r20,lo8(10) + 2080 087a 50E0 ldi r21,0 + 2081 087c BE01 movw r22,r28 + 2082 087e 6B5F subi r22,-5 + 2083 0880 7F4F sbci r23,-1 + 2084 0882 8091 0000 lds r24,xVtyRec + 2085 0886 9091 0000 lds r25,xVtyRec+1 + 2086 088a 0E94 0000 call xQueueGenericReceive + 2087 088e 8823 tst r24 + 2088 0890 01F0 breq .L77 + 785:vty.c **** else + 2090 .LM203: + 2091 0892 8D81 ldd r24,Y+5 + 2092 0894 F401 movw r30,r8 + 2093 0896 8193 st Z+,r24 + 2094 0898 4F01 movw r8,r30 + 782:vty.c **** { + 2096 .LM204: + 2097 089a E394 inc r14 + 2098 089c F0E8 ldi r31,lo8(-128) + 2099 089e EF12 cpse r14,r31 + 2100 08a0 00C0 rjmp .L78 + 2101 08a2 00C0 rjmp .L79 + 2102 .L77: + 788:vty.c **** break; + 2104 .LM205: + 2105 08a4 F801 movw r30,r16 + 2106 08a6 A48E std Z+28,r10 + 2107 .L79: + 792:vty.c **** { + 2109 .LM206: + 2110 08a8 20E0 ldi r18,0 + 2111 08aa 4AE0 ldi r20,lo8(10) + 2112 08ac 50E0 ldi r21,0 + 2113 08ae BE01 movw r22,r28 + 2114 08b0 6E5F subi r22,-2 + 2115 08b2 7F4F sbci r23,-1 + 2116 08b4 8091 0000 lds r24,xVtyRec + 2117 08b8 9091 0000 lds r25,xVtyRec+1 + 2118 08bc 0E94 0000 call xQueueGenericReceive + 2119 08c0 8111 cpse r24,__zero_reg__ + 2120 08c2 00C0 rjmp .L80 + 794:vty.c **** state->err1 = 2; + 2122 .LM207: + 2123 08c4 86E0 ldi r24,lo8(6) + 2124 08c6 F801 movw r30,r16 + 2125 08c8 848F std Z+28,r24 + 795:vty.c **** break; + 2127 .LM208: + 2128 08ca 82E0 ldi r24,lo8(2) + 2129 08cc 90E0 ldi r25,0 + 2130 08ce 00C0 rjmp .L106 + 2131 .L80: + 798:vty.c **** { + 2133 .LM209: + 2134 08d0 20E0 ldi r18,0 + 2135 08d2 4AE0 ldi r20,lo8(10) + 2136 08d4 50E0 ldi r21,0 + 2137 08d6 BE01 movw r22,r28 + 2138 08d8 6F5F subi r22,-1 + 2139 08da 7F4F sbci r23,-1 + 2140 08dc 8091 0000 lds r24,xVtyRec + 2141 08e0 9091 0000 lds r25,xVtyRec+1 + 2142 08e4 0E94 0000 call xQueueGenericReceive + 2143 08e8 8111 cpse r24,__zero_reg__ + 2144 08ea 00C0 rjmp .L90 + 800:vty.c **** state->err1 = 1; + 2146 .LM210: + 2147 08ec 86E0 ldi r24,lo8(6) + 2148 08ee F801 movw r30,r16 + 2149 08f0 848F std Z+28,r24 + 801:vty.c **** break; + 2151 .LM211: + 2152 08f2 81E0 ldi r24,lo8(1) + 2153 08f4 90E0 ldi r25,0 + 2154 08f6 00C0 rjmp .L106 + 2155 .L90: + 798:vty.c **** { + 2157 .LM212: + 2158 08f8 30E0 ldi r19,0 + 2159 08fa 80E0 ldi r24,0 + 2160 08fc 90E0 ldi r25,0 + 2161 .L81: + 810:vty.c **** + 2163 .LM213: + 2164 08fe F601 movw r30,r12 + 2165 0900 2191 ld r18,Z+ + 2166 0902 6F01 movw r12,r30 + 2167 .LBB47: + 2168 .LBB48: + 2170 .Ltext1: + 1:/usr/lib/avr/include/util/crc16.h **** /* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz + 2:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2005, 2007 Joerg Wunsch + 3:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2013 Dave Hylands + 4:/usr/lib/avr/include/util/crc16.h **** Copyright (c) 2013 Frederic Nadeau + 5:/usr/lib/avr/include/util/crc16.h **** All rights reserved. + 6:/usr/lib/avr/include/util/crc16.h **** + 7:/usr/lib/avr/include/util/crc16.h **** Redistribution and use in source and binary forms, with or without + 8:/usr/lib/avr/include/util/crc16.h **** modification, are permitted provided that the following conditions are met: + 9:/usr/lib/avr/include/util/crc16.h **** + 10:/usr/lib/avr/include/util/crc16.h **** * Redistributions of source code must retain the above copyright + 11:/usr/lib/avr/include/util/crc16.h **** notice, this list of conditions and the following disclaimer. + 12:/usr/lib/avr/include/util/crc16.h **** + 13:/usr/lib/avr/include/util/crc16.h **** * Redistributions in binary form must reproduce the above copyright + 14:/usr/lib/avr/include/util/crc16.h **** notice, this list of conditions and the following disclaimer in + 15:/usr/lib/avr/include/util/crc16.h **** the documentation and/or other materials provided with the + 16:/usr/lib/avr/include/util/crc16.h **** distribution. + 17:/usr/lib/avr/include/util/crc16.h **** + 18:/usr/lib/avr/include/util/crc16.h **** * Neither the name of the copyright holders nor the names of + 19:/usr/lib/avr/include/util/crc16.h **** contributors may be used to endorse or promote products derived + 20:/usr/lib/avr/include/util/crc16.h **** from this software without specific prior written permission. + 21:/usr/lib/avr/include/util/crc16.h **** + 22:/usr/lib/avr/include/util/crc16.h **** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + 23:/usr/lib/avr/include/util/crc16.h **** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + 24:/usr/lib/avr/include/util/crc16.h **** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + 25:/usr/lib/avr/include/util/crc16.h **** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + 26:/usr/lib/avr/include/util/crc16.h **** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + 27:/usr/lib/avr/include/util/crc16.h **** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + 28:/usr/lib/avr/include/util/crc16.h **** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + 29:/usr/lib/avr/include/util/crc16.h **** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + 30:/usr/lib/avr/include/util/crc16.h **** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + 31:/usr/lib/avr/include/util/crc16.h **** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + 32:/usr/lib/avr/include/util/crc16.h **** POSSIBILITY OF SUCH DAMAGE. */ + 33:/usr/lib/avr/include/util/crc16.h **** + 34:/usr/lib/avr/include/util/crc16.h **** /* $Id$ */ + 35:/usr/lib/avr/include/util/crc16.h **** + 36:/usr/lib/avr/include/util/crc16.h **** #ifndef _UTIL_CRC16_H_ + 37:/usr/lib/avr/include/util/crc16.h **** #define _UTIL_CRC16_H_ + 38:/usr/lib/avr/include/util/crc16.h **** + 39:/usr/lib/avr/include/util/crc16.h **** #include + 40:/usr/lib/avr/include/util/crc16.h **** + 41:/usr/lib/avr/include/util/crc16.h **** /** \file */ + 42:/usr/lib/avr/include/util/crc16.h **** /** \defgroup util_crc : CRC Computations + 43:/usr/lib/avr/include/util/crc16.h **** \code#include \endcode + 44:/usr/lib/avr/include/util/crc16.h **** + 45:/usr/lib/avr/include/util/crc16.h **** This header file provides a optimized inline functions for calculating + 46:/usr/lib/avr/include/util/crc16.h **** cyclic redundancy checks (CRC) using common polynomials. + 47:/usr/lib/avr/include/util/crc16.h **** + 48:/usr/lib/avr/include/util/crc16.h **** \par References: + 49:/usr/lib/avr/include/util/crc16.h **** + 50:/usr/lib/avr/include/util/crc16.h **** \par + 51:/usr/lib/avr/include/util/crc16.h **** + 52:/usr/lib/avr/include/util/crc16.h **** See the Dallas Semiconductor app note 27 for 8051 assembler example and + 53:/usr/lib/avr/include/util/crc16.h **** general CRC optimization suggestions. The table on the last page of the + 54:/usr/lib/avr/include/util/crc16.h **** app note is the key to understanding these implementations. + 55:/usr/lib/avr/include/util/crc16.h **** + 56:/usr/lib/avr/include/util/crc16.h **** \par + 57:/usr/lib/avr/include/util/crc16.h **** + 58:/usr/lib/avr/include/util/crc16.h **** Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e + 59:/usr/lib/avr/include/util/crc16.h **** Embedded \e Systems \e Programming. This may be difficult to find, but it + 60:/usr/lib/avr/include/util/crc16.h **** explains CRC's in very clear and concise terms. Well worth the effort to + 61:/usr/lib/avr/include/util/crc16.h **** obtain a copy. + 62:/usr/lib/avr/include/util/crc16.h **** + 63:/usr/lib/avr/include/util/crc16.h **** A typical application would look like: + 64:/usr/lib/avr/include/util/crc16.h **** + 65:/usr/lib/avr/include/util/crc16.h **** \code + 66:/usr/lib/avr/include/util/crc16.h **** // Dallas iButton test vector. + 67:/usr/lib/avr/include/util/crc16.h **** uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + 68:/usr/lib/avr/include/util/crc16.h **** + 69:/usr/lib/avr/include/util/crc16.h **** int + 70:/usr/lib/avr/include/util/crc16.h **** checkcrc(void) + 71:/usr/lib/avr/include/util/crc16.h **** { + 72:/usr/lib/avr/include/util/crc16.h **** uint8_t crc = 0, i; + 73:/usr/lib/avr/include/util/crc16.h **** + 74:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + 75:/usr/lib/avr/include/util/crc16.h **** crc = _crc_ibutton_update(crc, serno[i]); + 76:/usr/lib/avr/include/util/crc16.h **** + 77:/usr/lib/avr/include/util/crc16.h **** return crc; // must be 0 + 78:/usr/lib/avr/include/util/crc16.h **** } + 79:/usr/lib/avr/include/util/crc16.h **** \endcode + 80:/usr/lib/avr/include/util/crc16.h **** */ + 81:/usr/lib/avr/include/util/crc16.h **** + 82:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 83:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-16 calculation. + 84:/usr/lib/avr/include/util/crc16.h **** + 85:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ 86:/usr/lib/avr/include/util/crc16.h **** Initial value: 0xffff + 87:/usr/lib/avr/include/util/crc16.h **** + 88:/usr/lib/avr/include/util/crc16.h **** This CRC is normally used in disk-drive controllers. + 89:/usr/lib/avr/include/util/crc16.h **** + 90:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 91:/usr/lib/avr/include/util/crc16.h **** + 92:/usr/lib/avr/include/util/crc16.h **** \code + 93:/usr/lib/avr/include/util/crc16.h **** uint16_t + 94:/usr/lib/avr/include/util/crc16.h **** crc16_update(uint16_t crc, uint8_t a) + 95:/usr/lib/avr/include/util/crc16.h **** { + 96:/usr/lib/avr/include/util/crc16.h **** int i; + 97:/usr/lib/avr/include/util/crc16.h **** + 98:/usr/lib/avr/include/util/crc16.h **** crc ^= a; + 99:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < 8; ++i) + 100:/usr/lib/avr/include/util/crc16.h **** { + 101:/usr/lib/avr/include/util/crc16.h **** if (crc & 1) + 102:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1) ^ 0xA001; + 103:/usr/lib/avr/include/util/crc16.h **** else + 104:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1); + 105:/usr/lib/avr/include/util/crc16.h **** } + 106:/usr/lib/avr/include/util/crc16.h **** + 107:/usr/lib/avr/include/util/crc16.h **** return crc; + 108:/usr/lib/avr/include/util/crc16.h **** } + 109:/usr/lib/avr/include/util/crc16.h **** + 110:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 111:/usr/lib/avr/include/util/crc16.h **** + 112:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 113:/usr/lib/avr/include/util/crc16.h **** _crc16_update(uint16_t __crc, uint8_t __data) + 114:/usr/lib/avr/include/util/crc16.h **** { + 115:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp; + 116:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; + 117:/usr/lib/avr/include/util/crc16.h **** + 118:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 119:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%2" "\n\t" + 120:/usr/lib/avr/include/util/crc16.h **** "mov %1,%A0" "\n\t" + 121:/usr/lib/avr/include/util/crc16.h **** "swap %1" "\n\t" + 122:/usr/lib/avr/include/util/crc16.h **** "eor %1,%A0" "\n\t" + 123:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 124:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 125:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 126:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 127:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 128:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 129:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 130:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x07" "\n\t" + 131:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%A0" "\n\t" + 132:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%B0" "\n\t" + 133:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 134:/usr/lib/avr/include/util/crc16.h **** "ror __tmp_reg__" "\n\t" + 135:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 136:/usr/lib/avr/include/util/crc16.h **** "mov %B0,__tmp_reg__" "\n\t" + 137:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" "\n\t" + 138:/usr/lib/avr/include/util/crc16.h **** "lsr __tmp_reg__" "\n\t" + 139:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 140:/usr/lib/avr/include/util/crc16.h **** "eor %B0,__tmp_reg__" "\n\t" + 141:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" + 142:/usr/lib/avr/include/util/crc16.h **** : "=r" (__ret), "=d" (__tmp) + 143:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 144:/usr/lib/avr/include/util/crc16.h **** : "r0" + 145:/usr/lib/avr/include/util/crc16.h **** ); + 146:/usr/lib/avr/include/util/crc16.h **** return __ret; + 147:/usr/lib/avr/include/util/crc16.h **** } + 148:/usr/lib/avr/include/util/crc16.h **** + 149:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 150:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-XMODEM calculation. + 151:/usr/lib/avr/include/util/crc16.h **** + 152:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ 153:/usr/lib/avr/include/util/crc16.h **** Initial value: 0x0 + 154:/usr/lib/avr/include/util/crc16.h **** + 155:/usr/lib/avr/include/util/crc16.h **** This is the CRC used by the Xmodem-CRC protocol. + 156:/usr/lib/avr/include/util/crc16.h **** + 157:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 158:/usr/lib/avr/include/util/crc16.h **** + 159:/usr/lib/avr/include/util/crc16.h **** \code + 160:/usr/lib/avr/include/util/crc16.h **** uint16_t + 161:/usr/lib/avr/include/util/crc16.h **** crc_xmodem_update (uint16_t crc, uint8_t data) + 162:/usr/lib/avr/include/util/crc16.h **** { + 163:/usr/lib/avr/include/util/crc16.h **** int i; + 164:/usr/lib/avr/include/util/crc16.h **** + 165:/usr/lib/avr/include/util/crc16.h **** crc = crc ^ ((uint16_t)data << 8); + 166:/usr/lib/avr/include/util/crc16.h **** for (i=0; i<8; i++) + 167:/usr/lib/avr/include/util/crc16.h **** { + 168:/usr/lib/avr/include/util/crc16.h **** if (crc & 0x8000) + 169:/usr/lib/avr/include/util/crc16.h **** crc = (crc << 1) ^ 0x1021; + 170:/usr/lib/avr/include/util/crc16.h **** else + 171:/usr/lib/avr/include/util/crc16.h **** crc <<= 1; + 172:/usr/lib/avr/include/util/crc16.h **** } + 173:/usr/lib/avr/include/util/crc16.h **** + 174:/usr/lib/avr/include/util/crc16.h **** return crc; + 175:/usr/lib/avr/include/util/crc16.h **** } + 176:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 177:/usr/lib/avr/include/util/crc16.h **** + 178:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 179:/usr/lib/avr/include/util/crc16.h **** _crc_xmodem_update(uint16_t __crc, uint8_t __data) + 180:/usr/lib/avr/include/util/crc16.h **** { + 181:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + 182:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp1; /* %1 */ + 183:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp2; /* %2 */ + 184:/usr/lib/avr/include/util/crc16.h **** /* %3 __data */ + 185:/usr/lib/avr/include/util/crc16.h **** + 186:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 2172 .LM214: + 2173 /* #APP */ + 2174 ; 186 "/usr/lib/avr/include/util/crc16.h" 1 + 2175 0904 9227 eor r25,r18 + 2176 0906 092E mov __tmp_reg__,r25 + 2177 0908 0294 swap __tmp_reg__ + 2178 090a 202D mov r18,__tmp_reg__ + 2179 090c 2F70 andi r18,0x0f + 2180 090e 2927 eor r18,r25 + 2181 0910 492F mov r20,r25 + 2182 0912 4025 eor r20,__tmp_reg__ + 2183 0914 440F lsl r20 + 2184 0916 407E andi r20,0xe0 + 2185 0918 2427 eor r18,r20 + 2186 091a 402D mov r20,__tmp_reg__ + 2187 091c 4927 eor r20,r25 + 2188 091e 407F andi r20,0xf0 + 2189 0920 4695 lsr r20 + 2190 0922 092E mov __tmp_reg__,r25 + 2191 0924 000C lsl __tmp_reg__ + 2192 0926 441F rol r20 + 2193 0928 9695 lsr r25 + 2194 092a 9695 lsr r25 + 2195 092c 9695 lsr r25 + 2196 092e 9F71 andi r25,0x1f + 2197 0930 9427 eor r25,r20 + 2198 0932 9827 eor r25,r24 + 2199 0934 822F mov r24,r18 + 2200 + 2201 ; 0 "" 2 + 2202 /* #NOAPP */ + 2203 .LBE48: + 2204 .LBE47: + 2206 .Ltext2: + 809:vty.c **** crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + 2208 .LM215: + 2209 0936 3F5F subi r19,lo8(-(1)) + 2210 0938 3038 cpi r19,lo8(-128) + 2211 093a 01F4 brne .L81 + 813:vty.c **** { + 2213 .LM216: + 2214 093c 2A81 ldd r18,Y+2 + 2215 093e 30E0 ldi r19,0 + 2216 0940 492F mov r20,r25 + 2217 0942 5527 clr r21 + 2218 0944 2417 cp r18,r20 + 2219 0946 3507 cpc r19,r21 + 2220 0948 01F4 brne .L82 + 2221 094a 2981 ldd r18,Y+1 + 2222 094c 30E0 ldi r19,0 + 2223 094e 9927 clr r25 + 2224 0950 2817 cp r18,r24 + 2225 0952 3907 cpc r19,r25 + 2226 0954 01F4 brne .L82 + 816:vty.c **** } + 2228 .LM217: + 2229 0956 86E0 ldi r24,lo8(6) + 2230 0958 0E94 0000 call uartVtySendByte + 815:vty.c **** uartVtySendByte(ACK); + 2232 .LM218: + 2233 095c 8AE0 ldi r24,lo8(10) + 2234 095e B82E mov r11,r24 + 2235 0960 00C0 rjmp .L83 + 2236 .L82: + 820:vty.c **** nrBloku--; + 2238 .LM219: + 2239 0962 BA94 dec r11 + 821:vty.c **** uartVtySendByte(NAK); + 2241 .LM220: + 2242 0964 FA94 dec r15 + 822:vty.c **** } + 2244 .LM221: + 2245 0966 85E1 ldi r24,lo8(21) + 2246 0968 0E94 0000 call uartVtySendByte + 825:vty.c **** { + 2248 .LM222: + 2249 096c B110 cpse r11,__zero_reg__ + 2250 096e 00C0 rjmp .L83 + 827:vty.c **** state->err2 = nrBloku; + 2252 .LM223: + 2253 0970 8C81 ldd r24,Y+4 + 2254 0972 90E0 ldi r25,0 + 2255 0974 F801 movw r30,r16 + 2256 0976 968F std Z+30,r25 + 2257 0978 858F std Z+29,r24 + 828:vty.c **** state->errno = (uint8_t)(xModemWrongFrameNo); + 2259 .LM224: + 2260 097a F78E std Z+31,r15 + 829:vty.c **** break; + 2262 .LM225: + 2263 097c 84E0 ldi r24,lo8(4) + 2264 097e 00C0 rjmp .L105 + 2265 .L83: + 833:vty.c **** { + 2267 .LM226: + 2268 0980 20E0 ldi r18,0 + 2269 0982 44E6 ldi r20,lo8(100) + 2270 0984 50E0 ldi r21,0 + 2271 0986 BE01 movw r22,r28 + 2272 0988 6A5F subi r22,-6 + 2273 098a 7F4F sbci r23,-1 + 2274 098c 8091 0000 lds r24,xVtyRec + 2275 0990 9091 0000 lds r25,xVtyRec+1 + 2276 0994 0E94 0000 call xQueueGenericReceive + 2277 0998 8823 tst r24 + 2278 099a 01F4 brne .+2 + 2279 099c 00C0 rjmp .L84 + 839:vty.c **** { + 2281 .LM227: + 2282 099e 8E81 ldd r24,Y+6 + 2283 09a0 8130 cpi r24,lo8(1) + 2284 09a2 01F4 brne .L85 + 841:vty.c **** zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + 2286 .LM228: + 2287 09a4 EE24 clr r14 + 2288 09a6 E394 inc r14 + 2289 09a8 EF0C add r14,r15 + 842:vty.c **** zapPtrKopia = zapPtr; + 2291 .LM229: + 2292 09aa 6E2D mov r22,r14 + 2293 09ac 70E0 ldi r23,0 + 2294 09ae 80E0 ldi r24,lo8(fdVty) + 2295 09b0 90E0 ldi r25,hi8(fdVty) + 2296 09b2 0E94 0000 call ramDyskDodajBlokXmodem + 2297 09b6 4C01 movw r8,r24 + 844:vty.c **** continue; + 2299 .LM230: + 2300 09b8 F801 movw r30,r16 + 2301 09ba 148E std Z+28,__zero_reg__ + 2302 09bc 00C0 rjmp .L86 + 2303 .L85: + 848:vty.c **** { + 2305 .LM231: + 2306 09be 8831 cpi r24,lo8(24) + 2307 09c0 01F4 brne .L87 + 850:vty.c **** state->errno = (uint8_t)(xModemRemoteSideCan); + 2309 .LM232: + 2310 09c2 8F2D mov r24,r15 + 2311 09c4 90E0 ldi r25,0 + 2312 09c6 F801 movw r30,r16 + 2313 09c8 968F std Z+30,r25 + 2314 09ca 858F std Z+29,r24 + 851:vty.c **** break; + 2316 .LM233: + 2317 09cc 87E0 ldi r24,lo8(7) + 2318 .L105: + 2319 09ce 848F std Z+28,r24 + 2320 09d0 00C0 rjmp .L72 + 2321 .L87: + 854:vty.c **** { + 2323 .LM234: + 2324 09d2 8430 cpi r24,lo8(4) + 2325 09d4 01F4 brne .L88 + 856:vty.c **** if (xQueueReceive(xVtyRec, &temp1, 10)) + 2327 .LM235: + 2328 09d6 85E1 ldi r24,lo8(21) + 2329 09d8 0E94 0000 call uartVtySendByte + 857:vty.c **** { + 2331 .LM236: + 2332 09dc 20E0 ldi r18,0 + 2333 09de 4AE0 ldi r20,lo8(10) + 2334 09e0 50E0 ldi r21,0 + 2335 09e2 BE01 movw r22,r28 + 2336 09e4 6A5F subi r22,-6 + 2337 09e6 7F4F sbci r23,-1 + 2338 09e8 8091 0000 lds r24,xVtyRec + 2339 09ec 9091 0000 lds r25,xVtyRec+1 + 2340 09f0 0E94 0000 call xQueueGenericReceive + 2341 09f4 8823 tst r24 + 2342 09f6 01F0 breq .L89 + 859:vty.c **** uartVtySendByte(ACK); + 2344 .LM237: + 2345 09f8 8E81 ldd r24,Y+6 + 2346 09fa 8430 cpi r24,lo8(4) + 2347 09fc 01F4 brne .L89 + 860:vty.c **** } + 2349 .LM238: + 2350 09fe 86E0 ldi r24,lo8(6) + 2351 0a00 0E94 0000 call uartVtySendByte + 2352 .L89: + 862:vty.c **** break; + 2354 .LM239: + 2355 0a04 F801 movw r30,r16 + 2356 0a06 148E std Z+28,__zero_reg__ + 2357 0a08 00C0 rjmp .L72 + 2358 .L88: + 865:vty.c **** state->err1 = temp1; + 2360 .LM240: + 2361 0a0a 98E0 ldi r25,lo8(8) + 2362 0a0c F801 movw r30,r16 + 2363 0a0e 948F std Z+28,r25 + 866:vty.c **** break; + 2365 .LM241: + 2366 0a10 90E0 ldi r25,0 + 2367 .L106: + 2368 0a12 968F std Z+30,r25 + 2369 0a14 858F std Z+29,r24 + 2370 .L72: + 869:vty.c **** return OK_SILENT; + 2372 .LM242: + 2373 0a16 80E0 ldi r24,lo8(fdVty) + 2374 0a18 90E0 ldi r25,hi8(fdVty) + 2375 0a1a 0E94 0000 call ramDyskZamknijPlik + 870:vty.c **** } + 2377 .LM243: + 2378 0a1e 80E0 ldi r24,0 + 2379 0a20 90E0 ldi r25,0 + 2380 .L65: + 2381 /* epilogue start */ + 2382 .LBE46: + 2383 .LBE45: + 871:vty.c **** + 2385 .LM244: + 2386 0a22 2696 adiw r28,6 + 2387 0a24 0FB6 in __tmp_reg__,__SREG__ + 2388 0a26 F894 cli + 2389 0a28 DEBF out __SP_H__,r29 + 2390 0a2a 0FBE out __SREG__,__tmp_reg__ + 2391 0a2c CDBF out __SP_L__,r28 + 2392 0a2e DF91 pop r29 + 2393 0a30 CF91 pop r28 + 2394 0a32 1F91 pop r17 + 2395 0a34 0F91 pop r16 + 2396 0a36 FF90 pop r15 + 2397 0a38 EF90 pop r14 + 2398 0a3a DF90 pop r13 + 2399 0a3c CF90 pop r12 + 2400 0a3e BF90 pop r11 + 2401 0a40 AF90 pop r10 + 2402 0a42 9F90 pop r9 + 2403 0a44 8F90 pop r8 + 2404 0a46 0895 ret + 2416 .Lscope22: + 2418 .stabd 78,0,0 + 2422 debugFunction: + 2423 .stabd 46,0,0 + 308:vty.c **** if (state->argc < 2) + 2425 .LM245: + 2426 .LFBB23: + 2427 0a48 FF92 push r15 + 2428 0a4a 0F93 push r16 + 2429 0a4c 1F93 push r17 + 2430 0a4e CF93 push r28 + 2431 0a50 DF93 push r29 + 2432 /* prologue: function */ + 2433 /* frame size = 0 */ + 2434 /* stack size = 5 */ + 2435 .L__stack_usage = 5 + 309:vty.c **** return SYNTAX_ERROR; + 2437 .LM246: + 2438 0a52 FC01 movw r30,r24 + 2439 0a54 218D ldd r18,Z+25 + 2440 0a56 2230 cpi r18,lo8(2) + 2441 0a58 00F4 brsh .L110 + 2442 .L117: + 310:vty.c **** + 2444 .LM247: + 2445 0a5a 82E0 ldi r24,lo8(2) + 2446 0a5c 90E0 ldi r25,0 + 2447 0a5e 00C0 rjmp .L111 + 2448 .L110: + 2449 0a60 EC01 movw r28,r24 + 2450 .LBB61: + 2451 .LBB62: + 312:vty.c **** const char *str = (const char*)cmdlineGetArgStr(1, state); + 2453 .LM248: + 2454 0a62 BC01 movw r22,r24 + 2455 0a64 82E0 ldi r24,lo8(2) + 2456 0a66 0E94 0000 call cmdlineGetArgInt + 2457 0a6a F62E mov r15,r22 + 313:vty.c **** if (level == 0) + 2459 .LM249: + 2460 0a6c BE01 movw r22,r28 + 2461 0a6e 81E0 ldi r24,lo8(1) + 2462 0a70 0E94 0000 call cmdlineGetArgStr + 2463 0a74 182F mov r17,r24 + 2464 0a76 092F mov r16,r25 + 316:vty.c **** { + 2466 .LM250: + 2467 0a78 43E0 ldi r20,lo8(3) + 2468 0a7a 50E0 ldi r21,0 + 314:vty.c **** { + 2470 .LM251: + 2471 0a7c F110 cpse r15,__zero_reg__ + 2472 0a7e 00C0 rjmp .L112 + 316:vty.c **** { + 2474 .LM252: + 2475 0a80 60E0 ldi r22,lo8(__c.3656) + 2476 0a82 70E0 ldi r23,hi8(__c.3656) + 2477 0a84 0E94 0000 call strncmp_P + 2478 0a88 892B or r24,r25 + 2479 0a8a 01F4 brne .L113 + 318:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2481 .LM253: + 2482 0a8c 60E0 ldi r22,0 + 2483 0a8e 80E0 ldi r24,0 + 2484 0a90 90E0 ldi r25,0 + 2485 0a92 0E94 0000 call setArpDebug + 2486 0a96 00C0 rjmp .L124 + 2487 .L113: + 323:vty.c **** { + 2489 .LM254: + 2490 0a98 42E0 ldi r20,lo8(2) + 2491 0a9a 50E0 ldi r21,0 + 2492 0a9c 60E0 ldi r22,lo8(__c.3658) + 2493 0a9e 70E0 ldi r23,hi8(__c.3658) + 2494 0aa0 812F mov r24,r17 + 2495 0aa2 902F mov r25,r16 + 2496 0aa4 0E94 0000 call strncmp_P + 2497 0aa8 892B or r24,r25 + 2498 0aaa 01F4 brne .L114 + 325:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2500 .LM255: + 2501 0aac 60E0 ldi r22,0 + 2502 0aae 80E0 ldi r24,0 + 2503 0ab0 90E0 ldi r25,0 + 2504 0ab2 0E94 0000 call setIpDebug + 2505 0ab6 00C0 rjmp .L124 + 2506 .L114: + 330:vty.c **** { + 2508 .LM256: + 2509 0ab8 42E0 ldi r20,lo8(2) + 2510 0aba 50E0 ldi r21,0 + 2511 0abc 60E0 ldi r22,lo8(__c.3660) + 2512 0abe 70E0 ldi r23,hi8(__c.3660) + 2513 0ac0 812F mov r24,r17 + 2514 0ac2 902F mov r25,r16 + 2515 0ac4 0E94 0000 call strncmp_P + 2516 0ac8 892B or r24,r25 + 2517 0aca 01F4 brne .L115 + 332:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2519 .LM257: + 2520 0acc 60E0 ldi r22,0 + 2521 0ace 80E0 ldi r24,0 + 2522 0ad0 90E0 ldi r25,0 + 2523 0ad2 0E94 0000 call setIcmpDebug + 2524 0ad6 00C0 rjmp .L124 + 2525 .L115: + 337:vty.c **** { + 2527 .LM258: + 2528 0ad8 42E0 ldi r20,lo8(2) + 2529 0ada 50E0 ldi r21,0 + 2530 0adc 60E0 ldi r22,lo8(__c.3662) + 2531 0ade 70E0 ldi r23,hi8(__c.3662) + 2532 0ae0 812F mov r24,r17 + 2533 0ae2 902F mov r25,r16 + 2534 0ae4 0E94 0000 call strncmp_P + 2535 0ae8 892B or r24,r25 + 2536 0aea 01F4 brne .L116 + 339:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2538 .LM259: + 2539 0aec 60E0 ldi r22,0 + 2540 0aee 80E0 ldi r24,0 + 2541 0af0 90E0 ldi r25,0 + 2542 0af2 0E94 0000 call setTcpDebug + 2543 .L124: + 340:vty.c **** return OK_SILENT; + 2545 .LM260: + 2546 0af6 0F93 push r16 + 2547 0af8 1F93 push r17 + 2548 0afa 80E0 ldi r24,lo8(debugDisabledInfoStr) + 2549 0afc 90E0 ldi r25,hi8(debugDisabledInfoStr) + 2550 0afe 00C0 rjmp .L122 + 2551 .L116: + 344:vty.c **** { + 2553 .LM261: + 2554 0b00 42E0 ldi r20,lo8(2) + 2555 0b02 50E0 ldi r21,0 + 2556 0b04 60E0 ldi r22,lo8(__c.3664) + 2557 0b06 70E0 ldi r23,hi8(__c.3664) + 2558 0b08 812F mov r24,r17 + 2559 0b0a 902F mov r25,r16 + 2560 0b0c 0E94 0000 call strncmp_P + 2561 0b10 892B or r24,r25 + 2562 0b12 01F0 breq .+2 + 2563 0b14 00C0 rjmp .L117 + 346:vty.c **** fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + 2565 .LM262: + 2566 0b16 60E0 ldi r22,0 + 2567 0b18 80E0 ldi r24,0 + 2568 0b1a 90E0 ldi r25,0 + 2569 0b1c 0E94 0000 call setUdpDebug + 2570 0b20 00C0 rjmp .L124 + 2571 .L112: + 355:vty.c **** { + 2573 .LM263: + 2574 0b22 60E0 ldi r22,lo8(__c.3666) + 2575 0b24 70E0 ldi r23,hi8(__c.3666) + 2576 0b26 0E94 0000 call strncmp_P + 2577 0b2a 892B or r24,r25 + 2578 0b2c 01F4 brne .L118 + 357:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2580 .LM264: + 2581 0b2e 6F2D mov r22,r15 + 2582 0b30 8A8D ldd r24,Y+26 + 2583 0b32 9B8D ldd r25,Y+27 + 2584 0b34 0E94 0000 call setArpDebug + 2585 0b38 00C0 rjmp .L123 + 2586 .L118: + 362:vty.c **** { + 2588 .LM265: + 2589 0b3a 42E0 ldi r20,lo8(2) + 2590 0b3c 50E0 ldi r21,0 + 2591 0b3e 60E0 ldi r22,lo8(__c.3668) + 2592 0b40 70E0 ldi r23,hi8(__c.3668) + 2593 0b42 812F mov r24,r17 + 2594 0b44 902F mov r25,r16 + 2595 0b46 0E94 0000 call strncmp_P + 2596 0b4a 892B or r24,r25 + 2597 0b4c 01F4 brne .L119 + 364:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2599 .LM266: + 2600 0b4e 6F2D mov r22,r15 + 2601 0b50 8A8D ldd r24,Y+26 + 2602 0b52 9B8D ldd r25,Y+27 + 2603 0b54 0E94 0000 call setIpDebug + 2604 0b58 00C0 rjmp .L123 + 2605 .L119: + 369:vty.c **** { + 2607 .LM267: + 2608 0b5a 42E0 ldi r20,lo8(2) + 2609 0b5c 50E0 ldi r21,0 + 2610 0b5e 60E0 ldi r22,lo8(__c.3670) + 2611 0b60 70E0 ldi r23,hi8(__c.3670) + 2612 0b62 812F mov r24,r17 + 2613 0b64 902F mov r25,r16 + 2614 0b66 0E94 0000 call strncmp_P + 2615 0b6a 892B or r24,r25 + 2616 0b6c 01F4 brne .L120 + 371:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2618 .LM268: + 2619 0b6e 6F2D mov r22,r15 + 2620 0b70 8A8D ldd r24,Y+26 + 2621 0b72 9B8D ldd r25,Y+27 + 2622 0b74 0E94 0000 call setIcmpDebug + 2623 0b78 00C0 rjmp .L123 + 2624 .L120: + 376:vty.c **** { + 2626 .LM269: + 2627 0b7a 42E0 ldi r20,lo8(2) + 2628 0b7c 50E0 ldi r21,0 + 2629 0b7e 60E0 ldi r22,lo8(__c.3672) + 2630 0b80 70E0 ldi r23,hi8(__c.3672) + 2631 0b82 812F mov r24,r17 + 2632 0b84 902F mov r25,r16 + 2633 0b86 0E94 0000 call strncmp_P + 2634 0b8a 892B or r24,r25 + 2635 0b8c 01F4 brne .L121 + 378:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2637 .LM270: + 2638 0b8e 6F2D mov r22,r15 + 2639 0b90 8A8D ldd r24,Y+26 + 2640 0b92 9B8D ldd r25,Y+27 + 2641 0b94 0E94 0000 call setTcpDebug + 2642 0b98 00C0 rjmp .L123 + 2643 .L121: + 383:vty.c **** { + 2645 .LM271: + 2646 0b9a 42E0 ldi r20,lo8(2) + 2647 0b9c 50E0 ldi r21,0 + 2648 0b9e 60E0 ldi r22,lo8(__c.3674) + 2649 0ba0 70E0 ldi r23,hi8(__c.3674) + 2650 0ba2 812F mov r24,r17 + 2651 0ba4 902F mov r25,r16 + 2652 0ba6 0E94 0000 call strncmp_P + 2653 0baa 892B or r24,r25 + 2654 0bac 01F0 breq .+2 + 2655 0bae 00C0 rjmp .L117 + 385:vty.c **** fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + 2657 .LM272: + 2658 0bb0 6F2D mov r22,r15 + 2659 0bb2 8A8D ldd r24,Y+26 + 2660 0bb4 9B8D ldd r25,Y+27 + 2661 0bb6 0E94 0000 call setUdpDebug + 2662 .L123: + 386:vty.c **** return OK_SILENT; + 2664 .LM273: + 2665 0bba 0F93 push r16 + 2666 0bbc 1F93 push r17 + 2667 0bbe 80E0 ldi r24,lo8(debugEnabledInfoStr) + 2668 0bc0 90E0 ldi r25,hi8(debugEnabledInfoStr) + 2669 .L122: + 2670 0bc2 9F93 push r25 + 2671 0bc4 8F93 push r24 + 2672 0bc6 8B8D ldd r24,Y+27 + 2673 0bc8 8F93 push r24 + 2674 0bca 8A8D ldd r24,Y+26 + 2675 0bcc 8F93 push r24 + 2676 0bce 0E94 0000 call fprintf_P + 2677 0bd2 0F90 pop __tmp_reg__ + 2678 0bd4 0F90 pop __tmp_reg__ + 2679 0bd6 0F90 pop __tmp_reg__ + 2680 0bd8 0F90 pop __tmp_reg__ + 2681 0bda 0F90 pop __tmp_reg__ + 2682 0bdc 0F90 pop __tmp_reg__ + 387:vty.c **** } + 2684 .LM274: + 2685 0bde 80E0 ldi r24,0 + 2686 0be0 90E0 ldi r25,0 + 2687 .L111: + 2688 /* epilogue start */ + 2689 .LBE62: + 2690 .LBE61: + 392:vty.c **** + 2692 .LM275: + 2693 0be2 DF91 pop r29 + 2694 0be4 CF91 pop r28 + 2695 0be6 1F91 pop r17 + 2696 0be8 0F91 pop r16 + 2697 0bea FF90 pop r15 + 2698 0bec 0895 ret + 2700 .Lscope23: + 2702 .stabd 78,0,0 + 2706 setMacAddrFunction: + 2707 .stabd 46,0,0 + 507:vty.c **** if (state->argc < 6) + 2709 .LM276: + 2710 .LFBB24: + 2711 0bee CF93 push r28 + 2712 0bf0 DF93 push r29 + 2713 /* prologue: function */ + 2714 /* frame size = 0 */ + 2715 /* stack size = 2 */ + 2716 .L__stack_usage = 2 + 508:vty.c **** return SYNTAX_ERROR; + 2718 .LM277: + 2719 0bf2 FC01 movw r30,r24 + 2720 0bf4 218D ldd r18,Z+25 + 2721 0bf6 2630 cpi r18,lo8(6) + 2722 0bf8 00F0 brlo .L127 + 2723 0bfa EC01 movw r28,r24 + 2724 .LBB65: + 2725 .LBB66: + 511:vty.c **** nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + 2727 .LM278: + 2728 0bfc BC01 movw r22,r24 + 2729 0bfe 81E0 ldi r24,lo8(1) + 2730 0c00 0E94 0000 call cmdlineGetArgHex + 2731 0c04 6093 0000 sts nicState+2,r22 + 512:vty.c **** nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + 2733 .LM279: + 2734 0c08 BE01 movw r22,r28 + 2735 0c0a 82E0 ldi r24,lo8(2) + 2736 0c0c 0E94 0000 call cmdlineGetArgHex + 2737 0c10 6093 0000 sts nicState+3,r22 + 513:vty.c **** nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + 2739 .LM280: + 2740 0c14 BE01 movw r22,r28 + 2741 0c16 83E0 ldi r24,lo8(3) + 2742 0c18 0E94 0000 call cmdlineGetArgHex + 2743 0c1c 6093 0000 sts nicState+4,r22 + 514:vty.c **** nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + 2745 .LM281: + 2746 0c20 BE01 movw r22,r28 + 2747 0c22 84E0 ldi r24,lo8(4) + 2748 0c24 0E94 0000 call cmdlineGetArgHex + 2749 0c28 6093 0000 sts nicState+5,r22 + 515:vty.c **** nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + 2751 .LM282: + 2752 0c2c BE01 movw r22,r28 + 2753 0c2e 85E0 ldi r24,lo8(5) + 2754 0c30 0E94 0000 call cmdlineGetArgHex + 2755 0c34 6093 0000 sts nicState+6,r22 + 516:vty.c **** nicSetMacAddress(nicState.mac.addr); + 2757 .LM283: + 2758 0c38 BE01 movw r22,r28 + 2759 0c3a 86E0 ldi r24,lo8(6) + 2760 0c3c 0E94 0000 call cmdlineGetArgHex + 2761 0c40 6093 0000 sts nicState+7,r22 + 517:vty.c **** return OK_SILENT; + 2763 .LM284: + 2764 0c44 80E0 ldi r24,lo8(nicState+2) + 2765 0c46 90E0 ldi r25,hi8(nicState+2) + 2766 0c48 0E94 0000 call nicSetMacAddress + 2767 0c4c 80E0 ldi r24,0 + 2768 0c4e 90E0 ldi r25,0 + 2769 0c50 00C0 rjmp .L126 + 2770 .L127: + 2771 .LBE66: + 2772 .LBE65: + 509:vty.c **** + 2774 .LM285: + 2775 0c52 82E0 ldi r24,lo8(2) + 2776 0c54 90E0 ldi r25,0 + 2777 .L126: + 2778 /* epilogue start */ + 519:vty.c **** + 2780 .LM286: + 2781 0c56 DF91 pop r29 + 2782 0c58 CF91 pop r28 + 2783 0c5a 0895 ret + 2785 .Lscope24: + 2787 .stabd 78,0,0 + 2791 setUdpFunction: + 2792 .stabd 46,0,0 + 437:vty.c **** if (state->argc < 5) + 2794 .LM287: + 2795 .LFBB25: + 2796 0c5c 8F92 push r8 + 2797 0c5e 9F92 push r9 + 2798 0c60 AF92 push r10 + 2799 0c62 BF92 push r11 + 2800 0c64 CF92 push r12 + 2801 0c66 DF92 push r13 + 2802 0c68 EF92 push r14 + 2803 0c6a FF92 push r15 + 2804 0c6c CF93 push r28 + 2805 0c6e DF93 push r29 + 2806 /* prologue: function */ + 2807 /* frame size = 0 */ + 2808 /* stack size = 10 */ + 2809 .L__stack_usage = 10 + 438:vty.c **** return SYNTAX_ERROR; + 2811 .LM288: + 2812 0c70 FC01 movw r30,r24 + 2813 0c72 218D ldd r18,Z+25 + 2814 0c74 2530 cpi r18,lo8(5) + 2815 0c76 00F4 brsh .+2 + 2816 0c78 00C0 rjmp .L130 + 2817 0c7a EC01 movw r28,r24 + 2818 .LBB69: + 2819 .LBB70: + 441:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2821 .LM289: + 2822 0c7c BC01 movw r22,r24 + 2823 0c7e 81E0 ldi r24,lo8(1) + 2824 0c80 0E94 0000 call cmdlineGetArgInt + 2825 0c84 6B01 movw r12,r22 + 2826 0c86 7C01 movw r14,r24 + 442:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2828 .LM290: + 2829 0c88 BE01 movw r22,r28 + 2830 0c8a 82E0 ldi r24,lo8(2) + 2831 0c8c 0E94 0000 call cmdlineGetArgInt + 2832 0c90 4B01 movw r8,r22 + 2833 0c92 5C01 movw r10,r24 + 443:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2835 .LM291: + 2836 0c94 BE01 movw r22,r28 + 2837 0c96 83E0 ldi r24,lo8(3) + 2838 0c98 0E94 0000 call cmdlineGetArgInt + 442:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2840 .LM292: + 2841 0c9c BA2C mov r11,r10 + 2842 0c9e A92C mov r10,r9 + 2843 0ca0 982C mov r9,r8 + 2844 0ca2 8824 clr r8 + 443:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 2846 .LM293: + 2847 0ca4 5527 clr r21 + 2848 0ca6 4427 clr r20 + 2849 0ca8 D501 movw r26,r10 + 2850 0caa C401 movw r24,r8 + 2851 0cac 840F add r24,r20 + 2852 0cae 951F adc r25,r21 + 2853 0cb0 A61F adc r26,r22 + 2854 0cb2 B71F adc r27,r23 + 442:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2856 .LM294: + 2857 0cb4 C80E add r12,r24 + 2858 0cb6 D91E adc r13,r25 + 2859 0cb8 EA1E adc r14,r26 + 2860 0cba FB1E adc r15,r27 + 444:vty.c **** udpSocket->dstIp = ip; + 2862 .LM295: + 2863 0cbc BE01 movw r22,r28 + 2864 0cbe 84E0 ldi r24,lo8(4) + 2865 0cc0 0E94 0000 call cmdlineGetArgInt + 445:vty.c **** + 2867 .LM296: + 2868 0cc4 E091 0000 lds r30,udpSocket + 2869 0cc8 F091 0000 lds r31,udpSocket+1 + 444:vty.c **** udpSocket->dstIp = ip; + 2871 .LM297: + 2872 0ccc B62F mov r27,r22 + 2873 0cce AA27 clr r26 + 2874 0cd0 9927 clr r25 + 2875 0cd2 8827 clr r24 + 441:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2877 .LM298: + 2878 0cd4 8C0D add r24,r12 + 2879 0cd6 9D1D adc r25,r13 + 2880 0cd8 AE1D adc r26,r14 + 2881 0cda BF1D adc r27,r15 + 445:vty.c **** + 2883 .LM299: + 2884 0cdc 8683 std Z+6,r24 + 2885 0cde 9783 std Z+7,r25 + 2886 0ce0 A087 std Z+8,r26 + 2887 0ce2 B187 std Z+9,r27 + 447:vty.c **** udpSocket->srcPort = htons(port); + 2889 .LM300: + 2890 0ce4 BE01 movw r22,r28 + 2891 0ce6 85E0 ldi r24,lo8(5) + 2892 0ce8 0E94 0000 call cmdlineGetArgInt + 448:vty.c **** + 2894 .LM301: + 2895 0cec E090 0000 lds r14,udpSocket + 2896 0cf0 F090 0000 lds r15,udpSocket+1 + 2897 0cf4 CB01 movw r24,r22 + 2898 0cf6 0E94 0000 call htons + 2899 0cfa F701 movw r30,r14 + 2900 0cfc 9583 std Z+5,r25 + 2901 0cfe 8483 std Z+4,r24 + 450:vty.c **** { + 2903 .LM302: + 2904 0d00 898D ldd r24,Y+25 + 2905 0d02 8630 cpi r24,lo8(6) + 2906 0d04 00F0 brlo .L131 + 452:vty.c **** udpSocket->dstPort = htons(port); + 2908 .LM303: + 2909 0d06 BE01 movw r22,r28 + 2910 0d08 86E0 ldi r24,lo8(6) + 2911 0d0a 0E94 0000 call cmdlineGetArgInt + 453:vty.c **** } + 2913 .LM304: + 2914 0d0e C091 0000 lds r28,udpSocket + 2915 0d12 D091 0000 lds r29,udpSocket+1 + 2916 0d16 CB01 movw r24,r22 + 2917 0d18 0E94 0000 call htons + 2918 0d1c 9B83 std Y+3,r25 + 2919 0d1e 8A83 std Y+2,r24 + 2920 0d20 00C0 rjmp .L131 + 2921 .L130: + 2922 .LBE70: + 2923 .LBE69: + 439:vty.c **** + 2925 .LM305: + 2926 0d22 82E0 ldi r24,lo8(2) + 2927 0d24 90E0 ldi r25,0 + 2928 0d26 00C0 rjmp .L129 + 2929 .L131: + 2930 .LBB72: + 2931 .LBB71: + 450:vty.c **** { + 2933 .LM306: + 2934 0d28 80E0 ldi r24,0 + 2935 0d2a 90E0 ldi r25,0 + 2936 .L129: + 2937 /* epilogue start */ + 2938 .LBE71: + 2939 .LBE72: + 456:vty.c **** + 2941 .LM307: + 2942 0d2c DF91 pop r29 + 2943 0d2e CF91 pop r28 + 2944 0d30 FF90 pop r15 + 2945 0d32 EF90 pop r14 + 2946 0d34 DF90 pop r13 + 2947 0d36 CF90 pop r12 + 2948 0d38 BF90 pop r11 + 2949 0d3a AF90 pop r10 + 2950 0d3c 9F90 pop r9 + 2951 0d3e 8F90 pop r8 + 2952 0d40 0895 ret + 2954 .Lscope25: + 2956 .stabd 78,0,0 + 2960 setIpGwFunction: + 2961 .stabd 46,0,0 + 472:vty.c **** if (state->argc < 4) + 2963 .LM308: + 2964 .LFBB26: + 2965 0d42 8F92 push r8 + 2966 0d44 9F92 push r9 + 2967 0d46 AF92 push r10 + 2968 0d48 BF92 push r11 + 2969 0d4a CF92 push r12 + 2970 0d4c DF92 push r13 + 2971 0d4e EF92 push r14 + 2972 0d50 FF92 push r15 + 2973 0d52 CF93 push r28 + 2974 0d54 DF93 push r29 + 2975 /* prologue: function */ + 2976 /* frame size = 0 */ + 2977 /* stack size = 10 */ + 2978 .L__stack_usage = 10 + 473:vty.c **** return SYNTAX_ERROR; + 2980 .LM309: + 2981 0d56 FC01 movw r30,r24 + 2982 0d58 218D ldd r18,Z+25 + 2983 0d5a 2430 cpi r18,lo8(4) + 2984 0d5c 00F0 brlo .L134 + 2985 0d5e EC01 movw r28,r24 + 2986 .LBB75: + 2987 .LBB76: + 476:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 2989 .LM310: + 2990 0d60 BC01 movw r22,r24 + 2991 0d62 81E0 ldi r24,lo8(1) + 2992 0d64 0E94 0000 call cmdlineGetArgInt + 2993 0d68 6B01 movw r12,r22 + 2994 0d6a 7C01 movw r14,r24 + 477:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 2996 .LM311: + 2997 0d6c BE01 movw r22,r28 + 2998 0d6e 82E0 ldi r24,lo8(2) + 2999 0d70 0E94 0000 call cmdlineGetArgInt + 3000 0d74 4B01 movw r8,r22 + 3001 0d76 5C01 movw r10,r24 + 478:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 3003 .LM312: + 3004 0d78 BE01 movw r22,r28 + 3005 0d7a 83E0 ldi r24,lo8(3) + 3006 0d7c 0E94 0000 call cmdlineGetArgInt + 477:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 3008 .LM313: + 3009 0d80 BA2C mov r11,r10 + 3010 0d82 A92C mov r10,r9 + 3011 0d84 982C mov r9,r8 + 3012 0d86 8824 clr r8 + 478:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 3014 .LM314: + 3015 0d88 5527 clr r21 + 3016 0d8a 4427 clr r20 + 3017 0d8c D501 movw r26,r10 + 3018 0d8e C401 movw r24,r8 + 3019 0d90 840F add r24,r20 + 3020 0d92 951F adc r25,r21 + 3021 0d94 A61F adc r26,r22 + 3022 0d96 B71F adc r27,r23 + 477:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 3024 .LM315: + 3025 0d98 C80E add r12,r24 + 3026 0d9a D91E adc r13,r25 + 3027 0d9c EA1E adc r14,r26 + 3028 0d9e FB1E adc r15,r27 + 479:vty.c **** ipSetConfigGw(gw); + 3030 .LM316: + 3031 0da0 BE01 movw r22,r28 + 3032 0da2 84E0 ldi r24,lo8(4) + 3033 0da4 0E94 0000 call cmdlineGetArgInt + 3034 0da8 B62F mov r27,r22 + 3035 0daa AA27 clr r26 + 3036 0dac 9927 clr r25 + 3037 0dae 8827 clr r24 + 476:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 3039 .LM317: + 3040 0db0 BC01 movw r22,r24 + 3041 0db2 CD01 movw r24,r26 + 3042 0db4 6C0D add r22,r12 + 3043 0db6 7D1D adc r23,r13 + 3044 0db8 8E1D adc r24,r14 + 3045 0dba 9F1D adc r25,r15 + 480:vty.c **** return OK_SILENT; + 3047 .LM318: + 3048 0dbc 0E94 0000 call ipSetConfigGw + 3049 0dc0 80E0 ldi r24,0 + 3050 0dc2 90E0 ldi r25,0 + 3051 0dc4 00C0 rjmp .L133 + 3052 .L134: + 3053 .LBE76: + 3054 .LBE75: + 474:vty.c **** + 3056 .LM319: + 3057 0dc6 82E0 ldi r24,lo8(2) + 3058 0dc8 90E0 ldi r25,0 + 3059 .L133: + 3060 /* epilogue start */ + 482:vty.c **** + 3062 .LM320: + 3063 0dca DF91 pop r29 + 3064 0dcc CF91 pop r28 + 3065 0dce FF90 pop r15 + 3066 0dd0 EF90 pop r14 + 3067 0dd2 DF90 pop r13 + 3068 0dd4 CF90 pop r12 + 3069 0dd6 BF90 pop r11 + 3070 0dd8 AF90 pop r10 + 3071 0dda 9F90 pop r9 + 3072 0ddc 8F90 pop r8 + 3073 0dde 0895 ret + 3075 .Lscope26: + 3077 .stabd 78,0,0 + 3081 setIpMaskFunction: + 3082 .stabd 46,0,0 + 460:vty.c **** if (state->argc < 1) + 3084 .LM321: + 3085 .LFBB27: + 3086 /* prologue: function */ + 3087 /* frame size = 0 */ + 3088 /* stack size = 0 */ + 3089 .L__stack_usage = 0 + 461:vty.c **** return SYNTAX_ERROR; + 3091 .LM322: + 3092 0de0 FC01 movw r30,r24 + 3093 0de2 218D ldd r18,Z+25 + 3094 0de4 2223 tst r18 + 3095 0de6 01F0 breq .L137 + 3096 0de8 BC01 movw r22,r24 + 3097 .LBB79: + 3098 .LBB80: + 464:vty.c **** + 3100 .LM323: + 3101 0dea 81E0 ldi r24,lo8(1) + 3102 0dec 0E94 0000 call cmdlineGetArgInt + 3103 0df0 20E2 ldi r18,lo8(32) + 3104 0df2 30E0 ldi r19,0 + 3105 0df4 261B sub r18,r22 + 3106 0df6 370B sbc r19,r23 + 3107 0df8 8FEF ldi r24,lo8(-1) + 3108 0dfa 9FEF ldi r25,lo8(-1) + 3109 0dfc DC01 movw r26,r24 + 3110 0dfe BC01 movw r22,r24 + 3111 0e00 CD01 movw r24,r26 + 3112 0e02 00C0 rjmp 2f + 3113 1: + 3114 0e04 9695 lsr r25 + 3115 0e06 8795 ror r24 + 3116 0e08 7795 ror r23 + 3117 0e0a 6795 ror r22 + 3118 2: + 3119 0e0c 2A95 dec r18 + 3120 0e0e 02F4 brpl 1b + 466:vty.c **** return OK_SILENT; + 3122 .LM324: + 3123 0e10 0E94 0000 call ipSetConfigMask + 3124 0e14 80E0 ldi r24,0 + 3125 0e16 90E0 ldi r25,0 + 3126 0e18 0895 ret + 3127 .L137: + 3128 .LBE80: + 3129 .LBE79: + 462:vty.c **** + 3131 .LM325: + 3132 0e1a 82E0 ldi r24,lo8(2) + 3133 0e1c 90E0 ldi r25,0 + 468:vty.c **** + 3135 .LM326: + 3136 0e1e 0895 ret + 3138 .Lscope27: + 3140 .stabd 78,0,0 + 3144 setIpFunction: + 3145 .stabd 46,0,0 + 423:vty.c **** if (state->argc < 4) + 3147 .LM327: + 3148 .LFBB28: + 3149 0e20 8F92 push r8 + 3150 0e22 9F92 push r9 + 3151 0e24 AF92 push r10 + 3152 0e26 BF92 push r11 + 3153 0e28 CF92 push r12 + 3154 0e2a DF92 push r13 + 3155 0e2c EF92 push r14 + 3156 0e2e FF92 push r15 + 3157 0e30 CF93 push r28 + 3158 0e32 DF93 push r29 + 3159 /* prologue: function */ + 3160 /* frame size = 0 */ + 3161 /* stack size = 10 */ + 3162 .L__stack_usage = 10 + 424:vty.c **** return SYNTAX_ERROR; + 3164 .LM328: + 3165 0e34 FC01 movw r30,r24 + 3166 0e36 218D ldd r18,Z+25 + 3167 0e38 2430 cpi r18,lo8(4) + 3168 0e3a 00F0 brlo .L140 + 3169 0e3c EC01 movw r28,r24 + 3170 .LBB83: + 3171 .LBB84: + 427:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 3173 .LM329: + 3174 0e3e BC01 movw r22,r24 + 3175 0e40 81E0 ldi r24,lo8(1) + 3176 0e42 0E94 0000 call cmdlineGetArgInt + 3177 0e46 6B01 movw r12,r22 + 3178 0e48 7C01 movw r14,r24 + 428:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 3180 .LM330: + 3181 0e4a BE01 movw r22,r28 + 3182 0e4c 82E0 ldi r24,lo8(2) + 3183 0e4e 0E94 0000 call cmdlineGetArgInt + 3184 0e52 4B01 movw r8,r22 + 3185 0e54 5C01 movw r10,r24 + 429:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 3187 .LM331: + 3188 0e56 BE01 movw r22,r28 + 3189 0e58 83E0 ldi r24,lo8(3) + 3190 0e5a 0E94 0000 call cmdlineGetArgInt + 428:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 3192 .LM332: + 3193 0e5e BA2C mov r11,r10 + 3194 0e60 A92C mov r10,r9 + 3195 0e62 982C mov r9,r8 + 3196 0e64 8824 clr r8 + 429:vty.c **** (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + 3198 .LM333: + 3199 0e66 5527 clr r21 + 3200 0e68 4427 clr r20 + 3201 0e6a D501 movw r26,r10 + 3202 0e6c C401 movw r24,r8 + 3203 0e6e 840F add r24,r20 + 3204 0e70 951F adc r25,r21 + 3205 0e72 A61F adc r26,r22 + 3206 0e74 B71F adc r27,r23 + 428:vty.c **** (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + 3208 .LM334: + 3209 0e76 C80E add r12,r24 + 3210 0e78 D91E adc r13,r25 + 3211 0e7a EA1E adc r14,r26 + 3212 0e7c FB1E adc r15,r27 + 430:vty.c **** + 3214 .LM335: + 3215 0e7e BE01 movw r22,r28 + 3216 0e80 84E0 ldi r24,lo8(4) + 3217 0e82 0E94 0000 call cmdlineGetArgInt + 3218 0e86 B62F mov r27,r22 + 3219 0e88 AA27 clr r26 + 3220 0e8a 9927 clr r25 + 3221 0e8c 8827 clr r24 + 427:vty.c **** (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + 3223 .LM336: + 3224 0e8e BC01 movw r22,r24 + 3225 0e90 CD01 movw r24,r26 + 3226 0e92 6C0D add r22,r12 + 3227 0e94 7D1D adc r23,r13 + 3228 0e96 8E1D adc r24,r14 + 3229 0e98 9F1D adc r25,r15 + 432:vty.c **** return OK_SILENT; + 3231 .LM337: + 3232 0e9a 0E94 0000 call ipSetConfigIp + 3233 0e9e 80E0 ldi r24,0 + 3234 0ea0 90E0 ldi r25,0 + 3235 0ea2 00C0 rjmp .L139 + 3236 .L140: + 3237 .LBE84: + 3238 .LBE83: + 425:vty.c **** + 3240 .LM338: + 3241 0ea4 82E0 ldi r24,lo8(2) + 3242 0ea6 90E0 ldi r25,0 + 3243 .L139: + 3244 /* epilogue start */ + 434:vty.c **** + 3246 .LM339: + 3247 0ea8 DF91 pop r29 + 3248 0eaa CF91 pop r28 + 3249 0eac FF90 pop r15 + 3250 0eae EF90 pop r14 + 3251 0eb0 DF90 pop r13 + 3252 0eb2 CF90 pop r12 + 3253 0eb4 BF90 pop r11 + 3254 0eb6 AF90 pop r10 + 3255 0eb8 9F90 pop r9 + 3256 0eba 8F90 pop r8 + 3257 0ebc 0895 ret + 3259 .Lscope28: + 3261 .stabd 78,0,0 + 3265 .global VtyInit + 3267 VtyInit: + 3268 .stabd 46,0,0 + 165:vty.c **** cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR + 3270 .LM340: + 3271 .LFBB29: + 3272 0ebe EF92 push r14 + 3273 0ec0 0F93 push r16 + 3274 0ec2 1F93 push r17 + 3275 /* prologue: function */ + 3276 /* frame size = 0 */ + 3277 /* stack size = 3 */ + 3278 .L__stack_usage = 3 + 3279 0ec4 9B01 movw r18,r22 + 166:vty.c **** } + 3281 .LM341: + 3282 0ec6 E12C mov r14,__zero_reg__ + 3283 0ec8 00E0 ldi r16,lo8(cmdListNormal) + 3284 0eca 10E0 ldi r17,hi8(cmdListNormal) + 3285 0ecc 40E0 ldi r20,0 + 3286 0ece 51E0 ldi r21,lo8(1) + 3287 0ed0 60E0 ldi r22,0 + 3288 0ed2 78E2 ldi r23,lo8(40) + 3289 0ed4 0E94 0000 call cmdStateConfigure + 3290 /* epilogue start */ + 167:vty.c **** + 3292 .LM342: + 3293 0ed8 1F91 pop r17 + 3294 0eda 0F91 pop r16 + 3295 0edc EF90 pop r14 + 3296 0ede 0895 ret + 3298 .Lscope29: + 3300 .stabd 78,0,0 + 3303 .global printErrorInfo + 3305 printErrorInfo: + 3306 .stabd 46,0,0 + 170:vty.c **** if (state->errno != 0) + 3308 .LM343: + 3309 .LFBB30: + 3310 0ee0 CF93 push r28 + 3311 0ee2 DF93 push r29 + 3312 /* prologue: function */ + 3313 /* frame size = 0 */ + 3314 /* stack size = 2 */ + 3315 .L__stack_usage = 2 + 3316 0ee4 EC01 movw r28,r24 + 171:vty.c **** { + 3318 .LM344: + 3319 0ee6 EC8D ldd r30,Y+28 + 3320 0ee8 EE23 tst r30 + 3321 0eea 01F0 breq .L143 + 3322 .LBB85: + 173:vty.c **** } + 3324 .LM345: + 3325 0eec F0E0 ldi r31,0 + 3326 0eee EE0F lsl r30 + 3327 0ef0 FF1F rol r31 + 3328 0ef2 E050 subi r30,lo8(-(errorStrings)) + 3329 0ef4 F040 sbci r31,hi8(-(errorStrings)) + 3330 /* #APP */ + 3331 ; 173 "vty.c" 1 + 3332 0ef6 8591 lpm r24, Z+ + 3333 0ef8 9491 lpm r25, Z + 3334 + 3335 ; 0 "" 2 + 3336 /* #NOAPP */ + 3337 .LBE85: + 3338 0efa 2F8D ldd r18,Y+31 + 3339 0efc 1F92 push __zero_reg__ + 3340 0efe 2F93 push r18 + 3341 0f00 2E8D ldd r18,Y+30 + 3342 0f02 2F93 push r18 + 3343 0f04 2D8D ldd r18,Y+29 + 3344 0f06 2F93 push r18 + 3345 0f08 9F93 push r25 + 3346 0f0a 8F93 push r24 + 3347 0f0c 8B8D ldd r24,Y+27 + 3348 0f0e 8F93 push r24 + 3349 0f10 8A8D ldd r24,Y+26 + 3350 0f12 8F93 push r24 + 3351 0f14 0E94 0000 call fprintf_P + 3352 0f18 8DB7 in r24,__SP_L__ + 3353 0f1a 9EB7 in r25,__SP_H__ + 3354 0f1c 0896 adiw r24,8 + 3355 0f1e 0FB6 in __tmp_reg__,__SREG__ + 3356 0f20 F894 cli + 3357 0f22 9EBF out __SP_H__,r25 + 3358 0f24 0FBE out __SREG__,__tmp_reg__ + 3359 0f26 8DBF out __SP_L__,r24 + 3360 .L143: + 175:vty.c **** state->err1 = 0; + 3362 .LM346: + 3363 0f28 1C8E std Y+28,__zero_reg__ + 176:vty.c **** state->err2 = 0; + 3365 .LM347: + 3366 0f2a 1E8E std Y+30,__zero_reg__ + 3367 0f2c 1D8E std Y+29,__zero_reg__ + 177:vty.c **** } + 3369 .LM348: + 3370 0f2e 1F8E std Y+31,__zero_reg__ + 3371 /* epilogue start */ + 178:vty.c **** + 3373 .LM349: + 3374 0f30 DF91 pop r29 + 3375 0f32 CF91 pop r28 + 3376 0f34 0895 ret + 3381 .Lscope30: + 3383 .stabd 78,0,0 + 3387 rpingFunction: + 3388 .stabd 46,0,0 + 611:vty.c **** if (state->argc < 1) + 3390 .LM350: + 3391 .LFBB31: + 3392 0f36 0F93 push r16 + 3393 0f38 1F93 push r17 + 3394 0f3a CF93 push r28 + 3395 0f3c DF93 push r29 + 3396 0f3e 1F92 push __zero_reg__ + 3397 0f40 CDB7 in r28,__SP_L__ + 3398 0f42 DEB7 in r29,__SP_H__ + 3399 /* prologue: function */ + 3400 /* frame size = 1 */ + 3401 /* stack size = 5 */ + 3402 .L__stack_usage = 5 + 612:vty.c **** return SYNTAX_ERROR; + 3404 .LM351: + 3405 0f44 FC01 movw r30,r24 + 3406 0f46 218D ldd r18,Z+25 + 3407 0f48 2223 tst r18 + 3408 0f4a 01F0 breq .L149 + 3409 0f4c 8C01 movw r16,r24 + 3410 .LBB88: + 3411 .LBB89: + 615:vty.c **** if ((state->err2 = rs485ping(nrSterownika)) == 0) + 3413 .LM352: + 3414 0f4e BC01 movw r22,r24 + 3415 0f50 81E0 ldi r24,lo8(1) + 3416 0f52 0E94 0000 call cmdlineGetArgInt + 616:vty.c **** return OK_INFORM; + 3418 .LM353: + 3419 0f56 862F mov r24,r22 + 3420 0f58 6983 std Y+1,r22 + 3421 0f5a 0E94 0000 call rs485ping + 3422 0f5e F801 movw r30,r16 + 3423 0f60 878F std Z+31,r24 + 3424 0f62 6981 ldd r22,Y+1 + 3425 0f64 8823 tst r24 + 3426 0f66 01F0 breq .L150 + 619:vty.c **** state->err1 = nrSterownika; + 3428 .LM354: + 3429 0f68 89E0 ldi r24,lo8(9) + 3430 0f6a 848F std Z+28,r24 + 620:vty.c **** printErrorInfo(state); + 3432 .LM355: + 3433 0f6c 70E0 ldi r23,0 + 3434 0f6e 768F std Z+30,r23 + 3435 0f70 658F std Z+29,r22 + 621:vty.c **** return OK_SILENT; + 3437 .LM356: + 3438 0f72 C801 movw r24,r16 + 3439 0f74 0E94 0000 call printErrorInfo + 622:vty.c **** } + 3441 .LM357: + 3442 0f78 80E0 ldi r24,0 + 3443 0f7a 90E0 ldi r25,0 + 3444 0f7c 00C0 rjmp .L148 + 3445 .L149: + 3446 .LBE89: + 3447 .LBE88: + 613:vty.c **** + 3449 .LM358: + 3450 0f7e 82E0 ldi r24,lo8(2) + 3451 0f80 90E0 ldi r25,0 + 3452 0f82 00C0 rjmp .L148 + 3453 .L150: + 3454 .LBB91: + 3455 .LBB90: + 617:vty.c **** + 3457 .LM359: + 3458 0f84 81E0 ldi r24,lo8(1) + 3459 0f86 90E0 ldi r25,0 + 3460 .L148: + 3461 /* epilogue start */ + 3462 .LBE90: + 3463 .LBE91: + 623:vty.c **** + 3465 .LM360: + 3466 0f88 0F90 pop __tmp_reg__ + 3467 0f8a DF91 pop r29 + 3468 0f8c CF91 pop r28 + 3469 0f8e 1F91 pop r17 + 3470 0f90 0F91 pop r16 + 3471 0f92 0895 ret + 3473 .Lscope31: + 3475 .stabd 78,0,0 + 3479 eraseRamFileFunction: + 3480 .stabd 46,0,0 + 874:vty.c **** if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + 3482 .LM361: + 3483 .LFBB32: + 3484 0f94 CF93 push r28 + 3485 0f96 DF93 push r29 + 3486 /* prologue: function */ + 3487 /* frame size = 0 */ + 3488 /* stack size = 2 */ + 3489 .L__stack_usage = 2 + 3490 0f98 EC01 movw r28,r24 + 875:vty.c **** return OK_INFORM; + 3492 .LM362: + 3493 0f9a BC01 movw r22,r24 + 3494 0f9c 81E0 ldi r24,lo8(1) + 3495 0f9e 0E94 0000 call cmdlineGetArgStr + 3496 0fa2 0E94 0000 call ramDyskUsunPlik + 3497 0fa6 8823 tst r24 + 3498 0fa8 01F0 breq .L153 + 878:vty.c **** return ERROR_INFORM; + 3500 .LM363: + 3501 0faa CE01 movw r24,r28 + 3502 0fac 0E94 0000 call printErrorInfo + 879:vty.c **** } + 3504 .LM364: + 3505 0fb0 84E0 ldi r24,lo8(4) + 3506 0fb2 90E0 ldi r25,0 + 3507 0fb4 00C0 rjmp .L152 + 3508 .L153: + 876:vty.c **** + 3510 .LM365: + 3511 0fb6 81E0 ldi r24,lo8(1) + 3512 0fb8 90E0 ldi r25,0 + 3513 .L152: + 3514 /* epilogue start */ + 880:vty.c **** + 3516 .LM366: + 3517 0fba DF91 pop r29 + 3518 0fbc CF91 pop r28 + 3519 0fbe 0895 ret + 3521 .Lscope32: + 3523 .stabd 78,0,0 + 3527 dodajRamPlikFunction: + 3528 .stabd 46,0,0 + 883:vty.c **** if (state->argc != 1) + 3530 .LM367: + 3531 .LFBB33: + 3532 0fc0 CF93 push r28 + 3533 0fc2 DF93 push r29 + 3534 /* prologue: function */ + 3535 /* frame size = 0 */ + 3536 /* stack size = 2 */ + 3537 .L__stack_usage = 2 + 884:vty.c **** return SYNTAX_ERROR; + 3539 .LM368: + 3540 0fc4 FC01 movw r30,r24 + 3541 0fc6 218D ldd r18,Z+25 + 3542 0fc8 2130 cpi r18,lo8(1) + 3543 0fca 01F4 brne .L156 + 3544 0fcc EC01 movw r28,r24 + 3545 .LBB94: + 3546 .LBB95: + 887:vty.c **** { + 3548 .LM369: + 3549 0fce BC01 movw r22,r24 + 3550 0fd0 81E0 ldi r24,lo8(1) + 3551 0fd2 0E94 0000 call cmdlineGetArgStr + 3552 0fd6 0E94 0000 call ramDyskUtworzPlik + 3553 0fda 8823 tst r24 + 3554 0fdc 01F0 breq .L157 + 891:vty.c **** return ERROR_INFORM; + 3556 .LM370: + 3557 0fde CE01 movw r24,r28 + 3558 0fe0 0E94 0000 call printErrorInfo + 892:vty.c **** } + 3560 .LM371: + 3561 0fe4 84E0 ldi r24,lo8(4) + 3562 0fe6 90E0 ldi r25,0 + 3563 0fe8 00C0 rjmp .L155 + 3564 .L156: + 3565 .LBE95: + 3566 .LBE94: + 885:vty.c **** + 3568 .LM372: + 3569 0fea 82E0 ldi r24,lo8(2) + 3570 0fec 90E0 ldi r25,0 + 3571 0fee 00C0 rjmp .L155 + 3572 .L157: + 3573 .LBB97: + 3574 .LBB96: + 889:vty.c **** } + 3576 .LM373: + 3577 0ff0 81E0 ldi r24,lo8(1) + 3578 0ff2 90E0 ldi r25,0 + 3579 .L155: + 3580 /* epilogue start */ + 3581 .LBE96: + 3582 .LBE97: + 893:vty.c **** + 3584 .LM374: + 3585 0ff4 DF91 pop r29 + 3586 0ff6 CF91 pop r28 + 3587 0ff8 0895 ret + 3589 .Lscope33: + 3591 .stabd 78,0,0 + 3595 flashExModuleFunction: + 3596 .stabd 46,0,0 + 642:vty.c **** if (state->argc != 2) + 3598 .LM375: + 3599 .LFBB34: + 3600 0ffa FF92 push r15 + 3601 0ffc 0F93 push r16 + 3602 0ffe 1F93 push r17 + 3603 1000 CF93 push r28 + 3604 1002 DF93 push r29 + 3605 /* prologue: function */ + 3606 /* frame size = 0 */ + 3607 /* stack size = 5 */ + 3608 .L__stack_usage = 5 + 643:vty.c **** return SYNTAX_ERROR; + 3610 .LM376: + 3611 1004 FC01 movw r30,r24 + 3612 1006 218D ldd r18,Z+25 + 3613 1008 2230 cpi r18,lo8(2) + 3614 100a 01F0 breq .+2 + 3615 100c 00C0 rjmp .L162 + 3616 100e EC01 movw r28,r24 + 3617 .LBB100: + 3618 .LBB101: + 646:vty.c **** char *nazwaPliku = cmdlineGetArgStr(2, state); + 3620 .LM377: + 3621 1010 BC01 movw r22,r24 + 3622 1012 81E0 ldi r24,lo8(1) + 3623 1014 0E94 0000 call cmdlineGetArgInt + 3624 1018 162F mov r17,r22 + 647:vty.c **** uint8_t blad; + 3626 .LM378: + 3627 101a BE01 movw r22,r28 + 3628 101c 82E0 ldi r24,lo8(2) + 3629 101e 0E94 0000 call cmdlineGetArgStr + 3630 1022 082F mov r16,r24 + 3631 1024 F92E mov r15,r25 + 651:vty.c **** { + 3633 .LM379: + 3634 1026 812F mov r24,r17 + 3635 1028 0E94 0000 call rs485ping + 3636 102c 8823 tst r24 + 3637 102e 01F0 breq .L160 + 653:vty.c **** printErrorInfo(state); + 3639 .LM380: + 3640 1030 89E0 ldi r24,lo8(9) + 3641 1032 8C8F std Y+28,r24 + 654:vty.c **** return ERROR_INFORM; + 3643 .LM381: + 3644 1034 CE01 movw r24,r28 + 3645 1036 0E94 0000 call printErrorInfo + 3646 103a 00C0 rjmp .L163 + 3647 .L160: + 659:vty.c **** { + 3649 .LM382: + 3650 103c 60E0 ldi r22,lo8(fdVty) + 3651 103e 70E0 ldi r23,hi8(fdVty) + 3652 1040 802F mov r24,r16 + 3653 1042 9F2D mov r25,r15 + 3654 1044 0E94 0000 call ramDyskOtworzPlik + 3655 1048 8823 tst r24 + 3656 104a 01F0 breq .L161 + 661:vty.c **** return ERROR_INFORM; + 3658 .LM383: + 3659 104c FF92 push r15 + 3660 104e 0F93 push r16 + 3661 1050 80E0 ldi r24,lo8(errorOpenFile) + 3662 1052 90E0 ldi r25,hi8(errorOpenFile) + 3663 1054 9F93 push r25 + 3664 1056 8F93 push r24 + 3665 1058 8B8D ldd r24,Y+27 + 3666 105a 8F93 push r24 + 3667 105c 8A8D ldd r24,Y+26 + 3668 105e 8F93 push r24 + 3669 1060 0E94 0000 call fprintf_P + 3670 1064 0F90 pop __tmp_reg__ + 3671 1066 0F90 pop __tmp_reg__ + 3672 1068 0F90 pop __tmp_reg__ + 3673 106a 0F90 pop __tmp_reg__ + 3674 106c 0F90 pop __tmp_reg__ + 3675 106e 0F90 pop __tmp_reg__ + 3676 1070 00C0 rjmp .L163 + 3677 .L161: + 665:vty.c **** + 3679 .LM384: + 3680 1072 4A8D ldd r20,Y+26 + 3681 1074 5B8D ldd r21,Y+27 + 3682 1076 612F mov r22,r17 + 3683 1078 80E0 ldi r24,lo8(fdVty) + 3684 107a 90E0 ldi r25,hi8(fdVty) + 3685 107c 0E94 0000 call rs485xModemFlash + 3686 1080 C82F mov r28,r24 + 667:vty.c **** + 3688 .LM385: + 3689 1082 80E0 ldi r24,lo8(fdVty) + 3690 1084 90E0 ldi r25,hi8(fdVty) + 3691 1086 0E94 0000 call ramDyskZamknijPlik + 669:vty.c **** return ERROR_INFORM; + 3693 .LM386: + 3694 108a C111 cpse r28,__zero_reg__ + 3695 108c 00C0 rjmp .L163 + 672:vty.c **** } + 3697 .LM387: + 3698 108e 80E0 ldi r24,0 + 3699 1090 90E0 ldi r25,0 + 3700 1092 00C0 rjmp .L159 + 3701 .L162: + 3702 .LBE101: + 3703 .LBE100: + 644:vty.c **** + 3705 .LM388: + 3706 1094 82E0 ldi r24,lo8(2) + 3707 1096 90E0 ldi r25,0 + 3708 1098 00C0 rjmp .L159 + 3709 .L163: + 3710 .LBB103: + 3711 .LBB102: + 670:vty.c **** + 3713 .LM389: + 3714 109a 84E0 ldi r24,lo8(4) + 3715 109c 90E0 ldi r25,0 + 3716 .L159: + 3717 /* epilogue start */ + 3718 .LBE102: + 3719 .LBE103: + 673:vty.c **** + 3721 .LM390: + 3722 109e DF91 pop r29 + 3723 10a0 CF91 pop r28 + 3724 10a2 1F91 pop r17 + 3725 10a4 0F91 pop r16 + 3726 10a6 FF90 pop r15 + 3727 10a8 0895 ret + 3735 .Lscope34: + 3737 .stabd 78,0,0 + 3739 .global printStatus + 3741 printStatus: + 3742 .stabd 46,0,0 + 212:vty.c **** fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + 3744 .LM391: + 3745 .LFBB35: + 3746 10aa CF93 push r28 + 3747 10ac DF93 push r29 + 3748 /* prologue: function */ + 3749 /* frame size = 0 */ + 3750 /* stack size = 2 */ + 3751 .L__stack_usage = 2 + 3752 10ae D82F mov r29,r24 + 3753 10b0 C92F mov r28,r25 + 213:vty.c **** //Print system state + 3755 .LM392: + 3756 10b2 80E0 ldi r24,lo8(__c.3625) + 3757 10b4 90E0 ldi r25,hi8(__c.3625) + 3758 10b6 9F93 push r25 + 3759 10b8 8F93 push r24 + 3760 10ba CF93 push r28 + 3761 10bc DF93 push r29 + 3762 10be 0E94 0000 call fprintf_P + 215:vty.c **** fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + 3764 .LM393: + 3765 10c2 80E0 ldi r24,lo8(systemStateStr) + 3766 10c4 90E0 ldi r25,hi8(systemStateStr) + 3767 10c6 9F93 push r25 + 3768 10c8 8F93 push r24 + 3769 10ca CF93 push r28 + 3770 10cc DF93 push r29 + 3771 10ce 0E94 0000 call fprintf_P + 216:vty.c **** fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + 3773 .LM394: + 3774 10d2 0E94 0000 call uxTaskGetNumberOfTasks + 3775 10d6 1F92 push __zero_reg__ + 3776 10d8 8F93 push r24 + 3777 10da 80E0 ldi r24,lo8(statusNumberOfTasksStr) + 3778 10dc 90E0 ldi r25,hi8(statusNumberOfTasksStr) + 3779 10de 9F93 push r25 + 3780 10e0 8F93 push r24 + 3781 10e2 CF93 push r28 + 3782 10e4 DF93 push r29 + 3783 10e6 0E94 0000 call fprintf_P + 217:vty.c **** fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + 3785 .LM395: + 3786 10ea 0E94 0000 call xPortGetFreeHeapSize + 3787 10ee 2CE0 ldi r18,lo8(12) + 3788 10f0 2F93 push r18 + 3789 10f2 2CE1 ldi r18,lo8(28) + 3790 10f4 2F93 push r18 + 3791 10f6 9F93 push r25 + 3792 10f8 8F93 push r24 + 3793 10fa 80E0 ldi r24,lo8(statusStaticHeapStateStr) + 3794 10fc 90E0 ldi r25,hi8(statusStaticHeapStateStr) + 3795 10fe 9F93 push r25 + 3796 1100 8F93 push r24 + 3797 1102 CF93 push r28 + 3798 1104 DF93 push r29 + 3799 1106 0E94 0000 call fprintf_P + 218:vty.c **** fprintf_P(stream, statusTemperatureStr, temperature); + 3801 .LM396: + 3802 110a 0E94 0000 call xmallocAvailable + 3803 110e 27E1 ldi r18,lo8(23) + 3804 1110 2F93 push r18 + 3805 1112 1F92 push __zero_reg__ + 3806 1114 9F93 push r25 + 3807 1116 8F93 push r24 + 3808 1118 80E0 ldi r24,lo8(statusDynamicHeapStateStr) + 3809 111a 90E0 ldi r25,hi8(statusDynamicHeapStateStr) + 3810 111c 9F93 push r25 + 3811 111e 8F93 push r24 + 3812 1120 CF93 push r28 + 3813 1122 DF93 push r29 + 3814 1124 0E94 0000 call fprintf_P + 219:vty.c **** fprintf_P(stream, statusVoltageStr, voltage); + 3816 .LM397: + 3817 1128 8091 0000 lds r24,temperature + 3818 112c 1F92 push __zero_reg__ + 3819 112e 8F93 push r24 + 3820 1130 80E0 ldi r24,lo8(statusTemperatureStr) + 3821 1132 90E0 ldi r25,hi8(statusTemperatureStr) + 3822 1134 9F93 push r25 + 3823 1136 8F93 push r24 + 3824 1138 CF93 push r28 + 3825 113a DF93 push r29 + 3826 113c 0E94 0000 call fprintf_P + 220:vty.c **** + 3828 .LM398: + 3829 1140 8091 0000 lds r24,voltage + 3830 1144 2DB7 in r18,__SP_L__ + 3831 1146 3EB7 in r19,__SP_H__ + 3832 1148 2C5D subi r18,-36 + 3833 114a 3F4F sbci r19,-1 + 3834 114c 0FB6 in __tmp_reg__,__SREG__ + 3835 114e F894 cli + 3836 1150 3EBF out __SP_H__,r19 + 3837 1152 0FBE out __SREG__,__tmp_reg__ + 3838 1154 2DBF out __SP_L__,r18 + 3839 1156 1F92 push __zero_reg__ + 3840 1158 8F93 push r24 + 3841 115a 80E0 ldi r24,lo8(statusVoltageStr) + 3842 115c 90E0 ldi r25,hi8(statusVoltageStr) + 3843 115e 9F93 push r25 + 3844 1160 8F93 push r24 + 3845 1162 CF93 push r28 + 3846 1164 DF93 push r29 + 3847 1166 0E94 0000 call fprintf_P + 222:vty.c **** fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); + 3849 .LM399: + 3850 116a 0E94 0000 call ramDyskLiczbaWolnychKlastrow + 223:vty.c **** // printErrorInfo(state); //TODO fix and uncomment + 3852 .LM400: + 3853 116e 1F92 push __zero_reg__ + 3854 1170 90E8 ldi r25,lo8(-128) + 3855 1172 9F93 push r25 + 3856 1174 1F92 push __zero_reg__ + 3857 1176 8F93 push r24 + 3858 1178 80E0 ldi r24,lo8(statusRamDiskStateStr) + 3859 117a 90E0 ldi r25,hi8(statusRamDiskStateStr) + 3860 117c 9F93 push r25 + 3861 117e 8F93 push r24 + 3862 1180 CF93 push r28 + 3863 1182 DF93 push r29 + 3864 1184 0E94 0000 call fprintf_P + 227:vty.c **** + 3866 .LM401: + 3867 1188 80E0 ldi r24,lo8(systemRamConfigStr) + 3868 118a 90E0 ldi r25,hi8(systemRamConfigStr) + 3869 118c 9F93 push r25 + 3870 118e 8F93 push r24 + 3871 1190 CF93 push r28 + 3872 1192 DF93 push r29 + 3873 1194 0E94 0000 call fprintf_P + 229:vty.c **** netPrintEthAddr(stream, &nicState.mac); + 3875 .LM402: + 3876 1198 80E0 ldi r24,lo8(statusMacStr) + 3877 119a 90E0 ldi r25,hi8(statusMacStr) + 3878 119c 9F93 push r25 + 3879 119e 8F93 push r24 + 3880 11a0 CF93 push r28 + 3881 11a2 DF93 push r29 + 3882 11a4 0E94 0000 call fprintf_P + 230:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 3884 .LM403: + 3885 11a8 60E0 ldi r22,lo8(nicState+2) + 3886 11aa 70E0 ldi r23,hi8(nicState+2) + 3887 11ac 8D2F mov r24,r29 + 3888 11ae 9C2F mov r25,r28 + 3889 11b0 0E94 0000 call netPrintEthAddr + 231:vty.c **** + 3891 .LM404: + 3892 11b4 80E0 ldi r24,lo8(__c.3628) + 3893 11b6 90E0 ldi r25,hi8(__c.3628) + 3894 11b8 9F93 push r25 + 3895 11ba 8F93 push r24 + 3896 11bc CF93 push r28 + 3897 11be DF93 push r29 + 3898 11c0 0E94 0000 call fprintf_P + 233:vty.c **** netPrintIPAddr(stream, ipGetConfig()->ip); + 3900 .LM405: + 3901 11c4 80E0 ldi r24,lo8(statusIpStr) + 3902 11c6 90E0 ldi r25,hi8(statusIpStr) + 3903 11c8 9F93 push r25 + 3904 11ca 8F93 push r24 + 3905 11cc CF93 push r28 + 3906 11ce DF93 push r29 + 3907 11d0 0E94 0000 call fprintf_P + 234:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 3909 .LM406: + 3910 11d4 0E94 0000 call ipGetConfig + 3911 11d8 FC01 movw r30,r24 + 3912 11da 4081 ld r20,Z + 3913 11dc 5181 ldd r21,Z+1 + 3914 11de 6281 ldd r22,Z+2 + 3915 11e0 7381 ldd r23,Z+3 + 3916 11e2 8D2F mov r24,r29 + 3917 11e4 9C2F mov r25,r28 + 3918 11e6 0E94 0000 call netPrintIPAddr + 235:vty.c **** + 3920 .LM407: + 3921 11ea 80E0 ldi r24,lo8(__c.3630) + 3922 11ec 90E0 ldi r25,hi8(__c.3630) + 3923 11ee 9F93 push r25 + 3924 11f0 8F93 push r24 + 3925 11f2 CF93 push r28 + 3926 11f4 DF93 push r29 + 3927 11f6 0E94 0000 call fprintf_P + 237:vty.c **** netPrintIPAddr(stream, ipGetConfig()->netmask); + 3929 .LM408: + 3930 11fa 2DB7 in r18,__SP_L__ + 3931 11fc 3EB7 in r19,__SP_H__ + 3932 11fe 2E5D subi r18,-34 + 3933 1200 3F4F sbci r19,-1 + 3934 1202 0FB6 in __tmp_reg__,__SREG__ + 3935 1204 F894 cli + 3936 1206 3EBF out __SP_H__,r19 + 3937 1208 0FBE out __SREG__,__tmp_reg__ + 3938 120a 2DBF out __SP_L__,r18 + 3939 120c 80E0 ldi r24,lo8(statusIpMaskStr) + 3940 120e 90E0 ldi r25,hi8(statusIpMaskStr) + 3941 1210 9F93 push r25 + 3942 1212 8F93 push r24 + 3943 1214 CF93 push r28 + 3944 1216 DF93 push r29 + 3945 1218 0E94 0000 call fprintf_P + 238:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 3947 .LM409: + 3948 121c 0E94 0000 call ipGetConfig + 3949 1220 FC01 movw r30,r24 + 3950 1222 4481 ldd r20,Z+4 + 3951 1224 5581 ldd r21,Z+5 + 3952 1226 6681 ldd r22,Z+6 + 3953 1228 7781 ldd r23,Z+7 + 3954 122a 8D2F mov r24,r29 + 3955 122c 9C2F mov r25,r28 + 3956 122e 0E94 0000 call netPrintIPAddr + 239:vty.c **** + 3958 .LM410: + 3959 1232 80E0 ldi r24,lo8(__c.3632) + 3960 1234 90E0 ldi r25,hi8(__c.3632) + 3961 1236 9F93 push r25 + 3962 1238 8F93 push r24 + 3963 123a CF93 push r28 + 3964 123c DF93 push r29 + 3965 123e 0E94 0000 call fprintf_P + 241:vty.c **** netPrintIPAddr(stream, ipGetConfig()->gateway); + 3967 .LM411: + 3968 1242 80E0 ldi r24,lo8(statusIpGwStr) + 3969 1244 90E0 ldi r25,hi8(statusIpGwStr) + 3970 1246 9F93 push r25 + 3971 1248 8F93 push r24 + 3972 124a CF93 push r28 + 3973 124c DF93 push r29 + 3974 124e 0E94 0000 call fprintf_P + 242:vty.c **** fprintf_P(stream, PSTR("\r\n")); + 3976 .LM412: + 3977 1252 0E94 0000 call ipGetConfig + 3978 1256 FC01 movw r30,r24 + 3979 1258 4085 ldd r20,Z+8 + 3980 125a 5185 ldd r21,Z+9 + 3981 125c 6285 ldd r22,Z+10 + 3982 125e 7385 ldd r23,Z+11 + 3983 1260 8D2F mov r24,r29 + 3984 1262 9C2F mov r25,r28 + 3985 1264 0E94 0000 call netPrintIPAddr + 243:vty.c **** + 3987 .LM413: + 3988 1268 80E0 ldi r24,lo8(__c.3634) + 3989 126a 90E0 ldi r25,hi8(__c.3634) + 3990 126c 9F93 push r25 + 3991 126e 8F93 push r24 + 3992 1270 CF93 push r28 + 3993 1272 DF93 push r29 + 3994 1274 0E94 0000 call fprintf_P + 246:vty.c **** // tmp = printRs485devices(stream); + 3996 .LM414: + 3997 1278 80E0 ldi r24,lo8(statusRs485listStr) + 3998 127a 90E0 ldi r25,hi8(statusRs485listStr) + 3999 127c 9F93 push r25 + 4000 127e 8F93 push r24 + 4001 1280 CF93 push r28 + 4002 1282 DF93 push r29 + 4003 1284 0E94 0000 call fprintf_P + 252:vty.c **** tmp = printLockers(stream); + 4005 .LM415: + 4006 1288 80E0 ldi r24,lo8(statusLockerSensorsStr) + 4007 128a 90E0 ldi r25,hi8(statusLockerSensorsStr) + 4008 128c 9F93 push r25 + 4009 128e 8F93 push r24 + 4010 1290 CF93 push r28 + 4011 1292 DF93 push r29 + 4012 1294 0E94 0000 call fprintf_P + 253:vty.c **** if (tmp == 0) + 4014 .LM416: + 4015 1298 8D2F mov r24,r29 + 4016 129a 9C2F mov r25,r28 + 4017 129c 0E94 0000 call printLockers + 254:vty.c **** fprintf_P(stream, statusLockerSensorsDisStr); + 4019 .LM417: + 4020 12a0 2DB7 in r18,__SP_L__ + 4021 12a2 3EB7 in r19,__SP_H__ + 4022 12a4 285E subi r18,-24 + 4023 12a6 3F4F sbci r19,-1 + 4024 12a8 0FB6 in __tmp_reg__,__SREG__ + 4025 12aa F894 cli + 4026 12ac 3EBF out __SP_H__,r19 + 4027 12ae 0FBE out __SREG__,__tmp_reg__ + 4028 12b0 2DBF out __SP_L__,r18 + 4029 12b2 8111 cpse r24,__zero_reg__ + 4030 12b4 00C0 rjmp .L165 + 255:vty.c **** + 4032 .LM418: + 4033 12b6 80E0 ldi r24,lo8(statusLockerSensorsDisStr) + 4034 12b8 90E0 ldi r25,hi8(statusLockerSensorsDisStr) + 4035 12ba 9F93 push r25 + 4036 12bc 8F93 push r24 + 4037 12be CF93 push r28 + 4038 12c0 DF93 push r29 + 4039 12c2 0E94 0000 call fprintf_P + 4040 12c6 0F90 pop __tmp_reg__ + 4041 12c8 0F90 pop __tmp_reg__ + 4042 12ca 0F90 pop __tmp_reg__ + 4043 12cc 0F90 pop __tmp_reg__ + 4044 .L165: + 264:vty.c **** // arpPrintTable(stream); + 4046 .LM419: + 4047 12ce 8D2F mov r24,r29 + 4048 12d0 9C2F mov r25,r28 + 4049 /* epilogue start */ + 266:vty.c **** + 4051 .LM420: + 4052 12d2 DF91 pop r29 + 4053 12d4 CF91 pop r28 + 264:vty.c **** // arpPrintTable(stream); + 4055 .LM421: + 4056 12d6 0C94 0000 jmp udpPrintStatus + 4058 .Lscope35: + 4060 .stabd 78,0,0 + 4064 statusFunction: + 4065 .stabd 46,0,0 + 272:vty.c **** if (state->argc < 1) + 4067 .LM422: + 4068 .LFBB36: + 4069 12da 0F93 push r16 + 4070 12dc 1F93 push r17 + 4071 12de CF93 push r28 + 4072 12e0 DF93 push r29 + 4073 12e2 CDB7 in r28,__SP_L__ + 4074 12e4 DEB7 in r29,__SP_H__ + 4075 12e6 2E97 sbiw r28,14 + 4076 12e8 0FB6 in __tmp_reg__,__SREG__ + 4077 12ea F894 cli + 4078 12ec DEBF out __SP_H__,r29 + 4079 12ee 0FBE out __SREG__,__tmp_reg__ + 4080 12f0 CDBF out __SP_L__,r28 + 4081 /* prologue: function */ + 4082 /* frame size = 14 */ + 4083 /* stack size = 18 */ + 4084 .L__stack_usage = 18 + 4085 12f2 8C01 movw r16,r24 + 273:vty.c **** { + 4087 .LM423: + 4088 12f4 FC01 movw r30,r24 + 4089 12f6 818D ldd r24,Z+25 + 4090 12f8 8111 cpse r24,__zero_reg__ + 4091 12fa 00C0 rjmp .L167 + 275:vty.c **** return OK_SILENT; + 4093 .LM424: + 4094 12fc 828D ldd r24,Z+26 + 4095 12fe 938D ldd r25,Z+27 + 4096 1300 0E94 0000 call printStatus + 4097 1304 00C0 rjmp .L170 + 4098 .L167: + 280:vty.c **** { + 4100 .LM425: + 4101 1306 B801 movw r22,r16 + 4102 1308 81E0 ldi r24,lo8(1) + 4103 130a 0E94 0000 call cmdlineGetArgStr + 4104 130e 23E0 ldi r18,lo8(3) + 4105 1310 AE01 movw r20,r28 + 4106 1312 4F5F subi r20,-1 + 4107 1314 5F4F sbci r21,-1 + 4108 1316 60E0 ldi r22,lo8(fdVty) + 4109 1318 70E0 ldi r23,hi8(fdVty) + 4110 131a 0E94 0000 call ramDyskOtworzPlikStdIo + 4111 131e 8823 tst r24 + 4112 1320 01F0 breq .L169 + 4113 .LBB106: + 4114 .LBB107: + 282:vty.c **** return ERROR_INFORM; + 4116 .LM426: + 4117 1322 B801 movw r22,r16 + 4118 1324 81E0 ldi r24,lo8(1) + 4119 1326 0E94 0000 call cmdlineGetArgStr + 4120 132a 9F93 push r25 + 4121 132c 8F93 push r24 + 4122 132e 80E0 ldi r24,lo8(errorOpenFile) + 4123 1330 90E0 ldi r25,hi8(errorOpenFile) + 4124 1332 9F93 push r25 + 4125 1334 8F93 push r24 + 4126 1336 F801 movw r30,r16 + 4127 1338 838D ldd r24,Z+27 + 4128 133a 8F93 push r24 + 4129 133c 828D ldd r24,Z+26 + 4130 133e 8F93 push r24 + 4131 1340 0E94 0000 call fprintf_P + 4132 1344 0F90 pop __tmp_reg__ + 4133 1346 0F90 pop __tmp_reg__ + 4134 1348 0F90 pop __tmp_reg__ + 4135 134a 0F90 pop __tmp_reg__ + 4136 134c 0F90 pop __tmp_reg__ + 4137 134e 0F90 pop __tmp_reg__ + 4138 1350 84E0 ldi r24,lo8(4) + 4139 1352 90E0 ldi r25,0 + 4140 1354 00C0 rjmp .L168 + 4141 .L169: + 4142 .LBE107: + 4143 .LBE106: + 286:vty.c **** ramDyskZamknijPlikStdIo(&stream); + 4145 .LM427: + 4146 1356 CE01 movw r24,r28 + 4147 1358 0196 adiw r24,1 + 4148 135a 0E94 0000 call printStatus + 287:vty.c **** return OK_SILENT; + 4150 .LM428: + 4151 135e CE01 movw r24,r28 + 4152 1360 0196 adiw r24,1 + 4153 1362 0E94 0000 call ramDyskZamknijPlikStdIo + 4154 .L170: + 288:vty.c **** } + 4156 .LM429: + 4157 1366 80E0 ldi r24,0 + 4158 1368 90E0 ldi r25,0 + 4159 .L168: + 4160 /* epilogue start */ + 289:vty.c **** + 4162 .LM430: + 4163 136a 2E96 adiw r28,14 + 4164 136c 0FB6 in __tmp_reg__,__SREG__ + 4165 136e F894 cli + 4166 1370 DEBF out __SP_H__,r29 + 4167 1372 0FBE out __SREG__,__tmp_reg__ + 4168 1374 CDBF out __SP_L__,r28 + 4169 1376 DF91 pop r29 + 4170 1378 CF91 pop r28 + 4171 137a 1F91 pop r17 + 4172 137c 0F91 pop r16 + 4173 137e 0895 ret + 4178 .Lscope36: + 4180 .stabd 78,0,0 + 4181 .section .progmem.data,"a",@progbits + 4184 __c.3634: + 4185 0000 0D0A 00 .string "\r\n" + 4188 __c.3632: + 4189 0003 0D0A 00 .string "\r\n" + 4192 __c.3630: + 4193 0006 0D0A 00 .string "\r\n" + 4196 __c.3628: + 4197 0009 0D0A 00 .string "\r\n" + 4200 __c.3625: + 4201 000c 4672 6565 .string "FreeRtos+ ver 0.31 build: Aug 18 2017, 16:12:44\r\n" + 4201 5274 6F73 + 4201 2B20 7665 + 4201 7220 302E + 4201 3331 2062 + 4204 __c.3674: + 4205 003e 7564 7000 .string "udp" + 4208 __c.3672: + 4209 0042 7463 7000 .string "tcp" + 4212 __c.3670: + 4213 0046 6963 6D70 .string "icmp" + 4213 00 + 4216 __c.3668: + 4217 004b 6970 00 .string "ip" + 4220 __c.3666: + 4221 004e 6172 7000 .string "arp" + 4224 __c.3664: + 4225 0052 7564 7000 .string "udp" + 4228 __c.3662: + 4229 0056 7463 7000 .string "tcp" + 4232 __c.3660: + 4233 005a 6963 6D70 .string "icmp" + 4233 00 + 4236 __c.3658: + 4237 005f 6970 00 .string "ip" + 4240 __c.3656: + 4241 0062 6172 7000 .string "arp" + 4244 __c.3768: + 4245 0066 586D 6F64 .string "Xmodem: rozpoczynanie odbioru\r\n" + 4245 656D 3A20 + 4245 726F 7A70 + 4245 6F63 7A79 + 4245 6E61 6E69 + 4248 __c.3718: + 4249 0086 5761 7274 .string "Wartosc probki na wejsciu %d: %d\r\n" + 4249 6F73 6320 + 4249 7072 6F62 + 4249 6B69 206E + 4249 6120 7765 + 4252 __c.3649: + 4253 00a9 416B 7475 .string "Aktualny czas %d:%d:%d\r\n" + 4253 616C 6E79 + 4253 2063 7A61 + 4253 7320 2564 + 4253 3A25 643A + 4254 .global cmdListConfigure + 4257 cmdListConfigure: + 4258 00c2 0000 .word cmd_help + 4259 00c4 0000 .word cmd_help_help + 4260 00c6 0000 .word gs(helpFunction) + 4261 00c8 0000 .word cmd_status + 4262 00ca 0000 .word cmd_help_status + 4263 00cc 0000 .word gs(statusFunction) + 4264 00ce 0000 .word cmd_time + 4265 00d0 0000 .word cmd_help_time + 4266 00d2 0000 .word gs(pokazCzasFunction) + 4267 00d4 0000 .word cmd_settime + 4268 00d6 0000 .word cmd_help_settime + 4269 00d8 0000 .word gs(setTimeFunction) + 4270 00da 0000 .word cmd_conf_ip + 4271 00dc 0000 .word cmd_help_conf_ip + 4272 00de 0000 .word gs(setIpFunction) + 4273 00e0 0000 .word cmd_conf_ip_mask + 4274 00e2 0000 .word cmd_conf_ip_mask_help + 4275 00e4 0000 .word gs(setIpMaskFunction) + 4276 00e6 0000 .word cmd_conf_ip_gw + 4277 00e8 0000 .word cmd_conf_ip_gw_help + 4278 00ea 0000 .word gs(setIpGwFunction) + 4279 00ec 0000 .word cmd_conf_udp + 4280 00ee 0000 .word cmd_help_conf_udp + 4281 00f0 0000 .word gs(setUdpFunction) + 4282 00f2 0000 .word cmd_conf_mac + 4283 00f4 0000 .word cmd_help_conf_mac + 4284 00f6 0000 .word gs(setMacAddrFunction) + 4285 00f8 0000 .word cmd_conf_save + 4286 00fa 0000 .word cmd_help_conf_save + 4287 00fc 0000 .word gs(saveConfigFunction) + 4288 00fe 0000 .word cmd_enable + 4289 0100 0000 .word cmd_help_enable + 4290 0102 0000 .word gs(enableFunction) + 4291 0104 0000 .word cmd_disable + 4292 0106 0000 .word cmd_help_disable + 4293 0108 0000 .word gs(disableFunction) + 4294 010a 0000 .word 0 + 4295 010c 0000 .word 0 + 4296 010e 0000 .word 0 + 4297 .global cmdListEnable + 4300 cmdListEnable: + 4301 0110 0000 .word cmd_help + 4302 0112 0000 .word cmd_help_help + 4303 0114 0000 .word gs(helpFunction) + 4304 0116 0000 .word cmd_status + 4305 0118 0000 .word cmd_help_status + 4306 011a 0000 .word gs(statusFunction) + 4307 011c 0000 .word cmd_enc_stat + 4308 011e 0000 .word cmd_help_enc_stat + 4309 0120 0000 .word gs(statusEncFunction) + 4310 0122 0000 .word cmd_time + 4311 0124 0000 .word cmd_help_time + 4312 0126 0000 .word gs(pokazCzasFunction) + 4313 0128 0000 .word cmd_net_dbg + 4314 012a 0000 .word cmd_help_net_dbg + 4315 012c 0000 .word gs(debugFunction) + 4316 012e 0000 .word cmd_rping + 4317 0130 0000 .word cmd_help_rping + 4318 0132 0000 .word gs(rpingFunction) + 4319 0134 0000 .word cmd_ping + 4320 0136 0000 .word cmd_help_ping + 4321 0138 0000 .word gs(pingFunction) + 4322 013a 0000 .word cmd_xRec + 4323 013c 0000 .word cmd_help_xRec + 4324 013e 0000 .word gs(goXmodemOdbierzFunction) + 4325 0140 0000 .word cmd_xSend + 4326 0142 0000 .word cmd_help_xSend + 4327 0144 0000 .word gs(goXmodemWyslijFunction) + 4328 0146 0000 .word cmd_xflash + 4329 0148 0000 .word cmd_help_xflash + 4330 014a 0000 .word gs(flashExModuleFunction) + 4331 014c 0000 .word cmd_dir_rf + 4332 014e 0000 .word cmd_help_dir_rf + 4333 0150 0000 .word gs(writeRamFileFunction) + 4334 0152 0000 .word cmd_create_rf + 4335 0154 0000 .word cmd_help_create_rf + 4336 0156 0000 .word gs(dodajRamPlikFunction) + 4337 0158 0000 .word cmd_erase_rf + 4338 015a 0000 .word cmd_help_erase_rf + 4339 015c 0000 .word gs(eraseRamFileFunction) + 4340 015e 0000 .word cmd_edit_rf + 4341 0160 0000 .word cmd_help_edit_rf + 4342 0162 0000 .word gs(editRamFileFunction) + 4343 0164 0000 .word cmd_read_rf + 4344 0166 0000 .word cmd_help_read_rf + 4345 0168 0000 .word gs(readRamFIleFunction) + 4346 016a 0000 .word cmd_up + 4347 016c 0000 .word cmd_help_up + 4348 016e 0000 .word gs(curtainUpFunction) + 4349 0170 0000 .word cmd_down + 4350 0172 0000 .word cmd_help_down + 4351 0174 0000 .word gs(curtainDownFunction) + 4352 0176 0000 .word cmd_spa + 4353 0178 0000 .word cmd_help_spa + 4354 017a 0000 .word gs(ustawPortExtAFunction) + 4355 017c 0000 .word cmd_spb + 4356 017e 0000 .word cmd_help_spb + 4357 0180 0000 .word gs(ustawPortExtBFunction) + 4358 0182 0000 .word cmd_ustawR + 4359 0184 0000 .word cmd_help_ustawR + 4360 0186 0000 .word gs(ustawPortRezystor) + 4361 0188 0000 .word cmd_settime + 4362 018a 0000 .word cmd_help_settime + 4363 018c 0000 .word gs(setTimeFunction) + 4364 018e 0000 .word cmd_ac + 4365 0190 0000 .word cmd_help_ac + 4366 0192 0000 .word gs(czytajAC_Function) + 4367 0194 0000 .word cmd_disable + 4368 0196 0000 .word cmd_help_disable + 4369 0198 0000 .word gs(disableFunction) + 4370 019a 0000 .word cmd_configure + 4371 019c 0000 .word cmd_help_configure + 4372 019e 0000 .word gs(configureModeFunction) + 4373 01a0 0000 .word cmd_ustawMW + 4374 01a2 0000 .word cmd_help_ustawMW + 4375 01a4 0000 .word gs(ustawModWykFunction) + 4376 01a6 0000 .word cmd_zapiszMW + 4377 01a8 0000 .word cmd_help_zapiszMW + 4378 01aa 0000 .word gs(zapiszModWykFunction) + 4379 01ac 0000 .word 0 + 4380 01ae 0000 .word 0 + 4381 01b0 0000 .word 0 + 4382 .global cmdListNormal + 4385 cmdListNormal: + 4386 01b2 0000 .word cmd_help + 4387 01b4 0000 .word cmd_help_help + 4388 01b6 0000 .word gs(helpFunction) + 4389 01b8 0000 .word cmd_status + 4390 01ba 0000 .word cmd_help_status + 4391 01bc 0000 .word gs(statusFunction) + 4392 01be 0000 .word cmd_time + 4393 01c0 0000 .word cmd_help_time + 4394 01c2 0000 .word gs(pokazCzasFunction) + 4395 01c4 0000 .word cmd_rping + 4396 01c6 0000 .word cmd_help_rping + 4397 01c8 0000 .word gs(rpingFunction) + 4398 01ca 0000 .word cmd_ping + 4399 01cc 0000 .word cmd_help_ping + 4400 01ce 0000 .word gs(pingFunction) + 4401 01d0 0000 .word cmd_dir_rf + 4402 01d2 0000 .word cmd_help_dir_rf + 4403 01d4 0000 .word gs(writeRamFileFunction) + 4404 01d6 0000 .word cmd_read_rf + 4405 01d8 0000 .word cmd_help_read_rf + 4406 01da 0000 .word gs(readRamFIleFunction) + 4407 01dc 0000 .word cmd_enable + 4408 01de 0000 .word cmd_help_enable + 4409 01e0 0000 .word gs(enableFunction) + 4410 01e2 0000 .word 0 + 4411 01e4 0000 .word 0 + 4412 01e6 0000 .word 0 + 4413 .global errorStrings + 4416 errorStrings: + 4417 01e8 0000 .word errorOK + 4418 01ea 0000 .word errorNoFile + 4419 01ec 0000 .word errorxModemFrameStartTimeout + 4420 01ee 0000 .word errorxModemByteSendTimeout + 4421 01f0 0000 .word errorxModemWrongFrameNo + 4422 01f2 0000 .word errorxModemFrameFrameNoCorrectionNotMatch + 4423 01f4 0000 .word errorxModemFrameCrc + 4424 01f6 0000 .word errorxModemRemoteSideCan + 4425 01f8 0000 .word errorxModemUnknownResponse + 4426 01fa 0000 .word errorNoRemoteDevice + 4427 01fc 0000 .word errorBootloaderNotResponding + 4428 01fe 0000 .word errorOpenFile + 4429 .global BladBuforaPozostaloBajtowStr + 4432 BladBuforaPozostaloBajtowStr: + 4433 0200 2121 2120 .string "!!! W budorze Rs485 pozostalo %d bajtow\r\n" + 4433 5720 6275 + 4433 646F 727A + 4433 6520 5273 + 4433 3438 3520 + 4434 .global nlStr + 4437 nlStr: + 4438 022a 0D0A 00 .string "\r\n" + 4439 .global okStr + 4442 okStr: + 4443 022d 4F4B 0D0A .string "OK\r\n" + 4443 00 + 4444 .comm fdVty,6,1 + 4445 .global cmd_help_zapiszMW + 4448 cmd_help_zapiszMW: + 4449 0232 5B41 5D20 .string "[A] save execution module settings" + 4449 7361 7665 + 4449 2065 7865 + 4449 6375 7469 + 4449 6F6E 206D + 4450 .global cmd_zapiszMW + 4453 cmd_zapiszMW: + 4454 0255 7273 6176 .string "rsave" + 4454 6500 + 4455 .global cmd_help_ustawMW + 4458 cmd_help_ustawMW: + 4459 025b 5B41 5D20 .string "[A] [C] set execution module" + 4459 5B43 5D20 + 4459 7365 7420 + 4459 6578 6563 + 4459 7574 696F + 4460 .global cmd_ustawMW + 4463 cmd_ustawMW: + 4464 0278 7273 6574 .string "rset" + 4464 00 + 4465 .global cmd_help_ustawR + 4468 cmd_help_ustawR: + 4469 027d 5B76 616C .string "[value] set resistance value" + 4469 7565 5D20 + 4469 7365 7420 + 4469 7265 7369 + 4469 7374 616E + 4470 .global cmd_ustawR + 4473 cmd_ustawR: + 4474 029a 7365 7472 .string "setr" + 4474 00 + 4475 .global cmd_help_conf_save + 4478 cmd_help_conf_save: + 4479 029f 5361 7665 .string "Save configuration" + 4479 2063 6F6E + 4479 6669 6775 + 4479 7261 7469 + 4479 6F6E 00 + 4480 .global cmd_conf_save + 4483 cmd_conf_save: + 4484 02b2 7361 7665 .string "save" + 4484 00 + 4485 .global cmd_help_conf_mac + 4488 cmd_help_conf_mac: + 4489 02b7 5B41 315D .string "[A1] [A2] [A3] [A4] [A5] [A6] set MAC address" + 4489 205B 4132 + 4489 5D20 5B41 + 4489 335D 205B + 4489 4134 5D20 + 4490 .global cmd_conf_mac + 4493 cmd_conf_mac: + 4494 02e5 6D61 6300 .string "mac" + 4495 .global cmd_conf_ip_gw_help + 4498 cmd_conf_ip_gw_help: + 4499 02e9 5B41 315D .string "[A1] [A2] [A3] [A4] set default gateway" + 4499 205B 4132 + 4499 5D20 5B41 + 4499 335D 205B + 4499 4134 5D20 + 4500 .global cmd_conf_ip_gw + 4503 cmd_conf_ip_gw: + 4504 0311 6777 00 .string "gw" + 4505 .global cmd_conf_ip_mask_help + 4508 cmd_conf_ip_mask_help: + 4509 0314 5B6D 6173 .string "[mask] set mask" + 4509 6B5D 2073 + 4509 6574 206D + 4509 6173 6B00 + 4510 .global cmd_conf_ip_mask + 4513 cmd_conf_ip_mask: + 4514 0324 6D61 736B .string "mask" + 4514 00 + 4515 .global cmd_help_conf_udp + 4518 cmd_help_conf_udp: + 4519 0329 5B41 315D .string "[A1] [A2] [A3] [A4] [src port] {dst port} set udp client IP address and ports" + 4519 205B 4132 + 4519 5D20 5B41 + 4519 335D 205B + 4519 4134 5D20 + 4520 .global cmd_conf_udp + 4523 cmd_conf_udp: + 4524 0377 7564 7000 .string "udp" + 4525 .global cmd_help_conf_ip + 4528 cmd_help_conf_ip: + 4529 037b 5B41 315D .string "[A1] [A2] [A3] [A4] set IP address" + 4529 205B 4132 + 4529 5D20 5B41 + 4529 335D 205B + 4529 4134 5D20 + 4530 .global cmd_conf_ip + 4533 cmd_conf_ip: + 4534 039e 6970 00 .string "ip" + 4535 .global cmd_help_configure + 4538 cmd_help_configure: + 4539 03a1 436F 6E66 .string "Configure mode" + 4539 6967 7572 + 4539 6520 6D6F + 4539 6465 00 + 4540 .global cmd_configure + 4543 cmd_configure: + 4544 03b0 636F 6E66 .string "config" + 4544 6967 00 + 4545 .global cmd_help_disable + 4548 cmd_help_disable: + 4549 03b7 5669 6577 .string "View mode" + 4549 206D 6F64 + 4549 6500 + 4550 .global cmd_disable + 4553 cmd_disable: + 4554 03c1 6469 7361 .string "disable" + 4554 626C 6500 + 4555 .global cmd_help_enable + 4558 cmd_help_enable: + 4559 03c9 456E 6162 .string "Enable mode" + 4559 6C65 206D + 4559 6F64 6500 + 4560 .global cmd_enable + 4563 cmd_enable: + 4564 03d5 656E 6162 .string "enable" + 4564 6C65 00 + 4565 .global cmd_help_ac + 4568 cmd_help_ac: + 4569 03dc 5B63 6861 .string "[channel 0-7] read analog value" + 4569 6E6E 656C + 4569 2030 2D37 + 4569 5D20 7265 + 4569 6164 2061 + 4570 .global cmd_ac + 4573 cmd_ac: + 4574 03fc 6163 00 .string "ac" + 4575 .global cmd_help_settime + 4578 cmd_help_settime: + 4579 03ff 5B68 5D20 .string "[h] [m] [s] set time (24h format)" + 4579 5B6D 5D20 + 4579 5B73 5D20 + 4579 7365 7420 + 4579 7469 6D65 + 4580 .global cmd_settime + 4583 cmd_settime: + 4584 0421 7365 7474 .string "settime" + 4584 696D 6500 + 4585 .global cmd_help_spb + 4588 cmd_help_spb: + 4589 0429 5B76 616C .string "[value] set port B" + 4589 7565 5D20 + 4589 7365 7420 + 4589 706F 7274 + 4589 2042 00 + 4590 .global cmd_spb + 4593 cmd_spb: + 4594 043c 7370 6200 .string "spb" + 4595 .global cmd_help_spa + 4598 cmd_help_spa: + 4599 0440 5B76 616C .string "[value] set port A" + 4599 7565 5D20 + 4599 7365 7420 + 4599 706F 7274 + 4599 2041 00 + 4600 .global cmd_spa + 4603 cmd_spa: + 4604 0453 7370 6100 .string "spa" + 4605 .global cmd_help_down + 4608 cmd_help_down: + 4609 0457 5B64 7269 .string "[driver no] [channel] {value} move down" + 4609 7665 7220 + 4609 6E6F 5D20 + 4609 5B63 6861 + 4609 6E6E 656C + 4610 .global cmd_down + 4613 cmd_down: + 4614 047f 646F 776E .string "down" + 4614 00 + 4615 .global cmd_help_up + 4618 cmd_help_up: + 4619 0484 5B64 7269 .string "[driver no] [channel] {value} move up" + 4619 7665 7220 + 4619 6E6F 5D20 + 4619 5B63 6861 + 4619 6E6E 656C + 4620 .global cmd_up + 4623 cmd_up: + 4624 04aa 7570 00 .string "up" + 4625 .global cmd_help_read_rf + 4628 cmd_help_read_rf: + 4629 04ad 5B66 696C .string "[file name] read file located on ram disk" + 4629 6520 6E61 + 4629 6D65 5D20 + 4629 7265 6164 + 4629 2066 696C + 4630 .global cmd_read_rf + 4633 cmd_read_rf: + 4634 04d7 7265 6164 .string "readrf" + 4634 7266 00 + 4635 .global cmd_help_edit_rf + 4638 cmd_help_edit_rf: + 4639 04de 5B66 696C .string "[file name] edit file located on ram disk" + 4639 6520 6E61 + 4639 6D65 5D20 + 4639 6564 6974 + 4639 2066 696C + 4640 .global cmd_edit_rf + 4643 cmd_edit_rf: + 4644 0508 6564 6974 .string "editrf" + 4644 7266 00 + 4645 .global cmd_help_erase_rf + 4648 cmd_help_erase_rf: + 4649 050f 5B66 696C .string "[file name] erase file from ram disk" + 4649 6520 6E61 + 4649 6D65 5D20 + 4649 6572 6173 + 4649 6520 6669 + 4650 .global cmd_erase_rf + 4653 cmd_erase_rf: + 4654 0534 6572 6173 .string "eraserf" + 4654 6572 6600 + 4655 .global cmd_help_create_rf + 4658 cmd_help_create_rf: + 4659 053c 5B66 696C .string "[file name] create ram file" + 4659 6520 6E61 + 4659 6D65 5D20 + 4659 6372 6561 + 4659 7465 2072 + 4660 .global cmd_create_rf + 4663 cmd_create_rf: + 4664 0558 6372 6600 .string "crf" + 4665 .global cmd_help_dir_rf + 4668 cmd_help_dir_rf: + 4669 055c 5072 696E .string "Print ramdisk files" + 4669 7420 7261 + 4669 6D64 6973 + 4669 6B20 6669 + 4669 6C65 7300 + 4670 .global cmd_dir_rf + 4673 cmd_dir_rf: + 4674 0570 6469 7272 .string "dirrf" + 4674 6600 + 4675 .global cmd_help_xflash + 4678 cmd_help_xflash: + 4679 0576 5B64 6576 .string "[device no] [file name] flash device connected to Rs485" + 4679 6963 6520 + 4679 6E6F 5D20 + 4679 5B66 696C + 4679 6520 6E61 + 4680 .global cmd_xflash + 4683 cmd_xflash: + 4684 05ae 7866 6C61 .string "xflash" + 4684 7368 00 + 4685 .global cmd_help_xSend + 4688 cmd_help_xSend: + 4689 05b5 5B66 696C .string "[file name] send file using xModem" + 4689 6520 6E61 + 4689 6D65 5D20 + 4689 7365 6E64 + 4689 2066 696C + 4690 .global cmd_xSend + 4693 cmd_xSend: + 4694 05d8 7873 656E .string "xsend" + 4694 6400 + 4695 .global cmd_help_xRec + 4698 cmd_help_xRec: + 4699 05de 5B66 696C .string "[file name] receive file using xModem" + 4699 6520 6E61 + 4699 6D65 5D20 + 4699 7265 6365 + 4699 6976 6520 + 4700 .global cmd_xRec + 4703 cmd_xRec: + 4704 0604 7872 6563 .string "xrec" + 4704 00 + 4705 .global cmd_help_ping + 4708 cmd_help_ping: + 4709 0609 5B41 315D .string "[A1] [A2] [A3] [A4] Sends ping throught ethernet" + 4709 205B 4132 + 4709 5D20 5B41 + 4709 335D 205B + 4709 4134 5D20 + 4710 .global cmd_ping + 4713 cmd_ping: + 4714 063a 7069 6E67 .string "ping" + 4714 00 + 4715 .global cmd_help_rping + 4718 cmd_help_rping: + 4719 063f 5B44 6576 .string "[Device no] Send ping to Rs485 device" + 4719 6963 6520 + 4719 6E6F 5D20 + 4719 5365 6E64 + 4719 2070 696E + 4720 .global cmd_rping + 4723 cmd_rping: + 4724 0665 7270 696E .string "rping" + 4724 6700 + 4725 .global cmd_help_net_dbg + 4728 cmd_help_net_dbg: + 4729 066b 5B61 7270 .string "[arp|icmp|ip|tcp|udp] [level] write debug info. Level 0 disable debuging" + 4729 7C69 636D + 4729 707C 6970 + 4729 7C74 6370 + 4729 7C75 6470 + 4730 .global cmd_net_dbg + 4733 cmd_net_dbg: + 4734 06b4 6465 6275 .string "debug" + 4734 6700 + 4735 .global cmd_help_time + 4738 cmd_help_time: + 4739 06ba 5072 696E .string "Print time" + 4739 7420 7469 + 4739 6D65 00 + 4740 .global cmd_time + 4743 cmd_time: + 4744 06c5 7469 6D65 .string "time" + 4744 00 + 4745 .global cmd_help_enc_stat + 4748 cmd_help_enc_stat: + 4749 06ca 5072 696E .string "Print Enc 28j60 registers" + 4749 7420 456E + 4749 6320 3238 + 4749 6A36 3020 + 4749 7265 6769 + 4750 .global cmd_enc_stat + 4753 cmd_enc_stat: + 4754 06e4 656E 6373 .string "encstat" + 4754 7461 7400 + 4755 .global cmd_help_status + 4758 cmd_help_status: + 4759 06ec 7B66 696C .string "{filename} Print device status on VTY or write to file" + 4759 656E 616D + 4759 657D 2050 + 4759 7269 6E74 + 4759 2064 6576 + 4760 .global cmd_status + 4763 cmd_status: + 4764 0723 7374 6174 .string "status" + 4764 7573 00 + 4765 .global cmd_help_help + 4768 cmd_help_help: + 4769 072a 5072 696E .string "Print help string" + 4769 7420 6865 + 4769 6C70 2073 + 4769 7472 696E + 4769 6700 + 4770 .global cmd_help + 4773 cmd_help: + 4774 073c 6865 6C70 .string "help" + 4774 00 + 4775 .global debugDisabledInfoStr + 4778 debugDisabledInfoStr: + 4779 0741 4469 7361 .string "Disabled %s debug\r\n" + 4779 626C 6564 + 4779 2025 7320 + 4779 6465 6275 + 4779 670D 0A00 + 4780 .global debugEnabledInfoStr + 4783 debugEnabledInfoStr: + 4784 0755 456E 6162 .string "Enabled %s debug\r\n" + 4784 6C65 6420 + 4784 2573 2064 + 4784 6562 7567 + 4784 0D0A 00 + 4785 .global movingCurtainPosStr + 4788 movingCurtainPosStr: + 4789 0768 0970 6F7A .string "\tpozycja %d\r\n" + 4789 7963 6A61 + 4789 2020 2025 + 4789 640D 0A00 + 4790 .global movingCurtainDownStr + 4793 movingCurtainDownStr: + 4794 0778 4F70 7573 .string "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n" + 4794 7A63 7A61 + 4794 6E69 6520 + 4794 726F 6C65 + 4794 7479 0D0A + 4795 .global movingCurtainUpStr + 4798 movingCurtainUpStr: + 4799 07ab 506F 646E .string "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n" + 4799 6F73 7A65 + 4799 6E69 6520 + 4799 726F 6C65 + 4799 7479 0D0A + 4800 .global xwyslijStartStr + 4803 xwyslijStartStr: + 4804 07de 586D 6F64 .string "Xmodem: Transmission start\r\n" + 4804 656D 3A20 + 4804 5472 616E + 4804 736D 6973 + 4804 7369 6F6E + 4805 .global readRamFIleLenStr + 4808 readRamFIleLenStr: + 4809 07fb 4669 6C65 .string "File length: %d\r\n" + 4809 206C 656E + 4809 6774 683A + 4809 2025 640D + 4809 0A00 + 4810 .global editRamFileIntroStr + 4813 editRamFileIntroStr: + 4814 080d 5772 6974 .string "Writing to file. Press CTRL+C to quit\r\n" + 4814 696E 6720 + 4814 746F 2066 + 4814 696C 652E + 4814 2050 7265 + 4815 .global statusLockerSensorsDisStr + 4818 statusLockerSensorsDisStr: + 4819 0835 2020 4C6F .string " Locker sensors disabled\r\n" + 4819 636B 6572 + 4819 2073 656E + 4819 736F 7273 + 4819 2064 6973 + 4820 .global statusLockerSensorsStr + 4823 statusLockerSensorsStr: + 4824 0851 4C6F 636B .string "Locker sensors states:\r\n" + 4824 6572 2073 + 4824 656E 736F + 4824 7273 2073 + 4824 7461 7465 + 4825 .global statusNoRs485Dev + 4828 statusNoRs485Dev: + 4829 086a 2020 4361 .string " Can't find any device\r\n" + 4829 6E27 7420 + 4829 6669 6E64 + 4829 2061 6E79 + 4829 2064 6576 + 4830 .global statusRs485listStr + 4833 statusRs485listStr: + 4834 0884 4465 7465 .string "Detected RS 485 devices:\r\n" + 4834 6374 6564 + 4834 2052 5320 + 4834 3438 3520 + 4834 6465 7669 + 4835 .global statusIpGwStr + 4838 statusIpGwStr: + 4839 089f 2020 6761 .string " gateway : " + 4839 7465 7761 + 4839 7920 2020 + 4839 2020 2020 + 4839 2020 3A20 + 4840 .global statusIpMaskStr + 4843 statusIpMaskStr: + 4844 08b4 2020 6D61 .string " mask : " + 4844 736B 2020 + 4844 2020 2020 + 4844 2020 2020 + 4844 2020 3A20 + 4845 .global statusIpStr + 4848 statusIpStr: + 4849 08c9 2020 4950 .string " IP address : " + 4849 2061 6464 + 4849 7265 7373 + 4849 2020 2020 + 4849 2020 3A20 + 4850 .global statusMacStr + 4853 statusMacStr: + 4854 08de 2020 4D61 .string " Mac address : " + 4854 6320 6164 + 4854 6472 6573 + 4854 7320 2020 + 4854 2020 3A20 + 4855 .global systemRamConfigStr + 4858 systemRamConfigStr: + 4859 08f3 5379 7374 .string "System settings:\r\n" + 4859 656D 2073 + 4859 6574 7469 + 4859 6E67 733A + 4859 0D0A 00 + 4860 .global statusVoltageStr + 4863 statusVoltageStr: + 4864 0906 2020 566F .string " Voltage : %d V\r\n" + 4864 6C74 6167 + 4864 6520 2020 + 4864 2020 2020 + 4864 2020 3A20 + 4865 .global statusTemperatureStr + 4868 statusTemperatureStr: + 4869 0921 2020 5465 .string " Temperature : %d C\r\n" + 4869 6D70 6572 + 4869 6174 7572 + 4869 6520 2020 + 4869 2020 3A20 + 4870 .global statusRamDiskStateStr + 4873 statusRamDiskStateStr: + 4874 093c 2020 5261 .string " Ram disc space : %d free of %d clusters\r\n" + 4874 6D20 6469 + 4874 7363 2073 + 4874 7061 6365 + 4874 2020 3A20 + 4875 .global statusDynamicHeapStateStr + 4878 statusDynamicHeapStateStr: + 4879 0969 2020 4D61 .string " Malloc heap : %d free of %d bytes\r\n" + 4879 6C6C 6F63 + 4879 2068 6561 + 4879 7020 2020 + 4879 2020 3A20 + 4880 .global statusStaticHeapStateStr + 4883 statusStaticHeapStateStr: + 4884 0993 2020 4672 .string " FreeRtos heap : %d free of %d bytes\r\n" + 4884 6565 5274 + 4884 6F73 2068 + 4884 6561 7020 + 4884 2020 3A20 + 4885 .global statusNumberOfTasksStr + 4888 statusNumberOfTasksStr: + 4889 09bd 2020 4E75 .string " Number of tasks : %d\r\n" + 4889 6D62 6572 + 4889 206F 6620 + 4889 7461 736B + 4889 7320 3A20 + 4890 .global systemStateStr + 4893 systemStateStr: + 4894 09d6 5379 7374 .string "System state:\r\n" + 4894 656D 2073 + 4894 7461 7465 + 4894 3A0D 0A00 + 4895 .global errorOpenFile + 4898 errorOpenFile: + 4899 09e6 4361 6E27 .string "Can't open file %s\r\n" + 4899 7420 6F70 + 4899 656E 2066 + 4899 696C 6520 + 4899 2573 0D0A + 4900 .global errorBootloaderNotResponding + 4903 errorBootloaderNotResponding: + 4904 09fb 426F 6F74 .string "Bootloader is not responding\r\n" + 4904 6C6F 6164 + 4904 6572 2069 + 4904 7320 6E6F + 4904 7420 7265 + 4905 .global errorNoRemoteDevice + 4908 errorNoRemoteDevice: + 4909 0a1a 4465 7669 .string "Device %d is not responding (%d)\r\n" + 4909 6365 2025 + 4909 6420 6973 + 4909 206E 6F74 + 4909 2072 6573 + 4910 .global errorxModemUnknownResponse + 4913 errorxModemUnknownResponse: + 4914 0a3d 784D 6F64 .string "xModem unknown response 0x%x\r\n" + 4914 656D 2075 + 4914 6E6B 6E6F + 4914 776E 2072 + 4914 6573 706F + 4915 .global errorxModemRemoteSideCan + 4918 errorxModemRemoteSideCan: + 4919 0a5c 5265 6D6F .string "Remote side cancelled at frame no %d\r\n" + 4919 7465 2073 + 4919 6964 6520 + 4919 6361 6E63 + 4919 656C 6C65 + 4920 .global errorxModemFrameCrc + 4923 errorxModemFrameCrc: + 4924 0a83 784D 6F64 .string "xModem CRC error\r\n" + 4924 656D 2043 + 4924 5243 2065 + 4924 7272 6F72 + 4924 0D0A 00 + 4925 .global errorxModemFrameFrameNoCorrectionNotMatch + 4928 errorxModemFrameFrameNoCorrectionNotMatch: + 4929 0a96 0D0A 00 .string "\r\n" + 4930 .global errorxModemWrongFrameNo + 4933 errorxModemWrongFrameNo: + 4934 0a99 0D0A 00 .string "\r\n" + 4935 .global errorxModemByteSendTimeout + 4938 errorxModemByteSendTimeout: + 4939 0a9c 0D0A 00 .string "\r\n" + 4940 .global errorxModemFrameStartTimeout + 4943 errorxModemFrameStartTimeout: + 4944 0a9f 0D0A 00 .string "\r\n" + 4945 .global errorNoFile + 4948 errorNoFile: + 4949 0aa2 4E6F 2046 .string "No File\r\n" + 4949 696C 650D + 4949 0A00 + 4950 .global errorOK + 4953 errorOK: + 4954 0aac 416C 6C20 .string "All OK\r\n" + 4954 4F4B 0D0A + 4954 00 + 4955 .comm czasRtc,7,1 + 4956 .comm sockets,2,1 + 4957 .comm tcpDebugLevel,1,1 + 4958 .comm tcpDebugStream,2,1 + 4959 .comm IpMyConfig,15,1 + 4960 .comm udpDbgLevel,1,1 + 4961 .comm udpDbgStream,2,1 + 4962 .comm udpSocket,2,1 + 4963 .comm icmpDebugLevel,1,1 + 4964 .comm icmpDebug,2,1 + 4965 .comm arpDebugLevel,1,1 + 4966 .comm arpDebug,2,1 + 4967 .comm nicState,14,1 + 4968 .comm xSemaphoreRs485,2,1 + 4969 .comm lockSensors,2,1 + 4970 .comm portB,1,1 + 4971 .comm portA,1,1 + 4972 .comm xSemaphoreSpiSS,2,1 + 4973 .comm rollers,2,1 + 4974 .comm wwwport,1,1 + 4975 .comm klastry,128,1 + 5107 .weak nicSetMacAddress + 5108 .weak nicRegDump + 5109 .text + 5111 .Letext0: + 5112 .ident "GCC: (GNU) 4.9.2" + 5113 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 vty.c + /tmp/cc7Bb8kr.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/cc7Bb8kr.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/cc7Bb8kr.s:4 *ABS*:000000000000003f __SREG__ + /tmp/cc7Bb8kr.s:5 *ABS*:000000000000003b __RAMPZ__ + /tmp/cc7Bb8kr.s:6 *ABS*:0000000000000000 __tmp_reg__ + /tmp/cc7Bb8kr.s:7 *ABS*:0000000000000001 __zero_reg__ + /tmp/cc7Bb8kr.s:275 .text:0000000000000000 enableFunction + /tmp/cc7Bb8kr.s:4300 .progmem.data:0000000000000110 cmdListEnable + /tmp/cc7Bb8kr.s:320 .text:0000000000000020 disableFunction + /tmp/cc7Bb8kr.s:4385 .progmem.data:00000000000001b2 cmdListNormal + /tmp/cc7Bb8kr.s:357 .text:0000000000000038 configureModeFunction + /tmp/cc7Bb8kr.s:4257 .progmem.data:00000000000000c2 cmdListConfigure + /tmp/cc7Bb8kr.s:402 .text:0000000000000058 pingFunction + /tmp/cc7Bb8kr.s:437 .text:000000000000006c readRamFIleFunction + *COM*:0000000000000006 fdVty + /tmp/cc7Bb8kr.s:4898 .progmem.data:00000000000009e6 errorOpenFile + /tmp/cc7Bb8kr.s:4808 .progmem.data:00000000000007fb readRamFIleLenStr + /tmp/cc7Bb8kr.s:4437 .progmem.data:000000000000022a nlStr + /tmp/cc7Bb8kr.s:603 .text:0000000000000164 writeRamFileFunction + /tmp/cc7Bb8kr.s:630 .text:0000000000000174 pokazCzasFunction + *COM*:0000000000000007 czasRtc + /tmp/cc7Bb8kr.s:4252 .progmem.data:00000000000000a9 __c.3649 + /tmp/cc7Bb8kr.s:745 .text:0000000000000210 helpFunction + /tmp/cc7Bb8kr.s:769 .text:000000000000021a czytajAC_Function + /tmp/cc7Bb8kr.s:4248 .progmem.data:0000000000000086 __c.3718 + /tmp/cc7Bb8kr.s:838 .text:0000000000000274 setTimeFunction + /tmp/cc7Bb8kr.s:989 .text:0000000000000348 ustawPortExtBFunction + /tmp/cc7Bb8kr.s:1029 .text:000000000000036c ustawPortExtAFunction + /tmp/cc7Bb8kr.s:1069 .text:0000000000000390 curtainDownFunction + /tmp/cc7Bb8kr.s:4793 .progmem.data:0000000000000778 movingCurtainDownStr + /tmp/cc7Bb8kr.s:4788 .progmem.data:0000000000000768 movingCurtainPosStr + /tmp/cc7Bb8kr.s:1200 .text:0000000000000442 statusEncFunction + /tmp/cc7Bb8kr.s:1227 .text:0000000000000452 saveConfigFunction + /tmp/cc7Bb8kr.s:1251 .text:000000000000045c goXmodemWyslijFunction + /tmp/cc7Bb8kr.s:4803 .progmem.data:00000000000007de xwyslijStartStr + /tmp/cc7Bb8kr.s:1336 .text:00000000000004ce zapiszModWykFunction + /tmp/cc7Bb8kr.s:1382 .text:00000000000004f0 ustawModWykFunction + /tmp/cc7Bb8kr.s:1443 .text:000000000000052a ustawPortRezystor + /tmp/cc7Bb8kr.s:1489 .text:000000000000054c curtainUpFunction + /tmp/cc7Bb8kr.s:4798 .progmem.data:00000000000007ab movingCurtainUpStr + /tmp/cc7Bb8kr.s:1656 .text:0000000000000618 editRamFileFunction + /tmp/cc7Bb8kr.s:4813 .progmem.data:000000000000080d editRamFileIntroStr + /tmp/cc7Bb8kr.s:1797 .text:00000000000006e2 goXmodemOdbierzFunction + /tmp/cc7Bb8kr.s:4244 .progmem.data:0000000000000066 __c.3768 + /tmp/cc7Bb8kr.s:2422 .text:0000000000000a48 debugFunction + /tmp/cc7Bb8kr.s:4240 .progmem.data:0000000000000062 __c.3656 + /tmp/cc7Bb8kr.s:4236 .progmem.data:000000000000005f __c.3658 + /tmp/cc7Bb8kr.s:4232 .progmem.data:000000000000005a __c.3660 + /tmp/cc7Bb8kr.s:4228 .progmem.data:0000000000000056 __c.3662 + /tmp/cc7Bb8kr.s:4778 .progmem.data:0000000000000741 debugDisabledInfoStr + /tmp/cc7Bb8kr.s:4224 .progmem.data:0000000000000052 __c.3664 + /tmp/cc7Bb8kr.s:4220 .progmem.data:000000000000004e __c.3666 + /tmp/cc7Bb8kr.s:4216 .progmem.data:000000000000004b __c.3668 + /tmp/cc7Bb8kr.s:4212 .progmem.data:0000000000000046 __c.3670 + /tmp/cc7Bb8kr.s:4208 .progmem.data:0000000000000042 __c.3672 + /tmp/cc7Bb8kr.s:4204 .progmem.data:000000000000003e __c.3674 + /tmp/cc7Bb8kr.s:4783 .progmem.data:0000000000000755 debugEnabledInfoStr + /tmp/cc7Bb8kr.s:2706 .text:0000000000000bee setMacAddrFunction + *COM*:000000000000000e nicState + /tmp/cc7Bb8kr.s:2791 .text:0000000000000c5c setUdpFunction + *COM*:0000000000000002 udpSocket + /tmp/cc7Bb8kr.s:2960 .text:0000000000000d42 setIpGwFunction + /tmp/cc7Bb8kr.s:3081 .text:0000000000000de0 setIpMaskFunction + /tmp/cc7Bb8kr.s:3144 .text:0000000000000e20 setIpFunction + /tmp/cc7Bb8kr.s:3267 .text:0000000000000ebe VtyInit + /tmp/cc7Bb8kr.s:3305 .text:0000000000000ee0 printErrorInfo + /tmp/cc7Bb8kr.s:4416 .progmem.data:00000000000001e8 errorStrings + /tmp/cc7Bb8kr.s:3387 .text:0000000000000f36 rpingFunction + /tmp/cc7Bb8kr.s:3479 .text:0000000000000f94 eraseRamFileFunction + /tmp/cc7Bb8kr.s:3527 .text:0000000000000fc0 dodajRamPlikFunction + /tmp/cc7Bb8kr.s:3595 .text:0000000000000ffa flashExModuleFunction + /tmp/cc7Bb8kr.s:3741 .text:00000000000010aa printStatus + /tmp/cc7Bb8kr.s:4200 .progmem.data:000000000000000c __c.3625 + /tmp/cc7Bb8kr.s:4893 .progmem.data:00000000000009d6 systemStateStr + /tmp/cc7Bb8kr.s:4888 .progmem.data:00000000000009bd statusNumberOfTasksStr + /tmp/cc7Bb8kr.s:4883 .progmem.data:0000000000000993 statusStaticHeapStateStr + /tmp/cc7Bb8kr.s:4878 .progmem.data:0000000000000969 statusDynamicHeapStateStr + /tmp/cc7Bb8kr.s:4868 .progmem.data:0000000000000921 statusTemperatureStr + /tmp/cc7Bb8kr.s:4863 .progmem.data:0000000000000906 statusVoltageStr + /tmp/cc7Bb8kr.s:4873 .progmem.data:000000000000093c statusRamDiskStateStr + /tmp/cc7Bb8kr.s:4858 .progmem.data:00000000000008f3 systemRamConfigStr + /tmp/cc7Bb8kr.s:4853 .progmem.data:00000000000008de statusMacStr + /tmp/cc7Bb8kr.s:4196 .progmem.data:0000000000000009 __c.3628 + /tmp/cc7Bb8kr.s:4848 .progmem.data:00000000000008c9 statusIpStr + /tmp/cc7Bb8kr.s:4192 .progmem.data:0000000000000006 __c.3630 + /tmp/cc7Bb8kr.s:4843 .progmem.data:00000000000008b4 statusIpMaskStr + /tmp/cc7Bb8kr.s:4188 .progmem.data:0000000000000003 __c.3632 + /tmp/cc7Bb8kr.s:4838 .progmem.data:000000000000089f statusIpGwStr + /tmp/cc7Bb8kr.s:4184 .progmem.data:0000000000000000 __c.3634 + /tmp/cc7Bb8kr.s:4833 .progmem.data:0000000000000884 statusRs485listStr + /tmp/cc7Bb8kr.s:4823 .progmem.data:0000000000000851 statusLockerSensorsStr + /tmp/cc7Bb8kr.s:4818 .progmem.data:0000000000000835 statusLockerSensorsDisStr + /tmp/cc7Bb8kr.s:4064 .text:00000000000012da statusFunction + /tmp/cc7Bb8kr.s:4773 .progmem.data:000000000000073c cmd_help + /tmp/cc7Bb8kr.s:4768 .progmem.data:000000000000072a cmd_help_help + /tmp/cc7Bb8kr.s:4763 .progmem.data:0000000000000723 cmd_status + /tmp/cc7Bb8kr.s:4758 .progmem.data:00000000000006ec cmd_help_status + /tmp/cc7Bb8kr.s:4743 .progmem.data:00000000000006c5 cmd_time + /tmp/cc7Bb8kr.s:4738 .progmem.data:00000000000006ba cmd_help_time + /tmp/cc7Bb8kr.s:4583 .progmem.data:0000000000000421 cmd_settime + /tmp/cc7Bb8kr.s:4578 .progmem.data:00000000000003ff cmd_help_settime + /tmp/cc7Bb8kr.s:4533 .progmem.data:000000000000039e cmd_conf_ip + /tmp/cc7Bb8kr.s:4528 .progmem.data:000000000000037b cmd_help_conf_ip + /tmp/cc7Bb8kr.s:4513 .progmem.data:0000000000000324 cmd_conf_ip_mask + /tmp/cc7Bb8kr.s:4508 .progmem.data:0000000000000314 cmd_conf_ip_mask_help + /tmp/cc7Bb8kr.s:4503 .progmem.data:0000000000000311 cmd_conf_ip_gw + /tmp/cc7Bb8kr.s:4498 .progmem.data:00000000000002e9 cmd_conf_ip_gw_help + /tmp/cc7Bb8kr.s:4523 .progmem.data:0000000000000377 cmd_conf_udp + /tmp/cc7Bb8kr.s:4518 .progmem.data:0000000000000329 cmd_help_conf_udp + /tmp/cc7Bb8kr.s:4493 .progmem.data:00000000000002e5 cmd_conf_mac + /tmp/cc7Bb8kr.s:4488 .progmem.data:00000000000002b7 cmd_help_conf_mac + /tmp/cc7Bb8kr.s:4483 .progmem.data:00000000000002b2 cmd_conf_save + /tmp/cc7Bb8kr.s:4478 .progmem.data:000000000000029f cmd_help_conf_save + /tmp/cc7Bb8kr.s:4563 .progmem.data:00000000000003d5 cmd_enable + /tmp/cc7Bb8kr.s:4558 .progmem.data:00000000000003c9 cmd_help_enable + /tmp/cc7Bb8kr.s:4553 .progmem.data:00000000000003c1 cmd_disable + /tmp/cc7Bb8kr.s:4548 .progmem.data:00000000000003b7 cmd_help_disable + /tmp/cc7Bb8kr.s:4753 .progmem.data:00000000000006e4 cmd_enc_stat + /tmp/cc7Bb8kr.s:4748 .progmem.data:00000000000006ca cmd_help_enc_stat + /tmp/cc7Bb8kr.s:4733 .progmem.data:00000000000006b4 cmd_net_dbg + /tmp/cc7Bb8kr.s:4728 .progmem.data:000000000000066b cmd_help_net_dbg + /tmp/cc7Bb8kr.s:4723 .progmem.data:0000000000000665 cmd_rping + /tmp/cc7Bb8kr.s:4718 .progmem.data:000000000000063f cmd_help_rping + /tmp/cc7Bb8kr.s:4713 .progmem.data:000000000000063a cmd_ping + /tmp/cc7Bb8kr.s:4708 .progmem.data:0000000000000609 cmd_help_ping + /tmp/cc7Bb8kr.s:4703 .progmem.data:0000000000000604 cmd_xRec + /tmp/cc7Bb8kr.s:4698 .progmem.data:00000000000005de cmd_help_xRec + /tmp/cc7Bb8kr.s:4693 .progmem.data:00000000000005d8 cmd_xSend + /tmp/cc7Bb8kr.s:4688 .progmem.data:00000000000005b5 cmd_help_xSend + /tmp/cc7Bb8kr.s:4683 .progmem.data:00000000000005ae cmd_xflash + /tmp/cc7Bb8kr.s:4678 .progmem.data:0000000000000576 cmd_help_xflash + /tmp/cc7Bb8kr.s:4673 .progmem.data:0000000000000570 cmd_dir_rf + /tmp/cc7Bb8kr.s:4668 .progmem.data:000000000000055c cmd_help_dir_rf + /tmp/cc7Bb8kr.s:4663 .progmem.data:0000000000000558 cmd_create_rf + /tmp/cc7Bb8kr.s:4658 .progmem.data:000000000000053c cmd_help_create_rf + /tmp/cc7Bb8kr.s:4653 .progmem.data:0000000000000534 cmd_erase_rf + /tmp/cc7Bb8kr.s:4648 .progmem.data:000000000000050f cmd_help_erase_rf + /tmp/cc7Bb8kr.s:4643 .progmem.data:0000000000000508 cmd_edit_rf + /tmp/cc7Bb8kr.s:4638 .progmem.data:00000000000004de cmd_help_edit_rf + /tmp/cc7Bb8kr.s:4633 .progmem.data:00000000000004d7 cmd_read_rf + /tmp/cc7Bb8kr.s:4628 .progmem.data:00000000000004ad cmd_help_read_rf + /tmp/cc7Bb8kr.s:4623 .progmem.data:00000000000004aa cmd_up + /tmp/cc7Bb8kr.s:4618 .progmem.data:0000000000000484 cmd_help_up + /tmp/cc7Bb8kr.s:4613 .progmem.data:000000000000047f cmd_down + /tmp/cc7Bb8kr.s:4608 .progmem.data:0000000000000457 cmd_help_down + /tmp/cc7Bb8kr.s:4603 .progmem.data:0000000000000453 cmd_spa + /tmp/cc7Bb8kr.s:4598 .progmem.data:0000000000000440 cmd_help_spa + /tmp/cc7Bb8kr.s:4593 .progmem.data:000000000000043c cmd_spb + /tmp/cc7Bb8kr.s:4588 .progmem.data:0000000000000429 cmd_help_spb + /tmp/cc7Bb8kr.s:4473 .progmem.data:000000000000029a cmd_ustawR + /tmp/cc7Bb8kr.s:4468 .progmem.data:000000000000027d cmd_help_ustawR + /tmp/cc7Bb8kr.s:4573 .progmem.data:00000000000003fc cmd_ac + /tmp/cc7Bb8kr.s:4568 .progmem.data:00000000000003dc cmd_help_ac + /tmp/cc7Bb8kr.s:4543 .progmem.data:00000000000003b0 cmd_configure + /tmp/cc7Bb8kr.s:4538 .progmem.data:00000000000003a1 cmd_help_configure + /tmp/cc7Bb8kr.s:4463 .progmem.data:0000000000000278 cmd_ustawMW + /tmp/cc7Bb8kr.s:4458 .progmem.data:000000000000025b cmd_help_ustawMW + /tmp/cc7Bb8kr.s:4453 .progmem.data:0000000000000255 cmd_zapiszMW + /tmp/cc7Bb8kr.s:4448 .progmem.data:0000000000000232 cmd_help_zapiszMW + /tmp/cc7Bb8kr.s:4953 .progmem.data:0000000000000aac errorOK + /tmp/cc7Bb8kr.s:4948 .progmem.data:0000000000000aa2 errorNoFile + /tmp/cc7Bb8kr.s:4943 .progmem.data:0000000000000a9f errorxModemFrameStartTimeout + /tmp/cc7Bb8kr.s:4938 .progmem.data:0000000000000a9c errorxModemByteSendTimeout + /tmp/cc7Bb8kr.s:4933 .progmem.data:0000000000000a99 errorxModemWrongFrameNo + /tmp/cc7Bb8kr.s:4928 .progmem.data:0000000000000a96 errorxModemFrameFrameNoCorrectionNotMatch + /tmp/cc7Bb8kr.s:4923 .progmem.data:0000000000000a83 errorxModemFrameCrc + /tmp/cc7Bb8kr.s:4918 .progmem.data:0000000000000a5c errorxModemRemoteSideCan + /tmp/cc7Bb8kr.s:4913 .progmem.data:0000000000000a3d errorxModemUnknownResponse + /tmp/cc7Bb8kr.s:4908 .progmem.data:0000000000000a1a errorNoRemoteDevice + /tmp/cc7Bb8kr.s:4903 .progmem.data:00000000000009fb errorBootloaderNotResponding + /tmp/cc7Bb8kr.s:4432 .progmem.data:0000000000000200 BladBuforaPozostaloBajtowStr + /tmp/cc7Bb8kr.s:4442 .progmem.data:000000000000022d okStr + /tmp/cc7Bb8kr.s:4828 .progmem.data:000000000000086a statusNoRs485Dev + *COM*:0000000000000002 sockets + *COM*:0000000000000001 tcpDebugLevel + *COM*:0000000000000002 tcpDebugStream + *COM*:000000000000000f IpMyConfig + *COM*:0000000000000001 udpDbgLevel + *COM*:0000000000000002 udpDbgStream + *COM*:0000000000000001 icmpDebugLevel + *COM*:0000000000000002 icmpDebug + *COM*:0000000000000001 arpDebugLevel + *COM*:0000000000000002 arpDebug + *COM*:0000000000000002 xSemaphoreRs485 + *COM*:0000000000000002 lockSensors + *COM*:0000000000000001 portB + *COM*:0000000000000001 portA + *COM*:0000000000000002 xSemaphoreSpiSS + *COM*:0000000000000002 rollers + *COM*:0000000000000001 wwwport + *COM*:0000000000000080 klastry + +UNDEFINED SYMBOLS +cmdlineGetArgStr +ramDyskOtworzPlik +fprintf_P +ramDyskCzytajBajtZPliku +uartVtySendByte +ramDyskZamknijPlik +ramDyskDir +readTimeDecoded +cmdPrintHelp +cmdlineGetArgInt +MCP3008_getSampleSingle +ds1305start +__udivmodqi4 +setTimeDecoded +MPC23s17SetDirB +MPC23s17SetPortB +MPC23s17SetDirA +MPC23s17SetPortA +rs485curtainDown +nicRegDump +saveConfiguration +saveSettings +cmdlineGetArgHex +sendSettings +MCP4150_setValue +rs485curtainUp +ramDyskUstawWskaznikNaKoniec +xVtyRec +xQueueGenericReceive +ramDyskZapiszBajtDoPliku +fputc +ramDyskDodajBlokXmodem +strncmp_P +setArpDebug +setIpDebug +setIcmpDebug +setTcpDebug +setUdpDebug +nicSetMacAddress +htons +ipSetConfigGw +ipSetConfigMask +ipSetConfigIp +cmdStateConfigure +rs485ping +ramDyskUsunPlik +ramDyskUtworzPlik +rs485xModemFlash +uxTaskGetNumberOfTasks +xPortGetFreeHeapSize +xmallocAvailable +temperature +voltage +ramDyskLiczbaWolnychKlastrow +netPrintEthAddr +ipGetConfig +netPrintIPAddr +printLockers +udpPrintStatus +ramDyskOtworzPlikStdIo +ramDyskZamknijPlikStdIo +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/MainController/vty_en.h b/Projects/DidacticSystem/Adam/MainController/vty_en.h new file mode 100644 index 0000000..a535e93 --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/vty_en.h @@ -0,0 +1,96 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; +const char errorNoFile[] PROGMEM = "No File\r\n"; +const char errorxModemFrameStartTimeout[] PROGMEM = "\r\n"; +const char errorxModemByteSendTimeout[] PROGMEM = "\r\n"; +const char errorxModemWrongFrameNo[] PROGMEM = "\r\n"; +const char errorxModemFrameFrameNoCorrectionNotMatch[] PROGMEM = "\r\n"; +const char errorxModemFrameCrc[] PROGMEM = "xModem CRC error\r\n"; +const char errorxModemRemoteSideCan[] PROGMEM = "Remote side cancelled at frame no %d\r\n"; +const char errorxModemUnknownResponse[] PROGMEM = "xModem unknown response 0x%x\r\n"; +const char errorNoRemoteDevice[] PROGMEM = "Device %d is not responding (%d)\r\n"; +const char errorBootloaderNotResponding[] PROGMEM = "Bootloader is not responding\r\n"; +const char errorOpenFile[] PROGMEM = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char statusRamDiskStateStr[] PROGMEM = " Ram disc space : %d free of %d clusters\r\n"; +const char statusTemperatureStr[] PROGMEM = " Temperature : %d C\r\n"; +const char statusVoltageStr[] PROGMEM = " Voltage : %d V\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; +const char statusMacStr[] PROGMEM = " Mac address : "; +const char statusIpStr[] PROGMEM = " IP address : "; +const char statusIpMaskStr[] PROGMEM = " mask : "; +const char statusIpGwStr[] PROGMEM = " gateway : "; + +const char statusRs485listStr[] PROGMEM = "Detected RS 485 devices:\r\n"; +const char statusNoRs485Dev[] PROGMEM = " Can't find any device\r\n"; + +const char statusLockerSensorsStr[] PROGMEM = "Locker sensors states:\r\n"; +const char statusLockerSensorsDisStr[] PROGMEM = " Locker sensors disabled\r\n"; + +const char editRamFileIntroStr[] PROGMEM = "Writing to file. Press CTRL+C to quit\r\n"; +const char readRamFIleLenStr[] PROGMEM = "File length: %d\r\n"; + +const char xwyslijStartStr[] PROGMEM = "Xmodem: Transmission start\r\n"; + +const char movingCurtainUpStr[] PROGMEM = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +const char movingCurtainDownStr[] PROGMEM = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +const char movingCurtainPosStr[] PROGMEM = "\tpozycja %d\r\n"; + +const char debugEnabledInfoStr[] PROGMEM = "Enabled %s debug\r\n"; +const char debugDisabledInfoStr[] PROGMEM = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; +const char cmd_enc_stat[] PROGMEM = "encstat"; const char cmd_help_enc_stat[] PROGMEM = "Print Enc 28j60 registers"; +const char cmd_time[] PROGMEM = "time"; const char cmd_help_time[] PROGMEM = "Print time"; +const char cmd_net_dbg[] PROGMEM = "debug"; const char cmd_help_net_dbg[] PROGMEM = "[arp|icmp|ip|tcp|udp] [level] write debug info. Level 0 disable debuging"; + +const char cmd_rping[] PROGMEM = "rping"; const char cmd_help_rping[] PROGMEM = "[Device no] Send ping to Rs485 device"; +const char cmd_ping[] PROGMEM = "ping"; const char cmd_help_ping[] PROGMEM = "[A1] [A2] [A3] [A4] Sends ping throught ethernet"; +const char cmd_xRec[] PROGMEM = "xrec"; const char cmd_help_xRec[] PROGMEM = "[file name] receive file using xModem"; +const char cmd_xSend[] PROGMEM = "xsend"; const char cmd_help_xSend[] PROGMEM = "[file name] send file using xModem"; +const char cmd_xflash[] PROGMEM = "xflash"; const char cmd_help_xflash[] PROGMEM = "[device no] [file name] flash device connected to Rs485"; +#ifdef testZewPamiec +const char cmd_rtest[] PROGMEM = "rtest"; const char cmd_help_rtest[] PROGMEM = "External ram test"; +#endif +const char cmd_dir_rf[] PROGMEM = "dirrf"; const char cmd_help_dir_rf[] PROGMEM = "Print ramdisk files"; +const char cmd_create_rf[] PROGMEM = "crf"; const char cmd_help_create_rf[] PROGMEM = "[file name] create ram file"; +const char cmd_erase_rf[] PROGMEM = "eraserf"; const char cmd_help_erase_rf[] PROGMEM = "[file name] erase file from ram disk"; +const char cmd_edit_rf[] PROGMEM = "editrf"; const char cmd_help_edit_rf[] PROGMEM = "[file name] edit file located on ram disk"; +const char cmd_read_rf[] PROGMEM = "readrf"; const char cmd_help_read_rf[] PROGMEM = "[file name] read file located on ram disk"; + +const char cmd_up[] PROGMEM = "up"; const char cmd_help_up[] PROGMEM = "[driver no] [channel] {value} move up"; +const char cmd_down[] PROGMEM = "down"; const char cmd_help_down[] PROGMEM = "[driver no] [channel] {value} move down"; +const char cmd_spa[] PROGMEM = "spa"; const char cmd_help_spa[] PROGMEM = "[value] set port A"; +const char cmd_spb[] PROGMEM = "spb"; const char cmd_help_spb[] PROGMEM = "[value] set port B"; + +const char cmd_settime[] PROGMEM = "settime"; const char cmd_help_settime[] PROGMEM = "[h] [m] [s] set time (24h format)"; +const char cmd_ac[] PROGMEM = "ac"; const char cmd_help_ac[] PROGMEM = "[channel 0-7] read analog value"; +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Enable mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "View mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configure mode"; +const char cmd_conf_ip[] PROGMEM = "ip"; const char cmd_help_conf_ip[] PROGMEM = "[A1] [A2] [A3] [A4] set IP address"; +const char cmd_conf_udp[] PROGMEM = "udp"; const char cmd_help_conf_udp[] PROGMEM = "[A1] [A2] [A3] [A4] [src port] {dst port} set udp client IP address and ports"; +const char cmd_conf_ip_mask[] PROGMEM = "mask"; const char cmd_conf_ip_mask_help[] PROGMEM = "[mask] set mask"; +const char cmd_conf_ip_gw[] PROGMEM = "gw"; const char cmd_conf_ip_gw_help[] PROGMEM = "[A1] [A2] [A3] [A4] set default gateway"; +const char cmd_conf_mac[] PROGMEM = "mac"; const char cmd_help_conf_mac[] PROGMEM = "[A1] [A2] [A3] [A4] [A5] [A6] set MAC address"; +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; +const char cmd_ustawR[] PROGMEM = "setr"; const char cmd_help_ustawR[] PROGMEM = "[value] set resistance value"; + +const char cmd_ustawMW[] PROGMEM = "rset"; const char cmd_help_ustawMW[] PROGMEM = "[A] [C] set execution module"; +const char cmd_zapiszMW[] PROGMEM = "rsave"; const char cmd_help_zapiszMW[] PROGMEM = "[A] save execution module settings"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/MainController/vty_pl.h b/Projects/DidacticSystem/Adam/MainController/vty_pl.h new file mode 100644 index 0000000..7550a2a --- /dev/null +++ b/Projects/DidacticSystem/Adam/MainController/vty_pl.h @@ -0,0 +1,92 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char statusRamDiskStateStr[] = " Ram dysk : %d wolnych z %d klastrow\r\n"; +prog_char statusTemperatureStr[] = " Temperatura : %d C\r\n"; +prog_char statusVoltageStr[] = " Napiecie : %d V\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; +prog_char statusMacStr[] = " Adres MAC : "; +prog_char statusIpStr[] = " IP adres : "; +prog_char statusIpMaskStr[] = " maska : "; +prog_char statusIpGwStr[] = " brama : "; + +prog_char statusRs485listStr[] = "Wykryte urzadzenia na magistrali RS 485:\r\n"; +prog_char statusNoRs485Dev[] = " Nie moge znale ani jednego urzadzenia\r\n"; + +prog_char statusLockerSensorsStr[] = "Stan czujników rygli:\r\n"; +prog_char statusLockerSensorsDisStr[] = " Czujniki rygli wyłączone\r\n"; + +prog_char editRamFileIntroStr[] = "Zapis do pliku. CTRL+C koniec\r\n"; +prog_char readRamFIleLenStr[] = "Dlugosc pliku: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: rozpoczynanie wysylania\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Wlaczono debugowanie %s\r\n"; +prog_char debugDisabledInfoStr[] = "Wylaczono debugowanie %s\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Wypisz rejestry Enc 28j60"; +prog_char cmd_time[] = "czas"; prog_char cmd_help_time[] = "Wypisuje czas"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[arp|icmp|ip|tcp|udp] [poziom] wypisywanie komunikatow. Poziom 0 wylacza komunikaty"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[numer sterownika] Wysyla ping do sterownika podpietego do magistrali Rs485"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Wysyla ping przez ethernet"; +prog_char cmd_xRec[] = "xodb"; prog_char cmd_help_xRec[] = "[nazwa pliku] odbiera plik za pomoca protokolu xModem"; +prog_char cmd_xSend[] = "xwyslij"; prog_char cmd_help_xSend[] = "[nazwa pliku] wysyla plik za pomoca protokolu xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[numer urzadzenia] [nazwa pliku] wgrywa firmware do urzadzenia podpietego do Rs485"; +#ifdef testZewPamiec +prog_char cmd_rtest[] = "rtest"; prog_char cmd_help_rtest[] = "Test pamieci zewnetrznej"; +#endif +prog_char cmd_dir_rf[] = "dirrp" ; prog_char cmd_help_dir_rf[] = "Wypisuje nazwy plikow zapisanych w pamieci RAM"; +prog_char cmd_create_rf[] = "utwrp"; prog_char cmd_help_create_rf[] = "[nazwa pliku] Tworzy plik w pamieci RAM"; +prog_char cmd_erase_rf[] = "kasrp"; prog_char cmd_help_erase_rf[] = "[nazwa pliku] Usuwa plik z pamieci RAM"; +prog_char cmd_edit_rf[] = "dopiszrp"; prog_char cmd_help_edit_rf[] = "[nazwa pliku] Dopisuje do pliku zapisanego w pamieci ram"; +prog_char cmd_read_rf[] = "czytrp"; prog_char cmd_help_read_rf[] = "[nazwa pliku] Wypisuje zawartosc pliku"; + +prog_char cmd_up[] = "podnies"; prog_char cmd_help_up[] = "[numer sterownika] [nr rolety] {wartosc} podnoszenie rolety"; +prog_char cmd_down[] = "opusc"; prog_char cmd_help_down[] = "[numer sterownika] [nr rolety] {wartosc} opuszczanie rolety"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[wartosc] ustaw zewnetrzny port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[wartosc] ustaw zewnetrzny port B"; + +prog_char cmd_settime[] = "ustawcz"; prog_char cmd_help_settime[] = "[h] [m] [s] ustawia czas w formacie 24h format"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[wejscie 0-7] czyta analogowa wartosc na wejsciu przetwornika"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A2] [A3] ustaw adres IP"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} ustaw adres klienta udp oraz porty"; +prog_char cmd_conf_ip_mask[]= "maska"; prog_char cmd_conf_ip_mask_help[]= "[maska] ustaw maske adresu IP"; +prog_char cmd_conf_ip_gw[] = "brama"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] ustaw domyslna brame"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] set MAC address"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] ustaw adres MAC"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/FreeRTOSConfig.h b/Projects/DidacticSystem/Adam/RemoteServer/FreeRTOSConfig.h new file mode 100644 index 0000000..8b258a0 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/FreeRTOSConfig.h @@ -0,0 +1,103 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 16000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 100 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 3200 ) ) +//2800 +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 600 +#define STACK_SIZE_ENC 500 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Adam/RemoteServer/Makefile b/Projects/DidacticSystem/Adam/RemoteServer/Makefile new file mode 100644 index 0000000..3d19af3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/Makefile @@ -0,0 +1,452 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega128 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../Lib +LIB_NET_DIR = ../../Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +vty.c \ +cli_task.c \ +spi_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/udp.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#$(LIB_DIR)/ramdysk.c \ + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../Lib/include -I../../Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +AVRDUDE_PORT = /dev/jtag +#AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +restart: + $(AVRDUDE) $(AVRDUDE_FLAGS) -n + + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program restart + diff --git a/Projects/DidacticSystem/Adam/RemoteServer/Makefile64 b/Projects/DidacticSystem/Adam/RemoteServer/Makefile64 new file mode 100644 index 0000000..e8946d3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/Makefile64 @@ -0,0 +1,454 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega64 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../freeRtos/Lib +LIB_NET_DIR = ../../freeRtos/Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../freeRtos/Lib/include -I../../freeRtos/Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git "a/Projects/DidacticSystem/Adam/RemoteServer/Opis zada\305\204" "b/Projects/DidacticSystem/Adam/RemoteServer/Opis zada\305\204" new file mode 100644 index 0000000..74a6ea8 --- /dev/null +++ "b/Projects/DidacticSystem/Adam/RemoteServer/Opis zada\305\204" @@ -0,0 +1,4 @@ +1) Modyfikacja bibliotek. Zrezygnować ze wskaźników do funkcji. Zastosować __attribute__(weak) +2) Dodać możliwość tworzenia buforów cyklicznych, których tablica pamięci umieszczona jest w zewnętrznej pamięci +3) Dodać obsługę specjalnych koment VTY (odpowiednia interpretacja nowych linii, itd) +4) Uruchomić sokety \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/RemoteServer/SerwerDostepowy.cbp b/Projects/DidacticSystem/Adam/RemoteServer/SerwerDostepowy.cbp new file mode 100644 index 0000000..fe226ba --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/SerwerDostepowy.cbp @@ -0,0 +1,179 @@ + + + + + + diff --git a/Projects/DidacticSystem/Adam/RemoteServer/cli_task.c b/Projects/DidacticSystem/Adam/RemoteServer/cli_task.c new file mode 100644 index 0000000..a894539 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/cli_task.c @@ -0,0 +1,32 @@ +#include "cli_task.h" + +void vTaskVtyRs1(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xRs1Rec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + +void vTaskVTYsocket(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + + char znak; + for( ;; ) + { + znak = 0; + znak = fgetc(state->myStdInOut); + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } +} diff --git a/Projects/DidacticSystem/Adam/RemoteServer/cli_task.h b/Projects/DidacticSystem/Adam/RemoteServer/cli_task.h new file mode 100644 index 0000000..dbc003c --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/cli_task.h @@ -0,0 +1,30 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xRs1Rec; +extern xQueueHandle xRs1Tx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVtyRs1(void *cliStatePtr); + + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod uniwersalny dla dowolnego strumienai FILE + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYsocket(void *cliStatePtr); + + +#endif /* CLI_TASK_H */ diff --git a/Projects/DidacticSystem/Adam/RemoteServer/configuration.c b/Projects/DidacticSystem/Adam/RemoteServer/configuration.c new file mode 100644 index 0000000..06e89e4 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/configuration.c @@ -0,0 +1,40 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" +#include "nic.h" + +uint32_t udpIpDst_eep __attribute__((section (".eeprom"))) = ((uint32_t)UDP_DST_IP4 << 24) + ((uint32_t)UDP_DST_IP3 <<16) + ((uint32_t)UDP_DST_IP2 <<8) + UDP_DST_IP1; +uint16_t udpPortDstEep __attribute__((section (".eeprom"))) = HTONS(UDP_DST_PORT); +uint16_t udpPortSrcEep __attribute__((section (".eeprom"))) = HTONS(UDP_SRC_PORT); + +static uint8_t NoOfSerialPortsEep __attribute__((section (".eeprom"))) = 8;//HTONS(UDP_SRC_PORT); + + +void loadConfiguration() +{ + nicLoadConfig(); + ipLoadConfig(); + udpLoadConfig(); + spiLoadConfig(); +} + +void saveConfiguration() +{ + nicSaveConfig(); + ipSaveConfig(); + udpSaveConfig(); + spiSaveConfig(); +} + +void spiLoadConfig() +{ + NoOfSerialPorts = eeprom_read_byte(&NoOfSerialPortsEep); + NoOfSpiSlaves = (NoOfSerialPorts+1)>>1; +} + +void spiSaveConfig() +{ + eeprom_update_byte(&NoOfSerialPortsEep, NoOfSerialPorts); +} diff --git a/Projects/DidacticSystem/Adam/RemoteServer/configuration.h b/Projects/DidacticSystem/Adam/RemoteServer/configuration.h new file mode 100644 index 0000000..68496b7 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/configuration.h @@ -0,0 +1,22 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "enc28j60.h" +#include "hardware.h" +#include "ip.h" +#include "nic.h" +#include "udp.h" + +uint8_t NoOfSerialPorts; +uint8_t NoOfSpiSlaves; + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + +void spiLoadConfig(void); +void spiSaveConfig(void); + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/enc_task.c b/Projects/DidacticSystem/Adam/RemoteServer/enc_task.c new file mode 100644 index 0000000..ccb0a52 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/enc_task.c @@ -0,0 +1,267 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include +#include +#include "enc_task.h" +#include "ip_arp_udp_tcp.h" +#include "enc28j60.h" +//#include "timeout.h" +//#include "avr_compat.h" +#include "net.h" +#include "main.h" +#include "hardware.h" +//#include "netstack.h" + +// the password string (only the first 5 char checked), (only a-z,0-9,_ characters): +char password[]="secret"; // must not be longer than 9 char + + +uint8_t verify_password ( char *str ) +{ + // the first characters of the received string are + // a simple password/cookie: + if ( strncmp ( password,str,5 ) ==0 ) + { + return ( 1 ); + } + return ( 0 ); +} + +int8_t analyse_get_url ( char *str ) +{ + uint8_t loop=1; + uint8_t i=0; + while ( loop ) + { + if ( password[i] ) + { + if ( *str==password[i] ) + { + str++; + i++; + } + else + { + return ( -1 ); + } + } + else + { + // end of password + loop=0; + } + } + // is is now one char after the password + if ( *str == '/' ) + { + str++; + } + else + { + return ( -3 ); + } + // check the first char, garbage after this is ignored (including a slash) + if ( *str < 0x3a && *str > 0x2f ) + { + // is a ASCII number, return it + return ( *str-0x30 ); + } + return ( -2 ); +} + +uint16_t moved_perm ( uint8_t *buf1 ) +{ + uint16_t plen; + plen=fill_tcp_data_p ( buf1, 0, PSTR ( "HTTP/1.0 301 Moved Permanently\r\nLocation: " ) ); + plen=fill_tcp_data ( buf1, plen, password ); + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "/\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n" ) ); + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "

301 Moved Permanently

\n" ) ); + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "add a trailing slash to the url\n" ) ); + return ( plen ); +} + +uint16_t print_webpage ( uint8_t *buf1,uint8_t on_off ) +{ + uint16_t plen; + plen=fill_tcp_data_p ( buf1, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n" ) ); + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "

Output is: " ) ); + if ( on_off ) + { + plen=fill_tcp_data_p ( buf1, plen, PSTR ( " ON" ) ); + } + else + { + plen=fill_tcp_data_p ( buf1, plen,PSTR ( "OFF" ) ); + } + plen=fill_tcp_data_p ( buf1, plen, PSTR ( " [refresh status]

\n

Switch off

" ) ); + } + else + { + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "/1\">Switch on

" ) ); + } + plen=fill_tcp_data_p ( buf1, plen, PSTR ( "



version 2.17, tuxgraphics.org\n" ) ); + return ( plen ); +} + +void enc28j60chipInit ( void ) +{ + vTaskDelay (5); + enc28j60Init (mymac); +// enc28j60clkout (2); // change clkout from 6.25MHz to 12.5MHz + vTaskDelay (5); + enc28j60PhyWrite (PHLCON, 0x476); + vTaskDelay (2); + init_ip_arp_udp_tcp (mymac, myip, MYWWWPORT); +} + + +void encTask ( void *pvParameters ) +{ + pvParameters = NULL; + uint16_t plen; + uint16_t dat_p; +// uint8_t i=1; + uint8_t cmd_pos=0; + int8_t cmd; + uint8_t payloadlen=0; + char str[30]; + char cmdval; + +// buf = Enc28j60_global.buf; + enc28j60chipInit(); + +// for ( ; ; ) +// { +// vTaskDelay(10); +// } + + for ( ; ; ) + { + vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebrzeniu przerwania od ENC + + // get the next new packet: + plen = enc28j60PacketReceive ( ENC28J60BUF_SIZE, Enc28j60_global.buf ); + + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + continue; +// fprintf(&state->myStdInOut, "Dat %d\r\n", plen); + + // arp is broadcast if unknown but a host may also + // verify the mac address by sending it to + // a unicast address. + if ( eth_type_is_arp_and_my_ip(Enc28j60_global.buf, plen)) + { + make_arp_answer_from_request(Enc28j60_global.buf); + continue; + } + + // check if ip packets are for us: + if ( eth_type_is_ip_and_my_ip ( Enc28j60_global.buf,plen ) ==0 ) + continue; + + + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_ICMP_V && Enc28j60_global.buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V ) + { + // a ping packet, let's send pong + make_echo_reply_from_request (Enc28j60_global.buf, plen); + continue; + } + + // tcp port www start, compare only the lower byte + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP_V && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_L_P]==MYWWWPORT ) + { + if ( Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V ) + { + make_tcp_synack_from_syn (Enc28j60_global.buf ); + // make_tcp_synack_from_syn does already send the syn,ack + continue; + } + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) + { + init_len_info (Enc28j60_global.buf ); // init some data structures + // we can possibly have no data, just ack: + dat_p=get_tcp_data_pointer(); + if ( dat_p==0 ) + { + if (Enc28j60_global.buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V ) + { + // finack, answer with ack + make_tcp_ack_from_any (Enc28j60_global.buf ); + } + // just an ack with no data, wait for next packet + continue; + } + if ( strncmp ( "GET ", ( char * ) & (Enc28j60_global.buf[dat_p] ),4 ) !=0 ) + { + // head, post and other methods: + // + // for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=fill_tcp_data_p (Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

" ) ); + goto SENDTCP; + } + if ( strncmp ( "/ ", ( char * ) & (Enc28j60_global.buf[dat_p+4] ),2 ) ==0 ) + { + plen=fill_tcp_data_p(Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ) ); + plen=fill_tcp_data_p(Enc28j60_global.buf, plen, PSTR ( "

Usage: http://host_or_ip/password

\n" ) ); + goto SENDTCP; + } + cmd=analyse_get_url ( ( char * ) & (Enc28j60_global.buf[dat_p+5] ) ); + // for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + if ( cmd==-1 ) + { + plen=fill_tcp_data_p (Enc28j60_global.buf, 0, PSTR ( "HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n

401 Unauthorized

")); + goto SENDTCP; + } +// if ( cmd==1 ) +// { +// PORTD|= ( 1< +#include +#include +#include +#include "ip_arp_udp_tcp.h" +#include "enc28j60.h" +#include "avr_compat.h" +//#include "net.h" +#include "hardwareConfig.h" + +#define MYWWWPORT 80 +#define MYTELNETPORT 23 +#define MYUDPPORT 1200 + +uint8_t mymac[6]; +uint8_t myip[4]; +uint8_t mask; + +uint8_t verify_password(char *str); + +//! takes a string of the form password/commandNumber and analyse it +//! return values: -1 invalid password, otherwise command number +//! -2 no command given but password valid +//! -3 valid password, no command and no trailing "/" +int8_t analyse_get_url(char *str); + +//! answer HTTP/1.0 301 Moved Permanently\r\nLocation: password/\r\n\r\n +//! to redirect to the url ending in a slash +uint16_t moved_perm(uint8_t *buf); + +//! prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf,uint8_t on_off); + +//! Enc28j60 task +void encTask(void *pvParameters); + +//! initialize enc28j60 +void enc28j60chipInit(void); + +extern struct Enc28j60_config Enc28j60_global; +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/firmware.efuse b/Projects/DidacticSystem/Adam/RemoteServer/firmware.efuse new file mode 100644 index 0000000..4a40b3f --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/firmware.efuse @@ -0,0 +1,2 @@ +:01000000FF00 +:00000001FF diff --git a/Projects/DidacticSystem/Adam/RemoteServer/firmware.hfuse b/Projects/DidacticSystem/Adam/RemoteServer/firmware.hfuse new file mode 100644 index 0000000..623ec90 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/firmware.hfuse @@ -0,0 +1,2 @@ +:010000009966 +:00000001FF diff --git a/Projects/DidacticSystem/Adam/RemoteServer/firmware.lfuse b/Projects/DidacticSystem/Adam/RemoteServer/firmware.lfuse new file mode 100644 index 0000000..ae09436 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/firmware.lfuse @@ -0,0 +1,2 @@ +:01000000E41B +:00000001FF diff --git a/Projects/DidacticSystem/Adam/RemoteServer/hardware.c b/Projects/DidacticSystem/Adam/RemoteServer/hardware.c new file mode 100644 index 0000000..76173b9 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/hardware.c @@ -0,0 +1,240 @@ +#include "hardware.h" + +#if LANG_EN +#include "hardware_en.h" +#endif + +#if LANG_PL +#include "hardware_pl.h" +#endif + +xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję do czasu zakończenia wysyłania poprzedniego bajtu + +void hardwareInit(void) +{ + //DDRA = 0x00; //External Memory + portENTER_CRITICAL(); + xSpiRx = xQueueCreate(1, 1); + portEXIT_CRITICAL(); + + DDRB = 0xF7; + PORTB = 0xF1; + /* + 0 - Sl_RST + 1 - SCK + 2 - MOSI + 3 - MISO + 4 - External SPI ASR 4 + 5 - External SPI ASR 5 + 6 - External SPI ASR 6 + 7 - External SPI ASR 7 + */ + + //DDRC = 0x00; //External Memory + + DDRD = 0xF0; + /* + 0 - SCL + 1 - SDA + 2 - RxD USB + 3 - TxD USB + 4 - External SPI ASR 0 + 5 - External SPI ASR 1 + 6 - External SPI ASR 2 + 7 - External SPI ASR 3 + */ + + DDRE = 0x0E; + PORTE = 0x0C; + /* + 0 - RxD Rs485 + 1 - TxD Rs485 + 2 - ENC RST + 3 - ENC CS + 4 - INT 4 + 5 - INT 5 + 6 - INT 6 + 7 - INT Enc28j60 + */ + DDRF = 0x00; //JTAG and A/C + DDRG = 0x1F; + /* + 0 - WR + 1 - RD + 2 - ALE + 3 - SD CS + 4 - RS485 TxEn + 5 - + 6 - + 7 - + */ +} + +uint8_t spiSend(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendENC(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendSpinBlock(uint8_t data) +{ + SPDR = data; + SPCR &= ~(1< +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "spi.h" + +#define ENC_RST_ON PORTE &= ~0x04; +#define ENC_RST_OFF PORTE |= 0x04; + + +/** + * Hardware initialize + */ +void hardwareInit(void); + + +// ************************ Obsługa Rs485 ****************************** +void rs485Send(uint8_t c); +uint8_t rs485Receive(uint8_t *c, uint8_t timeout); + +// ************************ Obsługa SPI ******************************** +uint8_t spiSend(uint8_t data); +uint8_t spiSendENC(uint8_t data); +uint8_t spiSendSpinBlock(uint8_t data); +uint8_t spiSendENCSpinBlock(uint8_t data); + +void disableAllSpiDevices(void); + +void spiEnableEnc28j60(void); +void spiDisableEnc28j60(void); + +void spiEnableDev(uint8_t devNo); +void spiDisableDev(uint8_t devNo); + +#endif + diff --git a/Projects/DidacticSystem/Adam/RemoteServer/hardwareConfig.h b/Projects/DidacticSystem/Adam/RemoteServer/hardwareConfig.h new file mode 100644 index 0000000..d8f1e89 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/hardwareConfig.h @@ -0,0 +1,178 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +// --------------------- Configuration I/O module -------------------------------- + +//Locker 1 (723 / 687) broken +#define LOCK_SENS_1_LIGHT 0x40 +#define LOCK_SENS_1_AC_IN 4 +#define LOCK_SENS_1_THR 700 +#define LOCK_SENS_1_ENA 0 + +//Locker 2 (603 / 993) OK +#define LOCK_SENS_2_LIGHT 0x20 +#define LOCK_SENS_2_AC_IN 5 +#define LOCK_SENS_2_THR 750 +#define LOCK_SENS_2_ENA 1 + +//Locker 3 (934/937) broken +#define LOCK_SENS_3_LIGHT 0x10 +#define LOCK_SENS_3_AC_IN 6 +#define LOCK_SENS_3_THR 700 +#define LOCK_SENS_3_ENA 0 + +//Locker 4 (831 / 980) OK +#define LOCK_SENS_4_LIGHT 0x08 +#define LOCK_SENS_4_AC_IN 7 +#define LOCK_SENS_4_THR 900 +#define LOCK_SENS_4_ENA 1 + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + +#define HEAP_BEGIN 0x1100 +#define HEAP_END CLI_1_BUF_ADDR - 1 +#define HEAP_SIZE HEAP_END - HEAP_BEGIN + 1 + +#define CLI_BUF_TOT_LEN 0x0100 +#define CLI_1_BUF_ADDR 0x2800 +#define CLI_2_BUF_ADDR 0x2900 +#define CLI_3_BUF_ADDR 0x2A00 +#define CLI_4_BUF_ADDR 0x2B00 + +#define RTOS_TCP_BUF_BASE_ADDR 0x2C00 + +#define SPI_TX_BUFFER 0x7000 +#define SPI_RX_BUFFER 0x7400 + +#define RTOS_UDP_TX_BUF_ADDR 0x7800 +#define RTOS_UDP_RX_BUF_ADDR 0x7900 + +#define SPI2SERIAl_TX_BUFFERS 0x8000 +#define NO_OF_SPI2SERIAL_TX_BUF 16 +#define OF_SPI2SERIAL_TX_BUF_SIZE 256 +#define SPI2SERIAl_RX_BUFFERS 0x9000 +#define NO_OF_SPI2SERIAL_RX_BUF 16 +#define OF_SPI2SERIAL_RX_BUF_SIZE 256 + +#define NETWORK_STACK_BUF_SIZE 0x0600 // 1532 bytes +#define NETWORK_STACK_BUF_ADDR 0x7A00 // 30 1/4 - 32 kB +#define ENC28J60BUF_ADDR_END ENC28J60BUF_ADDR + ENC28J60BUF_SIZE - 1 + +/* Memory Map + 0x0000 +-----------------------------+ + 256 | Controll registers | + 0x0100 +-----------------------------+ + 4k | Internal memory | + 0x1100 +-----------------------------+ 4 K + 5k768 | Heap | + 0x2800 +-----------------------------+ 11 k 768 + 256 * CLI 1 buffer + + 0x2900 +-----------------------------+ + 256 * CLI 2 buffer + + 0x2A00 +-----------------------------+ + + + 0x7000 +-----------------------------+ 28 k + 1k | SPI Tx Buffer | + 0x7400 +-----------------------------+ 29 k + 1k | SPI Rx Buffer | + 0x7800 +-----------------------------+ 30 k + 256 | RTOS UDP Tx buffer | + 0x7900 +-----------------------------+ + 256 | RTOS UDP Rx buffer | + 0x7A00 +-----------------------------+ + 1k512 | Enc28j60Buffer | + 0x8000 +-----------------------------+ 32 k + 4k | Spi2SerialTx | + 0x9000 +-----------------------------+ 36 k + 4k | Spi2SerialRx | + 0xA000 +-----------------------------+ 40 k + +*/ + + +//Konfiguracja biblioteki ds1305.h +#define USE_DECODED_TIME_STRUCT 1 + +//Konfiguracja Sterownika ethenretowego Enc28j60 +//CS jest na PORT E.3 +#define ENC_SPI_CS_PORT PORTE +#define ENC_SPI_CS_EN_MASK_OR 0x00 +#define ENC_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja Karty SD +//CS jest na PORT G.3 +#define SD_SPI_CS_PORT PORTG +#define SD_SPI_CS_EN_MASK_OR 0x00 +#define SD_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja portu równoległego MPC23S17 +//CS jest na PORT B.7 +#define MPC23S17_SPI_CS_PORT PORTB +#define MPC23S17_SPI_CS_EN_MASK_OR 0x00 +#define MPC23S17_SPI_CS_EN_MASK_AND 0x7F + +//Konfiguracja Układu analogowo cyfrowego MPC3008 +//CS jest na PORT B.6 +#define MCP3008_SPI_CS_PORT PORTB +#define MCP3008_SPI_CS_EN_MASK_OR 0x00 +#define MCP3008_SPI_CS_EN_MASK_AND 0xBF + +//Konfiguracja rezystora cyfrowego MCP4150 +//CS jest na PORT B.6 +#define MCP4150_SPI_CS_PORT PORTB +#define MCP4150_SPI_CS_EN_MASK_OR 0x00 +#define MCP4150_SPI_CS_EN_MASK_AND 0xBF + + +//Konfiguracja Zegara czasu rzeczywistego DS1305 +//CE jest na PORT B.5 +#define DS1305_SPI_CS_PORT PORTB +#define DS1305_SPI_CS_EN_MASK_OR 0x20 +#define DS1305_SPI_CS_EN_MASK_AND 0xFF + + + +//konfiguracja wyłączania wszystkich urządzeń SPI + +//PORT A: Zewnętrzna pamięć +#define disableSpiPORTA_OR 0x00 +#define disableSpiPORTA_AND 0xFF + +//PORT B: +// PB4 - Sl 3, CPU 1 +// PB5 - SL 3, CPU 2 +// PB6 - SL 4, CPU 1 +// PB7 - SL 4, CPU 2 +#define disableSpiPORTB_OR 0xF0 +#define disableSpiPORTB_AND 0xFF + +//PORT C: Zewnętrzna pamięć +#define disableSpiPORTC_OR 0x00 +#define disableSpiPORTC_AND 0xFF + +//PORD D: +// PD4 - Sl 1, CPU 1 +// PD5 - SL 1, CPU 2 +// PD6 - SL 2, CPU 1 +// PD7 - SL 2, CPU 2 +#define disableSpiPORTD_OR 0xF0 +#define disableSpiPORTD_AND 0xFF + +//PORT E +// PE3 - ENC28j60 0 - on, 1 - off +#define disableSpiPORTE_OR 0x08 +#define disableSpiPORTE_AND 0xFF + +//PORT F - brak SPI SS +#define disableSpiPORTF_OR 0x00 +#define disableSpiPORTF_AND 0xFF + +//PORT G +// PG3 - SD +#define disableSpiPORTG_OR 0x08 +#define disableSpiPORTG_AND 0xFF + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/hardware_en.h b/Projects/DidacticSystem/Adam/RemoteServer/hardware_en.h new file mode 100644 index 0000000..e92e921 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/hardware_en.h @@ -0,0 +1,10 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE EN + +#include +const char statusLockerSensDescStr[] PROGMEM = " locker %d"; +const char statusLockerOpenStr[] PROGMEM = " open "; +const char statusLockerCloseStr[] PROGMEM = " locked "; +const char statusLockerSensAdditionalDescStr[] PROGMEM = " (threshold %d, AC value %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/hardware_pl.h b/Projects/DidacticSystem/Adam/RemoteServer/hardware_pl.h new file mode 100644 index 0000000..9bf0733 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/hardware_pl.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE PL + +prog_char statusLockerSensDescStr[] = " rygiel %d"; +prog_char statusLockerOpenStr[] = " otwarty "; +prog_char statusLockerCloseStr[] = " zamkniety"; +prog_char statusLockerSensAdditionalDescStr[] = " (granica %d, wartosc AC %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/main.c b/Projects/DidacticSystem/Adam/RemoteServer/main.c new file mode 100644 index 0000000..5f70dbf --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/main.c @@ -0,0 +1,181 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + +uint8_t timer100Hz = 0; + +xQueueHandle xRs1Tx; +xQueueHandle xRs1Rec; + +xQueueHandle xRsLanRec; +xQueueHandle xRsLanTx; + +xQueueHandle xSpi2SerialTx[16]; +xQueueHandle xSpi2SerialRx[16]; +xQueueHandle xRsLanTx; + + +void vApplicationIdleHook( void ); + +/** + * RTC clock support + */ +void vApplicationTickHook( void ); + +xTaskHandle xHandleVTY_Rs1; +xTaskHandle xHandleEnc; + +xTaskHandle xHandleXpReceiver; +xTaskHandle xHandleXpTransmitter; + + +void initExternalMem(void) +{ + + MCUCR |= _BV(SRE); //Włączenie pamięci zewnętrznej + MCUCR |= 0x0E; + +#if testZewPamiec == 1 +#define SND(DTA) UDR1=DTA; \ + while( ! (UCSR1A & (1<>4 & 0x0F); + uint8_t znLo = (hiAddr & 0x0F); + + znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + + SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + + uint16_t addr; + uint16_t startAddr = hiAddr<<8; + uint16_t stopAddr = startAddr + 0xFF; + + for (addr = startAddr; addr <= stopAddr; addr++) + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + } + SND ('\r') SND ('\n') +#undef SND +#endif +} + +cmdState_t *CLIStateSerialRs1; +//cmdState_t *CLIStateSerialUdp; +FILE rs1Stream; +FILE udpStream; + +streamBuffers_t udpBuffers; + +portSHORT main( void ) +{ + //ramDyskInit(); //Inicjalizacja Ram dysku + hardwareInit(); + spiInit(disableAllSpiDevices); + +// VTY on serial + xSerialPortInitMinimal(); + CLIStateSerialRs1 = xmalloc(sizeof(cmdState_t)); + //CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + + + + initQueueRs1Stream(&rs1Stream); + VtyInit(CLIStateSerialRs1, &rs1Stream); + + + initQeuesSpi2Serial(); + + udpInit_0(); + loadConfiguration(); + + //initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + //VtyInit(CLIStateSerialUdp, &udpStream); + + xTaskCreate(spiTask, NULL /*"ENC" */, STACK_SIZE_ENC, NULL, 0, &xHandleEnc); + xTaskCreate(vTaskVtyRs1, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialRs1), 1, &xHandleVTY_Rs1); + xTaskCreate(XpNetReceiverTask, NULL /*"ENC" */, 128, NULL, 0, &xHandleXpReceiver); + xTaskCreate(XpNetTransmitterTask, NULL /*"nTX" */, 128, NULL, 0, &xHandleXpTransmitter); +//xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp), 1, &xHandleVTY_UDP); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + arpTimer(); + } +} diff --git a/Projects/DidacticSystem/Adam/RemoteServer/main.h b/Projects/DidacticSystem/Adam/RemoteServer/main.h new file mode 100644 index 0000000..5a83342 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/main.h @@ -0,0 +1,51 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +#include "memory_x.h" +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" + + +#include "queueStream.h" +#include "cli_task.h" + +#include "serial.h" +#include "hardware.h" +#include "spi.h" + +#include "enc28j60.h" +#include "spi_task.h" + +#include "cmdline.h" +#include "vty.h" + +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.01" + + +void initExternalMem(void) __attribute__ ((naked)) __attribute__ ((section (".init4"))); + +extern UdpSocket_t *udpSocket; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.c b/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.c new file mode 100644 index 0000000..c29f31d --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.c @@ -0,0 +1,108 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ + + + +/*uint16_t printHTMLstatus(char *buf, uint16_t pos, uint16_t maxPos) +{*/ +/* char *tmpPtr; + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "

Status

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

"SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), temperature); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp, L_KLASTROW); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Temperatura%d C
Napięcie na magistrali%d V
Liczba wolnych klastrów%d / %d

")); + + tmpPtr = getBufPosToWrite(buf, pos); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Czujniki rygli

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + for (tmp = 0; tmp < 4; tmp++) + { + if (lockSensors[tmp].enabled) + { + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp+1); + if (lockSensors[tmp].locked) + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + else + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), lockSensors[tmp].acVal, lockSensors[tmp].threshold); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + } + } + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Czujnik nrPołożenie ryglaOdczyt z przetwornika ACWart graniczna
%dzamkniętyotwarty%d%d

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Moduły wykonawcze

")); + return pos;*/ +// return 0; +// } + + + + +#if 0 +// uint16_t dat_p; +// uint8_t cmd_pos=0; +// int8_t cmd; +// uint8_t payloadlen=0; +// char str[30]; +// char cmdval; + + + // arp is broadcast if unknown but a host may also + // verify the mac address by sending it to + // a unicast address. + if ( eth_type_is_arp_and_my_ip(Enc28j60_global.buf, plen)) + { + make_arp_answer_from_request(Enc28j60_global.buf); + continue; + } + + // IP - check if ip packets are for us: + if ( eth_type_is_ip_and_my_ip ( Enc28j60_global.buf,plen ) ==0 ) + continue; + + // PING + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_ICMP && Enc28j60_global.buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V ) + { + // a ping packet, let's send pong + make_echo_reply_from_request (Enc28j60_global.buf, plen); + continue; + } + + } + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_H_P]==MYTELNETPOERT_H + && (Enc28j60_global.buf[TCP_DST_PORT_L_P]>=MYTELNETPOERT_L || Enc28j60_global.buf[TCP_DST_PORT_L_P]<=MYTELNETPOERT_L + 20)) + { + processIpPacket(Enc28j60_global.buf); + continue; + } +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.h b/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.h new file mode 100644 index 0000000..b02cb5f --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/netstack_task.h @@ -0,0 +1,50 @@ +#ifndef ENC_TASK_H +#define ENC_TASK_H 1 + +#include +#include +#include +#include +#include + +#include "enc28j60.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" +#include "icmp.h" +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +//TODO add new task: http server +typedef enum +{ + URLramDysk, + URLsdDysk, + URLstatus, + URLerror +} urlSource_t; + + + +uint8_t verify_password(char *str); + +/** + * takes a string of url address and process it + * @param str - part of URL string + * @param [out] - filename or command + * @return http source (SD, RamDysk, status) + */ +urlSource_t analyse_get_url (const char *str, char *fname); + +/** + * Enc28j60 task + */ +void encTask(void *pvParameters); + +extern nicState_t nicState; +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/serial.c b/Projects/DidacticSystem/Adam/RemoteServer/serial.c new file mode 100644 index 0000000..d5d8ef3 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/serial.c @@ -0,0 +1,210 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueRs1Stream(FILE *stream) +{ + fdev_setup_stream(stream, Rs1PutChar, Rs1GetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int Rs1GetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xRs1Rec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int Rs1PutChar(char c, FILE *stream) +{ + (void) stream; + uartRs1SendByte(c); + return 0; +} + +/* +void initQueueRsLanStream(FILE *stream) +{ + fdev_setup_stream(stream, RsLanPutChar, RsLanGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int RsLanGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xRsLanRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int RsLanPutChar(char c, FILE *stream) +{ + (void) stream; + uartRsLanSendByte(c); + return 0; +} +*/ + +void xSerialPortInitMinimal(void) +{ + portENTER_CRITICAL(); + { + xRs1Rec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xRs1Tx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xRsLanRec = xQueueCreate( 64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xRsLanTx = xQueueCreate( 32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + } + portEXIT_CRITICAL(); + + UBRR0L = 8; + UBRR0H = 0; + + UBRR1L = 8; + UBRR1H = 0; + +//UCSR0B = ((1< + +/* ************ Debug options ***************************************** */ +#define UDP_DEBUG 1 +#define IP_DEBUG 1 +#define ARP_DEBUG 1 +#define ICMP_DEBUG 1 +#define TCP_DEBUG 1 +#define NET_DEBUG 1 + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + + +/* maximum number of TCP connections */ +#define NUMBER_OF_SOCKETS 20 + +/* CLI */ +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + +/* Telnet */ +#define MYTELNETPOERT 25000 + + +//uint8_t wwwport; // 80 is just a default value. Gets overwritten during init +//int16_t info_hdr_len=0; +//int16_t info_data_len=0; + + +#define testZewPamiec 1 + +#define SEQNUM 0xFA000000; // my initial tcp sequence number + +#define ARP_TABLE_SIZE 10 +#define ARP_CACHE_TIME_TO_LIVE 128 + + +#define MYUDPPORT 1200 + +#define MY_IP1 192 +#define MY_IP2 168 +#define MY_IP3 0 +#define MY_IP4 251 + +#define MY_GW1 192 +#define MY_GW2 168 +#define MY_GW3 0 +#define MY_GW4 1 + +#define MY_MASK1 255 +#define MY_MASK2 255 +#define MY_MASK3 255 +#define MY_MASK4 0 + +#define UDP_SRC_PORT 3000 +#define UDP_DST_PORT 0 + +#define UDP_DST_IP1 192 +#define UDP_DST_IP2 168 +#define UDP_DST_IP3 0 +#define UDP_DST_IP4 20 + + +#define MAC_ADR1 0x12 +#define MAC_ADR2 0x13 +#define MAC_ADR3 0x32 +#define MAC_ADR4 0x12 +#define MAC_ADR5 0x13 +#define MAC_ADR6 0x32 + + +//#define NUMBER_OF_UDP_SOCK + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/spiStd.c b/Projects/DidacticSystem/Adam/RemoteServer/spiStd.c new file mode 100644 index 0000000..979c545 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/spiStd.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "hardware.h" +#include "spiStd.h" +#include "main.h" +#include "semphr.h" + +void spiInit(void) +{ + + portENTER_CRITICAL(); + { + vSemaphoreCreateBinary(xSemaphoreSpiSS); + xSpiRx = xQueueCreate(1, 1); + } + //SPCR = (1<Rx, &dta, 100)) + continue; + + switch (recState) + { + case ST_SYNC: + if (dta == 0xA5) + recState = ST_CMD; + crc = 0; + break; + + case ST_CMD: + crc = _crc16_update(crc, dta); + recState = ST_LEN; + bufNo = dta; + break; + + case ST_LEN: + crc = _crc16_update(crc, dta); + recState = ST_DATA; + dtaLen=dta; + break; + + case ST_DATA: + crc = _crc16_update(crc, dta); + if (bufNo < NO_OF_SPI2SERIAL_RX_BUF) + { + xQueueSend(xSpi2SerialTx[bufNo], &dta, 0); + } //dopisać obsługę resetowania + + if (bufNo == POWER_OFF) + { + if (dta < NO_OF_SPI2SERIAL_RX_BUF) + { + powerOff |= (1<Tx, &dta, 0); //SYNC - 1bajt ma zawsze wartość 0xA5 + crc = _crc16_update(crc, dta); + xQueueSend(udpSocket->Tx, &bufIdx, 0); //TYPE - 1 bajt, który określa numer portu lub polecenie. Polecenia: 254 wyłącz zasilanie, 255 włącz zasilanie + crc = _crc16_update(crc, dta); + xQueueSend(udpSocket->Tx, &dtaLen, 0); //LENGTH - 1 bajt który określa długość wiadomości (wiadomość nie może przekrczać 200 bajtów bo mam mało pamięci w CPU) + crc = _crc16_update(crc, dta); + while (dtaLen >0) //WIADOMOSC - no dane, które odebrano lub mają być wysłane pod określony port szeregowy + { + xQueueReceive(xSpi2SerialRx[bufIdx], &dta, 0); + xQueueSend(udpSocket->Tx, &dta, 0); + crc = _crc16_update(crc, dta); + dtaLen--; + } + dta = crc>>8; + xQueueSend(udpSocket->Tx, &dta, 0); + + dta = crc; + xQueueSend(udpSocket->Tx, &dta, 0); + } +} + +void spiTask ( void *pvParameters ) +{ + (void) pvParameters; + + + nicInit(); + arpInit(); + icmpInit(); + + + uint16_t plen; + + + //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + + uint8_t spiDevIdx = 0; + for ( ; ; ) + { + vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebraniu przerwania od ENC + + // get the next new packet: + plen = nicPoll(); + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + { + handleSpiDev(spiDevIdx); + + spiDevIdx++; + if (spiDevIdx == NoOfSpiSlaves) + spiDevIdx = 0; //spiDevIdx &= 0x07; + + flushUdpQueues(); + continue; + } + + if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + { + arpIpIn(); + netstackIPv4Process(); + } + else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + { + arpArpIn(); + } + } +} + +void handleSpiDev(uint8_t spiDevNo) +{ + uint8_t *bufTxPtr; + + uint8_t bufTx0_len=0; + uint8_t bufTx1_len=0; + + uint8_t bufRx0_len=0; + uint8_t bufRx1_len=0; + + uint8_t tmpDta; + uint8_t tmpDtaLo; + uint8_t tmpDtaHi; + + uint8_t qeueNo; + + uint8_t i; + uint8_t isDataOnSlave = 1; + + ///Przygotownanie bufora nadawczego do SPI. + qeueNo = 2*spiDevNo; + bufTxPtr = spiTxbuffer0; + +//if ((needToBeUpdated & (1<>4) & 0x0F) | 0x10; + + *(bufTxPtr++) = tmpDtaLo; + *(bufTxPtr++) = tmpDtaHi; + bufTx0_len += 2; + } + qeueNo++; + bufTxPtr = spiTxbuffer1; + +//if ((needToBeUpdated & (1<>4) & 0x0F) | 0x30; + + *(bufTxPtr++) = tmpDtaLo; + *(bufTxPtr++) = tmpDtaHi; + bufTx1_len += 2; + } + + + ///Wysłanie zawartości bufora TxSpi oraz odczyt od modułów slave + spiEnableDev(spiDevNo); + +#define SPI_TRANSMISSION(BUFNO) \ + { \ + tmpDta = spiSend(spiTxbuffer##BUFNO[i]); \ + if ((tmpDta & 0xC0) == 0xC0) \ + { \ + isDataOnSlave = 0; \ + continue; \ + } \ + if ((tmpDta & 0x20) == 0) \ + spiRxbuffer0[bufRx0_len++] = tmpDta; \ + else \ + spiRxbuffer1[bufRx1_len++] = tmpDta; \ + \ + if (bufRx0_len==254) break; \ + if (bufRx1_len==254) break; \ + } + + for (i=0; i +#include +#include +#include +#include + +#include "enc28j60.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "icmp.h" +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include + + +#if NET_DEBUG + + +FILE *netDebug; +uint8_t netDebugLevel; +void setNetDebug(FILE *stream, uint8_t level); + +#endif /*NET_DEBUG*/ + + + +extern xQueueHandle xSpi2SerialTx[]; +extern xQueueHandle xSpi2SerialRx[]; + +extern uint8_t NoOfSerialPorts; +extern uint8_t NoOfSpiSlaves; + + + +enum REC_STATE +{ + ST_SYNC, + ST_CMD, + ST_LEN, + ST_DATA, + ST_CRC_LO, + ST_CRC_HI +} ; + +void spiTask ( void *pvParameters ); +void XpNetReceiverTask ( void *pvParameters ); +void XpNetTransmitterTask ( void *pvParameters ); + +void handleSpiDev(uint8_t spiDevNo); +void initQeuesSpi2Serial(void); + +/** Format wiadomosci spi +Bajt danych odebrany przez porty szeregowych wsyłany jest jako 2 bajty przez SPI. Pierwszy bajt zawiera bity tanych 3-0, natomiast drugi bajt bity danych 7-4. Istotna jest kolejność + + * bit | znaczenie + * 7, 6 | 0x dane, 10 pusta ramka 11 rozkaz, + +Format danych + * 5 | portNo + * 4 | 1 in data are stored bits 7-4, 0 in data are stored bits 3-0 + * 3-0 | data bits + + +Format rozkazu + * 5 | 1 power On, 0 power Off + * 4 | portNo + * 3-0 | data bits + +Pusta ramka gdy: + - slave wysyła 0xCF + - master wysyłą 0x8F + + */ + +#define POWER_OFF 0xFE +#define POWER_ON 0xFF + + +/** Format wiadomości UDP + * 1 bajt Sync - wartość 0xA5 + * + */ + +#endif // SPI_TASK_H diff --git a/Projects/DidacticSystem/Adam/RemoteServer/timeout.h b/Projects/DidacticSystem/Adam/RemoteServer/timeout.h new file mode 100644 index 0000000..fd09299 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/timeout.h @@ -0,0 +1,8 @@ +/* vim: set sw=8 ts=8 si et: */ +#define F_CPU 12500000UL // 12.5 MHz +#ifndef ALIBC_OLD +#include +#else +#include +#endif + diff --git a/Projects/DidacticSystem/Adam/RemoteServer/vty.c b/Projects/DidacticSystem/Adam/RemoteServer/vty.c new file mode 100644 index 0000000..b5c829c --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/vty.c @@ -0,0 +1,416 @@ +#include "main.h" +#include "softwareConfig.h" +#include "vty.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "net.h" +#include "ip.h" +#include "arp.h" + + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t resetSlaves (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t statusEncFunction (cmdState_t *state); + +static cliExRes_t debugFunction (cmdState_t *state); + +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +static cliExRes_t setIpFunction (cmdState_t *state); +static cliExRes_t setIpMaskFunction (cmdState_t *state); +static cliExRes_t setIpGwFunction (cmdState_t *state); +static cliExRes_t setUdpFunction (cmdState_t *state); + +static cliExRes_t setMacAddrFunction (cmdState_t *state); +static cliExRes_t setNoOfSerialPorts (cmdState_t *state); + +static cliExRes_t saveConfigFunction (cmdState_t *state); + + +static cliExRes_t sentToUdpTestFunction (cmdState_t *state); +static cliExRes_t sentToSpiRsTestFunction(cmdState_t *state); + + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; +const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + + +const char * const errorStrings[] PROGMEM = { + errorOK, +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_net_test, cmd_help_net_test, sentToUdpTestFunction}, + {cmd_rs_test, cmd_help_rs_test, sentToSpiRsTestFunction}, + {cmd_res_sl, cmd_help_res_sl, resetSlaves}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enc_stat, cmd_help_enc_stat, statusEncFunction}, + {cmd_net_dbg, cmd_help_net_dbg, debugFunction}, + {cmd_net_test, cmd_help_net_test, sentToUdpTestFunction}, + {cmd_rs_test, cmd_help_rs_test, sentToSpiRsTestFunction}, + {cmd_res_sl, cmd_help_res_sl, resetSlaves}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_conf_ip, cmd_help_conf_ip, setIpFunction}, + {cmd_conf_ip_mask, cmd_conf_ip_mask_help, setIpMaskFunction}, + {cmd_conf_NoOfRs, cmd_help_conf_NoOfRs, setNoOfSerialPorts}, + {cmd_conf_ip_gw, cmd_conf_ip_gw_help, setIpGwFunction}, + {cmd_conf_udp, cmd_help_conf_udp, setUdpFunction}, + {cmd_conf_mac, cmd_help_conf_mac, setMacAddrFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + +// printErrorInfo(state); //TODO fix and uncomment + + //Print system configuration + fprintf_P(stream, systemRamConfigStr); + + fprintf_P(stream, statusMacStr); + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpStr); + netPrintIPAddr(stream, ipGetConfig()->ip); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpMaskStr); + netPrintIPAddr(stream, ipGetConfig()->netmask); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpGwStr); + netPrintIPAddr(stream, ipGetConfig()->gateway); + fprintf_P(stream, PSTR("\r\n")); + + udpPrintStatus(stream); + + fprintf_P(stream, PSTR("\r\nNumber of serial ports %d\r\n"), NoOfSerialPorts); +// arpPrintTable(stream); +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + printStatus(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t statusEncFunction(cmdState_t *state) +{ + nicRegDump(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t debugFunction (cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t level = cmdlineGetArgInt(2, state); + const char *str = (const char*)cmdlineGetArgStr(1, state); + + + if (strncmp_P(str, PSTR("net"), 3) == 0) + { + setNetDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + +#ifdef TCP_H + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } +#endif + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + return SYNTAX_ERROR; +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + return OK_SILENT; +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + udpSocket->dstIp = ip; + + uint16_t port = cmdlineGetArgInt(5, state); + udpSocket->srcPort = htons(port); + + if (state->argc > 5) + { + port = cmdlineGetArgInt(6, state); + udpSocket->dstPort = htons(port); + } + return OK_SILENT; +} + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + + ipSetConfigMask(mask); + return OK_SILENT; +} + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + return OK_SILENT; +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + if (state->argc < 6) + return SYNTAX_ERROR; + + nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + +static cliExRes_t setNoOfSerialPorts(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + NoOfSerialPorts = cmdlineGetArgInt(1, state); + NoOfSpiSlaves = (NoOfSerialPorts+1)>>1; + + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} + + +static cliExRes_t sentToUdpTestFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t rsNo = (uint8_t)(cmdlineGetArgInt(1, state)); + if (rsNo >= 16) + return SYNTAX_ERROR; + + uint8_t tmp; + if (state->argc >= 2) + { + char *msg=cmdlineGetArgStr(2, state); + while(*msg != '\0') + { + xQueueSend(xSpi2SerialRx[rsNo], msg, 0); + msg++; + } + } + tmp = '\r'; + xQueueSend(xSpi2SerialRx[rsNo], &tmp, 0); + tmp = '\n'; + xQueueSend(xSpi2SerialRx[rsNo], &tmp, 0); + + return OK_SILENT; +} + +static cliExRes_t sentToSpiRsTestFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t rsNo = (uint8_t)(cmdlineGetArgInt(1, state)); + if (rsNo >= 16) + return SYNTAX_ERROR; + + uint8_t tmp; + + if (state->argc >= 2) + { + char *msg=cmdlineGetArgStr(2, state); + while(*msg != '\0') + { + xQueueSend(xSpi2SerialTx[rsNo], msg, 0); + msg++; + } + } + tmp = '\r'; + xQueueSend(xSpi2SerialTx[rsNo], &tmp, 0); + tmp = '\n'; + xQueueSend(xSpi2SerialTx[rsNo], &tmp, 0); + + return OK_SILENT; +} + +static cliExRes_t resetSlaves(cmdState_t *state) +{ + PORTB &= 0xFE; + fprintf_P(state->myStdInOut, PSTR("Restarting slave devices\r\n")); + PORTB |= 0x01; + return OK_INFORM; +} diff --git a/Projects/DidacticSystem/Adam/RemoteServer/vty.h b/Projects/DidacticSystem/Adam/RemoteServer/vty.h new file mode 100644 index 0000000..3849bec --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/vty.h @@ -0,0 +1,80 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include +#include + +#include "enc28j60.h" +#include "memory_x.h" +#include "configuration.h" +#include "nic.h" +#include "ip.h" +#include "net.h" +#include "arp.h" +#include "cmdline.h" +#include "udp.h" + +#include "spi_task.h" + + +// Znaki kontrolne w protokole Xmodem +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +// xmodem timeout/retry parameters +#define XMODEM_RETRY_LIMIT 16 + +// error return codes +#define XMODEM_ERROR_REMOTECANCEL 1 +#define XMODEM_ERROR_OUTOFSYNC 2 +#define XMODEM_ERROR_RETRYEXCEED 3 + +#define XMODEM_BUFFER_SIZE 128 + + +extern nicState_t nicState; +extern UdpSocket_t *udpSocket; + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + + + + +extern struct Enc28j60_config Enc28j60_global; + +extern uint8_t NoOfSerialPorts; +extern uint8_t NoOfSpiSlaves; + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/vty_en.h b/Projects/DidacticSystem/Adam/RemoteServer/vty_en.h new file mode 100644 index 0000000..42b9279 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/vty_en.h @@ -0,0 +1,73 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char statusRamDiskStateStr[] PROGMEM = " Ram disc space : %d free of %d clusters\r\n"; +const char statusTemperatureStr[] PROGMEM = " Temperature : %d C\r\n"; +const char statusVoltageStr[] PROGMEM = " Voltage : %d V\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; +const char statusMacStr[] PROGMEM = " Mac address : "; +const char statusIpStr[] PROGMEM = " IP address : "; +const char statusIpMaskStr[] PROGMEM = " mask : "; +const char statusIpGwStr[] PROGMEM = " gateway : "; + +const char debugEnabledInfoStr[] PROGMEM = "Enabled %s debug\r\n"; +const char debugDisabledInfoStr[] PROGMEM = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; +const char cmd_enc_stat[] PROGMEM = "encstat"; const char cmd_help_enc_stat[] PROGMEM = "Print Enc 28j60 registers"; +const char cmd_time[] PROGMEM = "time"; const char cmd_help_time[] PROGMEM = "Print time"; +const char cmd_net_dbg[] PROGMEM = "debug"; const char cmd_help_net_dbg[] PROGMEM = "[net|arp|icmp|ip|tcp|udp] [level] write debug info. Level 0 disable debugging"; + +const char cmd_net_test[] PROGMEM = "ntest"; const char cmd_help_net_test[] PROGMEM = "[serialNo] {msg} forward fake message from serial to net"; +const char cmd_rs_test[] PROGMEM = "rtest"; const char cmd_help_rs_test[] PROGMEM = "[serialNo] {msg} forward fake message from net to serial"; + + +const char cmd_res_sl[] PROGMEM = "reset"; const char cmd_help_res_sl[] PROGMEM = "Restart slave devices"; + +const char cmd_ping[] PROGMEM = "ping"; const char cmd_help_ping[] PROGMEM = "[A1] [A2] [A3] [A4] Sends ping throught ethernet"; +const char cmd_xRec[] PROGMEM = "xrec"; const char cmd_help_xRec[] PROGMEM = "[file name] receive file using xModem"; +const char cmd_xSend[] PROGMEM = "xsend"; const char cmd_help_xSend[] PROGMEM = "[file name] send file using xModem"; +const char cmd_xflash[] PROGMEM = "xflash"; const char cmd_help_xflash[] PROGMEM = "[device no] [file name] flash device connected to Rs485"; +const char cmd_dir_rf[] PROGMEM = "dirrf"; const char cmd_help_dir_rf[] PROGMEM = "Print ramdisk files"; +const char cmd_create_rf[] PROGMEM = "crf"; const char cmd_help_create_rf[] PROGMEM = "[file name] create ram file"; +const char cmd_erase_rf[] PROGMEM = "eraserf"; const char cmd_help_erase_rf[] PROGMEM = "[file name] erase file from ram disk"; +const char cmd_edit_rf[] PROGMEM = "editrf"; const char cmd_help_edit_rf[] PROGMEM = "[file name] edit file located on ram disk"; +const char cmd_read_rf[] PROGMEM = "readrf"; const char cmd_help_read_rf[] PROGMEM = "[file name] read file located on ram disk"; + +const char cmd_up[] PROGMEM = "up"; const char cmd_help_up[] PROGMEM = "[driver no] [channel] {value} move up"; +const char cmd_down[] PROGMEM = "down"; const char cmd_help_down[] PROGMEM = "[driver no] [channel] {value} move down"; +const char cmd_spa[] PROGMEM = "spa"; const char cmd_help_spa[] PROGMEM = "[value] set port A"; +const char cmd_spb[] PROGMEM = "spb"; const char cmd_help_spb[] PROGMEM = "[value] set port B"; + +const char cmd_settime[] PROGMEM = "settime"; const char cmd_help_settime[] PROGMEM = "[h] [m] [s] set time (24h format)"; +const char cmd_ac[] PROGMEM = "ac"; const char cmd_help_ac[] PROGMEM = "[channel 0-7] read analog value"; +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Enable mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "View mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configure mode"; +const char cmd_conf_ip[] PROGMEM = "ip"; const char cmd_help_conf_ip[] PROGMEM = "[A1] [A2] [A3] [A4] set IP address"; +const char cmd_conf_udp[] PROGMEM = "udp"; const char cmd_help_conf_udp[] PROGMEM = "[A1] [A2] [A3] [A4] [src port] {dst port} set udp client IP address and ports"; +const char cmd_conf_ip_mask[] PROGMEM = "mask"; const char cmd_conf_ip_mask_help[] PROGMEM = "[mask] set mask"; +const char cmd_conf_ip_gw[] PROGMEM = "gw"; const char cmd_conf_ip_gw_help[] PROGMEM = "[A1] [A2] [A3] [A4] set default gateway"; +const char cmd_conf_mac[] PROGMEM = "mac"; const char cmd_help_conf_mac[] PROGMEM = "[A1] [A2] [A3] [A4] [A5] [A6] set MAC address"; +const char cmd_conf_NoOfRs[] PROGMEM = "maxser"; const char cmd_help_conf_NoOfRs[] PROGMEM = "Maximum number of serial port [0-15]"; +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; +const char cmd_ustawR[] PROGMEM = "setr"; const char cmd_help_ustawR[] PROGMEM = "[value] set resistance value"; + +const char cmd_ustawMW[] PROGMEM = "rset"; const char cmd_help_ustawMW[] PROGMEM = "[A] [C] set execution module"; +const char cmd_zapiszMW[] PROGMEM = "rsave"; const char cmd_help_zapiszMW[] PROGMEM = "[A] save execution module settings"; + +#endif diff --git a/Projects/DidacticSystem/Adam/RemoteServer/vty_pl.h b/Projects/DidacticSystem/Adam/RemoteServer/vty_pl.h new file mode 100644 index 0000000..6d7d555 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RemoteServer/vty_pl.h @@ -0,0 +1,83 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char statusRamDiskStateStr[] = " Ram dysk : %d wolnych z %d klastrow\r\n"; +prog_char statusTemperatureStr[] = " Temperatura : %d C\r\n"; +prog_char statusVoltageStr[] = " Napiecie : %d V\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; +prog_char statusMacStr[] = " Adres MAC : "; +prog_char statusIpStr[] = " IP adres : "; +prog_char statusIpMaskStr[] = " maska : "; +prog_char statusIpGwStr[] = " brama : "; + +prog_char editRamFileIntroStr[] = "Zapis do pliku. CTRL+C koniec\r\n"; +prog_char readRamFIleLenStr[] = "Dlugosc pliku: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: rozpoczynanie wysylania\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Wlaczono debugowanie %s\r\n"; +prog_char debugDisabledInfoStr[] = "Wylaczono debugowanie %s\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Wypisz rejestry Enc 28j60"; +prog_char cmd_time[] = "czas"; prog_char cmd_help_time[] = "Wypisuje czas"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[net|arp|icmp|ip|tcp|udp] [poziom] wypisywanie komunikatow. Poziom 0 wylacza komunikaty"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[numer sterownika] Wysyla ping do sterownika podpietego do magistrali Rs485"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Wysyla ping przez ethernet"; +prog_char cmd_xRec[] = "xodb"; prog_char cmd_help_xRec[] = "[nazwa pliku] odbiera plik za pomoca protokolu xModem"; +prog_char cmd_xSend[] = "xwyslij"; prog_char cmd_help_xSend[] = "[nazwa pliku] wysyla plik za pomoca protokolu xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[numer urzadzenia] [nazwa pliku] wgrywa firmware do urzadzenia podpietego do Rs485"; +prog_char cmd_dir_rf[] = "dirrp" ; prog_char cmd_help_dir_rf[] = "Wypisuje nazwy plikow zapisanych w pamieci RAM"; +prog_char cmd_create_rf[] = "utwrp"; prog_char cmd_help_create_rf[] = "[nazwa pliku] Tworzy plik w pamieci RAM"; +prog_char cmd_erase_rf[] = "kasrp"; prog_char cmd_help_erase_rf[] = "[nazwa pliku] Usuwa plik z pamieci RAM"; +prog_char cmd_edit_rf[] = "dopiszrp"; prog_char cmd_help_edit_rf[] = "[nazwa pliku] Dopisuje do pliku zapisanego w pamieci ram"; +prog_char cmd_read_rf[] = "czytrp"; prog_char cmd_help_read_rf[] = "[nazwa pliku] Wypisuje zawartosc pliku"; + +prog_char cmd_up[] = "podnies"; prog_char cmd_help_up[] = "[numer sterownika] [nr rolety] {wartosc} podnoszenie rolety"; +prog_char cmd_down[] = "opusc"; prog_char cmd_help_down[] = "[numer sterownika] [nr rolety] {wartosc} opuszczanie rolety"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[wartosc] ustaw zewnetrzny port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[wartosc] ustaw zewnetrzny port B"; + +prog_char cmd_settime[] = "ustawcz"; prog_char cmd_help_settime[] = "[h] [m] [s] ustawia czas w formacie 24h format"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[wejscie 0-7] czyta analogowa wartosc na wejsciu przetwornika"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A2] [A3] ustaw adres IP"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} ustaw adres klienta udp oraz porty"; +prog_char cmd_conf_ip_mask[]= "maska"; prog_char cmd_conf_ip_mask_help[]= "[maska] ustaw maske adresu IP"; +prog_char cmd_conf_ip_gw[] = "brama"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] ustaw domyslna brame"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] set MAC address"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] ustaw adres MAC"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/.kdev_include_paths b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/.kdev_include_paths new file mode 100644 index 0000000..640b7f0 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/.kdev_include_paths @@ -0,0 +1,2 @@ +/home/adam/akme/FreeRtos/freeRtos/Source/include +/usr/lib/avr/include diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Bootldr.aps b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Bootldr.aps new file mode 100644 index 0000000..c28e432 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Bootldr.aps @@ -0,0 +1 @@ +Bootldr15-Mar-2007 10:14:1210-Apr-2010 21:35:15241015-Mar-2007 10:14:1244, 13, 0, 528AVR GCCdefault\Bootldr.elfD:\Dokumenty\Adam\FreeRtos\projekty\SterRoletAtMega168\Bootloader\AVR SimulatorATmega169falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000bootldr.cbootcfg.hbootldr.hreadme.txtdefaultNOatmega168100Bootldr.elfdefault\0-Wall -gdwarf-2 -DF_CPU=7372800UL -O0 -fsigned-char.textFLASH
0x1c00
default1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exe
02162321238000000011
diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Makefile b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Makefile new file mode 100644 index 0000000..dc2b897 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/Makefile @@ -0,0 +1,89 @@ +############################################################################### +# Makefile for the project Bootldr +############################################################################### + +## General Flags +PROJECT = Bootloader +MCU = atmega168 +TARGET = bootloader +CC = avr-gcc +CPP = avr-g++ + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -DF_CPU=7372800UL -Os -fsigned-char +#CFLAGS += -gdwarf-2 +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-section-start=.text=0x3800 + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + +## Objects that must be built in order to link +OBJECTS = bootldr.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET).elf Bootldr.hex Bootldr.eep size + +## Compile +bootldr.o: bootldr.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET).elf: $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf + +%.hex: $(TARGET).elf + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET).elf + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET).elf + avr-objdump -h -S $< > $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) Bootldr.elf dep/* Bootldr.hex Bootldr.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.aws b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.aws new file mode 100644 index 0000000..ab7171e --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.aws @@ -0,0 +1 @@ + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.c b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.c new file mode 100644 index 0000000..1e1d2a6 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Bootloader/bootldr.c @@ -0,0 +1,382 @@ +/* + Project: AVR Rs485 bootloader + Base on + Project: AVR Universal BootLoader + Author: Shaoziyang + Shaoziyang@gmail.com + http://avrubd.googlepages.com + + Author: Adam Kaliszan + adam.kaliszan@gmail.com + + File: bootldr.c + main program code + + Version: 0.9 + + Date: 2010.4 +*/ + +#include "bootldr.h" + +uint8_t helloBuf[] = {SYNC, 0, rHELLO, 7, 0xFF , 0xFF, 'b', '0', '.', '6', '3'}; //rHELLO response +uint8_t pingBuf[HDR_LEN+PROT_BUF_LEN] = {SYNC, 0, rPING, 8}; //rPING response +uint8_t noCommandBuf[] = {SYNC, 0, rUNKNOWN, 0}; //unknown command response + +uint8_t buf[BUFSIZE]; // xModem receive buffer +uint8_t bufptr; +uint8_t pagptr; +uint8_t ch; +uint8_t cl; +uint16_t FlashAddr; +uint8_t cnt; + +uint8_t tmp; +uint8_t adres; // Adres urządzenia zczytany na starcie +stanAutomatu_t stan; // Stan automatu +uint16_t crc; // Crc +uint16_t crcObl; // Crc +uint8_t protAddr; // Odebrany adres w magistrali Rs485 +uint8_t protRozkaz; // Odebrany kod rozkazu +uint8_t protDlDanych; // Odebrana inf. o długości pola danych +uint8_t protBuf[PROT_BUF_LEN]; // Odebrane dane do rozkazu +uint8_t protCrcHi; // Odebrany bardziej znaczący bajt CRC +uint8_t protCrcLo; // Odebrany mniej znaczący bajt CRC +uint8_t protDaneWsk; // Licznik odebranych danych + + +inline void write_one_page(unsigned char *buf) //Uaktualnianie strony z pamięcią flash +{ + boot_page_erase(FlashAddr); //Kasowanie strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji + + uint16_t *tmpPtr = (uint16_t *)(buf); //kompilator musi być little bit endian + for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2) + { + boot_page_fill(pagptr, *tmpPtr); //brzydkie rzutowanie 2X uint8_t na uint16_t + tmpPtr++; //wskaźnik zwiększa się o 2 + } + boot_page_write(FlashAddr); //Zapis strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji +} + +//send data to comport +void WriteCom(unsigned char dat) +{ + RS485Enable(); + UDRREG(COMPORTNo) = dat; + while(!(UCSR0A & (1<>8)); + WriteCom((uint8_t)(crc & 0xFF)); + crc=0; +} + + +void wykonajRozkaz(void) +{ + uint8_t tmpCrcLo = (uint8_t)(crcObl & 0xFF); + uint8_t tmpCrcHi = (uint8_t)(crcObl >>8); + + resetStateMachine(); + if ((tmpCrcHi != protCrcHi) ||(tmpCrcLo != protCrcLo)) + { + return; + } + stan = sync; +//cnt = TimeOutCnt; + if (adres != protAddr) + { + if (protRozkaz == rFLASH) + { + waitAndQuit(); + } + return; + } + if (protRozkaz == rFLASH) + { + stan = xModem; + return; + } + if (protRozkaz == rHELLO) + { + sendBuf(helloBuf, HDR_LEN+7); + return; + } + if (protRozkaz == rPING) + { + if (protDlDanych > PROT_BUF_LEN) + protDlDanych = PROT_BUF_LEN; + pingBuf[3] = protDlDanych; + for (tmp=0; tmp>1); //Read address + adres |= (PINC & 0x03); + + //initialize serial port UART0 + UCSR0A = 0; + UCSR0B = (1 << RXENBIT(COMPORTNo))|(1 << TXENBIT(COMPORTNo)); + UCSR0C = (1 << USEURSEL)|(1 << UCSZ01)|(1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 3; + + cnt = TimeOutCnt; // Timeout (wg. częstotliwości zegara 1Hz) + cl = 0; // Liczba poprawnych liter od hasła + + +//Wykonywanie poleceń. Tryb bootloadera. + while(stan != xModem) // Czekanie aż zostanie odebrany rozkaz rozpoczęcia transmisji xModemowej + { + if(TIFRREG & (1< + break; + } + + //begin xModem transmission - receive data + packNO = 1; + bufptr = 0; + cnt = 0; + FlashAddr = 0; + while(1) + { + ch = ReadCom_withLimitedWaiting(); // get package number + cl = ~ReadCom_withLimitedWaiting(); + if ((packNO == ch) && (packNO == cl)) + { + uint16_t crc = 0; // start calculate CRC + for(li = 0; li < BUFFERSIZE; li++) // receive a full data frame + { + tmp = ReadCom_withLimitedWaiting(); // read from uart + buf[bufptr++] = tmp; // write to temporary buffer + crc = _crc_xmodem_update(crc, tmp); // calculate CRC + } + + crch = ReadCom_withLimitedWaiting(); // get checksum Hi + crcl = ReadCom_withLimitedWaiting(); // get checksum Lo + ch = crc / 256; + cl = crc % 256; + if ((crch == ch) && (crcl == cl)) + { + PORTD |= (uint8_t)(0x40); + packNO++; + while(bufptr > 0) // receive one frame, write multi pages + { + write_one_page(&buf[BUFSIZE - bufptr]); + FlashAddr += SPM_PAGESIZE; // modify Flash page address + bufptr -= SPM_PAGESIZE; + if (FlashAddr >= 2*BootStart) // BootStart is word number (not byte number) + quit(); + } + WriteCom(XMODEM_ACK); // All OK send ACK + cnt = 0; + } + else //CRC + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + } + else //PackNo + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + //too much error, update abort + if(cnt > 3) + { + PORTD |= (uint8_t)(0x20); + break; + } + tmp = ReadCom_withLimitedWaiting(); + + if (tmp == XMODEM_EOT) + break; + } + WriteCom(XMODEM_NAK); + + quit(); + return 0; +} + +//! quit boot mode and jump to user's application +void quit(void) +{ + boot_rww_enable(); //enable application section + (*((void(*)(void))PROG_START))(); //jump +} + +//! wait 1 minute and jump to user's application +void waitAndQuit(void) +{ +// PORTD = 0x20; //LED 1 and 2 on + cnt=120; + while(1) + { + if(TIFRREG & (1< +#include +#include +#include +#include + +#include "../../../freeRtos/Lib/include/protocol1.h" +#include "../../../freeRtos/Lib/include/xModemCommands.h" + +#define PROT_BUF_LEN 32 /// Rs485 rec buffer length + + +#ifndef F_CPU ///system clock(Hz) +#define F_CPU 7372800UL +#endif + +#define PROG_START 0x0000 /// User's application start address +#define BootStart 0x1C00 /// Boot section address start + +#define BUFFERSIZE 128 /// Xmodem buffer length +#define BAUDRATE 115200 /// Rs485 baudrate + + +#define timeclk 500 /// basic timer interval(ms) +#define TimeOutCnt 10 /// max wait for password time = TimeOutCnt * timeclk +#define TimeOutCntC 40 /// numbers of sending C char for start xModem + + +#define COMPORTNo 0 /// comport number: 0/1/2.. + +#define RS485RXDis 2 /// Pin that disables Rs485 receiver +#define RS485TXEn 3 /// Pin that enables Rs485 transmitter +#define LEDPORTNo 5 /// Pin that is connected to the diode 1 +#define LED2PORTNo 6 /// Pin that is connected to the diode 2 + + +//receive buffer' size will not smaller than SPM_PAGESIZE +#if BUFFERSIZE < SPM_PAGESIZE +#define BUFSIZE SPM_PAGESIZE +#else +#define BUFSIZE BUFFERSIZE +#endif + + + + +//Don't modify code below, unless your really konw what to do + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE +#if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#else +#if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + +//check baudrate register error +//mocro below maybe not same in different C compiler +#define FreqTemp (16UL * BAUDRATE * (((F_CPU * 10) / (16 * BAUDRATE) + 5)/ 10)) +#if ((FreqTemp * 50) > (51 * F_CPU) || (FreqTemp * 50) < (49 * F_CPU)) +#error "BaudRate error > 2% ! Please check BaudRate and F_CPU value." +#endif + +#define True 1 +#define False 0 +#define TRUE 1 +#define FALSE 0 + +//internal use macro +#define CONCAT(a, b) a ## b +#define CONCAT3(a, b, c) a ## b ## c + +//register of PORT and bit define +#define PORTREG(No) CONCAT(PORT, No) +#define PINREG(No) CONCAT(PIN, No) +#define UDRREG(No) CONCAT(UDR, No) +#define DDRREG(No) CONCAT(DDR, No) +#define TXCBIT(No) CONCAT(TXC, No) +#define RXCBIT(No) CONCAT(RXC, No) +#define RXENBIT(No) CONCAT(RXEN, No) +#define TXENBIT(No) CONCAT(TXEN, No) +#define URSELBIT(No) CONCAT(URSEL, No) + +//some kind of AVR need URSEL define when comport initialize +#define USEURSEL 0 + + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#define RS485Enable() PORTD = 0x0C +#define RS485Disable() PORTD = 0x00 + +//#define DataInCom() (UCSRAREG(COMPORTNo) & (1 << RXCBIT(COMPORTNo))) +#define DataInCom() (UCSR0A & (1 << RXC0)) +#define ReadCom() UDR0 + +//@{ +/** + * Stan automatu: + * sync, addr, rozkaz, dlDanych, dane, crcHi, crcLo, xModem + */ +enum stanAutomatu +{ + sync, + addr, + rozkaz, + dlDanych, + dane, + crcHi, + crcLo, + xModem +}; +typedef enum stanAutomatu stanAutomatu_t; + +/** + * Leave bootloader mode + */ +void quit(void) __attribute__((noreturn)); + +/** + * Wait for a tame of different device flashing and leave next bootloader mode + */ +void waitAndQuit(void) __attribute__((noreturn)); + +//@} +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/CMakeLists.txt b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/CMakeLists.txt new file mode 100644 index 0000000..1f34388 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/CMakeLists.txt @@ -0,0 +1,4 @@ +PROJECT(ModWykonawczy) + +ADD_EXECUTABLE(modWykonawczy main.c automat.c hardware.c serial.c) +add_library(headers main.h automat.h FreeRTOSConfig.h hardware.h ../protocol1.h serial.h) diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/FreeRTOSConfig.h b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/FreeRTOSConfig.h new file mode 100644 index 0000000..ec621a7 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Makefile b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Makefile new file mode 100644 index 0000000..538a603 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/Makefile @@ -0,0 +1,418 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +PORT_DIR = ../../freeRtos/portable/GCC/ATMega168 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +serial.c \ +hardware.c\ +automat.c\ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +#AVRDUDE_PROGRAMMER = avrispmkII +AVRDUDE_PROGRAMMER = stk500v2 + +#AVRDUDE_PROGRAMMER_2 = 4232h +AVRDUDE_PROGRAMMER_2 = usbMultiToolV2spi + + +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +#AVRDUDE_PORT = usb # Stk500v2 on multi PCB + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS_2 = -p $(MCU) -C avrdude.conf -c $(AVRDUDE_PROGRAMMER_2) + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + + +program2: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS_2) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/ModWykonawczyTmpRtos.kdev4 b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/ModWykonawczyTmpRtos.kdev4 new file mode 100644 index 0000000..83c42cc --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/ModWykonawczyTmpRtos.kdev4 @@ -0,0 +1,3 @@ +[Project] +Manager=KDevCMakeManager +Name=ModWykonawczy diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.c b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.c new file mode 100644 index 0000000..49a8622 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.c @@ -0,0 +1,88 @@ +#include "automat.h" + +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + + if (klGoraOff) + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + stan->klGora_off++; + } + else + { + if (stan->klGora_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_gore; + wiadomosc = 0xBF; + } + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + stan->klGora_off = 0; + } + + if (klDolOff) + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klDol_on = 0; + stan->klDol_off++; + } + else + { + if (stan->klDol_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_dol; + wiadomosc = 0x3F; + } + } + if (stan->klDol_on == T_START_CONT) + { + stan->czynnosc = w_dol; + } + stan->klDol_on++; + stan->klDol_off = 0; + } + + if (stan->klDol_on == 255) + stan->klDol_on = 254; + if (stan->klGora_on == 255) + stan->klGora_on = 254; + + if (stan->klDol_off == 255) + stan->klDol_off = 254; + if (stan->klGora_off == 255) + stan->klGora_off = 254; + + return wiadomosc; +} diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.h b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.h new file mode 100644 index 0000000..702de30 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.h @@ -0,0 +1,29 @@ +#ifndef AUTOMAT_H +#define AUTOMAT_H + +#include "main.h" + + +typedef enum +{ + bezczynny, + do_konca_w_gore, + do_konca_w_dol, + w_gore, + w_dol +} t_czynnosc; + +typedef struct +{ + uint8_t klGora_on; + uint8_t klDol_on; + + uint8_t klGora_off; + uint8_t klDol_off; + t_czynnosc czynnosc; +} +t_stan_klawiszy; + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan); + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.lst b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.lst new file mode 100644 index 0000000..811da06 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/automat.lst @@ -0,0 +1,277 @@ + 1 .file "automat.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 171 .global automatStanowKlawiszy + 173 automatStanowKlawiszy: + 174 .stabd 46,0,0 + 1:automat.c **** #include "automat.h" + 2:automat.c **** + 3:automat.c **** #define T_START 5 + 4:automat.c **** #define T_START_CONT 40 + 5:automat.c **** #define T_STOP 5 + 6:automat.c **** + 7:automat.c **** uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) + 8:automat.c **** { + 176 .LM0: + 177 .LFBB1: + 178 /* prologue: function */ + 179 /* frame size = 0 */ + 180 /* stack size = 0 */ + 181 .L__stack_usage = 0 + 182 0000 FA01 movw r30,r20 + 9:automat.c **** uint8_t wiadomosc = 0; + 10:automat.c **** + 11:automat.c **** if (klGoraOff) + 184 .LM1: + 185 0002 8823 tst r24 + 186 0004 01F0 breq .L2 + 12:automat.c **** { + 13:automat.c **** if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + 188 .LM2: + 189 0006 8481 ldd r24,Z+4 + 190 0008 9281 ldd r25,Z+2 + 191 000a 8330 cpi r24,lo8(3) + 192 000c 01F4 brne .L21 + 194 .LM3: + 195 000e 9530 cpi r25,lo8(5) + 196 0010 01F4 brne .L21 + 14:automat.c **** { + 15:automat.c **** stan->czynnosc = bezczynny; + 198 .LM4: + 199 0012 1482 std Z+4,__zero_reg__ + 16:automat.c **** wiadomosc = 0x40; + 201 .LM5: + 202 0014 80E4 ldi r24,lo8(64) + 203 0016 00C0 rjmp .L3 + 204 .L21: + 9:automat.c **** + 206 .LM6: + 207 0018 80E0 ldi r24,0 + 208 .L3: + 17:automat.c **** } + 18:automat.c **** stan->klGora_on = 0; + 210 .LM7: + 211 001a 1082 st Z,__zero_reg__ + 19:automat.c **** stan->klGora_off++; + 213 .LM8: + 214 001c 9F5F subi r25,lo8(-(1)) + 215 001e 9283 std Z+2,r25 + 216 0020 00C0 rjmp .L4 + 217 .L2: + 20:automat.c **** } + 21:automat.c **** else + 22:automat.c **** { + 23:automat.c **** if (stan->klGora_on == T_START) + 219 .LM9: + 220 0022 9081 ld r25,Z + 221 0024 9530 cpi r25,lo8(5) + 222 0026 01F4 brne .L5 + 24:automat.c **** { + 25:automat.c **** if (stan->czynnosc != bezczynny) + 224 .LM10: + 225 0028 8481 ldd r24,Z+4 + 226 002a 8823 tst r24 + 227 002c 01F0 breq .L6 + 26:automat.c **** { + 27:automat.c **** stan->czynnosc = bezczynny; + 229 .LM11: + 230 002e 1482 std Z+4,__zero_reg__ + 28:automat.c **** wiadomosc = 0x40; + 232 .LM12: + 233 0030 80E4 ldi r24,lo8(64) + 234 0032 00C0 rjmp .L8 + 235 .L6: + 29:automat.c **** } + 30:automat.c **** else + 31:automat.c **** { + 32:automat.c **** stan->czynnosc = do_konca_w_gore; + 237 .LM13: + 238 0034 81E0 ldi r24,lo8(1) + 239 0036 8483 std Z+4,r24 + 33:automat.c **** wiadomosc = 0xBF; + 241 .LM14: + 242 0038 8FEB ldi r24,lo8(-65) + 243 003a 00C0 rjmp .L8 + 244 .L5: + 34:automat.c **** } + 35:automat.c **** } + 36:automat.c **** if (stan->klGora_on == T_START_CONT) + 246 .LM15: + 247 003c 9832 cpi r25,lo8(40) + 248 003e 01F4 brne .L22 + 37:automat.c **** { + 38:automat.c **** stan->czynnosc = w_gore; + 250 .LM16: + 251 0040 83E0 ldi r24,lo8(3) + 252 0042 8483 std Z+4,r24 + 253 .L22: + 9:automat.c **** + 255 .LM17: + 256 0044 80E0 ldi r24,0 + 257 .L8: + 39:automat.c **** } + 40:automat.c **** stan->klGora_on++; + 259 .LM18: + 260 0046 9F5F subi r25,lo8(-(1)) + 261 0048 9083 st Z,r25 + 41:automat.c **** stan->klGora_off = 0; + 263 .LM19: + 264 004a 1282 std Z+2,__zero_reg__ + 265 .L4: + 42:automat.c **** } + 43:automat.c **** + 44:automat.c **** if (klDolOff) + 267 .LM20: + 268 004c 6623 tst r22 + 269 004e 01F0 breq .L9 + 45:automat.c **** { + 46:automat.c **** if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + 271 .LM21: + 272 0050 2481 ldd r18,Z+4 + 273 0052 9381 ldd r25,Z+3 + 274 0054 2430 cpi r18,lo8(4) + 275 0056 01F4 brne .L10 + 277 .LM22: + 278 0058 9530 cpi r25,lo8(5) + 279 005a 01F4 brne .L10 + 47:automat.c **** { + 48:automat.c **** stan->czynnosc = bezczynny; + 281 .LM23: + 282 005c 1482 std Z+4,__zero_reg__ + 49:automat.c **** wiadomosc = 0x40; + 284 .LM24: + 285 005e 80E4 ldi r24,lo8(64) + 286 .L10: + 50:automat.c **** } + 51:automat.c **** stan->klDol_on = 0; + 288 .LM25: + 289 0060 1182 std Z+1,__zero_reg__ + 52:automat.c **** stan->klDol_off++; + 291 .LM26: + 292 0062 9F5F subi r25,lo8(-(1)) + 293 0064 9383 std Z+3,r25 + 294 0066 00C0 rjmp .L11 + 295 .L9: + 53:automat.c **** } + 54:automat.c **** else + 55:automat.c **** { + 56:automat.c **** if (stan->klDol_on == T_START) + 297 .LM27: + 298 0068 9181 ldd r25,Z+1 + 299 006a 9530 cpi r25,lo8(5) + 300 006c 01F4 brne .L12 + 57:automat.c **** { + 58:automat.c **** if (stan->czynnosc != bezczynny) + 302 .LM28: + 303 006e 8481 ldd r24,Z+4 + 304 0070 8823 tst r24 + 305 0072 01F0 breq .L13 + 59:automat.c **** { + 60:automat.c **** stan->czynnosc = bezczynny; + 307 .LM29: + 308 0074 1482 std Z+4,__zero_reg__ + 61:automat.c **** wiadomosc = 0x40; + 310 .LM30: + 311 0076 80E4 ldi r24,lo8(64) + 312 0078 00C0 rjmp .L15 + 313 .L13: + 62:automat.c **** } + 63:automat.c **** else + 64:automat.c **** { + 65:automat.c **** stan->czynnosc = do_konca_w_dol; + 315 .LM31: + 316 007a 82E0 ldi r24,lo8(2) + 317 007c 8483 std Z+4,r24 + 66:automat.c **** wiadomosc = 0x3F; + 319 .LM32: + 320 007e 8FE3 ldi r24,lo8(63) + 321 0080 00C0 rjmp .L15 + 322 .L12: + 67:automat.c **** } + 68:automat.c **** } + 69:automat.c **** if (stan->klDol_on == T_START_CONT) + 324 .LM33: + 325 0082 9832 cpi r25,lo8(40) + 326 0084 01F4 brne .L15 + 70:automat.c **** { + 71:automat.c **** stan->czynnosc = w_dol; + 328 .LM34: + 329 0086 24E0 ldi r18,lo8(4) + 330 0088 2483 std Z+4,r18 + 331 .L15: + 72:automat.c **** } + 73:automat.c **** stan->klDol_on++; + 333 .LM35: + 334 008a 9F5F subi r25,lo8(-(1)) + 335 008c 9183 std Z+1,r25 + 74:automat.c **** stan->klDol_off = 0; + 337 .LM36: + 338 008e 1382 std Z+3,__zero_reg__ + 339 .L11: + 75:automat.c **** } + 76:automat.c **** + 77:automat.c **** if (stan->klDol_on == 255) + 341 .LM37: + 342 0090 9181 ldd r25,Z+1 + 343 0092 9F3F cpi r25,lo8(-1) + 344 0094 01F4 brne .L16 + 78:automat.c **** stan->klDol_on = 254; + 346 .LM38: + 347 0096 9EEF ldi r25,lo8(-2) + 348 0098 9183 std Z+1,r25 + 349 .L16: + 79:automat.c **** if (stan->klGora_on == 255) + 351 .LM39: + 352 009a 9081 ld r25,Z + 353 009c 9F3F cpi r25,lo8(-1) + 354 009e 01F4 brne .L17 + 80:automat.c **** stan->klGora_on = 254; + 356 .LM40: + 357 00a0 9EEF ldi r25,lo8(-2) + 358 00a2 9083 st Z,r25 + 359 .L17: + 81:automat.c **** + 82:automat.c **** if (stan->klDol_off == 255) + 361 .LM41: + 362 00a4 9381 ldd r25,Z+3 + 363 00a6 9F3F cpi r25,lo8(-1) + 364 00a8 01F4 brne .L18 + 83:automat.c **** stan->klDol_off = 254; + 366 .LM42: + 367 00aa 9EEF ldi r25,lo8(-2) + 368 00ac 9383 std Z+3,r25 + 369 .L18: + 84:automat.c **** if (stan->klGora_off == 255) + 371 .LM43: + 372 00ae 9281 ldd r25,Z+2 + 373 00b0 9F3F cpi r25,lo8(-1) + 374 00b2 01F4 brne .L19 + 85:automat.c **** stan->klGora_off = 254; + 376 .LM44: + 377 00b4 9EEF ldi r25,lo8(-2) + 378 00b6 9283 std Z+2,r25 + 379 .L19: + 86:automat.c **** + 87:automat.c **** return wiadomosc; + 88:automat.c **** } + 381 .LM45: + 382 00b8 0895 ret + 387 .Lscope1: + 389 .stabd 78,0,0 + 391 .Letext0: + 392 .ident "GCC: (GNU) 4.9.2" +DEFINED SYMBOLS + *ABS*:0000000000000000 automat.c + /tmp/ccMWipl3.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccMWipl3.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccMWipl3.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccMWipl3.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccMWipl3.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccMWipl3.s:173 .text:0000000000000000 automatStanowKlawiszy + +NO UNDEFINED SYMBOLS diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/avrdude.conf b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/avrdude.conf new file mode 100644 index 0000000..1c44994 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/avrdude.conf @@ -0,0 +1,14885 @@ +# $Id: avrdude.conf.in 1360 2015-10-31 20:50:52Z joerg_wunsch $ -*- text -*- +# +# AVRDUDE Configuration File +# +# This file contains configuration data used by AVRDUDE which describes +# the programming hardware pinouts and also provides part definitions. +# AVRDUDE's "-C" command line option specifies the location of the +# configuration file. The "-c" option names the programmer configuration +# which must match one of the entry's "id" parameter. The "-p" option +# identifies which part AVRDUDE is going to be programming and must match +# one of the parts' "id" parameter. +# +# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next +# time a "make install" is run. For user-specific additions, use the +# "-C +filename" commandline option. +# +# Possible entry formats are: +# +# programmer +# parent # optional parent +# id = [, [, ] ...] ; # are quoted strings +# desc = ; # quoted string +# type = ; # programmer type, quoted string +# # supported programmer types can be listed by "-c ?type" +# connection_type = parallel | serial | usb +# baudrate = ; # baudrate for avr910-programmer +# vcc = [, ... ] ; # pin number(s) +# buff = [, ... ] ; # pin number(s) +# reset = ; # pin number +# sck = ; # pin number +# mosi = ; # pin number +# miso = ; # pin number +# errled = ; # pin number +# rdyled = ; # pin number +# pgmled = ; # pin number +# vfyled = ; # pin number +# usbvid = ; # USB VID (Vendor ID) +# usbpid = [, ...] # USB PID (Product ID) (1) +# usbdev = ; # USB interface or other device info +# usbvendor = ; # USB Vendor Name +# usbproduct = ; # USB Product Name +# usbsn = ; # USB Serial Number +# +# To invert a bit, use = ~ , the spaces are important. +# For a pin list all pins must be inverted. +# A single pin can be specified as usual = ~ , for lists +# specify it as follows = ~ ( [, ... ] ) . +# +# (1) Not all programmer types can process a list of PIDs. +# ; +# +# part +# id = ; # quoted string +# desc = ; # quoted string +# has_jtag = ; # part has JTAG i/f +# has_debugwire = ; # part has debugWire i/f +# has_pdi = ; # part has PDI i/f +# has_tpi = ; # part has TPI i/f +# devicecode = ; # deprecated, use stk500_devcode +# stk500_devcode = ; # numeric +# avr910_devcode = ; # numeric +# signature = ; # signature bytes +# usbpid = ; # DFU USB PID +# chip_erase_delay = ; # micro-seconds +# reset = dedicated | io; +# retry_pulse = reset | sck; +# pgm_enable = ; +# chip_erase = ; +# chip_erase_delay = ; # chip erase delay (us) +# # STK500 parameters (parallel programming IO lines) +# pagel = ; # pin name in hex, i.e., 0xD7 +# bs2 = ; # pin name in hex, i.e., 0xA0 +# serial = ; # can use serial downloading +# parallel = ; # can use par. programming +# # STK500v2 parameters, to be taken from Atmel's XML files +# timeout = ; +# stabdelay = ; +# cmdexedelay = ; +# synchloops = ; +# bytedelay = ; +# pollvalue = ; +# pollindex = ; +# predelay = ; +# postdelay = ; +# pollmethod = ; +# mode = ; +# delay = ; +# blocksize = ; +# readsize = ; +# hvspcmdexedelay = ; +# # STK500v2 HV programming parameters, from XML +# pp_controlstack = , , ...; # PP only +# hvsp_controlstack = , , ...; # HVSP only +# hventerstabdelay = ; +# progmodedelay = ; # PP only +# latchcycles = ; +# togglevtg = ; +# poweroffdelay = ; +# resetdelayms = ; +# resetdelayus = ; +# hvleavestabdelay = ; +# resetdelay = ; +# synchcycles = ; # HVSP only +# chiperasepulsewidth = ; # PP only +# chiperasepolltimeout = ; +# chiperasetime = ; # HVSP only +# programfusepulsewidth = ; # PP only +# programfusepolltimeout = ; +# programlockpulsewidth = ; # PP only +# programlockpolltimeout = ; +# # JTAG ICE mkII parameters, also from XML files +# allowfullpagebitstream = ; +# enablepageprogramming = ; +# idr = ; # IO addr of IDR (OCD) reg. +# rampz = ; # IO addr of RAMPZ reg. +# spmcr = ; # mem addr of SPMC[S]R reg. +# eecr = ; # mem addr of EECR reg. +# # (only when != 0x3c) +# is_at90s1200 = ; # AT90S1200 part +# is_avr32 = ; # AVR32 part +# +# memory +# paged = ; # yes / no +# size = ; # bytes +# page_size = ; # bytes +# num_pages = ; # numeric +# min_write_delay = ; # micro-seconds +# max_write_delay = ; # micro-seconds +# readback_p1 = ; # byte value +# readback_p2 = ; # byte value +# pwroff_after_write = ; # yes / no +# read = ; +# write = ; +# read_lo = ; +# read_hi = ; +# write_lo = ; +# write_hi = ; +# loadpage_lo = ; +# loadpage_hi = ; +# writepage = ; +# ; +# ; +# +# If any of the above parameters are not specified, the default value +# of 0 is used for numerics or the empty string ("") for string +# values. If a required parameter is left empty, AVRDUDE will +# complain. +# +# Parts can also inherit parameters from previously defined parts +# using the following syntax. In this case specified integer and +# string values override parameter values from the parent part. New +# memory definitions are added to the definitions inherited from the +# parent. +# +# part parent # quoted string +# id = ; # quoted string +# +# ; +# +# NOTES: +# * 'devicecode' is the device code used by the STK500 (see codes +# listed below) +# * Not all memory types will implement all instructions. +# * AVR Fuse bits and Lock bits are implemented as a type of memory. +# * Example memory types are: +# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high +# fuse), "signature", "calibration", "lock" +# * The memory type specified on the avrdude command line must match +# one of the memory types defined for the specified chip. +# * The pwroff_after_write flag causes avrdude to attempt to +# power the device off and back on after an unsuccessful write to +# the affected memory area if VCC programmer pins are defined. If +# VCC pins are not defined for the programmer, a message +# indicating that the device needs a power-cycle is printed out. +# This flag was added to work around a problem with the +# at90s4433/2333's; see the at90s4433 errata at: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf +# +# INSTRUCTION FORMATS +# +# Instruction formats are specified as a comma seperated list of +# string values containing information (bit specifiers) about each +# of the 32 bits of the instruction. Bit specifiers may be one of +# the following formats: +# +# '1' = the bit is always set on input as well as output +# +# '0' = the bit is always clear on input as well as output +# +# 'x' = the bit is ignored on input and output +# +# 'a' = the bit is an address bit, the bit-number matches this bit +# specifier's position within the current instruction byte +# +# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12 +# is address bit 12 on input, a0 is address bit 0. +# +# 'i' = the bit is an input data bit +# +# 'o' = the bit is an output data bit +# +# Each instruction must be composed of 32 bit specifiers. The +# instruction specification closely follows the instruction data +# provided in Atmel's data sheets for their parts. +# +# See below for some examples. +# +# +# The following are STK500 part device codes to use for the +# "devicecode" field of the part. These came from Atmel's software +# section avr061.zip which accompanies the application note +# AVR061 available from: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf +# + +#define ATTINY10 0x10 /* the _old_ one that never existed! */ +#define ATTINY11 0x11 +#define ATTINY12 0x12 +#define ATTINY15 0x13 +#define ATTINY13 0x14 + +#define ATTINY22 0x20 +#define ATTINY26 0x21 +#define ATTINY28 0x22 +#define ATTINY2313 0x23 + +#define AT90S1200 0x33 + +#define AT90S2313 0x40 +#define AT90S2323 0x41 +#define AT90S2333 0x42 +#define AT90S2343 0x43 + +#define AT90S4414 0x50 +#define AT90S4433 0x51 +#define AT90S4434 0x52 +#define ATMEGA48 0x59 + +#define AT90S8515 0x60 +#define AT90S8535 0x61 +#define AT90C8534 0x62 +#define ATMEGA8515 0x63 +#define ATMEGA8535 0x64 + +#define ATMEGA8 0x70 +#define ATMEGA88 0x73 +#define ATMEGA168 0x86 + +#define ATMEGA161 0x80 +#define ATMEGA163 0x81 +#define ATMEGA16 0x82 +#define ATMEGA162 0x83 +#define ATMEGA169 0x84 + +#define ATMEGA323 0x90 +#define ATMEGA32 0x91 + +#define ATMEGA64 0xA0 + +#define ATMEGA103 0xB1 +#define ATMEGA128 0xB2 +#define AT90CAN128 0xB3 +#define AT90CAN64 0xB3 +#define AT90CAN32 0xB3 + +#define AT86RF401 0xD0 + +#define AT89START 0xE0 +#define AT89S51 0xE0 +#define AT89S52 0xE1 + +# The following table lists the devices in the original AVR910 +# appnote: +# |Device |Signature | Code | +# +-------+----------+------+ +# |tiny12 | 1E 90 05 | 0x55 | +# |tiny15 | 1E 90 06 | 0x56 | +# | | | | +# | S1200 | 1E 90 01 | 0x13 | +# | | | | +# | S2313 | 1E 91 01 | 0x20 | +# | S2323 | 1E 91 02 | 0x48 | +# | S2333 | 1E 91 05 | 0x34 | +# | S2343 | 1E 91 03 | 0x4C | +# | | | | +# | S4414 | 1E 92 01 | 0x28 | +# | S4433 | 1E 92 03 | 0x30 | +# | S4434 | 1E 92 02 | 0x6C | +# | | | | +# | S8515 | 1E 93 01 | 0x38 | +# | S8535 | 1E 93 03 | 0x68 | +# | | | | +# |mega32 | 1E 95 01 | 0x72 | +# |mega83 | 1E 93 05 | 0x65 | +# |mega103| 1E 97 01 | 0x41 | +# |mega161| 1E 94 01 | 0x60 | +# |mega163| 1E 94 02 | 0x64 | + +# Appnote AVR109 also has a table of AVR910 device codes, which +# lists: +# dev avr910 signature +# ATmega8 0x77 0x1E 0x93 0x07 +# ATmega8515 0x3B 0x1E 0x93 0x06 +# ATmega8535 0x6A 0x1E 0x93 0x08 +# ATmega16 0x75 0x1E 0x94 0x03 +# ATmega162 0x63 0x1E 0x94 0x04 +# ATmega163 0x66 0x1E 0x94 0x02 +# ATmega169 0x79 0x1E 0x94 0x05 +# ATmega32 0x7F 0x1E 0x95 0x02 +# ATmega323 0x73 0x1E 0x95 0x01 +# ATmega64 0x46 0x1E 0x96 0x02 +# ATmega128 0x44 0x1E 0x97 0x02 +# +# These codes refer to "BOOT" device codes which are apparently +# different than standard device codes, for whatever reasons +# (often one above the standard code). + +# There are several extended versions of AVR910 implementations around +# in the Internet. These add the following codes (only devices that +# actually exist are listed): + +# ATmega8515 0x3A +# ATmega128 0x43 +# ATmega64 0x45 +# ATtiny26 0x5E +# ATmega8535 0x69 +# ATmega32 0x72 +# ATmega16 0x74 +# ATmega8 0x76 +# ATmega169 0x78 + +# +# Overall avrdude defaults; suitable for ~/.avrduderc +# +default_parallel = "/dev/parport0"; +default_serial = "/dev/ttyS0"; +# default_bitclock = 2.5; + +# Turn off safemode by default +#default_safemode = no; + + +# +# PROGRAMMER DEFINITIONS +# + +# http://wiring.org.co/ +# Basically STK500v2 protocol, with some glue to trigger the +# bootloader. +programmer + id = "wiring"; + desc = "Wiring"; + type = "wiring"; + connection_type = serial; +; + +programmer + id = "arduino"; + desc = "Arduino"; + type = "arduino"; + connection_type = serial; +; +# this will interface with the chips on these programmers: +# +# http://real.kiev.ua/old/avreal/en/adapters +# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml +# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html +# http://www.ethernut.de/en/hardware/turtelizer/index.html +# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html +# http://dangerousprototypes.com/docs/FT2232_breakout_board +# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H +# http://flashrom.org/FT2232SPI_Programmer +# +# The drivers will look for a specific device and use the first one found. +# If you have mulitple devices, then look for unique information (like SN) +# And fill that in here. +# +# Note that the pin numbers for the main ISP signals (reset, sck, +# mosi, miso) are fixed and cannot be changed, since they must match +# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of +# these FTDI ICs has been designed. + +programmer + id = "avrftdi"; + desc = "FT2232D based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x6010; + usbvendor = ""; + usbproduct = ""; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ADBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +#LED SIGNALs - higher ADBUS-Nibble +# errled = 4; +# rdyled = 5; +# pgmled = 6; +# vfyled = 7; +#Buffer Signal - ACBUS - Nibble +# buff = 8; +; +# This is an implementation of the above with a buffer IC (74AC244) and +# 4 LEDs directly attached, all active low. +programmer + id = "2232HIO"; + desc = "FT2232H based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is reserved for generic H devices and +# should be programmed into the EEPROM +# usbpid = 0x8A48; + usbpid = 0x6010; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + reset = 3; + sck = 0; + mosi = 1; + miso = 2; + buff = ~4; +#LED SIGNALs + errled = ~ 11; + rdyled = ~ 14; + pgmled = ~ 13; + vfyled = ~ 12; +; + +#The FT4232H can be treated as FT2232H, but it has a different USB +#device ID of 0x6011. +programmer parent "avrftdi" + id = "4232h"; + desc = "FT4232H based generic programmer"; + usbpid = 0x6011; +; + +programmer parent "4232h" + id = "usbMultiToolV2spi"; + desc = "Avr MultiTool v2 SPI"; + usbdev = "B"; +; + +programmer + id = "usbMultiToolV2jtag"; + desc = "Avr MultiTool v2 JTAG"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x6011; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; + reset = 3; # TMS 7 violet + sck = 0; # TCK 9 white + mosi = 1; # TDI 5 green + miso = 2; # TDO 13 orange +; + + + +programmer + id = "jtagkey"; + desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is used in all JTAGKey variants + usbpid = 0xCFF8; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals => 20 - Pin connector on JTAGKey + reset = 3; # TMS 7 violet + sck = 0; # TCK 9 white + mosi = 1; # TDI 5 green + miso = 2; # TDO 13 orange + buff = ~4; +# VTG VREF 1 brown with red tip +# GND GND 20 black +# The colors are on the 20 pin breakout cable +# from Amontec +; + +# UM232H module from FTDI and Glyn.com.au. +# See helix.air.net.au for detailed usage information. +# J1: Connect pin 2 and 3 for USB power. +# J2: Connect pin 2 and 3 for USB power. +# J2: Pin 7 is SCK +# : Pin 8 is MOSI +# : Pin 9 is MISO +# : Pin 11 is RST +# : Pin 6 is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "UM232H"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + +# C232HM module from FTDI and Glyn.com.au. +# : Orange is SCK +# : Yellow is MOSI +# : Green is MISO +# : Brown is RST +# : Black is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "C232HM"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + + +# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1" +# You can find it as "OpenJTAG ARM JTAG USB" in the internet. +# (But there are also several projects called Open JTAG, eg. +# http://www.openjtag.org, which are completely different.) +# http://www.100ask.net/shop/english.html (website seems to be outdated) +# http://item.taobao.com/item.htm?id=1559277013 +# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!) +# some other sources which call it O-Link +# http://www.andahammer.com/olink/ +# http://www.developmentboard.net/31-o-link-debugger.html +# http://armwerks.com/catalog/o-link-debugger-copy/ +# or just have a look at ebay ... +# It is basically the same entry as jtagkey with different usb ids. +programmer parent "jtagkey" + id = "o-link"; + desc = "O-Link, OpenJTAG from www.100ask.net"; + usbvid = 0x1457; + usbpid = 0x5118; + usbvendor = "www.100ask.net"; + usbproduct = "USB<=>JTAG&RS232"; +; + +# http://wiki.openmoko.org/wiki/Debug_Board_v3 +programmer + id = "openmoko"; + desc = "Openmoko debug board (v3)"; + type = "avrftdi"; + usbvid = 0x1457; + usbpid = 0x5118; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; + reset = 3; # TMS 7 + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 +; + +# Only Rev. A boards. +# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf +programmer + id = "lm3s811"; + desc = "Luminary Micro LM3S811 Eval Board (Rev. A)"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0xbcd9; + usbvendor = "LMI"; + usbproduct = "LM3S811 Evaluation Board"; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ACBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +# Enable correct buffers + buff = 7; +; + +# submitted as bug #46020 +programmer + id = "tumpa"; + desc = "TIAO USB Multi-Protocol Adapter"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x8A98; + usbdev = "A"; + usbvendor = "TIAO"; + usbproduct = ""; + usbsn = ""; + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 + reset = 3; # TMS 7 +; + +programmer + id = "avrisp"; + desc = "Atmel AVR ISP"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "avrispv2"; + desc = "Atmel AVR ISP V2"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "avrispmkII"; + desc = "Atmel AVR ISP mkII"; + type = "stk500v2"; + connection_type = usb; +; + +programmer parent "avrispmkII" + id = "avrisp2"; +; + +programmer + id = "buspirate"; + desc = "The Bus Pirate"; + type = "buspirate"; + connection_type = serial; +; + +programmer + id = "buspirate_bb"; + desc = "The Bus Pirate (bitbang interface, supports TPI)"; + type = "buspirate_bb"; + connection_type = serial; + # pins are bits in bitbang byte (numbers are 87654321) + # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS + reset = 1; + sck = 3; + mosi = 4; + miso = 2; + #vcc = 7; This is internally set independent of this setting. +; + +# This is supposed to be the "default" STK500 entry. +# Attempts to select the correct firmware version +# by probing for it. Better use one of the entries +# below instead. +programmer + id = "stk500"; + desc = "Atmel STK500"; + type = "stk500generic"; + connection_type = serial; +; + +programmer + id = "stk500v1"; + desc = "Atmel STK500 Version 1.x firmware"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "mib510"; + desc = "Crossbow MIB510 programming board"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "stk500v2"; + desc = "Atmel STK500 Version 2.x firmware"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "stk500pp"; + desc = "Atmel STK500 V2 in parallel programming mode"; + type = "stk500pp"; + connection_type = serial; +; + +programmer + id = "stk500hvsp"; + desc = "Atmel STK500 V2 in high-voltage serial programming mode"; + type = "stk500hvsp"; + connection_type = serial; +; + +programmer + id = "stk600"; + desc = "Atmel STK600"; + type = "stk600"; + connection_type = usb; +; + +programmer + id = "stk600pp"; + desc = "Atmel STK600 in parallel programming mode"; + type = "stk600pp"; + connection_type = usb; +; + +programmer + id = "stk600hvsp"; + desc = "Atmel STK600 in high-voltage serial programming mode"; + type = "stk600hvsp"; + connection_type = usb; +; + +programmer + id = "avr910"; + desc = "Atmel Low Cost Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "ft245r"; + desc = "FT245R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # D1 + sck = 0; # D0 + mosi = 2; # D2 + reset = 4; # D4 +; + +programmer + id = "ft232r"; + desc = "FT232R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # RxD + sck = 0; # TxD + mosi = 2; # RTS + reset = 4; # DTR +; + +# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega +programmer + id = "bwmega"; + desc = "BitWizard ftdi_atmega builtin programmer"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 5; # DSR + sck = 6; # DCD + mosi = 3; # CTS + reset = 7; # RI +; + +# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html +# Note: pins are numbered from 1! +programmer + id = "arduino-ft232r"; + desc = "Arduino: FT232R connected to ISP"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # CTS X3(1) + sck = 5; # DSR X3(2) + mosi = 6; # DCD X3(3) + reset = 7; # RI X3(4) +; + +# website mentioned above uses this id +programmer parent "arduino-ft232r" + id = "diecimila"; + desc = "alias for arduino-ft232r"; +; + +# There is a ATmega328P kit PCB called "uncompatino". +# This board allows ISP via its on-board FT232R. +# This is designed like Arduino Duemilanove but has no standard ICPS header. +# Its 4 pairs of pins are shorted to enable ftdi_syncbb. +# http://akizukidenshi.com/catalog/g/gP-07487/ +# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf +programmer + id = "uncompatino"; + desc = "uncompatino with all pairs of pins shorted"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # cts + sck = 5; # dsr + mosi = 6; # dcd + reset = 7; # ri +; + +# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP +# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm +# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf +# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf +# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...) +# TTL-232R GND 1 Black -> ICPS GND (pin 6) +# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4) +# TTL-232R VCC 3 Red -> ICPS VCC (pin 2) +# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5) +# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3) +# TTL-232R RTS 6 Green -> ICPS MISO (pin 1) +# Except for VCC and GND, you can connect arbitual pairs as long as +# the following table is adjusted. +programmer + id = "ttl232r"; + desc = "FTDI TTL232R-5V with ICSP adapter"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 2; # rts + sck = 1; # rxd + mosi = 3; # cts + reset = 0; # txd +; + +programmer + id = "usbasp"; + desc = "USBasp, http://www.fischl.de/usbasp/"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + usbvendor = "www.fischl.de"; + usbproduct = "USBasp"; + + # following variants are autodetected for id "usbasp" + + # original usbasp from fischl.de + # see above "usbasp" + + # old usbasp from fischl.de + #usbvid = 0x03EB; # ATMEL + #usbpid = 0xC7B4; # (unoffical) USBasp + #usbvendor = "www.fischl.de"; + #usbproduct = "USBasp"; + + # NIBObee (only if -P nibobee is given on command line) + # see below "nibobee" +; + +programmer + id = "nibobee"; + desc = "NIBObee"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x092F; # NIBObee PID + usbvendor = "www.nicai-systems.com"; + usbproduct = "NIBObee"; +; + +programmer + id = "usbasp-clone"; + desc = "Any usbasp clone with correct VID/PID"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + #usbvendor = ""; + #usbproduct = ""; +; + +programmer + id = "usbtiny"; + desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + type = "usbtiny"; + connection_type = usb; + usbvid = 0x1781; + usbpid = 0x0c9f; +; + +programmer + id = "butterfly"; + desc = "Atmel Butterfly Development Board"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr911"; + desc = "Atmel AppNote AVR911 AVROSP"; + type = "butterfly"; + connection_type = serial; +; + +# suggested in http://forum.mikrokopter.de/topic-post48317.html +programmer + id = "mkbutterfly"; + desc = "Mikrokopter.de Butterfly"; + type = "butterfly_mk"; + connection_type = serial; +; + +programmer parent "mkbutterfly" + id = "butterfly_mk"; +; + +programmer + id = "jtagmkI"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 115200; # default is 115200 + type = "jtagmki"; + connection_type = serial; +; + +# easier to type +programmer parent "jtagmkI" + id = "jtag1"; +; + +# easier to type +programmer parent "jtag1" + id = "jtag1slow"; + baudrate = 19200; +; + +# The JTAG ICE mkII has both, serial and USB connectivity. As it is +# mostly used through USB these days (AVR Studio 5 only supporting it +# that way), we make connection_type = usb the default. Users are +# still free to use a serial port with the -P option. + +programmer + id = "jtagmkII"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 19200; # default is 19200 + type = "jtagmkii"; + connection_type = usb; +; + +# easier to type +programmer parent "jtagmkII" + id = "jtag2slow"; +; + +# JTAG ICE mkII @ 115200 Bd +programmer parent "jtag2slow" + id = "jtag2fast"; + baudrate = 115200; +; + +# make the fast one the default, people will love that +programmer parent "jtag2fast" + id = "jtag2"; +; + +# JTAG ICE mkII in ISP mode +programmer + id = "jtag2isp"; + desc = "Atmel JTAG ICE mkII in ISP mode"; + baudrate = 115200; + type = "jtagmkii_isp"; + connection_type = usb; +; + +# JTAG ICE mkII in debugWire mode +programmer + id = "jtag2dw"; + desc = "Atmel JTAG ICE mkII in debugWire mode"; + baudrate = 115200; + type = "jtagmkii_dw"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtagmkII_avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtag2avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in PDI mode +programmer + id = "jtag2pdi"; + desc = "Atmel JTAG ICE mkII PDI mode"; + baudrate = 115200; + type = "jtagmkii_pdi"; + connection_type = usb; +; + +# AVR Dragon in JTAG mode +programmer + id = "dragon_jtag"; + desc = "Atmel AVR Dragon in JTAG mode"; + baudrate = 115200; + type = "dragon_jtag"; + connection_type = usb; +; + +# AVR Dragon in ISP mode +programmer + id = "dragon_isp"; + desc = "Atmel AVR Dragon in ISP mode"; + baudrate = 115200; + type = "dragon_isp"; + connection_type = usb; +; + +# AVR Dragon in PP mode +programmer + id = "dragon_pp"; + desc = "Atmel AVR Dragon in PP mode"; + baudrate = 115200; + type = "dragon_pp"; + connection_type = usb; +; + +# AVR Dragon in HVSP mode +programmer + id = "dragon_hvsp"; + desc = "Atmel AVR Dragon in HVSP mode"; + baudrate = 115200; + type = "dragon_hvsp"; + connection_type = usb; +; + +# AVR Dragon in debugWire mode +programmer + id = "dragon_dw"; + desc = "Atmel AVR Dragon in debugWire mode"; + baudrate = 115200; + type = "dragon_dw"; + connection_type = usb; +; + +# AVR Dragon in PDI mode +programmer + id = "dragon_pdi"; + desc = "Atmel AVR Dragon in PDI mode"; + baudrate = 115200; + type = "dragon_pdi"; + connection_type = usb; +; + +programmer + id = "jtag3"; + desc = "Atmel AVR JTAGICE3 in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3pdi"; + desc = "Atmel AVR JTAGICE3 in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3dw"; + desc = "Atmel AVR JTAGICE3 in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3isp"; + desc = "Atmel AVR JTAGICE3 in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "xplainedpro"; + desc = "Atmel AVR XplainedPro in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2111; +; + +programmer + id = "atmelice"; + desc = "Atmel-ICE (ARM/AVR) in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_pdi"; + desc = "Atmel-ICE (ARM/AVR) in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_dw"; + desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_isp"; + desc = "Atmel-ICE (ARM/AVR) in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2141; +; + + +programmer + id = "pavr"; + desc = "Jason Kyle's pAVR Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "pickit2"; + desc = "MicroChip's PICkit2 Programmer"; + type = "pickit2"; + connection_type = usb; +; + +programmer + id = "flip1"; + desc = "FLIP USB DFU protocol version 1 (doc7618)"; + type = "flip1"; + connection_type = usb; +; + +programmer + id = "flip2"; + desc = "FLIP USB DFU protocol version 2 (AVR4023)"; + type = "flip2"; + connection_type = usb; +; + +# Parallel port programmers. + +programmer + id = "bsd"; + desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; +; + +programmer + id = "stk200"; + desc = "STK200"; + type = "par"; + connection_type = parallel; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; +; + +# The programming dongle used by the popular Ponyprog +# utility. It is almost similar to the STK200 one, +# except that there is a LED indicating that the +# programming is currently in progress. + +programmer parent "stk200" + id = "pony-stk200"; + desc = "Pony Prog STK200"; + pgmled = 8; +; + +programmer + id = "dt006"; + desc = "Dontronics DT006"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer parent "dt006" + id = "bascom"; + desc = "Bascom SAMPLE programming cable"; +; + +programmer + id = "alf"; + desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + buff = 6; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; + errled = 1; + rdyled = 14; + pgmled = 16; + vfyled = 17; +; + +programmer + id = "sp12"; + desc = "Steve Bolt's Programmer"; + type = "par"; + connection_type = parallel; + vcc = 4,5,6,7,8; + reset = 3; + sck = 2; + mosi = 9; + miso = 11; +; + +programmer + id = "picoweb"; + desc = "Picoweb Programming Cable, http://www.picoweb.net/"; + type = "par"; + connection_type = parallel; + reset = 2; + sck = 3; + mosi = 4; + miso = 13; +; + +programmer + id = "abcmini"; + desc = "ABCmini Board, aka Dick Smith HOTCHIP"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "futurlec"; + desc = "Futurlec.com programming cable."; + type = "par"; + connection_type = parallel; + reset = 3; + sck = 2; + mosi = 1; + miso = 10; +; + + +# From the contributor of the "xil" jtag cable: +# The "vcc" definition isn't really vcc (the cable gets its power from +# the programming circuit) but is necessary to switch one of the +# buffer lines (trying to add it to the "buff" lines doesn't work in +# avrdude versions before 5.5j). +# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK +# to SCK (plus vcc/gnd of course) +programmer + id = "xil"; + desc = "Xilinx JTAG cable"; + type = "par"; + connection_type = parallel; + mosi = 2; + sck = 3; + reset = 4; + buff = 5; + miso = 13; + vcc = 6; +; + + +programmer + id = "dapa"; + desc = "Direct AVR Parallel Access cable"; + type = "par"; + connection_type = parallel; + vcc = 3; + reset = 16; + sck = 1; + mosi = 2; + miso = 11; +; + +programmer + id = "atisp"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + type = "par"; + connection_type = parallel; + reset = ~6; + sck = ~8; + mosi = ~7; + miso = ~10; +; + +programmer + id = "ere-isp-avr"; + desc = "ERE ISP-AVR "; + type = "par"; + connection_type = parallel; + reset = ~4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "blaster"; + desc = "Altera ByteBlaster"; + type = "par"; + connection_type = parallel; + sck = 2; + miso = 11; + reset = 3; + mosi = 8; + buff = 14; +; + +# It is almost same as pony-stk200, except vcc on pin 5 to auto +# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27) +programmer parent "pony-stk200" + id = "frank-stk200"; + desc = "Frank STK200"; + buff = ; # delete buff pin assignment + vcc = 5; +; + +# The AT98ISP Cable is a simple parallel dongle for AT89 family. +# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +programmer + id = "89isp"; + desc = "Atmel at89isp cable"; + type = "par"; + connection_type = parallel; + reset = 17; + sck = 1; + mosi = 2; + miso = 10; +; + + +#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface +# +#To enable it set the configuration below to match the GPIO lines connected to the +#relevant ISP header pins and uncomment the entry definition. In case you don't +#have the required permissions to edit this system wide config file put the +#entry in a separate .conf file and use it with -C+.conf +#on the command line. +# +#To check if your avrdude build has support for the linuxgpio programmer compiled in, +#use -c?type on the command line and look for linuxgpio in the list. If it's not available +#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude. +# +#programmer +# id = "linuxgpio"; +# desc = "Use the Linux sysfs interface to bitbang GPIO lines"; +# type = "linuxgpio"; +# reset = ?; +# sck = ?; +# mosi = ?; +# miso = ?; +#; + +# some ultra cheap programmers use bitbanging on the +# serialport. +# +# PC - DB9 - Pins for RS232: +# +# GND 5 -- |O +# | O| <- 9 RI +# DTR 4 <- |O | +# | O| <- 8 CTS +# TXD 3 <- |O | +# | O| -> 7 RTS +# RXD 2 -> |O | +# | O| <- 6 DSR +# DCD 1 -> |O +# +# Using RXD is currently not supported. +# Using RI is not supported under Win32 but is supported under Posix. + +# serial ponyprog design (dasa2 in uisp) +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer + id = "ponyser"; + desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~3; + sck = 7; + mosi = 4; + miso = 8; +; + +# Same as above, different name +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer parent "ponyser" + id = "siprog"; + desc = "Lancos SI-Prog "; +; + +# unknown (dasa in uisp) +# reset=rts sck=dtr mosi=txd miso=cts + +programmer + id = "dasa"; + desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = 7; + sck = 4; + mosi = 3; + miso = 8; +; + +# unknown (dasa3 in uisp) +# reset=!dtr sck=rts mosi=txd miso=cts + +programmer + id = "dasa3"; + desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~4; + sck = 7; + mosi = 3; + miso = 8; +; + +# C2N232i (jumper configuration "auto") +# reset=dtr sck=!rts mosi=!txd miso=!cts + +programmer + id = "c2n232i"; + desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts"; + type = "serbb"; + connection_type = serial; + reset = 4; + sck = ~7; + mosi = ~3; + miso = ~8; +; + +# +# PART DEFINITIONS +# + +#------------------------------------------------------------ +# ATtiny11 +#------------------------------------------------------------ + +# This is an HVSP-only device. + +part + id = "t11"; + desc = "ATtiny11"; + stk500_devcode = 0x11; + signature = 0x1e 0x90 0x04; + chip_erase_delay = 20000; + + timeout = 200; + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + blocksize = 64; + readsize = 256; + delay = 5; + ; + + memory "flash" + size = 1024; + blocksize = 128; + readsize = 256; + delay = 3; + ; + + memory "signature" + size = 3; + ; + + memory "lock" + size = 1; + ; + + memory "calibration" + size = 1; + ; + + memory "fuse" + size = 1; + ; +; + +#------------------------------------------------------------ +# ATtiny12 +#------------------------------------------------------------ + +part + id = "t12"; + desc = "ATtiny12"; + stk500_devcode = 0x12; + avr910_devcode = 0x55; + signature = 0x1e 0x90 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 8; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4500; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# ATtiny13 +#------------------------------------------------------------ + +part + id = "t13"; + desc = "ATtiny13"; + has_debugwire = yes; + flash_instr = 0xB4, 0x0E, 0x1E; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; + signature = 0x1e 0x90 0x07; + chip_erase_delay = 4000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 90; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 0; + + memory "eeprom" + size = 64; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 1024; + page_size = 32; + num_pages = 32; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny15 +#------------------------------------------------------------ + +part + id = "t15"; + desc = "ATtiny15"; + stk500_devcode = 0x13; + avr910_devcode = 0x56; + signature = 0x1e 0x90 0x06; + chip_erase_delay = 8200; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 5; + synchcycles = 6; + latchcycles = 16; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 8200; + max_write_delay = 8200; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4100; + max_write_delay = 4100; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o x x o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i 1 1 i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# AT90s1200 +#------------------------------------------------------------ + +part + id = "1200"; + desc = "AT90S1200"; + is_at90s1200 = yes; + stk500_devcode = 0x33; + avr910_devcode = 0x13; + signature = 0x1e 0x90 0x01; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 1; + bytedelay = 0; + pollindex = 0; + pollvalue = 0xFF; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 32; + readsize = 256; + ; + memory "flash" + size = 1024; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x02; + delay = 15; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4414 +#------------------------------------------------------------ + +part + id = "4414"; + desc = "AT90S4414"; + stk500_devcode = 0x50; + avr910_devcode = 0x28; + signature = 0x1e 0x92 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2313 +#------------------------------------------------------------ + +part + id = "2313"; + desc = "AT90S2313"; + stk500_devcode = 0x40; + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2333 +#------------------------------------------------------------ + +part + id = "2333"; +##### WARNING: No XML file for device 'AT90S2333'! ##### + desc = "AT90S2333"; + stk500_devcode = 0x42; + avr910_devcode = 0x34; + signature = 0x1e 0x91 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s2343 (also AT90s2323 and ATtiny22) +#------------------------------------------------------------ + +part + id = "2343"; + desc = "AT90S2343"; + stk500_devcode = 0x43; + avr910_devcode = 0x4c; + signature = 0x1e 0x91 0x03; + chip_erase_delay = 18000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 0; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 128; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s4433 +#------------------------------------------------------------ + +part + id = "4433"; + desc = "AT90S4433"; + stk500_devcode = 0x51; + avr910_devcode = 0x30; + signature = 0x1e 0x92 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4434 +#------------------------------------------------------------ + +part + id = "4434"; +##### WARNING: No XML file for device 'AT90S4434'! ##### + desc = "AT90S4434"; + stk500_devcode = 0x52; + avr910_devcode = 0x6c; + signature = 0x1e 0x92 0x02; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8515 +#------------------------------------------------------------ + +part + id = "8515"; + desc = "AT90S8515"; + stk500_devcode = 0x60; + avr910_devcode = 0x38; + signature = 0x1e 0x93 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s8535 +#------------------------------------------------------------ + +part + id = "8535"; + desc = "AT90S8535"; + stk500_devcode = 0x61; + avr910_devcode = 0x68; + signature = 0x1e 0x93 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# ATmega103 +#------------------------------------------------------------ + +part + id = "m103"; + desc = "ATmega103"; + stk500_devcode = 0xB1; + avr910_devcode = 0x41; + signature = 0x1e 0x97 0x01; + chip_erase_delay = 112000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE, + 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE, + 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A, + 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 10; + + memory "eeprom" + size = 4096; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 22000; + max_write_delay = 56000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 70; + blocksize = 256; + readsize = 256; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o x o 1 o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega64 +#------------------------------------------------------------ + +part + id = "m64"; + desc = "ATmega64"; + has_jtag = yes; + stk500_devcode = 0xA0; + avr910_devcode = 0x45; + signature = 0x1e 0x96 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega128 +#------------------------------------------------------------ + +part + id = "m128"; + desc = "ATmega128"; + has_jtag = yes; + stk500_devcode = 0xB2; + avr910_devcode = 0x43; + signature = 0x1e 0x97 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + rampz = 0x3b; + allowfullpagebitstream = yes; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN128 +#------------------------------------------------------------ + +part + id = "c128"; + desc = "AT90CAN128"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x97 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN64 +#------------------------------------------------------------ + +part + id = "c64"; + desc = "AT90CAN64"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x96 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN32 +#------------------------------------------------------------ + +part + id = "c32"; + desc = "AT90CAN32"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x95 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 256; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega16 +#------------------------------------------------------------ + +part + id = "m16"; + desc = "ATmega16"; + has_jtag = yes; + stk500_devcode = 0x82; + avr910_devcode = 0x74; + signature = 0x1e 0x94 0x03; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 100; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "calibration" + size = 4; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega164P +#------------------------------------------------------------ + +# close to ATmega16 + +part parent "m16" + id = "m164p"; + desc = "ATmega164P"; + signature = 0x1e 0x94 0x0a; + + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + allowfullpagebitstream = no; + chip_erase_delay = 55000; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega324P +#------------------------------------------------------------ + +# similar to ATmega164P + +part + id = "m324p"; + desc = "ATmega324P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x95 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega324PA +#------------------------------------------------------------ + +# similar to ATmega324P + +part parent "m324p" + id = "m324pa"; + desc = "ATmega324PA"; + signature = 0x1e 0x95 0x11; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega644 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m644"; + desc = "ATmega644"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x96 0x09; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega644P +#------------------------------------------------------------ + +# similar to ATmega164p + +part parent "m644" + id = "m644p"; + desc = "ATmega644P"; + signature = 0x1e 0x96 0x0a; + + ocdrev = 3; + ; + + + +#------------------------------------------------------------ +# ATmega1284 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m1284"; + desc = "ATmega1284"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x06; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega1284P +#------------------------------------------------------------ + +# similar to ATmega164p + +part + id = "m1284p"; + desc = "ATmega1284P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x05; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega162 +#------------------------------------------------------------ + +part + id = "m162"; + desc = "ATmega162"; + has_jtag = yes; + stk500_devcode = 0x83; + avr910_devcode = 0x63; + signature = 0x1e 0x94 0x04; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + + idr = 0x04; + spmcr = 0x57; + allowfullpagebitstream = yes; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + ocdrev = 2; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + + ; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; +; + + + +#------------------------------------------------------------ +# ATmega163 +#------------------------------------------------------------ + +part + id = "m163"; + desc = "ATmega163"; + stk500_devcode = 0x81; + avr910_devcode = 0x64; + signature = 0x1e 0x94 0x02; + chip_erase_delay = 32000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 16000; + max_write_delay = 16000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 20; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o x x o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i 1 1 i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x 1 o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x 0 x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega169 +#------------------------------------------------------------ + +part + id = "m169"; + desc = "ATmega169"; + has_jtag = yes; + stk500_devcode = 0x85; + avr910_devcode = 0x78; + signature = 0x1e 0x94 0x05; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329 +#------------------------------------------------------------ + +part + id = "m329"; + desc = "ATmega329"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329P +#------------------------------------------------------------ +# Identical to ATmega329 except of the signature + +part parent "m329" + id = "m329p"; + desc = "ATmega329P"; + signature = 0x1e 0x95 0x0b; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290 +#------------------------------------------------------------ + +# identical to ATmega329 + +part parent "m329" + id = "m3290"; + desc = "ATmega3290"; + signature = 0x1e 0x95 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290P +#------------------------------------------------------------ + +# identical to ATmega3290 except of the signature + +part parent "m3290" + id = "m3290p"; + desc = "ATmega3290P"; + signature = 0x1e 0x95 0x0c; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega649 +#------------------------------------------------------------ + +part + id = "m649"; + desc = "ATmega649"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x96 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega6490 +#------------------------------------------------------------ + +# identical to ATmega649 + +part parent "m649" + id = "m6490"; + desc = "ATmega6490"; + signature = 0x1e 0x96 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega32 +#------------------------------------------------------------ + +part + id = "m32"; + desc = "ATmega32"; + has_jtag = yes; + stk500_devcode = 0x91; + avr910_devcode = 0x72; + signature = 0x1e 0x95 0x02; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega161 +#------------------------------------------------------------ + +part + id = "m161"; + desc = "ATmega161"; + stk500_devcode = 0x80; + avr910_devcode = 0x60; + signature = 0x1e 0x94 0x01; + chip_erase_delay = 28000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + memory "eeprom" + size = 512; + min_write_delay = 3400; + max_write_delay = 3400; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 14000; + max_write_delay = 14000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 16; + blocksize = 128; + readsize = 256; + ; + + memory "fuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x o x o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x 1 i 1 i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega8 +#------------------------------------------------------------ + +part + id = "m8"; + desc = "ATmega8"; + stk500_devcode = 0x70; + avr910_devcode = 0x76; + signature = 0x1e 0x93 0x07; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 10000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + page_size = 4; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega8515 +#------------------------------------------------------------ + +part + id = "m8515"; + desc = "ATmega8515"; + stk500_devcode = 0x63; + avr910_devcode = 0x3A; + signature = 0x1e 0x93 0x06; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega8535 +#------------------------------------------------------------ + +part + id = "m8535"; + desc = "ATmega8535"; + stk500_devcode = 0x64; + avr910_devcode = 0x69; + signature = 0x1e 0x93 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny26 +#------------------------------------------------------------ + +part + id = "t26"; + desc = "ATtiny26"; + stk500_devcode = 0x21; + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x09; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 16; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x x x x i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny261 +#------------------------------------------------------------ +# Close to ATtiny26 + +part + id = "t261"; + desc = "ATtiny261"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0c; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 128; + page_size = 4; + num_pages = 32; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny461 +#------------------------------------------------------------ +# Close to ATtiny261 + +part + id = "t461"; + desc = "ATtiny461"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x08; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 256; + page_size = 4; + num_pages = 64; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny861 +#------------------------------------------------------------ +# Close to ATtiny461 + +part + id = "t861"; + desc = "ATtiny861"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x93 0x0d; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 512; + num_pages = 128; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATmega48 +#------------------------------------------------------------ + +part + id = "m48"; + desc = "ATmega48"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x59; +# avr910_devcode = 0x; + signature = 0x1e 0x92 0x05; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 45000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega48P +#------------------------------------------------------------ + +part parent "m48" + id = "m48p"; + desc = "ATmega48P"; + signature = 0x1e 0x92 0x0a; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega88 +#------------------------------------------------------------ + +part + id = "m88"; + desc = "ATmega88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x0a; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega88P +#------------------------------------------------------------ + +part parent "m88" + id = "m88p"; + desc = "ATmega88P"; + signature = 0x1e 0x93 0x0f; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega168 +#------------------------------------------------------------ + +part + id = "m168"; + desc = "ATmega168"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x06; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega168P +#------------------------------------------------------------ + +part parent "m168" + id = "m168p"; + desc = "ATmega168P"; + signature = 0x1e 0x94 0x0b; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATtiny88 +#------------------------------------------------------------ + +part + id = "t88"; + desc = "ATtiny88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x11; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 64; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 64; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega328 +#------------------------------------------------------------ + +part + id = "m328"; + desc = "ATmega328"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x14; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 1024; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +part parent "m328" + id = "m328p"; + desc = "ATmega328P"; + signature = 0x1e 0x95 0x0F; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATmega32m1 +#------------------------------------------------------------ + +part parent "m328" + id = "m32m1"; + desc = "ATmega32M1"; + # stk500_devcode = 0x; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x84; + bs2 = 0xe2; + + memory "efuse" + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x i i i i i i"; + ; +; + +#------------------------------------------------------------ +# ATtiny2313 +#------------------------------------------------------------ + +part + id = "t2313"; + desc = "ATtiny2313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0a; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +# The Tiny2313 has calibration data for both 4 MHz and 8 MHz. +# The information in the data sheet of April/2004 is wrong, this works: + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny4313 +#------------------------------------------------------------ + +part + id = "t4313"; + desc = "ATtiny4313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x0d; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM2 +#------------------------------------------------------------ + +part + id = "pwm2"; + desc = "AT90PWM2"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x81; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; +# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM3 +#------------------------------------------------------------ + +# Completely identical to AT90PWM2 (including the signature!) + +part parent "pwm2" + id = "pwm3"; + desc = "AT90PWM3"; + ; + +#------------------------------------------------------------ +# AT90PWM2B +#------------------------------------------------------------ +# Same as AT90PWM2 but different signature. + +part parent "pwm2" + id = "pwm2b"; + desc = "AT90PWM2B"; + signature = 0x1e 0x93 0x83; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM3B +#------------------------------------------------------------ + +# Completely identical to AT90PWM2B (including the signature!) + +part parent "pwm2b" + id = "pwm3b"; + desc = "AT90PWM3B"; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM316 +#------------------------------------------------------------ + +# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM. + +part parent "pwm3b" + id = "pwm316"; + desc = "AT90PWM316"; + signature = 0x1e 0x94 0x83; + + ocdrev = 1; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# AT90PWM216 +#------------------------------------------------------------ +# Completely identical to AT90PWM316 (including the signature!) + +part parent "pwm316" + id = "pwm216"; + desc = "AT90PWM216"; + ; + +#------------------------------------------------------------ +# ATtiny25 +#------------------------------------------------------------ + +part + id = "t25"; + desc = "ATtiny25"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x08; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny45 +#------------------------------------------------------------ + +part + id = "t45"; + desc = "ATtiny45"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x06; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!) + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny85 +#------------------------------------------------------------ + +part + id = "t85"; + desc = "ATtiny85"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega640 +#------------------------------------------------------------ +# Almost same as ATmega1280, except for different memory sizes + +part + id = "m640"; + desc = "ATmega640"; + signature = 0x1e 0x96 0x08; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1280 +#------------------------------------------------------------ + +part + id = "m1280"; + desc = "ATmega1280"; + signature = 0x1e 0x97 0x03; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1281 +#------------------------------------------------------------ +# Identical to ATmega1280 + +part parent "m1280" + id = "m1281"; + desc = "ATmega1281"; + signature = 0x1e 0x97 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega2560 +#------------------------------------------------------------ + +part + id = "m2560"; + desc = "ATmega2560"; + signature = 0x1e 0x98 0x01; + has_jtag = yes; + stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 4; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega2561 +#------------------------------------------------------------ + +part parent "m2560" + id = "m2561"; + desc = "ATmega2561"; + signature = 0x1e 0x98 0x02; + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFA1 +#------------------------------------------------------------ +# Identical to ATmega2561 but half the ROM + +part parent "m2561" + id = "m128rfa1"; + desc = "ATmega128RFA1"; + signature = 0x1e 0xa7 0x01; + chip_erase_delay = 55000; + bs2 = 0xE2; + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# ATmega256RFR2 +#------------------------------------------------------------ + +part parent "m2561" + id = "m256rfr2"; + desc = "ATmega256RFR2"; + signature = 0x1e 0xa8 0x02; + chip_erase_delay = 18500; + bs2 = 0xE2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 8192; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m128rfr2"; + desc = "ATmega128RFR2"; + signature = 0x1e 0xa7 0x02; + + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega64RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m64rfr2"; + desc = "ATmega64RFR2"; + signature = 0x1e 0xa6 0x02; + + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ; + +#------------------------------------------------------------ +# ATmega2564RFR2 +#------------------------------------------------------------ + +part parent "m256rfr2" + id = "m2564rfr2"; + desc = "ATmega2564RFR2"; + signature = 0x1e 0xa8 0x03; + ; + +#------------------------------------------------------------ +# ATmega1284RFR2 +#------------------------------------------------------------ + +part parent "m128rfr2" + id = "m1284rfr2"; + desc = "ATmega1284RFR2"; + signature = 0x1e 0xa7 0x03; + ; + +#------------------------------------------------------------ +# ATmega644RFR2 +#------------------------------------------------------------ + +part parent "m64rfr2" + id = "m644rfr2"; + desc = "ATmega644RFR2"; + signature = 0x1e 0xa6 0x03; + ; + +#------------------------------------------------------------ +# ATtiny24 +#------------------------------------------------------------ + +part + id = "t24"; + desc = "ATtiny24"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny44 +#------------------------------------------------------------ + +part + id = "t44"; + desc = "ATtiny44"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x07; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny84 +#------------------------------------------------------------ + +part + id = "t84"; + desc = "ATtiny84"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0c; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny43U +#------------------------------------------------------------ + +part + id = "t43u"; + desc = "ATtiny43u"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x0C; + reset = io; + chip_erase_delay = 1000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E, + 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56, + 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 20; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + memory "eeprom" + size = 64; + paged = yes; + page_size = 4; + num_pages = 16; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " 0 0 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega32u4 +#------------------------------------------------------------ + +part + id = "m32u4"; + desc = "ATmega32U4"; + signature = 0x1e 0x95 0x87; + usbpid = 0x2ff4; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB646 +#------------------------------------------------------------ + +part + id = "usb646"; + desc = "AT90USB646"; + signature = 0x1e 0x96 0x82; + usbpid = 0x2ff9; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB647 +#------------------------------------------------------------ +# identical to AT90USB646 + +part parent "usb646" + id = "usb647"; + desc = "AT90USB647"; + signature = 0x1e 0x96 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB1286 +#------------------------------------------------------------ + +part + id = "usb1286"; + desc = "AT90USB1286"; + signature = 0x1e 0x97 0x82; + usbpid = 0x2ffb; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB1287 +#------------------------------------------------------------ +# identical to AT90USB1286 + +part parent "usb1286" + id = "usb1287"; + desc = "AT90USB1287"; + signature = 0x1e 0x97 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB162 +#------------------------------------------------------------ + +part + id = "usb162"; + desc = "AT90USB162"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x82; + usbpid = 0x2ffa; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB82 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 8192; +# num_pages = 64; + +part + id = "usb82"; + desc = "AT90USB82"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x82; + usbpid = 0x2ff7; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32U2 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 32768; +# num_pages = 256; +# memory "eeprom" +# size = 1024; +# num_pages = 256; +part + id = "m32u2"; + desc = "ATmega32U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x95 0x8a; + usbpid = 0x2ff0; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + num_pages = 256; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega16U2 +#------------------------------------------------------------ +# Changes against ATmega32U2 (beside IDs) +# memory "flash" +# size = 16384; +# num_pages = 128; +# memory "eeprom" +# size = 512; +# num_pages = 128; +part + id = "m16u2"; + desc = "ATmega16U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x89; + usbpid = 0x2fef; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega8U2 +#------------------------------------------------------------ +# Changes against ATmega16U2 (beside IDs) +# memory "flash" +# size = 8192; +# page_size = 64; +# blocksize = 64; + +part + id = "m8u2"; + desc = "ATmega8U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x89; + usbpid = 0x2fee; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega325 +#------------------------------------------------------------ + +part + id = "m325"; + desc = "ATmega325"; + signature = 0x1e 0x95 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega645 +#------------------------------------------------------------ + +part + id = "m645"; + desc = "ATmega645"; + signature = 0x1E 0x96 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3250 +#------------------------------------------------------------ + +part parent "m325" + id = "m3250"; + desc = "ATmega3250"; + signature = 0x1E 0x95 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega6450 +#------------------------------------------------------------ + +part parent "m645" + id = "m6450"; + desc = "ATmega6450"; + signature = 0x1E 0x96 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AVR XMEGA family common values +#------------------------------------------------------------ + +part + id = ".xmega"; + desc = "AVR XMEGA family common values"; + has_pdi = yes; + nvm_base = 0x01c0; + mcu_base = 0x0090; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "prodsig" + size = 0x32; + offset = 0x8e0200; + page_size = 0x32; + readsize = 0x32; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; + + memory "data" + # SRAM, only used to supply the offset + offset = 0x1000000; + ; +; + +#------------------------------------------------------------ +# ATxmega16A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16a4u"; + desc = "ATxmega16A4U"; + signature = 0x1e 0x94 0x41; + usbpid = 0x2fe3; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x803000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x804000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16C4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16c4"; + desc = "ATxmega16C4"; + signature = 0x1e 0x95 0x44; +; + +#------------------------------------------------------------ +# ATxmega16D4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16d4"; + desc = "ATxmega16D4"; + signature = 0x1e 0x94 0x42; +; + +#------------------------------------------------------------ +# ATxmega16A4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16a4"; + desc = "ATxmega16A4"; + signature = 0x1e 0x94 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega32A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32a4u"; + desc = "ATxmega32A4U"; + signature = 0x1e 0x95 0x41; + usbpid = 0x2fe4; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x807000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x808000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32C4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32c4"; + desc = "ATxmega32C4"; + signature = 0x1e 0x94 0x43; +; + +#------------------------------------------------------------ +# ATxmega32D4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32d4"; + desc = "ATxmega32D4"; + signature = 0x1e 0x95 0x42; +; + +#------------------------------------------------------------ +# ATxmega32A4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32a4"; + desc = "ATxmega32A4"; + signature = 0x1e 0x95 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x64a4u"; + desc = "ATxmega64A4U"; + signature = 0x1e 0x96 0x46; + usbpid = 0x2fe5; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x10000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x80f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x11000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega64C3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64c3"; + desc = "ATxmega64C3"; + signature = 0x1e 0x96 0x49; + usbpid = 0x2fd6; +; + +#------------------------------------------------------------ +# ATxmega64D3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d3"; + desc = "ATxmega64D3"; + signature = 0x1e 0x96 0x4a; +; + +#------------------------------------------------------------ +# ATxmega64D4 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d4"; + desc = "ATxmega64D4"; + signature = 0x1e 0x96 0x47; +; + +#------------------------------------------------------------ +# ATxmega64A1 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64a1"; + desc = "ATxmega64A1"; + signature = 0x1e 0x96 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A1U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a1u"; + desc = "ATxmega64A1U"; + signature = 0x1e 0x96 0x4e; + usbpid = 0x2fe8; +; + +#------------------------------------------------------------ +# ATxmega64A3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3"; + desc = "ATxmega64A3"; + signature = 0x1e 0x96 0x42; +; + +#------------------------------------------------------------ +# ATxmega64A3U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3u"; + desc = "ATxmega64A3U"; + signature = 0x1e 0x96 0x42; + usbpid = 0x2fe5; +; + +#------------------------------------------------------------ +# ATxmega64A4 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a4"; + desc = "ATxmega64A4"; + signature = 0x1e 0x96 0x46; +; + +#------------------------------------------------------------ +# ATxmega64B1 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b1"; + desc = "ATxmega64B1"; + signature = 0x1e 0x96 0x52; + usbpid = 0x2fe1; +; + +#------------------------------------------------------------ +# ATxmega64B3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b3"; + desc = "ATxmega64B3"; + signature = 0x1e 0x96 0x51; + usbpid = 0x2fdf; +; + +#------------------------------------------------------------ +# ATxmega128C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128c3"; + desc = "ATxmega128C3"; + signature = 0x1e 0x97 0x52; + usbpid = 0x2fd7; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128D3 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d3"; + desc = "ATxmega128D3"; + signature = 0x1e 0x97 0x48; +; + +#------------------------------------------------------------ +# ATxmega128D4 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d4"; + desc = "ATxmega128D4"; + signature = 0x1e 0x97 0x47; +; + +#------------------------------------------------------------ +# ATxmega128A1 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128a1"; + desc = "ATxmega128A1"; + signature = 0x1e 0x97 0x4c; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A1 revision D +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1d"; + desc = "ATxmega128A1revD"; + signature = 0x1e 0x97 0x41; +; + +#------------------------------------------------------------ +# ATxmega128A1U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1u"; + desc = "ATxmega128A1U"; + signature = 0x1e 0x97 0x4c; + usbpid = 0x2fed; +; + +#------------------------------------------------------------ +# ATxmega128A3 +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3"; + desc = "ATxmega128A3"; + signature = 0x1e 0x97 0x42; +; + +#------------------------------------------------------------ +# ATxmega128A3U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3u"; + desc = "ATxmega128A3U"; + signature = 0x1e 0x97 0x42; + usbpid = 0x2fe6; +; + +#------------------------------------------------------------ +# ATxmega128A4 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4"; + desc = "ATxmega128A4"; + signature = 0x1e 0x97 0x46; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4u"; + desc = "ATxmega128A4U"; + signature = 0x1e 0x97 0x46; + usbpid = 0x2fde; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128B1 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128b1"; + desc = "ATxmega128B1"; + signature = 0x1e 0x97 0x4d; + usbpid = 0x2fea; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128B3 +#------------------------------------------------------------ + +part parent "x128b1" + id = "x128b3"; + desc = "ATxmega128B3"; + signature = 0x1e 0x97 0x4b; + usbpid = 0x2fe0; +; + +#------------------------------------------------------------ +# ATxmega192C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x192c3"; + desc = "ATxmega192C3"; + signature = 0x1e 0x97 0x51; + # usbpid = 0x2f??; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x30000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x82e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x830000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x32000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega192D3 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192d3"; + desc = "ATxmega192D3"; + signature = 0x1e 0x97 0x49; +; + +#------------------------------------------------------------ +# ATxmega192A1 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192a1"; + desc = "ATxmega192A1"; + signature = 0x1e 0x97 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega192A3 +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3"; + desc = "ATxmega192A3"; + signature = 0x1e 0x97 0x44; +; + +#------------------------------------------------------------ +# ATxmega192A3U +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3u"; + desc = "ATxmega192A3U"; + signature = 0x1e 0x97 0x44; + usbpid = 0x2fe7; +; + +#------------------------------------------------------------ +# ATxmega256C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x256c3"; + desc = "ATxmega256C3"; + signature = 0x1e 0x98 0x46; + usbpid = 0x2fda; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x40000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x83e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x840000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x42000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega256D3 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256d3"; + desc = "ATxmega256D3"; + signature = 0x1e 0x98 0x44; +; + +#------------------------------------------------------------ +# ATxmega256A1 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256a1"; + desc = "ATxmega256A1"; + signature = 0x1e 0x98 0x46; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega256A3 +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3"; + desc = "ATxmega256A3"; + signature = 0x1e 0x98 0x42; +; + +#------------------------------------------------------------ +# ATxmega256A3U +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3u"; + desc = "ATxmega256A3U"; + signature = 0x1e 0x98 0x42; + usbpid = 0x2fec; +; + +#------------------------------------------------------------ +# ATxmega256A3B +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3b"; + desc = "ATxmega256A3B"; + signature = 0x1e 0x98 0x43; +; + +#------------------------------------------------------------ +# ATxmega256A3BU +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3bu"; + desc = "ATxmega256A3BU"; + signature = 0x1e 0x98 0x43; + usbpid = 0x2fe2; +; + +#------------------------------------------------------------ +# ATxmega384C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x384c3"; + desc = "ATxmega384C3"; + signature = 0x1e 0x98 0x45; + usbpid = 0x2fdb; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x60000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x85e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x860000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x62000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega384D3 +#------------------------------------------------------------ + +part parent "x384c3" + id = "x384d3"; + desc = "ATxmega384D3"; + signature = 0x1e 0x98 0x47; +; + +#------------------------------------------------------------ +# ATxmega8E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x8e5"; + desc = "ATxmega8E5"; + signature = 0x1e 0x93 0x41; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x2000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x800; + offset = 0x00801800; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x800; + offset = 0x00802000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x2800; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16e5"; + desc = "ATxmega16E5"; + signature = 0x1e 0x94 0x45; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00803000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00804000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32e5"; + desc = "ATxmega32E5"; + signature = 0x1e 0x95 0x4c; + + memory "eeprom" + size = 0x0400; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00807000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00808000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# AVR32UC3A0512 +#------------------------------------------------------------ + +part + id = "uc3a0512"; + desc = "AT32UC3A0512"; + signature = 0xED 0xC0 0x3F; + has_jtag = yes; + is_avr32 = yes; + + memory "flash" + paged = yes; + page_size = 512; # bytes + readsize = 512; # bytes + num_pages = 1024; # could be set dynamicly + size = 0x00080000; # could be set dynamicly + offset = 0x80000000; + ; +; + +part parent "uc3a0512" + id = "ucr2"; + desc = "deprecated, use 'uc3a0512'"; +; + +#------------------------------------------------------------ +# ATtiny1634. +#------------------------------------------------------------ + +part + id = "t1634"; + desc = "ATtiny1634"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x12; + pagel = 0xB3; + bs2 = 0xB1; + reset = io; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 32; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 1 1 1 1 i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# Common values for reduced core tinys (4/5/9/10/20/40) +#------------------------------------------------------------ + +part + id = ".reduced_core_tiny"; + desc = "Common values for reduced core tinys"; + has_tpi = yes; + + memory "signature" + size = 3; + offset = 0x3fc0; + page_size = 16; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + page_size = 16; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + page_size = 16; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + page_size = 16; + ; +; + +#------------------------------------------------------------ +# ATtiny4 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t4"; + desc = "ATtiny4"; + signature = 0x1e 0x8f 0x0a; + + memory "flash" + size = 512; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny5 +#------------------------------------------------------------ + +part parent "t4" + id = "t5"; + desc = "ATtiny5"; + signature = 0x1e 0x8f 0x09; +; + +#------------------------------------------------------------ +# ATtiny9 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t9"; + desc = "ATtiny9"; + signature = 0x1e 0x90 0x08; + + memory "flash" + size = 1024; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny10 +#------------------------------------------------------------ + +part parent "t9" + id = "t10"; + desc = "ATtiny10"; + signature = 0x1e 0x90 0x03; +; + +#------------------------------------------------------------ +# ATtiny20 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t20"; + desc = "ATtiny20"; + signature = 0x1e 0x91 0x0F; + + memory "flash" + size = 2048; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny40 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t40"; + desc = "ATtiny40"; + signature = 0x1e 0x92 0x0E; + + memory "flash" + size = 4096; + offset = 0x4000; + page_size = 64; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATmega406 +#------------------------------------------------------------ + +part + id = "m406"; + desc = "ATMEGA406"; + has_jtag = yes; + signature = 0x1e 0x95 0x07; + + # STK500 parameters (parallel programming IO lines) + pagel = 0xa7; + bs2 = 0xa0; + serial = no; + parallel = yes; + + # STK500v2 HV programming parameters, from XML + pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f, + 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f, + 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b, + 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + + # JTAG ICE mkII parameters, also from XML files + allowfullpagebitstream = no; + enablepageprogramming = yes; + idr = 0x51; + rampz = 0x00; + spmcr = 0x57; + eecr = 0x3f; + + memory "eeprom" + paged = no; + size = 512; + page_size = 4; + blocksize = 4; + readsize = 4; + num_pages = 128; + ; + + memory "flash" + paged = yes; + size = 40960; + page_size = 128; + blocksize = 128; + readsize = 128; + num_pages = 320; + ; + + memory "hfuse" + size = 1; + ; + + memory "lfuse" + size = 1; + ; + + memory "lockbits" + size = 1; + ; + + memory "signature" + size = 3; + ; +; + + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.eep b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.eep new file mode 100644 index 0000000..1996e8f --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.eep @@ -0,0 +1 @@ +:00000001FF diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.lss b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.lss new file mode 100644 index 0000000..d14f462 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.lss @@ -0,0 +1,7920 @@ + +firmware.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .data 00000012 00800100 000029b8 00002a4c 2**0 + CONTENTS, ALLOC, LOAD, DATA + 1 .text 000029b8 00000000 00000000 00000094 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .bss 000003b4 00800112 00800112 00002a5e 2**0 + ALLOC + 3 .stab 00008088 00000000 00000000 00002a60 2**2 + CONTENTS, READONLY, DEBUGGING + 4 .stabstr 00003ac7 00000000 00000000 0000aae8 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .comment 00000011 00000000 00000000 0000e5af 2**0 + CONTENTS, READONLY + 6 .note.gnu.avr.deviceinfo 0000003c 00000000 00000000 0000e5c0 2**2 + CONTENTS, READONLY + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end> + 4: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 8: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 10: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 14: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 18: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 1c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 20: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 24: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 28: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 2c: 0c 94 93 14 jmp 0x2926 ; 0x2926 <__vector_11> + 30: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 34: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 38: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 3c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 40: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 44: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 48: 0c 94 b0 07 jmp 0xf60 ; 0xf60 <__vector_18> + 4c: 0c 94 e7 07 jmp 0xfce ; 0xfce <__vector_19> + 50: 0c 94 29 08 jmp 0x1052 ; 0x1052 <__vector_20> + 54: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 58: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 5c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 60: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + 64: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt> + +00000068 <__ctors_end>: + 68: 11 24 eor r1, r1 + 6a: 1f be out 0x3f, r1 ; 63 + 6c: cf ef ldi r28, 0xFF ; 255 + 6e: d4 e0 ldi r29, 0x04 ; 4 + 70: de bf out 0x3e, r29 ; 62 + 72: cd bf out 0x3d, r28 ; 61 + +00000074 <__do_copy_data>: + 74: 11 e0 ldi r17, 0x01 ; 1 + 76: a0 e0 ldi r26, 0x00 ; 0 + 78: b1 e0 ldi r27, 0x01 ; 1 + 7a: e8 eb ldi r30, 0xB8 ; 184 + 7c: f9 e2 ldi r31, 0x29 ; 41 + 7e: 02 c0 rjmp .+4 ; 0x84 <__do_copy_data+0x10> + 80: 05 90 lpm r0, Z+ + 82: 0d 92 st X+, r0 + 84: a2 31 cpi r26, 0x12 ; 18 + 86: b1 07 cpc r27, r17 + 88: d9 f7 brne .-10 ; 0x80 <__do_copy_data+0xc> + +0000008a <__do_clear_bss>: + 8a: 24 e0 ldi r18, 0x04 ; 4 + 8c: a2 e1 ldi r26, 0x12 ; 18 + 8e: b1 e0 ldi r27, 0x01 ; 1 + 90: 01 c0 rjmp .+2 ; 0x94 <.do_clear_bss_start> + +00000092 <.do_clear_bss_loop>: + 92: 1d 92 st X+, r1 + +00000094 <.do_clear_bss_start>: + 94: a6 3c cpi r26, 0xC6 ; 198 + 96: b2 07 cpc r27, r18 + 98: e1 f7 brne .-8 ; 0x92 <.do_clear_bss_loop> + 9a: 0e 94 96 14 call 0x292c ; 0x292c
+ 9e: 0c 94 da 14 jmp 0x29b4 ; 0x29b4 <_exit> + +000000a2 <__bad_interrupt>: + a2: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> + +000000a6 : + } + crEND(); +} + +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + a6: cf 92 push r12 + a8: df 92 push r13 + aa: ff 92 push r15 + ac: 0f 93 push r16 + ae: 1f 93 push r17 + b0: cf 93 push r28 + b2: df 93 push r29 + b4: 6c 01 movw r12, r24 + b6: f6 2e mov r15, r22 + static uint8_t rozkaz[2]; + static uint16_t czasAkcji[2]; + czasAkcji[uxIndex] = portMAX_DELAY; + b8: c6 2f mov r28, r22 + ba: d0 e0 ldi r29, 0x00 ; 0 + bc: 8e 01 movw r16, r28 + be: 00 0f add r16, r16 + c0: 11 1f adc r17, r17 + c2: f8 01 movw r30, r16 + c4: ef 5d subi r30, 0xDF ; 223 + c6: fe 4f sbci r31, 0xFE ; 254 + c8: 8f ef ldi r24, 0xFF ; 255 + ca: 9f ef ldi r25, 0xFF ; 255 + cc: 91 83 std Z+1, r25 ; 0x01 + ce: 80 83 st Z, r24 + static portBASE_TYPE xResult[2]; + crSTART( xHandle ); + d0: f6 01 movw r30, r12 + d2: 80 8d ldd r24, Z+24 ; 0x18 + d4: 91 8d ldd r25, Z+25 ; 0x19 + d6: 84 31 cpi r24, 0x14 ; 20 + d8: f1 e0 ldi r31, 0x01 ; 1 + da: 9f 07 cpc r25, r31 + dc: f9 f0 breq .+62 ; 0x11c + de: 85 31 cpi r24, 0x15 ; 21 + e0: 21 e0 ldi r18, 0x01 ; 1 + e2: 92 07 cpc r25, r18 + e4: b9 f1 breq .+110 ; 0x154 + e6: 89 2b or r24, r25 + e8: 09 f0 breq .+2 ; 0xec + ea: 6c c0 rjmp .+216 ; 0x1c4 + for (;;) + { + crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz[uxIndex], czasAkcji[uxIndex], &xResult[uxIndex]); + ec: f8 01 movw r30, r16 + ee: ef 5d subi r30, 0xDF ; 223 + f0: fe 4f sbci r31, 0xFE ; 254 + f2: 40 81 ld r20, Z + f4: 51 81 ldd r21, Z+1 ; 0x01 + f6: be 01 movw r22, r28 + f8: 61 5e subi r22, 0xE1 ; 225 + fa: 7e 4f sbci r23, 0xFE ; 254 + fc: f8 01 movw r30, r16 + fe: ee 53 subi r30, 0x3E ; 62 + 100: fb 4f sbci r31, 0xFB ; 251 + 102: 80 81 ld r24, Z + 104: 91 81 ldd r25, Z+1 ; 0x01 + 106: 0e 94 00 10 call 0x2000 ; 0x2000 + 10a: fe 01 movw r30, r28 + 10c: e3 5e subi r30, 0xE3 ; 227 + 10e: fe 4f sbci r31, 0xFE ; 254 + 110: 80 83 st Z, r24 + 112: 8c 3f cpi r24, 0xFC ; 252 + 114: 99 f4 brne .+38 ; 0x13c + 116: 84 e1 ldi r24, 0x14 ; 20 + 118: 91 e0 ldi r25, 0x01 ; 1 + 11a: 18 c0 rjmp .+48 ; 0x14c + 11c: 40 e0 ldi r20, 0x00 ; 0 + 11e: 50 e0 ldi r21, 0x00 ; 0 + 120: be 01 movw r22, r28 + 122: 61 5e subi r22, 0xE1 ; 225 + 124: 7e 4f sbci r23, 0xFE ; 254 + 126: f8 01 movw r30, r16 + 128: ee 53 subi r30, 0x3E ; 62 + 12a: fb 4f sbci r31, 0xFB ; 251 + 12c: 80 81 ld r24, Z + 12e: 91 81 ldd r25, Z+1 ; 0x01 + 130: 0e 94 00 10 call 0x2000 ; 0x2000 + 134: fe 01 movw r30, r28 + 136: e3 5e subi r30, 0xE3 ; 227 + 138: fe 4f sbci r31, 0xFE ; 254 + 13a: 80 83 st Z, r24 + 13c: fe 01 movw r30, r28 + 13e: e3 5e subi r30, 0xE3 ; 227 + 140: fe 4f sbci r31, 0xFE ; 254 + 142: 80 81 ld r24, Z + 144: 8b 3f cpi r24, 0xFB ; 251 + 146: 59 f4 brne .+22 ; 0x15e + 148: 85 e1 ldi r24, 0x15 ; 21 + 14a: 91 e0 ldi r25, 0x01 ; 1 + 14c: f6 01 movw r30, r12 + 14e: 91 8f std Z+25, r25 ; 0x19 + 150: 80 8f std Z+24, r24 ; 0x18 + 152: 38 c0 rjmp .+112 ; 0x1c4 + 154: 81 e0 ldi r24, 0x01 ; 1 + 156: fe 01 movw r30, r28 + 158: e3 5e subi r30, 0xE3 ; 227 + 15a: fe 4f sbci r31, 0xFE ; 254 + 15c: 80 83 st Z, r24 + + if (xResult[uxIndex] == pdTRUE) + 15e: fe 01 movw r30, r28 + 160: e3 5e subi r30, 0xE3 ; 227 + 162: fe 4f sbci r31, 0xFE ; 254 + 164: 80 81 ld r24, Z + 166: 81 30 cpi r24, 0x01 ; 1 + 168: 11 f5 brne .+68 ; 0x1ae + { + uint8_t tmp = rozkaz[uxIndex] & 0x3F; + 16a: fe 01 movw r30, r28 + 16c: e1 5e subi r30, 0xE1 ; 225 + 16e: fe 4f sbci r31, 0xFE ; 254 + 170: 80 81 ld r24, Z + 172: 28 2f mov r18, r24 + 174: 2f 73 andi r18, 0x3F ; 63 + if (tmp == 0) + 176: 31 f4 brne .+12 ; 0x184 + czasAkcji[uxIndex] = portMAX_DELAY; + 178: 2f ef ldi r18, 0xFF ; 255 + 17a: 3f ef ldi r19, 0xFF ; 255 + 17c: f8 01 movw r30, r16 + 17e: ef 5d subi r30, 0xDF ; 223 + 180: fe 4f sbci r31, 0xFE ; 254 + 182: 07 c0 rjmp .+14 ; 0x192 + else + czasAkcji[uxIndex] = tmp*20; + 184: f8 01 movw r30, r16 + 186: ef 5d subi r30, 0xDF ; 223 + 188: fe 4f sbci r31, 0xFE ; 254 + 18a: 94 e1 ldi r25, 0x14 ; 20 + 18c: 29 9f mul r18, r25 + 18e: 90 01 movw r18, r0 + 190: 11 24 eor r1, r1 + 192: 31 83 std Z+1, r19 ; 0x01 + 194: 20 83 st Z, r18 + if (rozkaz[uxIndex] & 0x40) + 196: 86 fd sbrc r24, 6 + 198: 11 c0 rjmp .+34 ; 0x1bc + { + roletaStop(uxIndex); + } + else + { + if (rozkaz[uxIndex] & 0x80) + 19a: 87 ff sbrs r24, 7 + 19c: 04 c0 rjmp .+8 ; 0x1a6 + roletawGore(uxIndex); + 19e: 8f 2d mov r24, r15 + 1a0: 0e 94 62 08 call 0x10c4 ; 0x10c4 + 1a4: a3 cf rjmp .-186 ; 0xec + else + roletawDol(uxIndex); + 1a6: 8f 2d mov r24, r15 + 1a8: 0e 94 6b 08 call 0x10d6 ; 0x10d6 + 1ac: 9f cf rjmp .-194 ; 0xec + } + } + else + { + czasAkcji[uxIndex] = portMAX_DELAY; + 1ae: 8f ef ldi r24, 0xFF ; 255 + 1b0: 9f ef ldi r25, 0xFF ; 255 + 1b2: f8 01 movw r30, r16 + 1b4: ef 5d subi r30, 0xDF ; 223 + 1b6: fe 4f sbci r31, 0xFE ; 254 + 1b8: 91 83 std Z+1, r25 ; 0x01 + 1ba: 80 83 st Z, r24 + roletaStop(uxIndex); + 1bc: 8f 2d mov r24, r15 + 1be: 0e 94 74 08 call 0x10e8 ; 0x10e8 + 1c2: 94 cf rjmp .-216 ; 0xec + } + } + crEND(); +} + 1c4: df 91 pop r29 + 1c6: cf 91 pop r28 + 1c8: 1f 91 pop r17 + 1ca: 0f 91 pop r16 + 1cc: ff 90 pop r15 + 1ce: df 90 pop r13 + 1d0: cf 90 pop r12 + 1d2: 08 95 ret + +000001d4 : + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + 1d4: 0f 93 push r16 + 1d6: 1f 93 push r17 + 1d8: cf 93 push r28 + 1da: df 93 push r29 + 1dc: 00 d0 rcall .+0 ; 0x1de + 1de: cd b7 in r28, 0x3d ; 61 + 1e0: de b7 in r29, 0x3e ; 62 + 1e2: 8c 01 movw r16, r24 + (void) uxIndex; + static portBASE_TYPE xResult; + + crSTART( xHandle ); + 1e4: fc 01 movw r30, r24 + 1e6: 20 8d ldd r18, Z+24 ; 0x18 + 1e8: 31 8d ldd r19, Z+25 ; 0x19 + 1ea: 2c 3e cpi r18, 0xEC ; 236 + 1ec: 31 05 cpc r19, r1 + 1ee: 09 f4 brne .+2 ; 0x1f2 + 1f0: 4d c0 rjmp .+154 ; 0x28c + 1f2: 38 f4 brcc .+14 ; 0x202 + 1f4: 21 15 cp r18, r1 + 1f6: 31 05 cpc r19, r1 + 1f8: 71 f1 breq .+92 ; 0x256 + 1fa: 22 3e cpi r18, 0xE2 ; 226 + 1fc: 31 05 cpc r19, r1 + 1fe: 89 f0 breq .+34 ; 0x222 + 200: 87 c0 rjmp .+270 ; 0x310 + 202: 26 3f cpi r18, 0xF6 ; 246 + 204: 31 05 cpc r19, r1 + 206: 09 f4 brne .+2 ; 0x20a + 208: 67 c0 rjmp .+206 ; 0x2d8 + 20a: 27 3f cpi r18, 0xF7 ; 247 + 20c: 31 05 cpc r19, r1 + 20e: 09 f4 brne .+2 ; 0x212 + 210: 7b c0 rjmp .+246 ; 0x308 + 212: 2d 3e cpi r18, 0xED ; 237 + 214: 31 05 cpc r19, r1 + 216: 09 f0 breq .+2 ; 0x21a + 218: 7b c0 rjmp .+246 ; 0x310 + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + 21a: 81 e0 ldi r24, 0x01 ; 1 + 21c: 80 93 1c 01 sts 0x011C, r24 + 220: 0d c0 rjmp .+26 ; 0x23c + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + 222: 0e 94 8f 08 call 0x111e ; 0x111e + 226: 8a 83 std Y+2, r24 ; 0x02 + 228: 0e 94 8c 08 call 0x1118 ; 0x1118 + 22c: 47 e1 ldi r20, 0x17 ; 23 + 22e: 51 e0 ldi r21, 0x01 ; 1 + 230: 6a 81 ldd r22, Y+2 ; 0x02 + 232: 0e 94 98 08 call 0x1130 ; 0x1130 + 236: 89 83 std Y+1, r24 ; 0x01 + if (wiadomosc) + 238: 81 11 cpse r24, r1 + 23a: 16 c0 rjmp .+44 ; 0x268 + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + } + wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta2)); + 23c: 0e 94 95 08 call 0x112a ; 0x112a + 240: 8a 83 std Y+2, r24 ; 0x02 + 242: 0e 94 92 08 call 0x1124 ; 0x1124 + 246: 42 e1 ldi r20, 0x12 ; 18 + 248: 51 e0 ldi r21, 0x01 ; 1 + 24a: 6a 81 ldd r22, Y+2 ; 0x02 + 24c: 0e 94 98 08 call 0x1130 ; 0x1130 + 250: 89 83 std Y+1, r24 ; 0x01 + if (wiadomosc) + 252: 81 11 cpse r24, r1 + 254: 2f c0 rjmp .+94 ; 0x2b4 + static portBASE_TYPE xResult; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + 256: 60 e0 ldi r22, 0x00 ; 0 + 258: 70 e0 ldi r23, 0x00 ; 0 + 25a: 81 e0 ldi r24, 0x01 ; 1 + 25c: 90 e0 ldi r25, 0x00 ; 0 + 25e: 0e 94 9f 11 call 0x233e ; 0x233e + 262: 82 ee ldi r24, 0xE2 ; 226 + 264: 90 e0 ldi r25, 0x00 ; 0 + 266: 4c c0 rjmp .+152 ; 0x300 + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + 268: 4a e0 ldi r20, 0x0A ; 10 + 26a: 50 e0 ldi r21, 0x00 ; 0 + 26c: be 01 movw r22, r28 + 26e: 6f 5f subi r22, 0xFF ; 255 + 270: 7f 4f sbci r23, 0xFF ; 255 + 272: 80 91 c2 04 lds r24, 0x04C2 + 276: 90 91 c3 04 lds r25, 0x04C3 + 27a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 27e: 80 93 1c 01 sts 0x011C, r24 + 282: 8c 3f cpi r24, 0xFC ; 252 + 284: 81 f4 brne .+32 ; 0x2a6 + 286: 8c ee ldi r24, 0xEC ; 236 + 288: 90 e0 ldi r25, 0x00 ; 0 + 28a: 3a c0 rjmp .+116 ; 0x300 + 28c: 40 e0 ldi r20, 0x00 ; 0 + 28e: 50 e0 ldi r21, 0x00 ; 0 + 290: be 01 movw r22, r28 + 292: 6f 5f subi r22, 0xFF ; 255 + 294: 7f 4f sbci r23, 0xFF ; 255 + 296: 80 91 c2 04 lds r24, 0x04C2 + 29a: 90 91 c3 04 lds r25, 0x04C3 + 29e: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 2a2: 80 93 1c 01 sts 0x011C, r24 + 2a6: 80 91 1c 01 lds r24, 0x011C + 2aa: 8b 3f cpi r24, 0xFB ; 251 + 2ac: 39 f6 brne .-114 ; 0x23c + 2ae: 8d ee ldi r24, 0xED ; 237 + 2b0: 90 e0 ldi r25, 0x00 ; 0 + 2b2: 26 c0 rjmp .+76 ; 0x300 + } + wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta2)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + 2b4: 4a e0 ldi r20, 0x0A ; 10 + 2b6: 50 e0 ldi r21, 0x00 ; 0 + 2b8: be 01 movw r22, r28 + 2ba: 6f 5f subi r22, 0xFF ; 255 + 2bc: 7f 4f sbci r23, 0xFF ; 255 + 2be: 80 91 c4 04 lds r24, 0x04C4 + 2c2: 90 91 c5 04 lds r25, 0x04C5 + 2c6: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 2ca: 80 93 1c 01 sts 0x011C, r24 + 2ce: 8c 3f cpi r24, 0xFC ; 252 + 2d0: 81 f4 brne .+32 ; 0x2f2 + 2d2: 86 ef ldi r24, 0xF6 ; 246 + 2d4: 90 e0 ldi r25, 0x00 ; 0 + 2d6: 14 c0 rjmp .+40 ; 0x300 + 2d8: 40 e0 ldi r20, 0x00 ; 0 + 2da: 50 e0 ldi r21, 0x00 ; 0 + 2dc: be 01 movw r22, r28 + 2de: 6f 5f subi r22, 0xFF ; 255 + 2e0: 7f 4f sbci r23, 0xFF ; 255 + 2e2: 80 91 c4 04 lds r24, 0x04C4 + 2e6: 90 91 c5 04 lds r25, 0x04C5 + 2ea: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 2ee: 80 93 1c 01 sts 0x011C, r24 + 2f2: 80 91 1c 01 lds r24, 0x011C + 2f6: 8b 3f cpi r24, 0xFB ; 251 + 2f8: 09 f0 breq .+2 ; 0x2fc + 2fa: ad cf rjmp .-166 ; 0x256 + 2fc: 87 ef ldi r24, 0xF7 ; 247 + 2fe: 90 e0 ldi r25, 0x00 ; 0 + 300: f8 01 movw r30, r16 + 302: 91 8f std Z+25, r25 ; 0x19 + 304: 80 8f std Z+24, r24 ; 0x18 + 306: 04 c0 rjmp .+8 ; 0x310 + 308: 81 e0 ldi r24, 0x01 ; 1 + 30a: 80 93 1c 01 sts 0x011C, r24 + } + } + 30e: a3 cf rjmp .-186 ; 0x256 + crEND(); +} + 310: 0f 90 pop r0 + 312: 0f 90 pop r0 + 314: df 91 pop r29 + 316: cf 91 pop r28 + 318: 1f 91 pop r17 + 31a: 0f 91 pop r16 + 31c: 08 95 ret + +0000031e : + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + 31e: 0e 94 e1 11 call 0x23c2 ; 0x23c2 + } + 322: fd cf rjmp .-6 ; 0x31e + +00000324 <_crc_xmodem_update>: + : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + : "r" (__data), "0" (__crc) + : "r0" + ); + return __ret; +} + 324: 96 27 eor r25, r22 + 326: 09 2e mov r0, r25 + 328: 02 94 swap r0 + 32a: 20 2d mov r18, r0 + 32c: 2f 70 andi r18, 0x0F ; 15 + 32e: 29 27 eor r18, r25 + 330: 69 2f mov r22, r25 + 332: 60 25 eor r22, r0 + 334: 66 0f add r22, r22 + 336: 60 7e andi r22, 0xE0 ; 224 + 338: 26 27 eor r18, r22 + 33a: 60 2d mov r22, r0 + 33c: 69 27 eor r22, r25 + 33e: 60 7f andi r22, 0xF0 ; 240 + 340: 66 95 lsr r22 + 342: 09 2e mov r0, r25 + 344: 00 0c add r0, r0 + 346: 66 1f adc r22, r22 + 348: 96 95 lsr r25 + 34a: 96 95 lsr r25 + 34c: 96 95 lsr r25 + 34e: 9f 71 andi r25, 0x1F ; 31 + 350: 96 27 eor r25, r22 + 352: 98 27 eor r25, r24 + 354: 82 2f mov r24, r18 + 356: 08 95 ret + +00000358 : + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + 358: ff 92 push r15 + 35a: 0f 93 push r16 + 35c: 1f 93 push r17 + 35e: cf 93 push r28 + 360: df 93 push r29 + 362: 1f 92 push r1 + 364: cd b7 in r28, 0x3d ; 61 + 366: de b7 in r29, 0x3e ; 62 + 368: 8c 01 movw r16, r24 + (void) uxIndex; + + crSTART( xHandle ); + 36a: fc 01 movw r30, r24 + 36c: 20 8d ldd r18, Z+24 ; 0x18 + 36e: 31 8d ldd r19, Z+25 ; 0x19 + 370: 25 35 cpi r18, 0x55 ; 85 + 372: f2 e0 ldi r31, 0x02 ; 2 + 374: 3f 07 cpc r19, r31 + 376: 09 f4 brne .+2 ; 0x37a + 378: d1 c3 rjmp .+1954 ; 0xb1c <__stack+0x61d> + 37a: 08 f0 brcs .+2 ; 0x37e + 37c: a4 c0 rjmp .+328 ; 0x4c6 + 37e: 22 3d cpi r18, 0xD2 ; 210 + 380: e1 e0 ldi r30, 0x01 ; 1 + 382: 3e 07 cpc r19, r30 + 384: 09 f4 brne .+2 ; 0x388 + 386: 64 c2 rjmp .+1224 ; 0x850 <__stack+0x351> + 388: 08 f0 brcs .+2 ; 0x38c + 38a: 4a c0 rjmp .+148 ; 0x420 + 38c: 21 36 cpi r18, 0x61 ; 97 + 38e: 81 e0 ldi r24, 0x01 ; 1 + 390: 38 07 cpc r19, r24 + 392: 09 f4 brne .+2 ; 0x396 + 394: 96 c1 rjmp .+812 ; 0x6c2 <__stack+0x1c3> + 396: 00 f5 brcc .+64 ; 0x3d8 + 398: 2c 34 cpi r18, 0x4C ; 76 + 39a: f1 e0 ldi r31, 0x01 ; 1 + 39c: 3f 07 cpc r19, r31 + 39e: 09 f4 brne .+2 ; 0x3a2 + 3a0: 4b c1 rjmp .+662 ; 0x638 <__stack+0x139> + 3a2: 20 f4 brcc .+8 ; 0x3ac + 3a4: 23 2b or r18, r19 + 3a6: 09 f4 brne .+2 ; 0x3aa + 3a8: 2e c1 rjmp .+604 ; 0x606 <__stack+0x107> + 3aa: 9f c5 rjmp .+2878 ; 0xeea <__stack+0x9eb> + 3ac: 2d 34 cpi r18, 0x4D ; 77 + 3ae: e1 e0 ldi r30, 0x01 ; 1 + 3b0: 3e 07 cpc r19, r30 + 3b2: 09 f4 brne .+2 ; 0x3b6 + 3b4: 54 c1 rjmp .+680 ; 0x65e <__stack+0x15f> + 3b6: 20 36 cpi r18, 0x60 ; 96 + 3b8: 31 40 sbci r19, 0x01 ; 1 + 3ba: 09 f0 breq .+2 ; 0x3be + 3bc: 96 c5 rjmp .+2860 ; 0xeea <__stack+0x9eb> + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 3be: 40 e0 ldi r20, 0x00 ; 0 + 3c0: 50 e0 ldi r21, 0x00 ; 0 + 3c2: 69 e2 ldi r22, 0x29 ; 41 + 3c4: 71 e0 ldi r23, 0x01 ; 1 + 3c6: 80 91 45 01 lds r24, 0x0145 + 3ca: 90 91 46 01 lds r25, 0x0146 + 3ce: 0e 94 00 10 call 0x2000 ; 0x2000 + 3d2: 80 93 28 01 sts 0x0128, r24 + 3d6: 6e c1 rjmp .+732 ; 0x6b4 <__stack+0x1b5> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 3d8: 27 38 cpi r18, 0x87 ; 135 + 3da: 81 e0 ldi r24, 0x01 ; 1 + 3dc: 38 07 cpc r19, r24 + 3de: 09 f4 brne .+2 ; 0x3e2 + 3e0: b5 c1 rjmp .+874 ; 0x74c <__stack+0x24d> + 3e2: 88 f4 brcc .+34 ; 0x406 + 3e4: 26 38 cpi r18, 0x86 ; 134 + 3e6: 31 40 sbci r19, 0x01 ; 1 + 3e8: 09 f0 breq .+2 ; 0x3ec + 3ea: 7f c5 rjmp .+2814 ; 0xeea <__stack+0x9eb> + } + if (stan == s_rozkaz) + { + Led1On(); + Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + 3ec: 40 e0 ldi r20, 0x00 ; 0 + 3ee: 50 e0 ldi r21, 0x00 ; 0 + 3f0: 62 e4 ldi r22, 0x42 ; 66 + 3f2: 71 e0 ldi r23, 0x01 ; 1 + 3f4: 80 91 45 01 lds r24, 0x0145 + 3f8: 90 91 46 01 lds r25, 0x0146 + 3fc: 0e 94 00 10 call 0x2000 ; 0x2000 + 400: 80 93 28 01 sts 0x0128, r24 + 404: 9c c1 rjmp .+824 ; 0x73e <__stack+0x23f> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 406: 24 3a cpi r18, 0xA4 ; 164 + 408: 81 e0 ldi r24, 0x01 ; 1 + 40a: 38 07 cpc r19, r24 + 40c: 09 f4 brne .+2 ; 0x410 + 40e: d1 c1 rjmp .+930 ; 0x7b2 <__stack+0x2b3> + 410: 25 3a cpi r18, 0xA5 ; 165 + 412: 31 40 sbci r19, 0x01 ; 1 + 414: 09 f0 breq .+2 ; 0x418 + 416: 69 c5 rjmp .+2770 ; 0xeea <__stack+0x9eb> + } + if (stan == s_len) + { + Led1Off(); + Led2On(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + 418: 81 e0 ldi r24, 0x01 ; 1 + 41a: 80 93 28 01 sts 0x0128, r24 + 41e: dc c1 rjmp .+952 ; 0x7d8 <__stack+0x2d9> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 420: 2f 30 cpi r18, 0x0F ; 15 + 422: f2 e0 ldi r31, 0x02 ; 2 + 424: 3f 07 cpc r19, r31 + 426: 09 f4 brne .+2 ; 0x42a + 428: 9c c2 rjmp .+1336 ; 0x962 <__stack+0x463> + 42a: 20 f5 brcc .+72 ; 0x474 + 42c: 24 3f cpi r18, 0xF4 ; 244 + 42e: e1 e0 ldi r30, 0x01 ; 1 + 430: 3e 07 cpc r19, r30 + 432: 09 f4 brne .+2 ; 0x436 + 434: 58 c2 rjmp .+1200 ; 0x8e6 <__stack+0x3e7> + 436: 40 f4 brcc .+16 ; 0x448 + 438: 23 3d cpi r18, 0xD3 ; 211 + 43a: 31 40 sbci r19, 0x01 ; 1 + 43c: 09 f0 breq .+2 ; 0x440 + 43e: 55 c5 rjmp .+2730 ; 0xeea <__stack+0x9eb> + stan = s_CRC_HI; + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 440: 81 e0 ldi r24, 0x01 ; 1 + 442: 80 93 28 01 sts 0x0128, r24 + 446: 17 c2 rjmp .+1070 ; 0x876 <__stack+0x377> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 448: 25 3f cpi r18, 0xF5 ; 245 + 44a: e1 e0 ldi r30, 0x01 ; 1 + 44c: 3e 07 cpc r19, r30 + 44e: 09 f4 brne .+2 ; 0x452 + 450: 5d c2 rjmp .+1210 ; 0x90c <__stack+0x40d> + 452: 2e 30 cpi r18, 0x0E ; 14 + 454: 32 40 sbci r19, 0x02 ; 2 + 456: 09 f0 breq .+2 ; 0x45a + 458: 48 c5 rjmp .+2704 ; 0xeea <__stack+0x9eb> + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + 45a: 40 e0 ldi r20, 0x00 ; 0 + 45c: 50 e0 ldi r21, 0x00 ; 0 + 45e: 6e e2 ldi r22, 0x2E ; 46 + 460: 71 e0 ldi r23, 0x01 ; 1 + 462: 80 91 45 01 lds r24, 0x0145 + 466: 90 91 46 01 lds r25, 0x0146 + 46a: 0e 94 00 10 call 0x2000 ; 0x2000 + 46e: 80 93 28 01 sts 0x0128, r24 + 472: 70 c2 rjmp .+1248 ; 0x954 <__stack+0x455> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 474: 2c 34 cpi r18, 0x4C ; 76 + 476: 82 e0 ldi r24, 0x02 ; 2 + 478: 38 07 cpc r19, r24 + 47a: 09 f4 brne .+2 ; 0x47e + 47c: 15 c3 rjmp .+1578 ; 0xaa8 <__stack+0x5a9> + 47e: 68 f4 brcc .+26 ; 0x49a + 480: 22 34 cpi r18, 0x42 ; 66 + 482: f2 e0 ldi r31, 0x02 ; 2 + 484: 3f 07 cpc r19, r31 + 486: 09 f4 brne .+2 ; 0x48a + 488: df c2 rjmp .+1470 ; 0xa48 <__stack+0x549> + 48a: 23 34 cpi r18, 0x43 ; 67 + 48c: 32 40 sbci r19, 0x02 ; 2 + 48e: 09 f0 breq .+2 ; 0x492 + 490: 2c c5 rjmp .+2648 ; 0xeea <__stack+0x9eb> + if (rezultat == 1) + { + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + 492: 81 e0 ldi r24, 0x01 ; 1 + 494: 80 93 28 01 sts 0x0128, r24 + 498: eb c2 rjmp .+1494 ; 0xa70 <__stack+0x571> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 49a: 2d 34 cpi r18, 0x4D ; 77 + 49c: e2 e0 ldi r30, 0x02 ; 2 + 49e: 3e 07 cpc r19, r30 + 4a0: 09 f4 brne .+2 ; 0x4a4 + 4a2: 16 c3 rjmp .+1580 ; 0xad0 <__stack+0x5d1> + 4a4: 24 35 cpi r18, 0x54 ; 84 + 4a6: 32 40 sbci r19, 0x02 ; 2 + 4a8: 09 f0 breq .+2 ; 0x4ac + 4aa: 1f c5 rjmp .+2622 ; 0xeea <__stack+0x9eb> + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + 4ac: 40 e0 ldi r20, 0x00 ; 0 + 4ae: 50 e0 ldi r21, 0x00 ; 0 + 4b0: 62 e4 ldi r22, 0x42 ; 66 + 4b2: 71 e0 ldi r23, 0x01 ; 1 + 4b4: 80 91 43 01 lds r24, 0x0143 + 4b8: 90 91 44 01 lds r25, 0x0144 + 4bc: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 4c0: 80 93 28 01 sts 0x0128, r24 + 4c4: 24 c3 rjmp .+1608 ; 0xb0e <__stack+0x60f> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 4c6: 2e 39 cpi r18, 0x9E ; 158 + 4c8: 82 e0 ldi r24, 0x02 ; 2 + 4ca: 38 07 cpc r19, r24 + 4cc: 09 f4 brne .+2 ; 0x4d0 + 4ce: 1e c4 rjmp .+2108 ; 0xd0c <__stack+0x80d> + 4d0: 08 f0 brcs .+2 ; 0x4d4 + 4d2: 49 c0 rjmp .+146 ; 0x566 <__stack+0x67> + 4d4: 22 37 cpi r18, 0x72 ; 114 + 4d6: f2 e0 ldi r31, 0x02 ; 2 + 4d8: 3f 07 cpc r19, r31 + 4da: 09 f4 brne .+2 ; 0x4de + 4dc: a6 c3 rjmp .+1868 ; 0xc2a <__stack+0x72b> + 4de: 20 f5 brcc .+72 ; 0x528 <__stack+0x29> + 4e0: 2d 35 cpi r18, 0x5D ; 93 + 4e2: e2 e0 ldi r30, 0x02 ; 2 + 4e4: 3e 07 cpc r19, r30 + 4e6: 09 f4 brne .+2 ; 0x4ea + 4e8: 40 c3 rjmp .+1664 ; 0xb6a <__stack+0x66b> + 4ea: 88 f4 brcc .+34 ; 0x50e <__stack+0xf> + 4ec: 2c 35 cpi r18, 0x5C ; 92 + 4ee: 32 40 sbci r19, 0x02 ; 2 + 4f0: 09 f0 breq .+2 ; 0x4f4 + 4f2: fb c4 rjmp .+2550 ; 0xeea <__stack+0x9eb> + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + 4f4: 40 e0 ldi r20, 0x00 ; 0 + 4f6: 50 e0 ldi r21, 0x00 ; 0 + 4f8: 66 e2 ldi r22, 0x26 ; 38 + 4fa: 71 e0 ldi r23, 0x01 ; 1 + 4fc: 80 91 43 01 lds r24, 0x0143 + 500: 90 91 44 01 lds r25, 0x0144 + 504: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 508: 80 93 28 01 sts 0x0128, r24 + 50c: 27 c3 rjmp .+1614 ; 0xb5c <__stack+0x65d> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 50e: 28 36 cpi r18, 0x68 ; 104 + 510: e2 e0 ldi r30, 0x02 ; 2 + 512: 3e 07 cpc r19, r30 + 514: 09 f4 brne .+2 ; 0x518 <__stack+0x19> + 516: 3a c3 rjmp .+1652 ; 0xb8c <__stack+0x68d> + 518: 29 36 cpi r18, 0x69 ; 105 + 51a: 32 40 sbci r19, 0x02 ; 2 + 51c: 09 f0 breq .+2 ; 0x520 <__stack+0x21> + 51e: e5 c4 rjmp .+2506 ; 0xeea <__stack+0x9eb> + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + 520: 81 e0 ldi r24, 0x01 ; 1 + 522: 80 93 28 01 sts 0x0128, r24 + 526: 47 c3 rjmp .+1678 ; 0xbb6 <__stack+0x6b7> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 528: 26 37 cpi r18, 0x76 ; 118 + 52a: 82 e0 ldi r24, 0x02 ; 2 + 52c: 38 07 cpc r19, r24 + 52e: 09 f4 brne .+2 ; 0x532 <__stack+0x33> + 530: a5 c3 rjmp .+1866 ; 0xc7c <__stack+0x77d> + 532: 40 f4 brcc .+16 ; 0x544 <__stack+0x45> + 534: 23 37 cpi r18, 0x73 ; 115 + 536: 32 40 sbci r19, 0x02 ; 2 + 538: 09 f0 breq .+2 ; 0x53c <__stack+0x3d> + 53a: d7 c4 rjmp .+2478 ; 0xeea <__stack+0x9eb> + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 53c: 81 e0 ldi r24, 0x01 ; 1 + 53e: 80 93 28 01 sts 0x0128, r24 + 542: 87 c3 rjmp .+1806 ; 0xc52 <__stack+0x753> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 544: 27 37 cpi r18, 0x77 ; 119 + 546: 82 e0 ldi r24, 0x02 ; 2 + 548: 38 07 cpc r19, r24 + 54a: 09 f4 brne .+2 ; 0x54e <__stack+0x4f> + 54c: ab c3 rjmp .+1878 ; 0xca4 <__stack+0x7a5> + 54e: 2e 38 cpi r18, 0x8E ; 142 + 550: 32 40 sbci r19, 0x02 ; 2 + 552: 09 f0 breq .+2 ; 0x556 <__stack+0x57> + 554: ca c4 rjmp .+2452 ; 0xeea <__stack+0x9eb> + if (kodRozkazu == rFLASH) + { + Led1On(); + Led2On(); + crDELAY(xHandle, 10); + Led1Off(); + 556: 0e 94 81 08 call 0x1102 ; 0x1102 + Led2Off(); + 55a: 0e 94 8a 08 call 0x1114 ; 0x1114 + (*((void(*)(void))BOOT_START))(); //reboot + 55e: e0 e0 ldi r30, 0x00 ; 0 + 560: fc e1 ldi r31, 0x1C ; 28 + 562: 09 95 icall + 564: 4c c0 rjmp .+152 ; 0x5fe <__stack+0xff> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 566: 2d 3b cpi r18, 0xBD ; 189 + 568: f2 e0 ldi r31, 0x02 ; 2 + 56a: 3f 07 cpc r19, r31 + 56c: 09 f4 brne .+2 ; 0x570 <__stack+0x71> + 56e: 19 c4 rjmp .+2098 ; 0xda2 <__stack+0x8a3> + 570: 08 f5 brcc .+66 ; 0x5b4 <__stack+0xb5> + 572: 26 3a cpi r18, 0xA6 ; 166 + 574: e2 e0 ldi r30, 0x02 ; 2 + 576: 3e 07 cpc r19, r30 + 578: 09 f4 brne .+2 ; 0x57c <__stack+0x7d> + 57a: ef c3 rjmp .+2014 ; 0xd5a <__stack+0x85b> + 57c: 20 f4 brcc .+8 ; 0x586 <__stack+0x87> + 57e: 2f 39 cpi r18, 0x9F ; 159 + 580: 32 40 sbci r19, 0x02 ; 2 + 582: d1 f1 breq .+116 ; 0x5f8 <__stack+0xf9> + 584: b2 c4 rjmp .+2404 ; 0xeea <__stack+0x9eb> + 586: 27 3a cpi r18, 0xA7 ; 167 + 588: e2 e0 ldi r30, 0x02 ; 2 + 58a: 3e 07 cpc r19, r30 + 58c: a9 f1 breq .+106 ; 0x5f8 <__stack+0xf9> + 58e: 2c 3b cpi r18, 0xBC ; 188 + 590: 32 40 sbci r19, 0x02 ; 2 + 592: 09 f0 breq .+2 ; 0x596 <__stack+0x97> + 594: aa c4 rjmp .+2388 ; 0xeea <__stack+0x9eb> + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + 596: 69 81 ldd r22, Y+1 ; 0x01 + 598: 70 e0 ldi r23, 0x00 ; 0 + 59a: 60 50 subi r22, 0x00 ; 0 + 59c: 7f 4f sbci r23, 0xFF ; 255 + 59e: 40 e0 ldi r20, 0x00 ; 0 + 5a0: 50 e0 ldi r21, 0x00 ; 0 + 5a2: 80 91 43 01 lds r24, 0x0143 + 5a6: 90 91 44 01 lds r25, 0x0144 + 5aa: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + 5ae: 80 93 28 01 sts 0x0128, r24 + 5b2: f0 c3 rjmp .+2016 ; 0xd94 <__stack+0x895> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 5b4: 2a 3c cpi r18, 0xCA ; 202 + 5b6: 82 e0 ldi r24, 0x02 ; 2 + 5b8: 38 07 cpc r19, r24 + 5ba: 09 f4 brne .+2 ; 0x5be <__stack+0xbf> + 5bc: 56 c4 rjmp .+2220 ; 0xe6a <__stack+0x96b> + 5be: 68 f4 brcc .+26 ; 0x5da <__stack+0xdb> + 5c0: 26 3c cpi r18, 0xC6 ; 198 + 5c2: f2 e0 ldi r31, 0x02 ; 2 + 5c4: 3f 07 cpc r19, r31 + 5c6: 09 f4 brne .+2 ; 0x5ca <__stack+0xcb> + 5c8: 27 c4 rjmp .+2126 ; 0xe18 <__stack+0x919> + 5ca: 27 3c cpi r18, 0xC7 ; 199 + 5cc: 32 40 sbci r19, 0x02 ; 2 + 5ce: 09 f0 breq .+2 ; 0x5d2 <__stack+0xd3> + 5d0: 8c c4 rjmp .+2328 ; 0xeea <__stack+0x9eb> + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 5d2: 81 e0 ldi r24, 0x01 ; 1 + 5d4: 80 93 28 01 sts 0x0128, r24 + 5d8: 33 c4 rjmp .+2150 ; 0xe40 <__stack+0x941> + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + 5da: 2b 3c cpi r18, 0xCB ; 203 + 5dc: e2 e0 ldi r30, 0x02 ; 2 + 5de: 3e 07 cpc r19, r30 + 5e0: 09 f4 brne .+2 ; 0x5e4 <__stack+0xe5> + 5e2: 57 c4 rjmp .+2222 ; 0xe92 <__stack+0x993> + 5e4: 22 3f cpi r18, 0xF2 ; 242 + 5e6: 32 40 sbci r19, 0x02 ; 2 + 5e8: 09 f0 breq .+2 ; 0x5ec <__stack+0xed> + 5ea: 7f c4 rjmp .+2302 ; 0xeea <__stack+0x9eb> + DISABLE_RX(); + Led1On(); + Led2On(); + //TODO disable RX buffer + crDELAY(xHandle, 1000); + ENABLE_RX(); + 5ec: 80 91 c1 00 lds r24, 0x00C1 + 5f0: 80 61 ori r24, 0x10 ; 16 + 5f2: 80 93 c1 00 sts 0x00C1, r24 + 5f6: 76 c4 rjmp .+2284 ; 0xee4 <__stack+0x9e5> + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 3) + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + 5f8: 81 e0 ldi r24, 0x01 ; 1 + 5fa: 80 93 28 01 sts 0x0128, r24 + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + Led1Off(); + 5fe: 0e 94 81 08 call 0x1102 ; 0x1102 + Led2Off(); + 602: 0e 94 8a 08 call 0x1114 ; 0x1114 + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + 606: 10 92 2a 01 sts 0x012A, r1 + crDELAY(xHandle, 100); + } +*/ + for( ;; ) + { + if (stan == s_sync) + 60a: 80 91 2a 01 lds r24, 0x012A + 60e: 81 11 cpse r24, r1 + 610: 3c c0 rjmp .+120 ; 0x68a <__stack+0x18b> + { + znak=0; + 612: 10 92 29 01 sts 0x0129, r1 + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + 616: 4f ef ldi r20, 0xFF ; 255 + 618: 5f ef ldi r21, 0xFF ; 255 + 61a: 69 e2 ldi r22, 0x29 ; 41 + 61c: 71 e0 ldi r23, 0x01 ; 1 + 61e: 80 91 45 01 lds r24, 0x0145 + 622: 90 91 46 01 lds r25, 0x0146 + 626: 0e 94 00 10 call 0x2000 ; 0x2000 + 62a: 80 93 28 01 sts 0x0128, r24 + 62e: 8c 3f cpi r24, 0xFC ; 252 + 630: 79 f4 brne .+30 ; 0x650 <__stack+0x151> + 632: 8c e4 ldi r24, 0x4C ; 76 + 634: 91 e0 ldi r25, 0x01 ; 1 + 636: 52 c4 rjmp .+2212 ; 0xedc <__stack+0x9dd> + 638: 40 e0 ldi r20, 0x00 ; 0 + 63a: 50 e0 ldi r21, 0x00 ; 0 + 63c: 69 e2 ldi r22, 0x29 ; 41 + 63e: 71 e0 ldi r23, 0x01 ; 1 + 640: 80 91 45 01 lds r24, 0x0145 + 644: 90 91 46 01 lds r25, 0x0146 + 648: 0e 94 00 10 call 0x2000 ; 0x2000 + 64c: 80 93 28 01 sts 0x0128, r24 + 650: 80 91 28 01 lds r24, 0x0128 + 654: 8b 3f cpi r24, 0xFB ; 251 + 656: 31 f4 brne .+12 ; 0x664 <__stack+0x165> + 658: 8d e4 ldi r24, 0x4D ; 77 + 65a: 91 e0 ldi r25, 0x01 ; 1 + 65c: 3f c4 rjmp .+2174 ; 0xedc <__stack+0x9dd> + 65e: 81 e0 ldi r24, 0x01 ; 1 + 660: 80 93 28 01 sts 0x0128, r24 + if ((xResult == pdPASS) && (znak == SYNC)) + 664: 80 91 28 01 lds r24, 0x0128 + 668: 81 30 cpi r24, 0x01 ; 1 + 66a: 79 f4 brne .+30 ; 0x68a <__stack+0x18b> + 66c: 90 91 29 01 lds r25, 0x0129 + 670: 9a 35 cpi r25, 0x5A ; 90 + 672: 59 f4 brne .+22 ; 0x68a <__stack+0x18b> + { + stan = s_addr; + 674: 80 93 2a 01 sts 0x012A, r24 + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + 678: 6a e5 ldi r22, 0x5A ; 90 + 67a: 80 e0 ldi r24, 0x00 ; 0 + 67c: 90 e0 ldi r25, 0x00 ; 0 + 67e: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + 682: 90 93 2c 01 sts 0x012C, r25 + 686: 80 93 2b 01 sts 0x012B, r24 + } + } + if (stan == s_addr) + 68a: 80 91 2a 01 lds r24, 0x012A + 68e: 81 30 cpi r24, 0x01 ; 1 + 690: e9 f5 brne .+122 ; 0x70c <__stack+0x20d> + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 692: 41 e0 ldi r20, 0x01 ; 1 + 694: 50 e0 ldi r21, 0x00 ; 0 + 696: 69 e2 ldi r22, 0x29 ; 41 + 698: 71 e0 ldi r23, 0x01 ; 1 + 69a: 80 91 45 01 lds r24, 0x0145 + 69e: 90 91 46 01 lds r25, 0x0146 + 6a2: 0e 94 00 10 call 0x2000 ; 0x2000 + 6a6: 80 93 28 01 sts 0x0128, r24 + 6aa: 8c 3f cpi r24, 0xFC ; 252 + 6ac: 19 f4 brne .+6 ; 0x6b4 <__stack+0x1b5> + 6ae: 80 e6 ldi r24, 0x60 ; 96 + 6b0: 91 e0 ldi r25, 0x01 ; 1 + 6b2: 14 c4 rjmp .+2088 ; 0xedc <__stack+0x9dd> + 6b4: 80 91 28 01 lds r24, 0x0128 + 6b8: 8b 3f cpi r24, 0xFB ; 251 + 6ba: 31 f4 brne .+12 ; 0x6c8 <__stack+0x1c9> + 6bc: 81 e6 ldi r24, 0x61 ; 97 + 6be: 91 e0 ldi r25, 0x01 ; 1 + 6c0: 0d c4 rjmp .+2074 ; 0xedc <__stack+0x9dd> + 6c2: 81 e0 ldi r24, 0x01 ; 1 + 6c4: 80 93 28 01 sts 0x0128, r24 + if (xResult == pdPASS) + 6c8: f0 90 28 01 lds r15, 0x0128 + 6cc: f1 e0 ldi r31, 0x01 ; 1 + 6ce: ff 12 cpse r15, r31 + 6d0: 1b c0 rjmp .+54 ; 0x708 <__stack+0x209> + { + stan = s_rozkaz; + 6d2: 82 e0 ldi r24, 0x02 ; 2 + 6d4: 80 93 2a 01 sts 0x012A, r24 + crc = _crc_xmodem_update(crc, znak); + 6d8: 60 91 29 01 lds r22, 0x0129 + 6dc: 80 91 2b 01 lds r24, 0x012B + 6e0: 90 91 2c 01 lds r25, 0x012C + 6e4: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + 6e8: 90 93 2c 01 sts 0x012C, r25 + 6ec: 80 93 2b 01 sts 0x012B, r24 + if (znak == adres) + 6f0: 90 91 29 01 lds r25, 0x0129 + 6f4: 80 91 c1 04 lds r24, 0x04C1 + 6f8: 98 13 cpse r25, r24 + 6fa: 03 c0 rjmp .+6 ; 0x702 <__stack+0x203> + dobryAdres = 1; + 6fc: f0 92 27 01 sts 0x0127, r15 + 700: 05 c0 rjmp .+10 ; 0x70c <__stack+0x20d> + else + dobryAdres = 0; + 702: 10 92 27 01 sts 0x0127, r1 + 706: 02 c0 rjmp .+4 ; 0x70c <__stack+0x20d> + } + else + { + stan = s_sync; + 708: 10 92 2a 01 sts 0x012A, r1 + } + } + if (stan == s_rozkaz) + 70c: 80 91 2a 01 lds r24, 0x012A + 710: 82 30 cpi r24, 0x02 ; 2 + 712: a9 f5 brne .+106 ; 0x77e <__stack+0x27f> + { + Led1On(); + 714: 0e 94 7a 08 call 0x10f4 ; 0x10f4 + Led2Off(); + 718: 0e 94 8a 08 call 0x1114 ; 0x1114 + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + 71c: 41 e0 ldi r20, 0x01 ; 1 + 71e: 50 e0 ldi r21, 0x00 ; 0 + 720: 62 e4 ldi r22, 0x42 ; 66 + 722: 71 e0 ldi r23, 0x01 ; 1 + 724: 80 91 45 01 lds r24, 0x0145 + 728: 90 91 46 01 lds r25, 0x0146 + 72c: 0e 94 00 10 call 0x2000 ; 0x2000 + 730: 80 93 28 01 sts 0x0128, r24 + 734: 8c 3f cpi r24, 0xFC ; 252 + 736: 19 f4 brne .+6 ; 0x73e <__stack+0x23f> + 738: 86 e8 ldi r24, 0x86 ; 134 + 73a: 91 e0 ldi r25, 0x01 ; 1 + 73c: cf c3 rjmp .+1950 ; 0xedc <__stack+0x9dd> + 73e: 80 91 28 01 lds r24, 0x0128 + 742: 8b 3f cpi r24, 0xFB ; 251 + 744: 31 f4 brne .+12 ; 0x752 <__stack+0x253> + 746: 87 e8 ldi r24, 0x87 ; 135 + 748: 91 e0 ldi r25, 0x01 ; 1 + 74a: c8 c3 rjmp .+1936 ; 0xedc <__stack+0x9dd> + 74c: 81 e0 ldi r24, 0x01 ; 1 + 74e: 80 93 28 01 sts 0x0128, r24 + if (xResult == pdPASS) + 752: 80 91 28 01 lds r24, 0x0128 + 756: 81 30 cpi r24, 0x01 ; 1 + 758: 81 f4 brne .+32 ; 0x77a <__stack+0x27b> + { + crc = _crc_xmodem_update(crc, kodRozkazu); + 75a: 60 91 42 01 lds r22, 0x0142 + 75e: 80 91 2b 01 lds r24, 0x012B + 762: 90 91 2c 01 lds r25, 0x012C + 766: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + 76a: 90 93 2c 01 sts 0x012C, r25 + 76e: 80 93 2b 01 sts 0x012B, r24 + stan = s_len; + 772: 83 e0 ldi r24, 0x03 ; 3 + 774: 80 93 2a 01 sts 0x012A, r24 + 778: 02 c0 rjmp .+4 ; 0x77e <__stack+0x27f> + } + else + { + stan = s_sync; + 77a: 10 92 2a 01 sts 0x012A, r1 + } + } + if (stan == s_len) + 77e: 80 91 2a 01 lds r24, 0x012A + 782: 83 30 cpi r24, 0x03 ; 3 + 784: 09 f0 breq .+2 ; 0x788 <__stack+0x289> + 786: 44 c0 rjmp .+136 ; 0x810 <__stack+0x311> + { + Led1Off(); + 788: 0e 94 81 08 call 0x1102 ; 0x1102 + Led2On(); + 78c: 0e 94 83 08 call 0x1106 ; 0x1106 + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + 790: 41 e0 ldi r20, 0x01 ; 1 + 792: 50 e0 ldi r21, 0x00 ; 0 + 794: 61 e4 ldi r22, 0x41 ; 65 + 796: 71 e0 ldi r23, 0x01 ; 1 + 798: 80 91 45 01 lds r24, 0x0145 + 79c: 90 91 46 01 lds r25, 0x0146 + 7a0: 0e 94 00 10 call 0x2000 ; 0x2000 + 7a4: 80 93 28 01 sts 0x0128, r24 + 7a8: 8c 3f cpi r24, 0xFC ; 252 + 7aa: 79 f4 brne .+30 ; 0x7ca <__stack+0x2cb> + 7ac: 84 ea ldi r24, 0xA4 ; 164 + 7ae: 91 e0 ldi r25, 0x01 ; 1 + 7b0: 95 c3 rjmp .+1834 ; 0xedc <__stack+0x9dd> + 7b2: 40 e0 ldi r20, 0x00 ; 0 + 7b4: 50 e0 ldi r21, 0x00 ; 0 + 7b6: 61 e4 ldi r22, 0x41 ; 65 + 7b8: 71 e0 ldi r23, 0x01 ; 1 + 7ba: 80 91 45 01 lds r24, 0x0145 + 7be: 90 91 46 01 lds r25, 0x0146 + 7c2: 0e 94 00 10 call 0x2000 ; 0x2000 + 7c6: 80 93 28 01 sts 0x0128, r24 + 7ca: 80 91 28 01 lds r24, 0x0128 + 7ce: 8b 3f cpi r24, 0xFB ; 251 + 7d0: 19 f4 brne .+6 ; 0x7d8 <__stack+0x2d9> + 7d2: 85 ea ldi r24, 0xA5 ; 165 + 7d4: 91 e0 ldi r25, 0x01 ; 1 + 7d6: 82 c3 rjmp .+1796 ; 0xedc <__stack+0x9dd> + if (xResult == pdPASS) + 7d8: 80 91 28 01 lds r24, 0x0128 + 7dc: 81 30 cpi r24, 0x01 ; 1 + 7de: b1 f4 brne .+44 ; 0x80c <__stack+0x30d> + { + crc = _crc_xmodem_update(crc, dlDanych); + 7e0: 60 91 41 01 lds r22, 0x0141 + 7e4: 80 91 2b 01 lds r24, 0x012B + 7e8: 90 91 2c 01 lds r25, 0x012C + 7ec: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + 7f0: 90 93 2c 01 sts 0x012C, r25 + 7f4: 80 93 2b 01 sts 0x012B, r24 + lOdebrDanych = 0; + 7f8: 10 92 26 01 sts 0x0126, r1 + stan = s_dane; + 7fc: 84 e0 ldi r24, 0x04 ; 4 + 7fe: 80 93 2a 01 sts 0x012A, r24 + Led1On(); + 802: 0e 94 7a 08 call 0x10f4 ; 0x10f4 + Led2On(); + 806: 0e 94 83 08 call 0x1106 ; 0x1106 + 80a: 02 c0 rjmp .+4 ; 0x810 <__stack+0x311> + } + else + { + stan = s_sync; + 80c: 10 92 2a 01 sts 0x012A, r1 + } + } + if (stan == s_dane) + 810: 80 91 2a 01 lds r24, 0x012A + 814: 84 30 cpi r24, 0x04 ; 4 + 816: 09 f0 breq .+2 ; 0x81a <__stack+0x31b> + 818: 51 c0 rjmp .+162 ; 0x8bc <__stack+0x3bd> + { + if (lOdebrDanych == dlDanych) + 81a: 80 91 41 01 lds r24, 0x0141 + 81e: 90 91 26 01 lds r25, 0x0126 + 822: 98 13 cpse r25, r24 + 824: 04 c0 rjmp .+8 ; 0x82e <__stack+0x32f> + { + stan = s_CRC_HI; + 826: 85 e0 ldi r24, 0x05 ; 5 + 828: 80 93 2a 01 sts 0x012A, r24 + 82c: 47 c0 rjmp .+142 ; 0x8bc <__stack+0x3bd> + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 82e: 41 e0 ldi r20, 0x01 ; 1 + 830: 50 e0 ldi r21, 0x00 ; 0 + 832: 69 e2 ldi r22, 0x29 ; 41 + 834: 71 e0 ldi r23, 0x01 ; 1 + 836: 80 91 45 01 lds r24, 0x0145 + 83a: 90 91 46 01 lds r25, 0x0146 + 83e: 0e 94 00 10 call 0x2000 ; 0x2000 + 842: 80 93 28 01 sts 0x0128, r24 + 846: 8c 3f cpi r24, 0xFC ; 252 + 848: 79 f4 brne .+30 ; 0x868 <__stack+0x369> + 84a: 82 ed ldi r24, 0xD2 ; 210 + 84c: 91 e0 ldi r25, 0x01 ; 1 + 84e: 46 c3 rjmp .+1676 ; 0xedc <__stack+0x9dd> + 850: 40 e0 ldi r20, 0x00 ; 0 + 852: 50 e0 ldi r21, 0x00 ; 0 + 854: 69 e2 ldi r22, 0x29 ; 41 + 856: 71 e0 ldi r23, 0x01 ; 1 + 858: 80 91 45 01 lds r24, 0x0145 + 85c: 90 91 46 01 lds r25, 0x0146 + 860: 0e 94 00 10 call 0x2000 ; 0x2000 + 864: 80 93 28 01 sts 0x0128, r24 + 868: 80 91 28 01 lds r24, 0x0128 + 86c: 8b 3f cpi r24, 0xFB ; 251 + 86e: 19 f4 brne .+6 ; 0x876 <__stack+0x377> + 870: 83 ed ldi r24, 0xD3 ; 211 + 872: 91 e0 ldi r25, 0x01 ; 1 + 874: 33 c3 rjmp .+1638 ; 0xedc <__stack+0x9dd> + if (xResult == pdPASS) + 876: 80 91 28 01 lds r24, 0x0128 + 87a: 81 30 cpi r24, 0x01 ; 1 + 87c: d9 f4 brne .+54 ; 0x8b4 <__stack+0x3b5> + { + crc = _crc_xmodem_update(crc, znak); + 87e: 60 91 29 01 lds r22, 0x0129 + 882: 80 91 2b 01 lds r24, 0x012B + 886: 90 91 2c 01 lds r25, 0x012C + 88a: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + 88e: 90 93 2c 01 sts 0x012C, r25 + 892: 80 93 2b 01 sts 0x012B, r24 + if (lOdebrDanych < MAX_DATA_LEN) + 896: 80 91 26 01 lds r24, 0x0126 + 89a: 8e 30 cpi r24, 0x0E ; 14 + 89c: 38 f4 brcc .+14 ; 0x8ac <__stack+0x3ad> + bDane[lOdebrDanych] = znak; + 89e: e8 2f mov r30, r24 + 8a0: f0 e0 ldi r31, 0x00 ; 0 + 8a2: ed 5c subi r30, 0xCD ; 205 + 8a4: fe 4f sbci r31, 0xFE ; 254 + 8a6: 90 91 29 01 lds r25, 0x0129 + 8aa: 90 83 st Z, r25 + lOdebrDanych++; + 8ac: 8f 5f subi r24, 0xFF ; 255 + 8ae: 80 93 26 01 sts 0x0126, r24 + 8b2: 04 c0 rjmp .+8 ; 0x8bc <__stack+0x3bd> + } + else + { + Led1Off(); + 8b4: 0e 94 81 08 call 0x1102 ; 0x1102 + stan = s_sync; + 8b8: 10 92 2a 01 sts 0x012A, r1 + } + } + } + if (stan == s_CRC_HI) + 8bc: 80 91 2a 01 lds r24, 0x012A + 8c0: 85 30 cpi r24, 0x05 ; 5 + 8c2: 99 f5 brne .+102 ; 0x92a <__stack+0x42b> + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + 8c4: 41 e0 ldi r20, 0x01 ; 1 + 8c6: 50 e0 ldi r21, 0x00 ; 0 + 8c8: 6d e2 ldi r22, 0x2D ; 45 + 8ca: 71 e0 ldi r23, 0x01 ; 1 + 8cc: 80 91 45 01 lds r24, 0x0145 + 8d0: 90 91 46 01 lds r25, 0x0146 + 8d4: 0e 94 00 10 call 0x2000 ; 0x2000 + 8d8: 80 93 28 01 sts 0x0128, r24 + 8dc: 8c 3f cpi r24, 0xFC ; 252 + 8de: 79 f4 brne .+30 ; 0x8fe <__stack+0x3ff> + 8e0: 84 ef ldi r24, 0xF4 ; 244 + 8e2: 91 e0 ldi r25, 0x01 ; 1 + 8e4: fb c2 rjmp .+1526 ; 0xedc <__stack+0x9dd> + 8e6: 40 e0 ldi r20, 0x00 ; 0 + 8e8: 50 e0 ldi r21, 0x00 ; 0 + 8ea: 6d e2 ldi r22, 0x2D ; 45 + 8ec: 71 e0 ldi r23, 0x01 ; 1 + 8ee: 80 91 45 01 lds r24, 0x0145 + 8f2: 90 91 46 01 lds r25, 0x0146 + 8f6: 0e 94 00 10 call 0x2000 ; 0x2000 + 8fa: 80 93 28 01 sts 0x0128, r24 + 8fe: 80 91 28 01 lds r24, 0x0128 + 902: 8b 3f cpi r24, 0xFB ; 251 + 904: 31 f4 brne .+12 ; 0x912 <__stack+0x413> + 906: 85 ef ldi r24, 0xF5 ; 245 + 908: 91 e0 ldi r25, 0x01 ; 1 + 90a: e8 c2 rjmp .+1488 ; 0xedc <__stack+0x9dd> + 90c: 81 e0 ldi r24, 0x01 ; 1 + 90e: 80 93 28 01 sts 0x0128, r24 + if (xResult == pdPASS) + 912: 80 91 28 01 lds r24, 0x0128 + 916: 81 30 cpi r24, 0x01 ; 1 + 918: 21 f4 brne .+8 ; 0x922 <__stack+0x423> + { + stan = s_CRC_LO; + 91a: 86 e0 ldi r24, 0x06 ; 6 + 91c: 80 93 2a 01 sts 0x012A, r24 + 920: 04 c0 rjmp .+8 ; 0x92a <__stack+0x42b> + } + else + { + Led1Off(); + 922: 0e 94 81 08 call 0x1102 ; 0x1102 + stan = s_sync; + 926: 10 92 2a 01 sts 0x012A, r1 + } + } + if (stan == s_CRC_LO) + 92a: 80 91 2a 01 lds r24, 0x012A + 92e: 86 30 cpi r24, 0x06 ; 6 + 930: 99 f5 brne .+102 ; 0x998 <__stack+0x499> + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + 932: 41 e0 ldi r20, 0x01 ; 1 + 934: 50 e0 ldi r21, 0x00 ; 0 + 936: 6e e2 ldi r22, 0x2E ; 46 + 938: 71 e0 ldi r23, 0x01 ; 1 + 93a: 80 91 45 01 lds r24, 0x0145 + 93e: 90 91 46 01 lds r25, 0x0146 + 942: 0e 94 00 10 call 0x2000 ; 0x2000 + 946: 80 93 28 01 sts 0x0128, r24 + 94a: 8c 3f cpi r24, 0xFC ; 252 + 94c: 19 f4 brne .+6 ; 0x954 <__stack+0x455> + 94e: 8e e0 ldi r24, 0x0E ; 14 + 950: 92 e0 ldi r25, 0x02 ; 2 + 952: c4 c2 rjmp .+1416 ; 0xedc <__stack+0x9dd> + 954: 80 91 28 01 lds r24, 0x0128 + 958: 8b 3f cpi r24, 0xFB ; 251 + 95a: 31 f4 brne .+12 ; 0x968 <__stack+0x469> + 95c: 8f e0 ldi r24, 0x0F ; 15 + 95e: 92 e0 ldi r25, 0x02 ; 2 + 960: bd c2 rjmp .+1402 ; 0xedc <__stack+0x9dd> + 962: 81 e0 ldi r24, 0x01 ; 1 + 964: 80 93 28 01 sts 0x0128, r24 + if (xResult == pdPASS) + 968: 80 91 28 01 lds r24, 0x0128 + 96c: 81 30 cpi r24, 0x01 ; 1 + 96e: a1 f4 brne .+40 ; 0x998 <__stack+0x499> + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + 970: 80 91 2b 01 lds r24, 0x012B + 974: 90 91 2c 01 lds r25, 0x012C + 978: 20 91 2d 01 lds r18, 0x012D + 97c: 29 13 cpse r18, r25 + 97e: 04 c0 rjmp .+8 ; 0x988 <__stack+0x489> + 980: 90 91 2e 01 lds r25, 0x012E + 984: 98 17 cp r25, r24 + 986: 29 f0 breq .+10 ; 0x992 <__stack+0x493> + { + Led1Off(); + 988: 0e 94 81 08 call 0x1102 ; 0x1102 + stan = s_sync; + 98c: 10 92 2a 01 sts 0x012A, r1 + 990: 03 c0 rjmp .+6 ; 0x998 <__stack+0x499> + } + else + { + stan = s_CRC_OK; + 992: 87 e0 ldi r24, 0x07 ; 7 + 994: 80 93 2a 01 sts 0x012A, r24 + } + } + } + if (stan == s_CRC_OK) + 998: 80 91 2a 01 lds r24, 0x012A + 99c: 87 30 cpi r24, 0x07 ; 7 + 99e: 09 f0 breq .+2 ; 0x9a2 <__stack+0x4a3> + 9a0: 34 ce rjmp .-920 ; 0x60a <__stack+0x10b> + { + if (dobryAdres == 1) + 9a2: 80 91 27 01 lds r24, 0x0127 + 9a6: 81 30 cpi r24, 0x01 ; 1 + 9a8: 09 f0 breq .+2 ; 0x9ac <__stack+0x4ad> + 9aa: 83 c2 rjmp .+1286 ; 0xeb2 <__stack+0x9b3> + { + if (lOdebrDanych > MAX_DATA_LEN) + 9ac: 80 91 26 01 lds r24, 0x0126 + 9b0: 8f 30 cpi r24, 0x0F ; 15 + 9b2: 18 f0 brcs .+6 ; 0x9ba <__stack+0x4bb> + lOdebrDanych = MAX_DATA_LEN; + 9b4: 8e e0 ldi r24, 0x0E ; 14 + 9b6: 80 93 26 01 sts 0x0126, r24 +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + 9ba: 80 91 42 01 lds r24, 0x0142 + 9be: 80 33 cpi r24, 0x30 ; 48 + 9c0: 39 f1 breq .+78 ; 0xa10 <__stack+0x511> + 9c2: 68 f4 brcc .+26 ; 0x9de <__stack+0x4df> + 9c4: 81 31 cpi r24, 0x11 ; 17 + 9c6: c9 f0 breq .+50 ; 0x9fa <__stack+0x4fb> + 9c8: 20 f4 brcc .+8 ; 0x9d2 <__stack+0x4d3> + 9ca: 80 31 cpi r24, 0x10 ; 16 + 9cc: 19 f5 brne .+70 ; 0xa14 <__stack+0x515> + { + case rOpuscRolete1: + wiadomosc = 0x3F; + 9ce: 8f e3 ldi r24, 0x3F ; 63 + 9d0: 17 c0 rjmp .+46 ; 0xa00 <__stack+0x501> +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + 9d2: 80 32 cpi r24, 0x20 ; 32 + 9d4: a1 f0 breq .+40 ; 0x9fe <__stack+0x4ff> + 9d6: 81 32 cpi r24, 0x21 ; 33 + 9d8: e9 f4 brne .+58 ; 0xa14 <__stack+0x515> + wiadomosc = 0xBF; + wysylac = 2; + break; + + case rPodniesRolete2: + wiadomosc = 0xBF; + 9da: 8f eb ldi r24, 0xBF ; 191 + 9dc: 15 c0 rjmp .+42 ; 0xa08 <__stack+0x509> +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + 9de: 82 38 cpi r24, 0x82 ; 130 + 9e0: 30 f4 brcc .+12 ; 0x9ee <__stack+0x4ef> + 9e2: 80 38 cpi r24, 0x80 ; 128 + 9e4: 40 f4 brcc .+16 ; 0x9f6 <__stack+0x4f7> + 9e6: 81 33 cpi r24, 0x31 ; 49 + 9e8: a9 f4 brne .+42 ; 0xa14 <__stack+0x515> + wiadomosc = 0x40; + wysylac = 2; + break; + + case rZatrzymajRolete2: + wiadomosc = 0x40; + 9ea: 80 e4 ldi r24, 0x40 ; 64 + 9ec: 0d c0 rjmp .+26 ; 0xa08 <__stack+0x509> +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + 9ee: 82 38 cpi r24, 0x82 ; 130 + 9f0: 89 f4 brne .+34 ; 0xa14 <__stack+0x515> + + case rPING: + wysylac = 1; + break; + case rHELLO: + wysylac = 4; + 9f2: 84 e0 ldi r24, 0x04 ; 4 + 9f4: 10 c0 rjmp .+32 ; 0xa16 <__stack+0x517> + wiadomosc = 0x40; + wysylac = 3; + break; + + case rPING: + wysylac = 1; + 9f6: 81 e0 ldi r24, 0x01 ; 1 + 9f8: 0e c0 rjmp .+28 ; 0xa16 <__stack+0x517> + wiadomosc = 0x3F; + wysylac = 2; + break; + + case rOpuscRolete2: + wiadomosc = 0x3F; + 9fa: 8f e3 ldi r24, 0x3F ; 63 + 9fc: 05 c0 rjmp .+10 ; 0xa08 <__stack+0x509> + wysylac = 3; + break; + + case rPodniesRolete1: + wiadomosc = 0xBF; + 9fe: 8f eb ldi r24, 0xBF ; 191 + a00: 80 93 32 01 sts 0x0132, r24 + wysylac = 2; + a04: 82 e0 ldi r24, 0x02 ; 2 + a06: 07 c0 rjmp .+14 ; 0xa16 <__stack+0x517> + break; + + case rPodniesRolete2: + wiadomosc = 0xBF; + a08: 80 93 32 01 sts 0x0132, r24 + wysylac = 3; + a0c: 83 e0 ldi r24, 0x03 ; 3 + a0e: 03 c0 rjmp .+6 ; 0xa16 <__stack+0x517> + break; + + case rZatrzymajRolete1: + wiadomosc = 0x40; + a10: 80 e4 ldi r24, 0x40 ; 64 + a12: f6 cf rjmp .-20 ; 0xa00 <__stack+0x501> +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + a14: 80 e0 ldi r24, 0x00 ; 0 + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + a16: 80 93 25 01 sts 0x0125, r24 + if (rezultat == 1) + a1a: 81 30 cpi r24, 0x01 ; 1 + a1c: 09 f0 breq .+2 ; 0xa20 <__stack+0x521> + a1e: 63 c1 rjmp .+710 ; 0xce6 <__stack+0x7e7> + { + //SYNC + uint8_t temp; + temp = SYNC; + a20: 8a e5 ldi r24, 0x5A ; 90 + a22: 89 83 std Y+1, r24 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + a24: 40 e0 ldi r20, 0x00 ; 0 + a26: 50 e0 ldi r21, 0x00 ; 0 + a28: be 01 movw r22, r28 + a2a: 6f 5f subi r22, 0xFF ; 255 + a2c: 7f 4f sbci r23, 0xFF ; 255 + a2e: 80 91 43 01 lds r24, 0x0143 + a32: 90 91 44 01 lds r25, 0x0144 + a36: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + a3a: 80 93 28 01 sts 0x0128, r24 + a3e: 8c 3f cpi r24, 0xFC ; 252 + a40: 81 f4 brne .+32 ; 0xa62 <__stack+0x563> + a42: 82 e4 ldi r24, 0x42 ; 66 + a44: 92 e0 ldi r25, 0x02 ; 2 + a46: 4a c2 rjmp .+1172 ; 0xedc <__stack+0x9dd> + a48: 40 e0 ldi r20, 0x00 ; 0 + a4a: 50 e0 ldi r21, 0x00 ; 0 + a4c: be 01 movw r22, r28 + a4e: 6f 5f subi r22, 0xFF ; 255 + a50: 7f 4f sbci r23, 0xFF ; 255 + a52: 80 91 43 01 lds r24, 0x0143 + a56: 90 91 44 01 lds r25, 0x0144 + a5a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + a5e: 80 93 28 01 sts 0x0128, r24 + a62: 80 91 28 01 lds r24, 0x0128 + a66: 8b 3f cpi r24, 0xFB ; 251 + a68: 19 f4 brne .+6 ; 0xa70 <__stack+0x571> + a6a: 83 e4 ldi r24, 0x43 ; 67 + a6c: 92 e0 ldi r25, 0x02 ; 2 + a6e: 36 c2 rjmp .+1132 ; 0xedc <__stack+0x9dd> + crc = _crc_xmodem_update(0, temp); + a70: 69 81 ldd r22, Y+1 ; 0x01 + a72: 80 e0 ldi r24, 0x00 ; 0 + a74: 90 e0 ldi r25, 0x00 ; 0 + a76: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + a7a: 90 93 2c 01 sts 0x012C, r25 + a7e: 80 93 2b 01 sts 0x012B, r24 + + //ADRES 0x00 adres mastera + temp = 0x00; + a82: 19 82 std Y+1, r1 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + a84: 40 e0 ldi r20, 0x00 ; 0 + a86: 50 e0 ldi r21, 0x00 ; 0 + a88: be 01 movw r22, r28 + a8a: 6f 5f subi r22, 0xFF ; 255 + a8c: 7f 4f sbci r23, 0xFF ; 255 + a8e: 80 91 43 01 lds r24, 0x0143 + a92: 90 91 44 01 lds r25, 0x0144 + a96: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + a9a: 80 93 28 01 sts 0x0128, r24 + a9e: 8c 3f cpi r24, 0xFC ; 252 + aa0: 81 f4 brne .+32 ; 0xac2 <__stack+0x5c3> + aa2: 8c e4 ldi r24, 0x4C ; 76 + aa4: 92 e0 ldi r25, 0x02 ; 2 + aa6: 1a c2 rjmp .+1076 ; 0xedc <__stack+0x9dd> + aa8: 40 e0 ldi r20, 0x00 ; 0 + aaa: 50 e0 ldi r21, 0x00 ; 0 + aac: be 01 movw r22, r28 + aae: 6f 5f subi r22, 0xFF ; 255 + ab0: 7f 4f sbci r23, 0xFF ; 255 + ab2: 80 91 43 01 lds r24, 0x0143 + ab6: 90 91 44 01 lds r25, 0x0144 + aba: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + abe: 80 93 28 01 sts 0x0128, r24 + ac2: 80 91 28 01 lds r24, 0x0128 + ac6: 8b 3f cpi r24, 0xFB ; 251 + ac8: 31 f4 brne .+12 ; 0xad6 <__stack+0x5d7> + aca: 8d e4 ldi r24, 0x4D ; 77 + acc: 92 e0 ldi r25, 0x02 ; 2 + ace: 06 c2 rjmp .+1036 ; 0xedc <__stack+0x9dd> + ad0: 81 e0 ldi r24, 0x01 ; 1 + ad2: 80 93 28 01 sts 0x0128, r24 + crc = _crc_xmodem_update(crc, temp); + ad6: 69 81 ldd r22, Y+1 ; 0x01 + ad8: 80 91 2b 01 lds r24, 0x012B + adc: 90 91 2c 01 lds r25, 0x012C + ae0: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + ae4: 90 93 2c 01 sts 0x012C, r25 + ae8: 80 93 2b 01 sts 0x012B, r24 + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + aec: 40 e0 ldi r20, 0x00 ; 0 + aee: 50 e0 ldi r21, 0x00 ; 0 + af0: 62 e4 ldi r22, 0x42 ; 66 + af2: 71 e0 ldi r23, 0x01 ; 1 + af4: 80 91 43 01 lds r24, 0x0143 + af8: 90 91 44 01 lds r25, 0x0144 + afc: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + b00: 80 93 28 01 sts 0x0128, r24 + b04: 8c 3f cpi r24, 0xFC ; 252 + b06: 19 f4 brne .+6 ; 0xb0e <__stack+0x60f> + b08: 84 e5 ldi r24, 0x54 ; 84 + b0a: 92 e0 ldi r25, 0x02 ; 2 + b0c: e7 c1 rjmp .+974 ; 0xedc <__stack+0x9dd> + b0e: 80 91 28 01 lds r24, 0x0128 + b12: 8b 3f cpi r24, 0xFB ; 251 + b14: 31 f4 brne .+12 ; 0xb22 <__stack+0x623> + b16: 85 e5 ldi r24, 0x55 ; 85 + b18: 92 e0 ldi r25, 0x02 ; 2 + b1a: e0 c1 rjmp .+960 ; 0xedc <__stack+0x9dd> + b1c: 81 e0 ldi r24, 0x01 ; 1 + b1e: 80 93 28 01 sts 0x0128, r24 + crc = _crc_xmodem_update(crc, kodRozkazu); + b22: 60 91 42 01 lds r22, 0x0142 + b26: 80 91 2b 01 lds r24, 0x012B + b2a: 90 91 2c 01 lds r25, 0x012C + b2e: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + b32: 90 93 2c 01 sts 0x012C, r25 + b36: 80 93 2b 01 sts 0x012B, r24 + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + b3a: 40 e0 ldi r20, 0x00 ; 0 + b3c: 50 e0 ldi r21, 0x00 ; 0 + b3e: 66 e2 ldi r22, 0x26 ; 38 + b40: 71 e0 ldi r23, 0x01 ; 1 + b42: 80 91 43 01 lds r24, 0x0143 + b46: 90 91 44 01 lds r25, 0x0144 + b4a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + b4e: 80 93 28 01 sts 0x0128, r24 + b52: 8c 3f cpi r24, 0xFC ; 252 + b54: 19 f4 brne .+6 ; 0xb5c <__stack+0x65d> + b56: 8c e5 ldi r24, 0x5C ; 92 + b58: 92 e0 ldi r25, 0x02 ; 2 + b5a: c0 c1 rjmp .+896 ; 0xedc <__stack+0x9dd> + b5c: 80 91 28 01 lds r24, 0x0128 + b60: 8b 3f cpi r24, 0xFB ; 251 + b62: 31 f4 brne .+12 ; 0xb70 <__stack+0x671> + b64: 8d e5 ldi r24, 0x5D ; 93 + b66: 92 e0 ldi r25, 0x02 ; 2 + b68: b9 c1 rjmp .+882 ; 0xedc <__stack+0x9dd> + b6a: 81 e0 ldi r24, 0x01 ; 1 + b6c: 80 93 28 01 sts 0x0128, r24 + crc = _crc_xmodem_update(crc, lOdebrDanych); + b70: 60 91 26 01 lds r22, 0x0126 + b74: 80 91 2b 01 lds r24, 0x012B + b78: 90 91 2c 01 lds r25, 0x012C + b7c: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + b80: 90 93 2c 01 sts 0x012C, r25 + b84: 80 93 2b 01 sts 0x012B, r24 + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + b88: 19 82 std Y+1, r1 ; 0x01 + b8a: 27 c0 rjmp .+78 ; 0xbda <__stack+0x6db> + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + b8c: 69 81 ldd r22, Y+1 ; 0x01 + b8e: 70 e0 ldi r23, 0x00 ; 0 + b90: 6d 5c subi r22, 0xCD ; 205 + b92: 7e 4f sbci r23, 0xFE ; 254 + b94: 40 e0 ldi r20, 0x00 ; 0 + b96: 50 e0 ldi r21, 0x00 ; 0 + b98: 80 91 43 01 lds r24, 0x0143 + b9c: 90 91 44 01 lds r25, 0x0144 + ba0: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + ba4: 80 93 28 01 sts 0x0128, r24 + ba8: 80 91 28 01 lds r24, 0x0128 + bac: 8b 3f cpi r24, 0xFB ; 251 + bae: 19 f4 brne .+6 ; 0xbb6 <__stack+0x6b7> + bb0: 89 e6 ldi r24, 0x69 ; 105 + bb2: 92 e0 ldi r25, 0x02 ; 2 + bb4: 93 c1 rjmp .+806 ; 0xedc <__stack+0x9dd> + crc = _crc_xmodem_update(crc, bDane[temp]); + bb6: e9 81 ldd r30, Y+1 ; 0x01 + bb8: f0 e0 ldi r31, 0x00 ; 0 + bba: ed 5c subi r30, 0xCD ; 205 + bbc: fe 4f sbci r31, 0xFE ; 254 + bbe: 60 81 ld r22, Z + bc0: 80 91 2b 01 lds r24, 0x012B + bc4: 90 91 2c 01 lds r25, 0x012C + bc8: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + bcc: 90 93 2c 01 sts 0x012C, r25 + bd0: 80 93 2b 01 sts 0x012B, r24 + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + bd4: 89 81 ldd r24, Y+1 ; 0x01 + bd6: 8f 5f subi r24, 0xFF ; 255 + bd8: 89 83 std Y+1, r24 ; 0x01 + bda: 69 81 ldd r22, Y+1 ; 0x01 + bdc: 20 91 26 01 lds r18, 0x0126 + be0: 80 91 43 01 lds r24, 0x0143 + be4: 90 91 44 01 lds r25, 0x0144 + be8: 62 17 cp r22, r18 + bea: 70 f4 brcc .+28 ; 0xc08 <__stack+0x709> + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + bec: 70 e0 ldi r23, 0x00 ; 0 + bee: 6d 5c subi r22, 0xCD ; 205 + bf0: 7e 4f sbci r23, 0xFE ; 254 + bf2: 41 e0 ldi r20, 0x01 ; 1 + bf4: 50 e0 ldi r21, 0x00 ; 0 + bf6: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + bfa: 80 93 28 01 sts 0x0128, r24 + bfe: 8c 3f cpi r24, 0xFC ; 252 + c00: 99 f6 brne .-90 ; 0xba8 <__stack+0x6a9> + c02: 88 e6 ldi r24, 0x68 ; 104 + c04: 92 e0 ldi r25, 0x02 ; 2 + c06: 6a c1 rjmp .+724 ; 0xedc <__stack+0x9dd> + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + c08: 20 91 2c 01 lds r18, 0x012C + c0c: 29 83 std Y+1, r18 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + c0e: 41 e0 ldi r20, 0x01 ; 1 + c10: 50 e0 ldi r21, 0x00 ; 0 + c12: be 01 movw r22, r28 + c14: 6f 5f subi r22, 0xFF ; 255 + c16: 7f 4f sbci r23, 0xFF ; 255 + c18: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + c1c: 80 93 28 01 sts 0x0128, r24 + c20: 8c 3f cpi r24, 0xFC ; 252 + c22: 81 f4 brne .+32 ; 0xc44 <__stack+0x745> + c24: 82 e7 ldi r24, 0x72 ; 114 + c26: 92 e0 ldi r25, 0x02 ; 2 + c28: 59 c1 rjmp .+690 ; 0xedc <__stack+0x9dd> + c2a: 40 e0 ldi r20, 0x00 ; 0 + c2c: 50 e0 ldi r21, 0x00 ; 0 + c2e: be 01 movw r22, r28 + c30: 6f 5f subi r22, 0xFF ; 255 + c32: 7f 4f sbci r23, 0xFF ; 255 + c34: 80 91 43 01 lds r24, 0x0143 + c38: 90 91 44 01 lds r25, 0x0144 + c3c: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + c40: 80 93 28 01 sts 0x0128, r24 + c44: 80 91 28 01 lds r24, 0x0128 + c48: 8b 3f cpi r24, 0xFB ; 251 + c4a: 19 f4 brne .+6 ; 0xc52 <__stack+0x753> + c4c: 83 e7 ldi r24, 0x73 ; 115 + c4e: 92 e0 ldi r25, 0x02 ; 2 + c50: 45 c1 rjmp .+650 ; 0xedc <__stack+0x9dd> + temp = (uint8_t)(crc & 0xFF); + c52: 80 91 2b 01 lds r24, 0x012B + c56: 89 83 std Y+1, r24 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + c58: 41 e0 ldi r20, 0x01 ; 1 + c5a: 50 e0 ldi r21, 0x00 ; 0 + c5c: be 01 movw r22, r28 + c5e: 6f 5f subi r22, 0xFF ; 255 + c60: 7f 4f sbci r23, 0xFF ; 255 + c62: 80 91 43 01 lds r24, 0x0143 + c66: 90 91 44 01 lds r25, 0x0144 + c6a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + c6e: 80 93 28 01 sts 0x0128, r24 + c72: 8c 3f cpi r24, 0xFC ; 252 + c74: 81 f4 brne .+32 ; 0xc96 <__stack+0x797> + c76: 86 e7 ldi r24, 0x76 ; 118 + c78: 92 e0 ldi r25, 0x02 ; 2 + c7a: 30 c1 rjmp .+608 ; 0xedc <__stack+0x9dd> + c7c: 40 e0 ldi r20, 0x00 ; 0 + c7e: 50 e0 ldi r21, 0x00 ; 0 + c80: be 01 movw r22, r28 + c82: 6f 5f subi r22, 0xFF ; 255 + c84: 7f 4f sbci r23, 0xFF ; 255 + c86: 80 91 43 01 lds r24, 0x0143 + c8a: 90 91 44 01 lds r25, 0x0144 + c8e: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + c92: 80 93 28 01 sts 0x0128, r24 + c96: 80 91 28 01 lds r24, 0x0128 + c9a: 8b 3f cpi r24, 0xFB ; 251 + c9c: 31 f4 brne .+12 ; 0xcaa <__stack+0x7ab> + c9e: 87 e7 ldi r24, 0x77 ; 119 + ca0: 92 e0 ldi r25, 0x02 ; 2 + ca2: 1c c1 rjmp .+568 ; 0xedc <__stack+0x9dd> + ca4: 81 e0 ldi r24, 0x01 ; 1 + ca6: 80 93 28 01 sts 0x0128, r24 + + if (xResult == pdPASS) + caa: 80 91 28 01 lds r24, 0x0128 + cae: 81 30 cpi r24, 0x01 ; 1 + cb0: 19 f4 brne .+6 ; 0xcb8 <__stack+0x7b9> + { + TxStart(); + cb2: 8b b1 in r24, 0x0b ; 11 + cb4: 8c 60 ori r24, 0x0C ; 12 + cb6: 8b b9 out 0x0b, r24 ; 11 + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + cb8: 80 91 c1 00 lds r24, 0x00C1 + cbc: 80 62 ori r24, 0x20 ; 32 + cbe: 80 93 c1 00 sts 0x00C1, r24 + + if (kodRozkazu == rFLASH) + cc2: 80 91 42 01 lds r24, 0x0142 + cc6: 81 38 cpi r24, 0x81 ; 129 + cc8: 09 f0 breq .+2 ; 0xccc <__stack+0x7cd> + cca: 99 cc rjmp .-1742 ; 0x5fe <__stack+0xff> + { + Led1On(); + ccc: 0e 94 7a 08 call 0x10f4 ; 0x10f4 + Led2On(); + cd0: 0e 94 83 08 call 0x1106 ; 0x1106 + crDELAY(xHandle, 10); + cd4: 60 e0 ldi r22, 0x00 ; 0 + cd6: 70 e0 ldi r23, 0x00 ; 0 + cd8: 8a e0 ldi r24, 0x0A ; 10 + cda: 90 e0 ldi r25, 0x00 ; 0 + cdc: 0e 94 9f 11 call 0x233e ; 0x233e + ce0: 8e e8 ldi r24, 0x8E ; 142 + ce2: 92 e0 ldi r25, 0x02 ; 2 + ce4: fb c0 rjmp .+502 ; 0xedc <__stack+0x9dd> + Led1Off(); + Led2Off(); + (*((void(*)(void))BOOT_START))(); //reboot + } + } + else if (rezultat == 2) + ce6: 82 30 cpi r24, 0x02 ; 2 + ce8: 29 f5 brne .+74 ; 0xd34 <__stack+0x835> + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + cea: 40 e0 ldi r20, 0x00 ; 0 + cec: 50 e0 ldi r21, 0x00 ; 0 + cee: 62 e3 ldi r22, 0x32 ; 50 + cf0: 71 e0 ldi r23, 0x01 ; 1 + cf2: 80 91 c2 04 lds r24, 0x04C2 + cf6: 90 91 c3 04 lds r25, 0x04C3 + cfa: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + cfe: 80 93 28 01 sts 0x0128, r24 + d02: 8c 3f cpi r24, 0xFC ; 252 + d04: 79 f4 brne .+30 ; 0xd24 <__stack+0x825> + d06: 8e e9 ldi r24, 0x9E ; 158 + d08: 92 e0 ldi r25, 0x02 ; 2 + d0a: e8 c0 rjmp .+464 ; 0xedc <__stack+0x9dd> + d0c: 40 e0 ldi r20, 0x00 ; 0 + d0e: 50 e0 ldi r21, 0x00 ; 0 + d10: 62 e3 ldi r22, 0x32 ; 50 + d12: 71 e0 ldi r23, 0x01 ; 1 + d14: 80 91 c2 04 lds r24, 0x04C2 + d18: 90 91 c3 04 lds r25, 0x04C3 + d1c: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + d20: 80 93 28 01 sts 0x0128, r24 + d24: 80 91 28 01 lds r24, 0x0128 + d28: 8b 3f cpi r24, 0xFB ; 251 + d2a: 09 f0 breq .+2 ; 0xd2e <__stack+0x82f> + d2c: 68 cc rjmp .-1840 ; 0x5fe <__stack+0xff> + d2e: 8f e9 ldi r24, 0x9F ; 159 + d30: 92 e0 ldi r25, 0x02 ; 2 + d32: d4 c0 rjmp .+424 ; 0xedc <__stack+0x9dd> + } + else if (rezultat == 3) + d34: 83 30 cpi r24, 0x03 ; 3 + d36: 29 f5 brne .+74 ; 0xd82 <__stack+0x883> + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + d38: 40 e0 ldi r20, 0x00 ; 0 + d3a: 50 e0 ldi r21, 0x00 ; 0 + d3c: 62 e3 ldi r22, 0x32 ; 50 + d3e: 71 e0 ldi r23, 0x01 ; 1 + d40: 80 91 c4 04 lds r24, 0x04C4 + d44: 90 91 c5 04 lds r25, 0x04C5 + d48: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + d4c: 80 93 28 01 sts 0x0128, r24 + d50: 8c 3f cpi r24, 0xFC ; 252 + d52: 79 f4 brne .+30 ; 0xd72 <__stack+0x873> + d54: 86 ea ldi r24, 0xA6 ; 166 + d56: 92 e0 ldi r25, 0x02 ; 2 + d58: c1 c0 rjmp .+386 ; 0xedc <__stack+0x9dd> + d5a: 40 e0 ldi r20, 0x00 ; 0 + d5c: 50 e0 ldi r21, 0x00 ; 0 + d5e: 62 e3 ldi r22, 0x32 ; 50 + d60: 71 e0 ldi r23, 0x01 ; 1 + d62: 80 91 c4 04 lds r24, 0x04C4 + d66: 90 91 c5 04 lds r25, 0x04C5 + d6a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + d6e: 80 93 28 01 sts 0x0128, r24 + d72: 80 91 28 01 lds r24, 0x0128 + d76: 8b 3f cpi r24, 0xFB ; 251 + d78: 09 f0 breq .+2 ; 0xd7c <__stack+0x87d> + d7a: 41 cc rjmp .-1918 ; 0x5fe <__stack+0xff> + d7c: 87 ea ldi r24, 0xA7 ; 167 + d7e: 92 e0 ldi r25, 0x02 ; 2 + d80: ad c0 rjmp .+346 ; 0xedc <__stack+0x9dd> + } + else if (rezultat == 4) + d82: 84 30 cpi r24, 0x04 ; 4 + d84: 09 f0 breq .+2 ; 0xd88 <__stack+0x889> + d86: 3b cc rjmp .-1930 ; 0x5fe <__stack+0xff> + { + //SYNC + crc = 0; + d88: 10 92 2c 01 sts 0x012C, r1 + d8c: 10 92 2b 01 sts 0x012B, r1 + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + d90: 19 82 std Y+1, r1 ; 0x01 + d92: 1c c0 rjmp .+56 ; 0xdcc <__stack+0x8cd> + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + d94: 80 91 28 01 lds r24, 0x0128 + d98: 8b 3f cpi r24, 0xFB ; 251 + d9a: 31 f4 brne .+12 ; 0xda8 <__stack+0x8a9> + d9c: 8d eb ldi r24, 0xBD ; 189 + d9e: 92 e0 ldi r25, 0x02 ; 2 + da0: 9d c0 rjmp .+314 ; 0xedc <__stack+0x9dd> + da2: 81 e0 ldi r24, 0x01 ; 1 + da4: 80 93 28 01 sts 0x0128, r24 + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + da8: e9 81 ldd r30, Y+1 ; 0x01 + daa: f0 e0 ldi r31, 0x00 ; 0 + dac: e0 50 subi r30, 0x00 ; 0 + dae: ff 4f sbci r31, 0xFF ; 255 + db0: 60 81 ld r22, Z + db2: 80 91 2b 01 lds r24, 0x012B + db6: 90 91 2c 01 lds r25, 0x012C + dba: 0e 94 92 01 call 0x324 ; 0x324 <_crc_xmodem_update> + dbe: 90 93 2c 01 sts 0x012C, r25 + dc2: 80 93 2b 01 sts 0x012B, r24 + //SYNC + crc = 0; + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + dc6: 89 81 ldd r24, Y+1 ; 0x01 + dc8: 8f 5f subi r24, 0xFF ; 255 + dca: 89 83 std Y+1, r24 ; 0x01 + dcc: 69 81 ldd r22, Y+1 ; 0x01 + dce: 80 91 43 01 lds r24, 0x0143 + dd2: 90 91 44 01 lds r25, 0x0144 + dd6: 6b 30 cpi r22, 0x0B ; 11 + dd8: 70 f4 brcc .+28 ; 0xdf6 <__stack+0x8f7> + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + dda: 70 e0 ldi r23, 0x00 ; 0 + ddc: 60 50 subi r22, 0x00 ; 0 + dde: 7f 4f sbci r23, 0xFF ; 255 + de0: 41 e0 ldi r20, 0x01 ; 1 + de2: 50 e0 ldi r21, 0x00 ; 0 + de4: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + de8: 80 93 28 01 sts 0x0128, r24 + dec: 8c 3f cpi r24, 0xFC ; 252 + dee: 91 f6 brne .-92 ; 0xd94 <__stack+0x895> + df0: 8c eb ldi r24, 0xBC ; 188 + df2: 92 e0 ldi r25, 0x02 ; 2 + df4: 73 c0 rjmp .+230 ; 0xedc <__stack+0x9dd> + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + df6: 20 91 2c 01 lds r18, 0x012C + dfa: 29 83 std Y+1, r18 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + dfc: 41 e0 ldi r20, 0x01 ; 1 + dfe: 50 e0 ldi r21, 0x00 ; 0 + e00: be 01 movw r22, r28 + e02: 6f 5f subi r22, 0xFF ; 255 + e04: 7f 4f sbci r23, 0xFF ; 255 + e06: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + e0a: 80 93 28 01 sts 0x0128, r24 + e0e: 8c 3f cpi r24, 0xFC ; 252 + e10: 81 f4 brne .+32 ; 0xe32 <__stack+0x933> + e12: 86 ec ldi r24, 0xC6 ; 198 + e14: 92 e0 ldi r25, 0x02 ; 2 + e16: 62 c0 rjmp .+196 ; 0xedc <__stack+0x9dd> + e18: 40 e0 ldi r20, 0x00 ; 0 + e1a: 50 e0 ldi r21, 0x00 ; 0 + e1c: be 01 movw r22, r28 + e1e: 6f 5f subi r22, 0xFF ; 255 + e20: 7f 4f sbci r23, 0xFF ; 255 + e22: 80 91 43 01 lds r24, 0x0143 + e26: 90 91 44 01 lds r25, 0x0144 + e2a: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + e2e: 80 93 28 01 sts 0x0128, r24 + e32: 80 91 28 01 lds r24, 0x0128 + e36: 8b 3f cpi r24, 0xFB ; 251 + e38: 19 f4 brne .+6 ; 0xe40 <__stack+0x941> + e3a: 87 ec ldi r24, 0xC7 ; 199 + e3c: 92 e0 ldi r25, 0x02 ; 2 + e3e: 4e c0 rjmp .+156 ; 0xedc <__stack+0x9dd> + temp = (uint8_t)(crc & 0xFF); + e40: 80 91 2b 01 lds r24, 0x012B + e44: 89 83 std Y+1, r24 ; 0x01 + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + e46: 41 e0 ldi r20, 0x01 ; 1 + e48: 50 e0 ldi r21, 0x00 ; 0 + e4a: be 01 movw r22, r28 + e4c: 6f 5f subi r22, 0xFF ; 255 + e4e: 7f 4f sbci r23, 0xFF ; 255 + e50: 80 91 43 01 lds r24, 0x0143 + e54: 90 91 44 01 lds r25, 0x0144 + e58: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + e5c: 80 93 28 01 sts 0x0128, r24 + e60: 8c 3f cpi r24, 0xFC ; 252 + e62: 81 f4 brne .+32 ; 0xe84 <__stack+0x985> + e64: 8a ec ldi r24, 0xCA ; 202 + e66: 92 e0 ldi r25, 0x02 ; 2 + e68: 39 c0 rjmp .+114 ; 0xedc <__stack+0x9dd> + e6a: 40 e0 ldi r20, 0x00 ; 0 + e6c: 50 e0 ldi r21, 0x00 ; 0 + e6e: be 01 movw r22, r28 + e70: 6f 5f subi r22, 0xFF ; 255 + e72: 7f 4f sbci r23, 0xFF ; 255 + e74: 80 91 43 01 lds r24, 0x0143 + e78: 90 91 44 01 lds r25, 0x0144 + e7c: 0e 94 c8 0f call 0x1f90 ; 0x1f90 + e80: 80 93 28 01 sts 0x0128, r24 + e84: 80 91 28 01 lds r24, 0x0128 + e88: 8b 3f cpi r24, 0xFB ; 251 + e8a: 31 f4 brne .+12 ; 0xe98 <__stack+0x999> + e8c: 8b ec ldi r24, 0xCB ; 203 + e8e: 92 e0 ldi r25, 0x02 ; 2 + e90: 25 c0 rjmp .+74 ; 0xedc <__stack+0x9dd> + e92: 81 e0 ldi r24, 0x01 ; 1 + e94: 80 93 28 01 sts 0x0128, r24 + + if (xResult == pdPASS) + e98: 80 91 28 01 lds r24, 0x0128 + e9c: 81 30 cpi r24, 0x01 ; 1 + e9e: 19 f4 brne .+6 ; 0xea6 <__stack+0x9a7> + { + TxStart(); + ea0: 8b b1 in r24, 0x0b ; 11 + ea2: 8c 60 ori r24, 0x0C ; 12 + ea4: 8b b9 out 0x0b, r24 ; 11 + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + ea6: 80 91 c1 00 lds r24, 0x00C1 + eaa: 80 62 ori r24, 0x20 ; 32 + eac: 80 93 c1 00 sts 0x00C1, r24 + eb0: a6 cb rjmp .-2228 ; 0x5fe <__stack+0xff> + Led2Off(); + stan = s_sync; + } + else //Zły adres + { + if (kodRozkazu == rFLASH) + eb2: 80 91 42 01 lds r24, 0x0142 + eb6: 81 38 cpi r24, 0x81 ; 129 + eb8: a9 f4 brne .+42 ; 0xee4 <__stack+0x9e5> + { + DISABLE_RX(); + eba: 80 91 c1 00 lds r24, 0x00C1 + ebe: 8f 7e andi r24, 0xEF ; 239 + ec0: 80 93 c1 00 sts 0x00C1, r24 + Led1On(); + ec4: 0e 94 7a 08 call 0x10f4 ; 0x10f4 + Led2On(); + ec8: 0e 94 83 08 call 0x1106 ; 0x1106 + //TODO disable RX buffer + crDELAY(xHandle, 1000); + ecc: 60 e0 ldi r22, 0x00 ; 0 + ece: 70 e0 ldi r23, 0x00 ; 0 + ed0: 88 ee ldi r24, 0xE8 ; 232 + ed2: 93 e0 ldi r25, 0x03 ; 3 + ed4: 0e 94 9f 11 call 0x233e ; 0x233e + ed8: 82 ef ldi r24, 0xF2 ; 242 + eda: 92 e0 ldi r25, 0x02 ; 2 + edc: f8 01 movw r30, r16 + ede: 91 8f std Z+25, r25 ; 0x19 + ee0: 80 8f std Z+24, r24 ; 0x18 + ee2: 03 c0 rjmp .+6 ; 0xeea <__stack+0x9eb> + ENABLE_RX(); + } + Led1Off(); + ee4: 0e 94 81 08 call 0x1102 ; 0x1102 + ee8: 8e cb rjmp .-2276 ; 0x606 <__stack+0x107> + stan = s_sync; + } + } + } + crEND(); +} + eea: 0f 90 pop r0 + eec: df 91 pop r29 + eee: cf 91 pop r28 + ef0: 1f 91 pop r17 + ef2: 0f 91 pop r16 + ef4: ff 90 pop r15 + ef6: 08 95 ret + +00000ef8 : + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + ef8: cf 93 push r28 + efa: c8 2f mov r28, r24 + portENTER_CRITICAL(); + efc: 0f b6 in r0, 0x3f ; 63 + efe: f8 94 cli + f00: 0f 92 push r0 + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + f02: 61 e0 ldi r22, 0x01 ; 1 + f04: 0e 94 8e 0d call 0x1b1c ; 0x1b1c + f08: 90 93 46 01 sts 0x0146, r25 + f0c: 80 93 45 01 sts 0x0145, r24 + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + f10: 61 e0 ldi r22, 0x01 ; 1 + f12: 8c 2f mov r24, r28 + f14: 0e 94 8e 0d call 0x1b1c ; 0x1b1c + f18: 90 93 44 01 sts 0x0144, r25 + f1c: 80 93 43 01 sts 0x0143, r24 + + UBRR0L = 3; + f20: 83 e0 ldi r24, 0x03 ; 3 + f22: 80 93 c4 00 sts 0x00C4, r24 + UBRR0H = 0; + f26: 10 92 c5 00 sts 0x00C5, r1 + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1< + f3e: 90 93 31 01 sts 0x0131, r25 + f42: 80 93 30 01 sts 0x0130, r24 + f46: 00 97 sbiw r24, 0x00 ; 0 + f48: 39 f0 breq .+14 ; 0xf58 + f4a: 20 e0 ldi r18, 0x00 ; 0 + f4c: 40 e0 ldi r20, 0x00 ; 0 + f4e: 50 e0 ldi r21, 0x00 ; 0 + f50: 60 e0 ldi r22, 0x00 ; 0 + f52: 70 e0 ldi r23, 0x00 ; 0 + f54: 0e 94 1b 0e call 0x1c36 ; 0x1c36 + } + portEXIT_CRITICAL(); + f58: 0f 90 pop r0 + f5a: 0f be out 0x3f, r0 ; 63 + return; +} + f5c: cf 91 pop r28 + f5e: 08 95 ret + +00000f60 <__vector_18>: + +/*-----------------------------------------------------------*/ +ISR(USART_RX_vect) +{ + f60: 1f 92 push r1 + f62: 0f 92 push r0 + f64: 0f b6 in r0, 0x3f ; 63 + f66: 0f 92 push r0 + f68: 11 24 eor r1, r1 + f6a: 2f 93 push r18 + f6c: 3f 93 push r19 + f6e: 4f 93 push r20 + f70: 5f 93 push r21 + f72: 6f 93 push r22 + f74: 7f 93 push r23 + f76: 8f 93 push r24 + f78: 9f 93 push r25 + f7a: af 93 push r26 + f7c: bf 93 push r27 + f7e: ef 93 push r30 + f80: ff 93 push r31 + f82: cf 93 push r28 + f84: df 93 push r29 + f86: 1f 92 push r1 + f88: cd b7 in r28, 0x3d ; 61 + f8a: de b7 in r29, 0x3e ; 62 + signed portCHAR cChar; + cChar = UDR0; + f8c: 80 91 c6 00 lds r24, 0x00C6 + f90: 89 83 std Y+1, r24 ; 0x01 +// Led2Toggle(); + crQUEUE_SEND_FROM_ISR( xRxedChars, &cChar, pdFALSE ); + f92: 40 e0 ldi r20, 0x00 ; 0 + f94: be 01 movw r22, r28 + f96: 6f 5f subi r22, 0xFF ; 255 + f98: 7f 4f sbci r23, 0xFF ; 255 + f9a: 80 91 45 01 lds r24, 0x0145 + f9e: 90 91 46 01 lds r25, 0x0146 + fa2: 0e 94 48 10 call 0x2090 ; 0x2090 +} + fa6: 0f 90 pop r0 + fa8: df 91 pop r29 + faa: cf 91 pop r28 + fac: ff 91 pop r31 + fae: ef 91 pop r30 + fb0: bf 91 pop r27 + fb2: af 91 pop r26 + fb4: 9f 91 pop r25 + fb6: 8f 91 pop r24 + fb8: 7f 91 pop r23 + fba: 6f 91 pop r22 + fbc: 5f 91 pop r21 + fbe: 4f 91 pop r20 + fc0: 3f 91 pop r19 + fc2: 2f 91 pop r18 + fc4: 0f 90 pop r0 + fc6: 0f be out 0x3f, r0 ; 63 + fc8: 0f 90 pop r0 + fca: 1f 90 pop r1 + fcc: 18 95 reti + +00000fce <__vector_19>: +/*-----------------------------------------------------------*/ + +ISR(USART_UDRE_vect) +{ + fce: 1f 92 push r1 + fd0: 0f 92 push r0 + fd2: 0f b6 in r0, 0x3f ; 63 + fd4: 0f 92 push r0 + fd6: 11 24 eor r1, r1 + fd8: 2f 93 push r18 + fda: 3f 93 push r19 + fdc: 4f 93 push r20 + fde: 5f 93 push r21 + fe0: 6f 93 push r22 + fe2: 7f 93 push r23 + fe4: 8f 93 push r24 + fe6: 9f 93 push r25 + fe8: af 93 push r26 + fea: bf 93 push r27 + fec: ef 93 push r30 + fee: ff 93 push r31 + ff0: cf 93 push r28 + ff2: df 93 push r29 + ff4: 00 d0 rcall .+0 ; 0xff6 <__vector_19+0x28> + ff6: cd b7 in r28, 0x3d ; 61 + ff8: de b7 in r29, 0x3e ; 62 + signed portCHAR cChar, cTaskWoken; + + if( xQueueReceiveFromISR( xCharsForTx, &cChar, &cTaskWoken ) == pdTRUE ) + ffa: ae 01 movw r20, r28 + ffc: 4f 5f subi r20, 0xFF ; 255 + ffe: 5f 4f sbci r21, 0xFF ; 255 + 1000: be 01 movw r22, r28 + 1002: 6e 5f subi r22, 0xFE ; 254 + 1004: 7f 4f sbci r23, 0xFF ; 255 + 1006: 80 91 43 01 lds r24, 0x0143 + 100a: 90 91 44 01 lds r25, 0x0144 + 100e: 0e 94 7b 0f call 0x1ef6 ; 0x1ef6 + 1012: 81 30 cpi r24, 0x01 ; 1 + 1014: 21 f4 brne .+8 ; 0x101e <__vector_19+0x50> + { + /* Send the next character queued for Tx. */ + UDR0 = cChar; + 1016: 8a 81 ldd r24, Y+2 ; 0x02 + 1018: 80 93 c6 00 sts 0x00C6, r24 + 101c: 05 c0 rjmp .+10 ; 0x1028 <__vector_19+0x5a> + } + else + { + /* Queue empty, nothing to send. */ + vInterruptOff(); + 101e: 80 91 c1 00 lds r24, 0x00C1 + 1022: 8f 7d andi r24, 0xDF ; 223 + 1024: 80 93 c1 00 sts 0x00C1, r24 + } +} + 1028: 0f 90 pop r0 + 102a: 0f 90 pop r0 + 102c: df 91 pop r29 + 102e: cf 91 pop r28 + 1030: ff 91 pop r31 + 1032: ef 91 pop r30 + 1034: bf 91 pop r27 + 1036: af 91 pop r26 + 1038: 9f 91 pop r25 + 103a: 8f 91 pop r24 + 103c: 7f 91 pop r23 + 103e: 6f 91 pop r22 + 1040: 5f 91 pop r21 + 1042: 4f 91 pop r20 + 1044: 3f 91 pop r19 + 1046: 2f 91 pop r18 + 1048: 0f 90 pop r0 + 104a: 0f be out 0x3f, r0 ; 63 + 104c: 0f 90 pop r0 + 104e: 1f 90 pop r1 + 1050: 18 95 reti + +00001052 <__vector_20>: + +ISR(USART_TX_vect) +{ + 1052: 1f 92 push r1 + 1054: 0f 92 push r0 + 1056: 0f b6 in r0, 0x3f ; 63 + 1058: 0f 92 push r0 + 105a: 11 24 eor r1, r1 + 105c: 8f 93 push r24 + if (!vIsInterruptOn()) + 105e: 80 91 c1 00 lds r24, 0x00C1 + 1062: 85 fd sbrc r24, 5 + 1064: 05 c0 rjmp .+10 ; 0x1070 <__vector_20+0x1e> + { + TxStop(); + 1066: 8b b1 in r24, 0x0b ; 11 + 1068: 83 7f andi r24, 0xF3 ; 243 + 106a: 8b b9 out 0x0b, r24 ; 11 + xHigherPriorityTaskWoken = pdFALSE; + 106c: 10 92 2f 01 sts 0x012F, r1 +// xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken); + } +} + 1070: 8f 91 pop r24 + 1072: 0f 90 pop r0 + 1074: 0f be out 0x3f, r0 ; 63 + 1076: 0f 90 pop r0 + 1078: 1f 90 pop r1 + 107a: 18 95 reti + +0000107c : +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - P3 , 1 - P2 , 2 - P1 + 107c: 87 e0 ldi r24, 0x07 ; 7 + 107e: 84 b9 out 0x04, r24 ; 4 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + 1080: 88 e3 ldi r24, 0x38 ; 56 + 1082: 85 b9 out 0x05, r24 ; 5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - KlRolety1Up, 3 - klRolety1Down + 1084: 17 b8 out 0x07, r1 ; 7 + PORTC = 0x3F; //4 - KlRolety2Up, 5 - KlRolety2Down + 1086: 8f e3 ldi r24, 0x3F ; 63 + 1088: 88 b9 out 0x08, r24 ; 8 + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + 108a: 8e ee ldi r24, 0xEE ; 238 + 108c: 8a b9 out 0x0a, r24 ; 10 + PORTD = 0x00; //5 - Led1, 6 - Led2, 7 - P4) + 108e: 1b b8 out 0x0b, r1 ; 11 + /*Ustalanie adresu + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = (PINB & 0x38) >> 1; + 1090: 83 b1 in r24, 0x03 ; 3 + 1092: 88 73 andi r24, 0x38 ; 56 + 1094: 90 e0 ldi r25, 0x00 ; 0 + 1096: 95 95 asr r25 + 1098: 87 95 ror r24 + 109a: 80 93 c1 04 sts 0x04C1, r24 + adres |= (PINC & 0x03); + 109e: 96 b1 in r25, 0x06 ; 6 + 10a0: 93 70 andi r25, 0x03 ; 3 + 10a2: 89 2b or r24, r25 + 10a4: 80 93 c1 04 sts 0x04C1, r24 + 10a8: 08 95 ret + +000010aa : + roleta2Stop(); +} + +inline void roleta1wGore(void) +{ + PORTB &= ~0x02; + 10aa: 29 98 cbi 0x05, 1 ; 5 + PORTB |= 0x04; + 10ac: 2a 9a sbi 0x05, 2 ; 5 + 10ae: 08 95 ret + +000010b0 : +} + +inline void roleta1wDol(void) +{ + PORTB &= ~0x04; + 10b0: 2a 98 cbi 0x05, 2 ; 5 + PORTB |= 0x02; + 10b2: 29 9a sbi 0x05, 1 ; 5 + 10b4: 08 95 ret + +000010b6 : +} + +inline void roleta1Stop(void) +{ + PORTB &= ~0x06; + 10b6: 85 b1 in r24, 0x05 ; 5 + 10b8: 89 7f andi r24, 0xF9 ; 249 + 10ba: 85 b9 out 0x05, r24 ; 5 + 10bc: 08 95 ret + +000010be : +} + +inline void roleta2wGore(void) +{ + PORTD &= ~0x80; + 10be: 5f 98 cbi 0x0b, 7 ; 11 + PORTB |= 0x01; + 10c0: 28 9a sbi 0x05, 0 ; 5 + 10c2: 08 95 ret + +000010c4 : + adres |= (PINC & 0x03); +} + +void roletawGore(uint8_t nrRolety) +{ + if (nrRolety == 0) + 10c4: 81 11 cpse r24, r1 + 10c6: 02 c0 rjmp .+4 ; 0x10cc + roleta1wGore(); + 10c8: 0c 94 55 08 jmp 0x10aa ; 0x10aa + else + roleta2wGore(); + 10cc: 0c 94 5f 08 jmp 0x10be ; 0x10be + +000010d0 : + PORTB |= 0x01; +} + +inline void roleta2wDol(void) +{ + PORTB &= ~0x01; + 10d0: 28 98 cbi 0x05, 0 ; 5 + PORTD |= 0x80; + 10d2: 5f 9a sbi 0x0b, 7 ; 11 + 10d4: 08 95 ret + +000010d6 : + roleta2wGore(); +} + +void roletawDol(uint8_t nrRolety) +{ + if (nrRolety == 0) + 10d6: 81 11 cpse r24, r1 + 10d8: 02 c0 rjmp .+4 ; 0x10de + roleta1wDol(); + 10da: 0c 94 58 08 jmp 0x10b0 ; 0x10b0 + else + roleta2wDol(); + 10de: 0c 94 68 08 jmp 0x10d0 ; 0x10d0 + +000010e2 : + PORTD |= 0x80; +} + +inline void roleta2Stop(void) +{ + PORTB &= ~0x01; + 10e2: 28 98 cbi 0x05, 0 ; 5 + PORTD &= ~0x80; + 10e4: 5f 98 cbi 0x0b, 7 ; 11 + 10e6: 08 95 ret + +000010e8 : + roleta2wDol(); +} + +void roletaStop(uint8_t nrRolety) +{ + if (nrRolety == 0) + 10e8: 81 11 cpse r24, r1 + 10ea: 02 c0 rjmp .+4 ; 0x10f0 + roleta1Stop(); + 10ec: 0c 94 5b 08 jmp 0x10b6 ; 0x10b6 + else + roleta2Stop(); + 10f0: 0c 94 71 08 jmp 0x10e2 ; 0x10e2 + +000010f4 : + PORTD &= ~0x80; +} + +inline void Led1On(void) +{ + PORTD |= 0x20; + 10f4: 5d 9a sbi 0x0b, 5 ; 11 + 10f6: 08 95 ret + +000010f8 : +} + +inline void Led1Toggle(void) +{ + PORTD ^= 0x20; + 10f8: 9b b1 in r25, 0x0b ; 11 + 10fa: 80 e2 ldi r24, 0x20 ; 32 + 10fc: 89 27 eor r24, r25 + 10fe: 8b b9 out 0x0b, r24 ; 11 + 1100: 08 95 ret + +00001102 : +} + +inline void Led1Off(void) +{ + PORTD &= ~0x20; + 1102: 5d 98 cbi 0x0b, 5 ; 11 + 1104: 08 95 ret + +00001106 : +} + +inline void Led2On(void) +{ + PORTD |= 0x40; + 1106: 5e 9a sbi 0x0b, 6 ; 11 + 1108: 08 95 ret + +0000110a : +} + +inline void Led2Toggle(void) +{ + PORTD ^= 0x40; + 110a: 9b b1 in r25, 0x0b ; 11 + 110c: 80 e4 ldi r24, 0x40 ; 64 + 110e: 89 27 eor r24, r25 + 1110: 8b b9 out 0x0b, r24 ; 11 + 1112: 08 95 ret + +00001114 : +} + +inline void Led2Off(void) +{ + PORTD &= ~0x40; + 1114: 5e 98 cbi 0x0b, 6 ; 11 + 1116: 08 95 ret + +00001118 : +} + +inline char czytKlawiszRol1wGore(void) +{ + return PINC & 0x04; + 1118: 86 b1 in r24, 0x06 ; 6 +} + 111a: 84 70 andi r24, 0x04 ; 4 + 111c: 08 95 ret + +0000111e : + +inline char czytKlawiszRol1wDol(void) +{ + return PINC & 0x08; + 111e: 86 b1 in r24, 0x06 ; 6 +} + 1120: 88 70 andi r24, 0x08 ; 8 + 1122: 08 95 ret + +00001124 : + +inline char czytKlawiszRol2wGore(void) +{ + return PINC & 0x10; + 1124: 86 b1 in r24, 0x06 ; 6 +} + 1126: 80 71 andi r24, 0x10 ; 16 + 1128: 08 95 ret + +0000112a : + +inline char czytKlawiszRol2wDol(void) +{ + return PINC & 0x20; + 112a: 86 b1 in r24, 0x06 ; 6 +} + 112c: 80 72 andi r24, 0x20 ; 32 + 112e: 08 95 ret + +00001130 : +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + 1130: fa 01 movw r30, r20 + uint8_t wiadomosc = 0; + + if (klGoraOff) + 1132: 88 23 and r24, r24 + 1134: 71 f0 breq .+28 ; 0x1152 + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + 1136: 84 81 ldd r24, Z+4 ; 0x04 + 1138: 92 81 ldd r25, Z+2 ; 0x02 + 113a: 83 30 cpi r24, 0x03 ; 3 + 113c: 29 f4 brne .+10 ; 0x1148 + 113e: 95 30 cpi r25, 0x05 ; 5 + 1140: 19 f4 brne .+6 ; 0x1148 + { + stan->czynnosc = bezczynny; + 1142: 14 82 std Z+4, r1 ; 0x04 + wiadomosc = 0x40; + 1144: 80 e4 ldi r24, 0x40 ; 64 + 1146: 01 c0 rjmp .+2 ; 0x114a +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + 1148: 80 e0 ldi r24, 0x00 ; 0 + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + 114a: 10 82 st Z, r1 + stan->klGora_off++; + 114c: 9f 5f subi r25, 0xFF ; 255 + 114e: 92 83 std Z+2, r25 ; 0x02 + 1150: 15 c0 rjmp .+42 ; 0x117c + } + else + { + if (stan->klGora_on == T_START) + 1152: 90 81 ld r25, Z + 1154: 95 30 cpi r25, 0x05 ; 5 + 1156: 51 f4 brne .+20 ; 0x116c + { + if (stan->czynnosc != bezczynny) + 1158: 84 81 ldd r24, Z+4 ; 0x04 + 115a: 88 23 and r24, r24 + 115c: 19 f0 breq .+6 ; 0x1164 + { + stan->czynnosc = bezczynny; + 115e: 14 82 std Z+4, r1 ; 0x04 + wiadomosc = 0x40; + 1160: 80 e4 ldi r24, 0x40 ; 64 + 1162: 09 c0 rjmp .+18 ; 0x1176 + } + else + { + stan->czynnosc = do_konca_w_gore; + 1164: 81 e0 ldi r24, 0x01 ; 1 + 1166: 84 83 std Z+4, r24 ; 0x04 + wiadomosc = 0xBF; + 1168: 8f eb ldi r24, 0xBF ; 191 + 116a: 05 c0 rjmp .+10 ; 0x1176 + } + } + if (stan->klGora_on == T_START_CONT) + 116c: 98 32 cpi r25, 0x28 ; 40 + 116e: 11 f4 brne .+4 ; 0x1174 + { + stan->czynnosc = w_gore; + 1170: 83 e0 ldi r24, 0x03 ; 3 + 1172: 84 83 std Z+4, r24 ; 0x04 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + 1174: 80 e0 ldi r24, 0x00 ; 0 + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + 1176: 9f 5f subi r25, 0xFF ; 255 + 1178: 90 83 st Z, r25 + stan->klGora_off = 0; + 117a: 12 82 std Z+2, r1 ; 0x02 + } + + if (klDolOff) + 117c: 66 23 and r22, r22 + 117e: 61 f0 breq .+24 ; 0x1198 + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + 1180: 24 81 ldd r18, Z+4 ; 0x04 + 1182: 93 81 ldd r25, Z+3 ; 0x03 + 1184: 24 30 cpi r18, 0x04 ; 4 + 1186: 21 f4 brne .+8 ; 0x1190 + 1188: 95 30 cpi r25, 0x05 ; 5 + 118a: 11 f4 brne .+4 ; 0x1190 + { + stan->czynnosc = bezczynny; + 118c: 14 82 std Z+4, r1 ; 0x04 + wiadomosc = 0x40; + 118e: 80 e4 ldi r24, 0x40 ; 64 + } + stan->klDol_on = 0; + 1190: 11 82 std Z+1, r1 ; 0x01 + stan->klDol_off++; + 1192: 9f 5f subi r25, 0xFF ; 255 + 1194: 93 83 std Z+3, r25 ; 0x03 + 1196: 14 c0 rjmp .+40 ; 0x11c0 + } + else + { + if (stan->klDol_on == T_START) + 1198: 91 81 ldd r25, Z+1 ; 0x01 + 119a: 95 30 cpi r25, 0x05 ; 5 + 119c: 51 f4 brne .+20 ; 0x11b2 + { + if (stan->czynnosc != bezczynny) + 119e: 84 81 ldd r24, Z+4 ; 0x04 + 11a0: 88 23 and r24, r24 + 11a2: 19 f0 breq .+6 ; 0x11aa + { + stan->czynnosc = bezczynny; + 11a4: 14 82 std Z+4, r1 ; 0x04 + wiadomosc = 0x40; + 11a6: 80 e4 ldi r24, 0x40 ; 64 + 11a8: 08 c0 rjmp .+16 ; 0x11ba + } + else + { + stan->czynnosc = do_konca_w_dol; + 11aa: 82 e0 ldi r24, 0x02 ; 2 + 11ac: 84 83 std Z+4, r24 ; 0x04 + wiadomosc = 0x3F; + 11ae: 8f e3 ldi r24, 0x3F ; 63 + 11b0: 04 c0 rjmp .+8 ; 0x11ba + } + } + if (stan->klDol_on == T_START_CONT) + 11b2: 98 32 cpi r25, 0x28 ; 40 + 11b4: 11 f4 brne .+4 ; 0x11ba + { + stan->czynnosc = w_dol; + 11b6: 24 e0 ldi r18, 0x04 ; 4 + 11b8: 24 83 std Z+4, r18 ; 0x04 + } + stan->klDol_on++; + 11ba: 9f 5f subi r25, 0xFF ; 255 + 11bc: 91 83 std Z+1, r25 ; 0x01 + stan->klDol_off = 0; + 11be: 13 82 std Z+3, r1 ; 0x03 + } + + if (stan->klDol_on == 255) + 11c0: 91 81 ldd r25, Z+1 ; 0x01 + 11c2: 9f 3f cpi r25, 0xFF ; 255 + 11c4: 11 f4 brne .+4 ; 0x11ca + stan->klDol_on = 254; + 11c6: 9e ef ldi r25, 0xFE ; 254 + 11c8: 91 83 std Z+1, r25 ; 0x01 + if (stan->klGora_on == 255) + 11ca: 90 81 ld r25, Z + 11cc: 9f 3f cpi r25, 0xFF ; 255 + 11ce: 11 f4 brne .+4 ; 0x11d4 + stan->klGora_on = 254; + 11d0: 9e ef ldi r25, 0xFE ; 254 + 11d2: 90 83 st Z, r25 + + if (stan->klDol_off == 255) + 11d4: 93 81 ldd r25, Z+3 ; 0x03 + 11d6: 9f 3f cpi r25, 0xFF ; 255 + 11d8: 11 f4 brne .+4 ; 0x11de + stan->klDol_off = 254; + 11da: 9e ef ldi r25, 0xFE ; 254 + 11dc: 93 83 std Z+3, r25 ; 0x03 + if (stan->klGora_off == 255) + 11de: 92 81 ldd r25, Z+2 ; 0x02 + 11e0: 9f 3f cpi r25, 0xFF ; 255 + 11e2: 11 f4 brne .+4 ; 0x11e8 + stan->klGora_off = 254; + 11e4: 9e ef ldi r25, 0xFE ; 254 + 11e6: 92 83 std Z+2, r25 ; 0x02 + + return wiadomosc; +} + 11e8: 08 95 ret + +000011ea : + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + 11ea: 0e 94 8f 01 call 0x31e ; 0x31e + } + #endif + } + 11ee: fd cf rjmp .-6 ; 0x11ea + +000011f0 : +/*----------------------------------------------------------- + * TASK CREATION API documented in task.h + *----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ + 11f0: 6f 92 push r6 + 11f2: 7f 92 push r7 + 11f4: 8f 92 push r8 + 11f6: 9f 92 push r9 + 11f8: af 92 push r10 + 11fa: bf 92 push r11 + 11fc: cf 92 push r12 + 11fe: df 92 push r13 + 1200: ef 92 push r14 + 1202: ff 92 push r15 + 1204: 0f 93 push r16 + 1206: 1f 93 push r17 + 1208: cf 93 push r28 + 120a: df 93 push r29 + 120c: 4c 01 movw r8, r24 + 120e: 5a 01 movw r10, r20 + 1210: 39 01 movw r6, r18 +{ +tskTCB *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) ); + 1212: 8a e1 ldi r24, 0x1A ; 26 + 1214: 90 e0 ldi r25, 0x00 ; 0 + 1216: 0e 94 02 13 call 0x2604 ; 0x2604 + 121a: ec 01 movw r28, r24 + + if( pxNewTCB != NULL ) + 121c: 89 2b or r24, r25 + 121e: 09 f4 brne .+2 ; 0x1222 + 1220: bc c0 rjmp .+376 ; 0x139a + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); + 1222: c1 14 cp r12, r1 + 1224: d1 04 cpc r13, r1 + 1226: 21 f4 brne .+8 ; 0x1230 + 1228: c5 01 movw r24, r10 + 122a: 0e 94 02 13 call 0x2604 ; 0x2604 + 122e: 01 c0 rjmp .+2 ; 0x1232 + 1230: c6 01 movw r24, r12 + 1232: 98 8f std Y+24, r25 ; 0x18 + 1234: 8f 8b std Y+23, r24 ; 0x17 + + if( pxNewTCB->pxStack == NULL ) + 1236: 00 97 sbiw r24, 0x00 ; 0 + 1238: 21 f4 brne .+8 ; 0x1242 + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + 123a: ce 01 movw r24, r28 + 123c: 0e 94 28 13 call 0x2650 ; 0x2650 + 1240: ac c0 rjmp .+344 ; 0x139a + pxNewTCB = NULL; + } + else + { + /* Just to help debugging. */ + memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) ); + 1242: a5 01 movw r20, r10 + 1244: 65 ea ldi r22, 0xA5 ; 165 + 1246: 70 e0 ldi r23, 0x00 ; 0 + 1248: 0e 94 d3 14 call 0x29a6 ; 0x29a6 + stack grows from high memory to low (as per the 80x86) or visa versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + 124c: 21 e0 ldi r18, 0x01 ; 1 + 124e: a2 1a sub r10, r18 + 1250: b1 08 sbc r11, r1 + 1252: cf 88 ldd r12, Y+23 ; 0x17 + 1254: d8 8c ldd r13, Y+24 ; 0x18 + 1256: ca 0c add r12, r10 + 1258: db 1c adc r13, r11 + { + /* Don't bring strncpy into the build unnecessarily. */ + strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN ); + } + #endif + pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0'; + 125a: 19 8e std Y+25, r1 ; 0x19 + 125c: 10 2f mov r17, r16 + 125e: 04 30 cpi r16, 0x04 ; 4 + 1260: 08 f0 brcs .+2 ; 0x1264 + 1262: 13 e0 ldi r17, 0x03 ; 3 + if( uxPriority >= configMAX_PRIORITIES ) + { + uxPriority = configMAX_PRIORITIES - 1; + } + + pxTCB->uxPriority = uxPriority; + 1264: 1e 8b std Y+22, r17 ; 0x16 + { + pxTCB->uxBasePriority = uxPriority; + } + #endif + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + 1266: 5e 01 movw r10, r28 + 1268: 82 e0 ldi r24, 0x02 ; 2 + 126a: a8 0e add r10, r24 + 126c: b1 1c adc r11, r1 + 126e: c5 01 movw r24, r10 + 1270: 0e 94 b6 10 call 0x216c ; 0x216c + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + 1274: ce 01 movw r24, r28 + 1276: 0c 96 adiw r24, 0x0c ; 12 + 1278: 0e 94 b6 10 call 0x216c ; 0x216c + + /* Set the pxTCB as a link back from the xListItem. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + 127c: d9 87 std Y+9, r29 ; 0x09 + 127e: c8 87 std Y+8, r28 ; 0x08 + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + 1280: 84 e0 ldi r24, 0x04 ; 4 + 1282: 90 e0 ldi r25, 0x00 ; 0 + 1284: 81 1b sub r24, r17 + 1286: 91 09 sbc r25, r1 + 1288: 9d 87 std Y+13, r25 ; 0x0d + 128a: 8c 87 std Y+12, r24 ; 0x0c + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + 128c: db 8b std Y+19, r29 ; 0x13 + 128e: ca 8b std Y+18, r28 ; 0x12 + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + 1290: a3 01 movw r20, r6 + 1292: b4 01 movw r22, r8 + 1294: c6 01 movw r24, r12 + 1296: 0e 94 37 13 call 0x266e ; 0x266e + 129a: 99 83 std Y+1, r25 ; 0x01 + 129c: 88 83 st Y, r24 + } + #endif + + /* We are going to manipulate the task queues to add this task to a + ready list, so must make sure no interrupts occur. */ + portENTER_CRITICAL(); + 129e: 0f b6 in r0, 0x3f ; 63 + 12a0: f8 94 cli + 12a2: 0f 92 push r0 + { + uxCurrentNumberOfTasks++; + 12a4: 80 91 53 01 lds r24, 0x0153 + 12a8: 8f 5f subi r24, 0xFF ; 255 + 12aa: 80 93 53 01 sts 0x0153, r24 + if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) + 12ae: 80 91 53 01 lds r24, 0x0153 + 12b2: 81 30 cpi r24, 0x01 ; 1 + 12b4: 89 f5 brne .+98 ; 0x1318 + { + /* As this is the first task it must also be the current task. */ + pxCurrentTCB = pxNewTCB; + 12b6: d0 93 48 01 sts 0x0148, r29 + 12ba: c0 93 47 01 sts 0x0147, r28 +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) ); + 12be: 8c e7 ldi r24, 0x7C ; 124 + 12c0: 91 e0 ldi r25, 0x01 ; 1 + 12c2: 0e 94 a8 10 call 0x2150 ; 0x2150 + 12c6: 85 e8 ldi r24, 0x85 ; 133 + 12c8: 91 e0 ldi r25, 0x01 ; 1 + 12ca: 0e 94 a8 10 call 0x2150 ; 0x2150 + 12ce: 8e e8 ldi r24, 0x8E ; 142 + 12d0: 91 e0 ldi r25, 0x01 ; 1 + 12d2: 0e 94 a8 10 call 0x2150 ; 0x2150 + 12d6: 87 e9 ldi r24, 0x97 ; 151 + 12d8: 91 e0 ldi r25, 0x01 ; 1 + 12da: 0e 94 a8 10 call 0x2150 ; 0x2150 + } + + vListInitialise( ( xList * ) &xDelayedTaskList1 ); + 12de: 83 e7 ldi r24, 0x73 ; 115 + 12e0: 91 e0 ldi r25, 0x01 ; 1 + 12e2: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( ( xList * ) &xDelayedTaskList2 ); + 12e6: 8a e6 ldi r24, 0x6A ; 106 + 12e8: 91 e0 ldi r25, 0x01 ; 1 + 12ea: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( ( xList * ) &xPendingReadyList ); + 12ee: 8d e5 ldi r24, 0x5D ; 93 + 12f0: 91 e0 ldi r25, 0x01 ; 1 + 12f2: 0e 94 a8 10 call 0x2150 ; 0x2150 + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( ( xList * ) &xSuspendedTaskList ); + 12f6: 84 e5 ldi r24, 0x54 ; 84 + 12f8: 91 e0 ldi r25, 0x01 ; 1 + 12fa: 0e 94 a8 10 call 0x2150 ; 0x2150 + } + #endif + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + 12fe: 83 e7 ldi r24, 0x73 ; 115 + 1300: 91 e0 ldi r25, 0x01 ; 1 + 1302: 90 93 69 01 sts 0x0169, r25 + 1306: 80 93 68 01 sts 0x0168, r24 + pxOverflowDelayedTaskList = &xDelayedTaskList2; + 130a: 8a e6 ldi r24, 0x6A ; 106 + 130c: 91 e0 ldi r25, 0x01 ; 1 + 130e: 90 93 67 01 sts 0x0167, r25 + 1312: 80 93 66 01 sts 0x0166, r24 + 1316: 0f c0 rjmp .+30 ; 0x1336 + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + 1318: 80 91 4e 01 lds r24, 0x014E + 131c: 81 11 cpse r24, r1 + 131e: 0b c0 rjmp .+22 ; 0x1336 + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + 1320: e0 91 47 01 lds r30, 0x0147 + 1324: f0 91 48 01 lds r31, 0x0148 + 1328: 86 89 ldd r24, Z+22 ; 0x16 + 132a: 08 17 cp r16, r24 + 132c: 20 f0 brcs .+8 ; 0x1336 + { + pxCurrentTCB = pxNewTCB; + 132e: d0 93 48 01 sts 0x0148, r29 + 1332: c0 93 47 01 sts 0x0147, r28 + } + } + + /* Remember the top priority to make context switching faster. Use + the priority in pxNewTCB as this has been capped to a valid value. */ + if( pxNewTCB->uxPriority > uxTopUsedPriority ) + 1336: 8e 89 ldd r24, Y+22 ; 0x16 + 1338: 90 91 50 01 lds r25, 0x0150 + 133c: 98 17 cp r25, r24 + 133e: 10 f4 brcc .+4 ; 0x1344 + { + uxTopUsedPriority = pxNewTCB->uxPriority; + 1340: 80 93 50 01 sts 0x0150, r24 + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif + uxTaskNumber++; + 1344: 90 91 49 01 lds r25, 0x0149 + 1348: 9f 5f subi r25, 0xFF ; 255 + 134a: 90 93 49 01 sts 0x0149, r25 + + prvAddTaskToReadyQueue( pxNewTCB ); + 134e: 90 91 4f 01 lds r25, 0x014F + 1352: 98 17 cp r25, r24 + 1354: 10 f4 brcc .+4 ; 0x135a + 1356: 80 93 4f 01 sts 0x014F, r24 + 135a: e9 e0 ldi r30, 0x09 ; 9 + 135c: 8e 9f mul r24, r30 + 135e: c0 01 movw r24, r0 + 1360: 11 24 eor r1, r1 + 1362: b5 01 movw r22, r10 + 1364: 84 58 subi r24, 0x84 ; 132 + 1366: 9e 4f sbci r25, 0xFE ; 254 + 1368: 0e 94 ba 10 call 0x2174 ; 0x2174 + + xReturn = pdPASS; + traceTASK_CREATE( pxNewTCB ); + } + portEXIT_CRITICAL(); + 136c: 0f 90 pop r0 + 136e: 0f be out 0x3f, r0 ; 63 + traceTASK_CREATE_FAILED( pxNewTCB ); + } + + if( xReturn == pdPASS ) + { + if( ( void * ) pxCreatedTask != NULL ) + 1370: e1 14 cp r14, r1 + 1372: f1 04 cpc r15, r1 + 1374: 19 f0 breq .+6 ; 0x137c + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( xTaskHandle ) pxNewTCB; + 1376: f7 01 movw r30, r14 + 1378: d1 83 std Z+1, r29 ; 0x01 + 137a: c0 83 st Z, r28 + } + + if( xSchedulerRunning != pdFALSE ) + 137c: 80 91 4e 01 lds r24, 0x014E + 1380: 88 23 and r24, r24 + 1382: 49 f0 breq .+18 ; 0x1396 + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + 1384: e0 91 47 01 lds r30, 0x0147 + 1388: f0 91 48 01 lds r31, 0x0148 + 138c: 86 89 ldd r24, Z+22 ; 0x16 + 138e: 80 17 cp r24, r16 + 1390: 10 f4 brcc .+4 ; 0x1396 + { + portYIELD_WITHIN_API(); + 1392: 0e 94 df 13 call 0x27be ; 0x27be + #endif + uxTaskNumber++; + + prvAddTaskToReadyQueue( pxNewTCB ); + + xReturn = pdPASS; + 1396: 81 e0 ldi r24, 0x01 ; 1 + 1398: 01 c0 rjmp .+2 ; 0x139c + } + portEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + 139a: 8f ef ldi r24, 0xFF ; 255 + } + } + } + + return xReturn; +} + 139c: df 91 pop r29 + 139e: cf 91 pop r28 + 13a0: 1f 91 pop r17 + 13a2: 0f 91 pop r16 + 13a4: ff 90 pop r15 + 13a6: ef 90 pop r14 + 13a8: df 90 pop r13 + 13aa: cf 90 pop r12 + 13ac: bf 90 pop r11 + 13ae: af 90 pop r10 + 13b0: 9f 90 pop r9 + 13b2: 8f 90 pop r8 + 13b4: 7f 90 pop r7 + 13b6: 6f 90 pop r6 + 13b8: 08 95 ret + +000013ba : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + 13ba: ef 92 push r14 + 13bc: ff 92 push r15 + 13be: 0f 93 push r16 + 13c0: 1f 93 push r17 + 13c2: cf 93 push r28 + 13c4: df 93 push r29 + 13c6: ec 01 movw r28, r24 + tskTCB *pxTCB; + + portENTER_CRITICAL(); + 13c8: 0f b6 in r0, 0x3f ; 63 + 13ca: f8 94 cli + 13cc: 0f 92 push r0 + { + /* Ensure a yield is performed if the current task is being + suspended. */ + if( pxTaskToSuspend == pxCurrentTCB ) + 13ce: 80 91 47 01 lds r24, 0x0147 + 13d2: 90 91 48 01 lds r25, 0x0148 + 13d6: c8 17 cp r28, r24 + 13d8: d9 07 cpc r29, r25 + 13da: 11 f0 breq .+4 ; 0x13e0 + { + pxTaskToSuspend = NULL; + } + + /* If null is passed in here then we are suspending ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToSuspend ); + 13dc: 20 97 sbiw r28, 0x00 ; 0 + 13de: 39 f4 brne .+14 ; 0x13ee + 13e0: 00 91 47 01 lds r16, 0x0147 + 13e4: 10 91 48 01 lds r17, 0x0148 + 13e8: c0 e0 ldi r28, 0x00 ; 0 + 13ea: d0 e0 ldi r29, 0x00 ; 0 + 13ec: 01 c0 rjmp .+2 ; 0x13f0 + 13ee: 8e 01 movw r16, r28 + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the suspended list. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + 13f0: 78 01 movw r14, r16 + 13f2: 82 e0 ldi r24, 0x02 ; 2 + 13f4: e8 0e add r14, r24 + 13f6: f1 1c adc r15, r1 + 13f8: c7 01 movw r24, r14 + 13fa: 0e 94 14 11 call 0x2228 ; 0x2228 + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + 13fe: f8 01 movw r30, r16 + 1400: 84 89 ldd r24, Z+20 ; 0x14 + 1402: 95 89 ldd r25, Z+21 ; 0x15 + 1404: 89 2b or r24, r25 + 1406: 21 f0 breq .+8 ; 0x1410 + { + vListRemove( &( pxTCB->xEventListItem ) ); + 1408: c8 01 movw r24, r16 + 140a: 0c 96 adiw r24, 0x0c ; 12 + 140c: 0e 94 14 11 call 0x2228 ; 0x2228 + } + + vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + 1410: b7 01 movw r22, r14 + 1412: 84 e5 ldi r24, 0x54 ; 84 + 1414: 91 e0 ldi r25, 0x01 ; 1 + 1416: 0e 94 ba 10 call 0x2174 ; 0x2174 + } + portEXIT_CRITICAL(); + 141a: 0f 90 pop r0 + 141c: 0f be out 0x3f, r0 ; 63 + + /* We may have just suspended the current task. */ + if( ( void * ) pxTaskToSuspend == NULL ) + 141e: cd 2b or r28, r29 + 1420: 11 f4 brne .+4 ; 0x1426 + { + portYIELD_WITHIN_API(); + 1422: 0e 94 df 13 call 0x27be ; 0x27be + } + } + 1426: df 91 pop r29 + 1428: cf 91 pop r28 + 142a: 1f 91 pop r17 + 142c: 0f 91 pop r16 + 142e: ff 90 pop r15 + 1430: ef 90 pop r14 + 1432: 08 95 ret + +00001434 : + portBASE_TYPE xReturn = pdFALSE; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + /* Is the task we are attempting to resume actually in the + suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + 1434: fc 01 movw r30, r24 + 1436: 22 85 ldd r18, Z+10 ; 0x0a + 1438: 33 85 ldd r19, Z+11 ; 0x0b + 143a: 24 55 subi r18, 0x54 ; 84 + 143c: 31 40 sbci r19, 0x01 ; 1 + 143e: 51 f4 brne .+20 ; 0x1454 + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) + 1440: fc 01 movw r30, r24 + 1442: 24 89 ldd r18, Z+20 ; 0x14 + 1444: 35 89 ldd r19, Z+21 ; 0x15 + 1446: f1 e0 ldi r31, 0x01 ; 1 + 1448: 2d 35 cpi r18, 0x5D ; 93 + 144a: 3f 07 cpc r19, r31 + 144c: 19 f0 breq .+6 ; 0x1454 + { + /* Is it in the suspended list because it is in the + Suspended state? It is possible to be in the suspended + list because it is blocked on a task with no timeout + specified. */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE ) + 144e: 81 e0 ldi r24, 0x01 ; 1 + 1450: 23 2b or r18, r19 + 1452: 09 f0 breq .+2 ; 0x1456 + +#if ( INCLUDE_vTaskSuspend == 1 ) + + signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) + { + portBASE_TYPE xReturn = pdFALSE; + 1454: 80 e0 ldi r24, 0x00 ; 0 + } + } + } + + return xReturn; + } + 1456: 08 95 ret + +00001458 : +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( xTaskHandle pxTaskToResume ) + { + 1458: 0f 93 push r16 + 145a: 1f 93 push r17 + 145c: cf 93 push r28 + 145e: df 93 push r29 + it in the ready list. */ + pxTCB = ( tskTCB * ) pxTaskToResume; + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + 1460: 00 97 sbiw r24, 0x00 ; 0 + 1462: 89 f1 breq .+98 ; 0x14c6 + 1464: 20 91 47 01 lds r18, 0x0147 + 1468: 30 91 48 01 lds r19, 0x0148 + 146c: 82 17 cp r24, r18 + 146e: 93 07 cpc r25, r19 + 1470: 51 f1 breq .+84 ; 0x14c6 + 1472: ec 01 movw r28, r24 + { + portENTER_CRITICAL(); + 1474: 0f b6 in r0, 0x3f ; 63 + 1476: f8 94 cli + 1478: 0f 92 push r0 + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + 147a: 0e 94 1a 0a call 0x1434 ; 0x1434 + 147e: 81 30 cpi r24, 0x01 ; 1 + 1480: 01 f5 brne .+64 ; 0x14c2 + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + 1482: 8e 01 movw r16, r28 + 1484: 0e 5f subi r16, 0xFE ; 254 + 1486: 1f 4f sbci r17, 0xFF ; 255 + 1488: c8 01 movw r24, r16 + 148a: 0e 94 14 11 call 0x2228 ; 0x2228 + prvAddTaskToReadyQueue( pxTCB ); + 148e: 9e 89 ldd r25, Y+22 ; 0x16 + 1490: 80 91 4f 01 lds r24, 0x014F + 1494: 89 17 cp r24, r25 + 1496: 10 f4 brcc .+4 ; 0x149c + 1498: 90 93 4f 01 sts 0x014F, r25 + 149c: 29 e0 ldi r18, 0x09 ; 9 + 149e: 92 9f mul r25, r18 + 14a0: c0 01 movw r24, r0 + 14a2: 11 24 eor r1, r1 + 14a4: b8 01 movw r22, r16 + 14a6: 84 58 subi r24, 0x84 ; 132 + 14a8: 9e 4f sbci r25, 0xFE ; 254 + 14aa: 0e 94 ba 10 call 0x2174 ; 0x2174 + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 14ae: e0 91 47 01 lds r30, 0x0147 + 14b2: f0 91 48 01 lds r31, 0x0148 + 14b6: 9e 89 ldd r25, Y+22 ; 0x16 + 14b8: 86 89 ldd r24, Z+22 ; 0x16 + 14ba: 98 17 cp r25, r24 + 14bc: 10 f0 brcs .+4 ; 0x14c2 + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + portYIELD_WITHIN_API(); + 14be: 0e 94 df 13 call 0x27be ; 0x27be + } + } + } + portEXIT_CRITICAL(); + 14c2: 0f 90 pop r0 + 14c4: 0f be out 0x3f, r0 ; 63 + } + } + 14c6: df 91 pop r29 + 14c8: cf 91 pop r28 + 14ca: 1f 91 pop r17 + 14cc: 0f 91 pop r16 + 14ce: 08 95 ret + +000014d0 : +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + 14d0: ef 92 push r14 + 14d2: ff 92 push r15 + 14d4: 1f 93 push r17 + 14d6: cf 93 push r28 + 14d8: df 93 push r29 + 14da: ec 01 movw r28, r24 + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + pxTCB = ( tskTCB * ) pxTaskToResume; + + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + 14dc: 0e 94 1a 0a call 0x1434 ; 0x1434 + 14e0: 81 30 cpi r24, 0x01 ; 1 + 14e2: 69 f5 brne .+90 ; 0x153e + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 14e4: 80 91 4d 01 lds r24, 0x014D + 14e8: 81 11 cpse r24, r1 + 14ea: 22 c0 rjmp .+68 ; 0x1530 + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + 14ec: e0 91 47 01 lds r30, 0x0147 + 14f0: f0 91 48 01 lds r31, 0x0148 + 14f4: 11 e0 ldi r17, 0x01 ; 1 + 14f6: 9e 89 ldd r25, Y+22 ; 0x16 + 14f8: 86 89 ldd r24, Z+22 ; 0x16 + 14fa: 98 17 cp r25, r24 + 14fc: 08 f4 brcc .+2 ; 0x1500 + 14fe: 10 e0 ldi r17, 0x00 ; 0 + vListRemove( &( pxTCB->xGenericListItem ) ); + 1500: 7e 01 movw r14, r28 + 1502: 32 e0 ldi r19, 0x02 ; 2 + 1504: e3 0e add r14, r19 + 1506: f1 1c adc r15, r1 + 1508: c7 01 movw r24, r14 + 150a: 0e 94 14 11 call 0x2228 ; 0x2228 + prvAddTaskToReadyQueue( pxTCB ); + 150e: 2e 89 ldd r18, Y+22 ; 0x16 + 1510: 80 91 4f 01 lds r24, 0x014F + 1514: 82 17 cp r24, r18 + 1516: 10 f4 brcc .+4 ; 0x151c + 1518: 20 93 4f 01 sts 0x014F, r18 + 151c: 39 e0 ldi r19, 0x09 ; 9 + 151e: 23 9f mul r18, r19 + 1520: c0 01 movw r24, r0 + 1522: 11 24 eor r1, r1 + 1524: b7 01 movw r22, r14 + 1526: 84 58 subi r24, 0x84 ; 132 + 1528: 9e 4f sbci r25, 0xFE ; 254 + 152a: 0e 94 ba 10 call 0x2174 ; 0x2174 + 152e: 08 c0 rjmp .+16 ; 0x1540 + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be performed if necessary. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + 1530: be 01 movw r22, r28 + 1532: 64 5f subi r22, 0xF4 ; 244 + 1534: 7f 4f sbci r23, 0xFF ; 255 + 1536: 8d e5 ldi r24, 0x5D ; 93 + 1538: 91 e0 ldi r25, 0x01 ; 1 + 153a: 0e 94 ba 10 call 0x2174 ; 0x2174 + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + 153e: 10 e0 ldi r17, 0x00 ; 0 + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + + return xYieldRequired; + } + 1540: 81 2f mov r24, r17 + 1542: df 91 pop r29 + 1544: cf 91 pop r28 + 1546: 1f 91 pop r17 + 1548: ff 90 pop r15 + 154a: ef 90 pop r14 + 154c: 08 95 ret + +0000154e : + * PUBLIC SCHEDULER CONTROL documented in task.h + *----------------------------------------------------------*/ + + +void vTaskStartScheduler( void ) +{ + 154e: af 92 push r10 + 1550: bf 92 push r11 + 1552: cf 92 push r12 + 1554: df 92 push r13 + 1556: ef 92 push r14 + 1558: ff 92 push r15 + 155a: 0f 93 push r16 +portBASE_TYPE xReturn; + + /* Add the idle task at the lowest priority. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL ); + 155c: a1 2c mov r10, r1 + 155e: b1 2c mov r11, r1 + 1560: c1 2c mov r12, r1 + 1562: d1 2c mov r13, r1 + 1564: e1 2c mov r14, r1 + 1566: f1 2c mov r15, r1 + 1568: 00 e0 ldi r16, 0x00 ; 0 + 156a: 20 e0 ldi r18, 0x00 ; 0 + 156c: 30 e0 ldi r19, 0x00 ; 0 + 156e: 45 e5 ldi r20, 0x55 ; 85 + 1570: 50 e0 ldi r21, 0x00 ; 0 + 1572: 6c e0 ldi r22, 0x0C ; 12 + 1574: 71 e0 ldi r23, 0x01 ; 1 + 1576: 85 ef ldi r24, 0xF5 ; 245 + 1578: 98 e0 ldi r25, 0x08 ; 8 + 157a: 0e 94 f8 08 call 0x11f0 ; 0x11f0 + + if( xReturn == pdPASS ) + 157e: 81 30 cpi r24, 0x01 ; 1 + 1580: 81 f4 brne .+32 ; 0x15a2 + so interrupts will automatically get re-enabled when the first task + starts to run. + + STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE + DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ + portDISABLE_INTERRUPTS(); + 1582: f8 94 cli + + xSchedulerRunning = pdTRUE; + 1584: 80 93 4e 01 sts 0x014E, r24 + xTickCount = ( portTickType ) 0; + 1588: 10 92 52 01 sts 0x0152, r1 + 158c: 10 92 51 01 sts 0x0151, r1 + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} + 1590: 0f 91 pop r16 + 1592: ff 90 pop r15 + 1594: ef 90 pop r14 + 1596: df 90 pop r13 + 1598: cf 90 pop r12 + 159a: bf 90 pop r11 + 159c: af 90 pop r10 + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() ) + 159e: 0c 94 a3 13 jmp 0x2746 ; 0x2746 + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} + 15a2: 0f 91 pop r16 + 15a4: ff 90 pop r15 + 15a6: ef 90 pop r14 + 15a8: df 90 pop r13 + 15aa: cf 90 pop r12 + 15ac: bf 90 pop r11 + 15ae: af 90 pop r10 + 15b0: 08 95 ret + +000015b2 : +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + 15b2: f8 94 cli + xSchedulerRunning = pdFALSE; + 15b4: 10 92 4e 01 sts 0x014E, r1 + vPortEndScheduler(); + 15b8: 0c 94 de 13 jmp 0x27bc ; 0x27bc + +000015bc : + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + portBASE_TYPE. */ + ++uxSchedulerSuspended; + 15bc: 80 91 4d 01 lds r24, 0x014D + 15c0: 8f 5f subi r24, 0xFF ; 255 + 15c2: 80 93 4d 01 sts 0x014D, r24 + 15c6: 08 95 ret + +000015c8 : +portTickType xTaskGetTickCount( void ) +{ +portTickType xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portENTER_CRITICAL(); + 15c8: 0f b6 in r0, 0x3f ; 63 + 15ca: f8 94 cli + 15cc: 0f 92 push r0 + { + xTicks = xTickCount; + 15ce: 80 91 51 01 lds r24, 0x0151 + 15d2: 90 91 52 01 lds r25, 0x0152 + } + portEXIT_CRITICAL(); + 15d6: 0f 90 pop r0 + 15d8: 0f be out 0x3f, r0 ; 63 + + return xTicks; +} + 15da: 08 95 ret + +000015dc : + +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + portBASE_TYPE. */ + return uxCurrentNumberOfTasks; + 15dc: 80 91 53 01 lds r24, 0x0153 +} + 15e0: 08 95 ret + +000015e2 : + * documented in task.h + *----------------------------------------------------------*/ + + +void vTaskIncrementTick( void ) +{ + 15e2: ff 92 push r15 + 15e4: 0f 93 push r16 + 15e6: 1f 93 push r17 + 15e8: cf 93 push r28 + 15ea: df 93 push r29 + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 15ec: 80 91 4d 01 lds r24, 0x014D + 15f0: 81 11 cpse r24, r1 + 15f2: 5f c0 rjmp .+190 ; 0x16b2 + { + ++xTickCount; + 15f4: 80 91 51 01 lds r24, 0x0151 + 15f8: 90 91 52 01 lds r25, 0x0152 + 15fc: 01 96 adiw r24, 0x01 ; 1 + 15fe: 90 93 52 01 sts 0x0152, r25 + 1602: 80 93 51 01 sts 0x0151, r24 + if( xTickCount == ( portTickType ) 0 ) + 1606: 80 91 51 01 lds r24, 0x0151 + 160a: 90 91 52 01 lds r25, 0x0152 + 160e: 89 2b or r24, r25 + 1610: a9 f4 brne .+42 ; 0x163c + xList *pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. + If there are any items in pxDelayedTaskList here then there is + an error! */ + pxTemp = pxDelayedTaskList; + 1612: 80 91 68 01 lds r24, 0x0168 + 1616: 90 91 69 01 lds r25, 0x0169 + pxDelayedTaskList = pxOverflowDelayedTaskList; + 161a: 20 91 66 01 lds r18, 0x0166 + 161e: 30 91 67 01 lds r19, 0x0167 + 1622: 30 93 69 01 sts 0x0169, r19 + 1626: 20 93 68 01 sts 0x0168, r18 + pxOverflowDelayedTaskList = pxTemp; + 162a: 90 93 67 01 sts 0x0167, r25 + 162e: 80 93 66 01 sts 0x0166, r24 + xNumOfOverflows++; + 1632: 80 91 4a 01 lds r24, 0x014A + 1636: 8f 5f subi r24, 0xFF ; 255 + 1638: 80 93 4a 01 sts 0x014A, r24 + } + + /* See if this tick has made a timeout expire. */ + prvCheckDelayedTasks(); + 163c: 89 e0 ldi r24, 0x09 ; 9 + 163e: f8 2e mov r15, r24 + 1640: e0 91 68 01 lds r30, 0x0168 + 1644: f0 91 69 01 lds r31, 0x0169 + 1648: 80 81 ld r24, Z + 164a: 88 23 and r24, r24 + 164c: b9 f1 breq .+110 ; 0x16bc + 164e: e0 91 68 01 lds r30, 0x0168 + 1652: f0 91 69 01 lds r31, 0x0169 + 1656: 05 80 ldd r0, Z+5 ; 0x05 + 1658: f6 81 ldd r31, Z+6 ; 0x06 + 165a: e0 2d mov r30, r0 + 165c: c6 81 ldd r28, Z+6 ; 0x06 + 165e: d7 81 ldd r29, Z+7 ; 0x07 + 1660: 20 97 sbiw r28, 0x00 ; 0 + 1662: 61 f1 breq .+88 ; 0x16bc + 1664: 20 91 51 01 lds r18, 0x0151 + 1668: 30 91 52 01 lds r19, 0x0152 + 166c: 8a 81 ldd r24, Y+2 ; 0x02 + 166e: 9b 81 ldd r25, Y+3 ; 0x03 + 1670: 28 17 cp r18, r24 + 1672: 39 07 cpc r19, r25 + 1674: 18 f1 brcs .+70 ; 0x16bc + 1676: 8e 01 movw r16, r28 + 1678: 0e 5f subi r16, 0xFE ; 254 + 167a: 1f 4f sbci r17, 0xFF ; 255 + 167c: c8 01 movw r24, r16 + 167e: 0e 94 14 11 call 0x2228 ; 0x2228 + 1682: 8c 89 ldd r24, Y+20 ; 0x14 + 1684: 9d 89 ldd r25, Y+21 ; 0x15 + 1686: 89 2b or r24, r25 + 1688: 21 f0 breq .+8 ; 0x1692 + 168a: ce 01 movw r24, r28 + 168c: 0c 96 adiw r24, 0x0c ; 12 + 168e: 0e 94 14 11 call 0x2228 ; 0x2228 + 1692: 9e 89 ldd r25, Y+22 ; 0x16 + 1694: 80 91 4f 01 lds r24, 0x014F + 1698: 89 17 cp r24, r25 + 169a: 10 f4 brcc .+4 ; 0x16a0 + 169c: 90 93 4f 01 sts 0x014F, r25 + 16a0: f9 9e mul r15, r25 + 16a2: c0 01 movw r24, r0 + 16a4: 11 24 eor r1, r1 + 16a6: b8 01 movw r22, r16 + 16a8: 84 58 subi r24, 0x84 ; 132 + 16aa: 9e 4f sbci r25, 0xFE ; 254 + 16ac: 0e 94 ba 10 call 0x2174 ; 0x2174 + 16b0: c7 cf rjmp .-114 ; 0x1640 + } + else + { + ++uxMissedTicks; + 16b2: 80 91 4c 01 lds r24, 0x014C + 16b6: 8f 5f subi r24, 0xFF ; 255 + 16b8: 80 93 4c 01 sts 0x014C, r24 + } + } + #endif + + traceTASK_INCREMENT_TICK( xTickCount ); +} + 16bc: df 91 pop r29 + 16be: cf 91 pop r28 + 16c0: 1f 91 pop r17 + 16c2: 0f 91 pop r16 + 16c4: ff 90 pop r15 + 16c6: 08 95 ret + +000016c8 : + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ + 16c8: ef 92 push r14 + 16ca: ff 92 push r15 + 16cc: 0f 93 push r16 + 16ce: 1f 93 push r17 + 16d0: cf 93 push r28 + 16d2: df 93 push r29 + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + portENTER_CRITICAL(); + 16d4: 0f b6 in r0, 0x3f ; 63 + 16d6: f8 94 cli + 16d8: 0f 92 push r0 + { + --uxSchedulerSuspended; + 16da: 80 91 4d 01 lds r24, 0x014D + 16de: 81 50 subi r24, 0x01 ; 1 + 16e0: 80 93 4d 01 sts 0x014D, r24 + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 16e4: 80 91 4d 01 lds r24, 0x014D + 16e8: 88 23 and r24, r24 + 16ea: 11 f0 breq .+4 ; 0x16f0 +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ +register tskTCB *pxTCB; +signed portBASE_TYPE xAlreadyYielded = pdFALSE; + 16ec: 80 e0 ldi r24, 0x00 ; 0 + 16ee: 55 c0 rjmp .+170 ; 0x179a + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 ) + 16f0: 80 91 53 01 lds r24, 0x0153 + 16f4: 88 23 and r24, r24 + 16f6: d1 f3 breq .-12 ; 0x16ec + 16f8: 10 e0 ldi r17, 0x00 ; 0 + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + 16fa: 09 e0 ldi r16, 0x09 ; 9 + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + 16fc: 80 91 5d 01 lds r24, 0x015D + 1700: 81 11 cpse r24, r1 + 1702: 05 c0 rjmp .+10 ; 0x170e + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + 1704: 80 91 4c 01 lds r24, 0x014C + 1708: 81 11 cpse r24, r1 + 170a: 2d c0 rjmp .+90 ; 0x1766 + 170c: 38 c0 rjmp .+112 ; 0x177e + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + 170e: e0 91 62 01 lds r30, 0x0162 + 1712: f0 91 63 01 lds r31, 0x0163 + 1716: c6 81 ldd r28, Z+6 ; 0x06 + 1718: d7 81 ldd r29, Z+7 ; 0x07 + 171a: 20 97 sbiw r28, 0x00 ; 0 + 171c: 99 f3 breq .-26 ; 0x1704 + { + vListRemove( &( pxTCB->xEventListItem ) ); + 171e: ce 01 movw r24, r28 + 1720: 0c 96 adiw r24, 0x0c ; 12 + 1722: 0e 94 14 11 call 0x2228 ; 0x2228 + vListRemove( &( pxTCB->xGenericListItem ) ); + 1726: 7e 01 movw r14, r28 + 1728: 82 e0 ldi r24, 0x02 ; 2 + 172a: e8 0e add r14, r24 + 172c: f1 1c adc r15, r1 + 172e: c7 01 movw r24, r14 + 1730: 0e 94 14 11 call 0x2228 ; 0x2228 + prvAddTaskToReadyQueue( pxTCB ); + 1734: 9e 89 ldd r25, Y+22 ; 0x16 + 1736: 80 91 4f 01 lds r24, 0x014F + 173a: 89 17 cp r24, r25 + 173c: 10 f4 brcc .+4 ; 0x1742 + 173e: 90 93 4f 01 sts 0x014F, r25 + 1742: 09 9f mul r16, r25 + 1744: c0 01 movw r24, r0 + 1746: 11 24 eor r1, r1 + 1748: b7 01 movw r22, r14 + 174a: 84 58 subi r24, 0x84 ; 132 + 174c: 9e 4f sbci r25, 0xFE ; 254 + 174e: 0e 94 ba 10 call 0x2174 ; 0x2174 + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 1752: e0 91 47 01 lds r30, 0x0147 + 1756: f0 91 48 01 lds r31, 0x0148 + 175a: 9e 89 ldd r25, Y+22 ; 0x16 + 175c: 86 89 ldd r24, Z+22 ; 0x16 + 175e: 98 17 cp r25, r24 + 1760: 68 f2 brcs .-102 ; 0x16fc + { + xYieldRequired = pdTRUE; + 1762: 11 e0 ldi r17, 0x01 ; 1 + 1764: cb cf rjmp .-106 ; 0x16fc + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + 1766: 80 91 4c 01 lds r24, 0x014C + 176a: 88 23 and r24, r24 + 176c: 51 f0 breq .+20 ; 0x1782 + { + vTaskIncrementTick(); + 176e: 0e 94 f1 0a call 0x15e2 ; 0x15e2 + --uxMissedTicks; + 1772: 80 91 4c 01 lds r24, 0x014C + 1776: 81 50 subi r24, 0x01 ; 1 + 1778: 80 93 4c 01 sts 0x014C, r24 + 177c: f4 cf rjmp .-24 ; 0x1766 + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + 177e: 11 30 cpi r17, 0x01 ; 1 + 1780: 31 f4 brne .+12 ; 0x178e + { + xAlreadyYielded = pdTRUE; + xMissedYield = pdFALSE; + 1782: 10 92 4b 01 sts 0x014B, r1 + portYIELD_WITHIN_API(); + 1786: 0e 94 df 13 call 0x27be ; 0x27be + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + { + xAlreadyYielded = pdTRUE; + 178a: 81 e0 ldi r24, 0x01 ; 1 + 178c: 06 c0 rjmp .+12 ; 0x179a + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + 178e: 80 91 4b 01 lds r24, 0x014B + 1792: 81 30 cpi r24, 0x01 ; 1 + 1794: 09 f0 breq .+2 ; 0x1798 + 1796: aa cf rjmp .-172 ; 0x16ec + 1798: f4 cf rjmp .-24 ; 0x1782 + portYIELD_WITHIN_API(); + } + } + } + } + portEXIT_CRITICAL(); + 179a: 0f 90 pop r0 + 179c: 0f be out 0x3f, r0 ; 63 + + return xAlreadyYielded; +} + 179e: df 91 pop r29 + 17a0: cf 91 pop r28 + 17a2: 1f 91 pop r17 + 17a4: 0f 91 pop r16 + 17a6: ff 90 pop r15 + 17a8: ef 90 pop r14 + 17aa: 08 95 ret + +000017ac : +#endif +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) + 17ac: 80 91 4d 01 lds r24, 0x014D + 17b0: 88 23 and r24, r24 + 17b2: 21 f0 breq .+8 ; 0x17bc + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xMissedYield = pdTRUE; + 17b4: 81 e0 ldi r24, 0x01 ; 1 + 17b6: 80 93 4b 01 sts 0x014B, r24 + return; + 17ba: 08 95 ret + + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + /* Find the highest priority queue that contains ready tasks. */ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) + 17bc: 99 e0 ldi r25, 0x09 ; 9 + 17be: e0 91 4f 01 lds r30, 0x014F + 17c2: 9e 9f mul r25, r30 + 17c4: f0 01 movw r30, r0 + 17c6: 11 24 eor r1, r1 + 17c8: e4 58 subi r30, 0x84 ; 132 + 17ca: fe 4f sbci r31, 0xFE ; 254 + 17cc: 80 81 ld r24, Z + 17ce: 81 11 cpse r24, r1 + 17d0: 06 c0 rjmp .+12 ; 0x17de + { + --uxTopReadyPriority; + 17d2: 80 91 4f 01 lds r24, 0x014F + 17d6: 81 50 subi r24, 0x01 ; 1 + 17d8: 80 93 4f 01 sts 0x014F, r24 + 17dc: f0 cf rjmp .-32 ; 0x17be + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the + same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); + 17de: 80 91 4f 01 lds r24, 0x014F + 17e2: 90 e0 ldi r25, 0x00 ; 0 + 17e4: 49 e0 ldi r20, 0x09 ; 9 + 17e6: 48 9f mul r20, r24 + 17e8: 90 01 movw r18, r0 + 17ea: 49 9f mul r20, r25 + 17ec: 30 0d add r19, r0 + 17ee: 11 24 eor r1, r1 + 17f0: f9 01 movw r30, r18 + 17f2: e4 58 subi r30, 0x84 ; 132 + 17f4: fe 4f sbci r31, 0xFE ; 254 + 17f6: a1 81 ldd r26, Z+1 ; 0x01 + 17f8: b2 81 ldd r27, Z+2 ; 0x02 + 17fa: 12 96 adiw r26, 0x02 ; 2 + 17fc: 0d 90 ld r0, X+ + 17fe: bc 91 ld r27, X + 1800: a0 2d mov r26, r0 + 1802: b2 83 std Z+2, r27 ; 0x02 + 1804: a1 83 std Z+1, r26 ; 0x01 + 1806: 21 58 subi r18, 0x81 ; 129 + 1808: 3e 4f sbci r19, 0xFE ; 254 + 180a: a2 17 cp r26, r18 + 180c: b3 07 cpc r27, r19 + 180e: 31 f4 brne .+12 ; 0x181c + 1810: 12 96 adiw r26, 0x02 ; 2 + 1812: 2d 91 ld r18, X+ + 1814: 3c 91 ld r19, X + 1816: 13 97 sbiw r26, 0x03 ; 3 + 1818: 32 83 std Z+2, r19 ; 0x02 + 181a: 21 83 std Z+1, r18 ; 0x01 + 181c: 29 e0 ldi r18, 0x09 ; 9 + 181e: 28 9f mul r18, r24 + 1820: f0 01 movw r30, r0 + 1822: 29 9f mul r18, r25 + 1824: f0 0d add r31, r0 + 1826: 11 24 eor r1, r1 + 1828: e4 58 subi r30, 0x84 ; 132 + 182a: fe 4f sbci r31, 0xFE ; 254 + 182c: 01 80 ldd r0, Z+1 ; 0x01 + 182e: f2 81 ldd r31, Z+2 ; 0x02 + 1830: e0 2d mov r30, r0 + 1832: 86 81 ldd r24, Z+6 ; 0x06 + 1834: 97 81 ldd r25, Z+7 ; 0x07 + 1836: 90 93 48 01 sts 0x0148, r25 + 183a: 80 93 47 01 sts 0x0147, r24 + 183e: 08 95 ret + +00001840 : + vWriteTraceToBuffer(); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) +{ + 1840: cf 93 push r28 + 1842: df 93 push r29 + 1844: eb 01 movw r28, r22 + SCHEDULER SUSPENDED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. */ + vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); + 1846: 20 91 47 01 lds r18, 0x0147 + 184a: 30 91 48 01 lds r19, 0x0148 + 184e: b9 01 movw r22, r18 + 1850: 64 5f subi r22, 0xF4 ; 244 + 1852: 7f 4f sbci r23, 0xFF ; 255 + 1854: 0e 94 dd 10 call 0x21ba ; 0x21ba + + /* We must remove ourselves from the ready list before adding ourselves + to the blocked list as the same list item is used for both lists. We have + exclusive access to the ready lists as the scheduler is locked. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 1858: 80 91 47 01 lds r24, 0x0147 + 185c: 90 91 48 01 lds r25, 0x0148 + 1860: 02 96 adiw r24, 0x02 ; 2 + 1862: 0e 94 14 11 call 0x2228 ; 0x2228 + + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + 1866: cf 3f cpi r28, 0xFF ; 255 + 1868: 8f ef ldi r24, 0xFF ; 255 + 186a: d8 07 cpc r29, r24 + 186c: 61 f4 brne .+24 ; 0x1886 + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 186e: 60 91 47 01 lds r22, 0x0147 + 1872: 70 91 48 01 lds r23, 0x0148 + 1876: 6e 5f subi r22, 0xFE ; 254 + 1878: 7f 4f sbci r23, 0xFF ; 255 + 187a: 84 e5 ldi r24, 0x54 ; 84 + 187c: 91 e0 ldi r25, 0x01 ; 1 + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} + 187e: df 91 pop r29 + 1880: cf 91 pop r28 + if( xTicksToWait == portMAX_DELAY ) + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 1882: 0c 94 ba 10 jmp 0x2174 ; 0x2174 + } + else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + 1886: 80 91 51 01 lds r24, 0x0151 + 188a: 90 91 52 01 lds r25, 0x0152 + 188e: be 01 movw r22, r28 + 1890: 68 0f add r22, r24 + 1892: 79 1f adc r23, r25 + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + 1894: e0 91 47 01 lds r30, 0x0147 + 1898: f0 91 48 01 lds r31, 0x0148 + 189c: 73 83 std Z+3, r23 ; 0x03 + 189e: 62 83 std Z+2, r22 ; 0x02 + + if( xTimeToWake < xTickCount ) + 18a0: 80 91 51 01 lds r24, 0x0151 + 18a4: 90 91 52 01 lds r25, 0x0152 + 18a8: 68 17 cp r22, r24 + 18aa: 79 07 cpc r23, r25 + 18ac: 48 f4 brcc .+18 ; 0x18c0 + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 18ae: 60 91 47 01 lds r22, 0x0147 + 18b2: 70 91 48 01 lds r23, 0x0148 + 18b6: 80 91 66 01 lds r24, 0x0166 + 18ba: 90 91 67 01 lds r25, 0x0167 + 18be: 08 c0 rjmp .+16 ; 0x18d0 + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 18c0: 60 91 47 01 lds r22, 0x0147 + 18c4: 70 91 48 01 lds r23, 0x0148 + 18c8: 80 91 68 01 lds r24, 0x0168 + 18cc: 90 91 69 01 lds r25, 0x0169 + 18d0: 6e 5f subi r22, 0xFE ; 254 + 18d2: 7f 4f sbci r23, 0xFF ; 255 + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} + 18d4: df 91 pop r29 + 18d6: cf 91 pop r28 + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + 18d8: 0c 94 dd 10 jmp 0x21ba ; 0x21ba + +000018dc : + #endif +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) +{ + 18dc: 0f 93 push r16 + 18de: 1f 93 push r17 + 18e0: cf 93 push r28 + 18e2: df 93 push r29 + it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means we can always expect exclusive access to the event list here. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + 18e4: dc 01 movw r26, r24 + 18e6: 2c 91 ld r18, X + 18e8: 22 23 and r18, r18 + 18ea: 39 f0 breq .+14 ; 0x18fa + 18ec: 15 96 adiw r26, 0x05 ; 5 + 18ee: ed 91 ld r30, X+ + 18f0: fc 91 ld r31, X + 18f2: 16 97 sbiw r26, 0x06 ; 6 + 18f4: c6 81 ldd r28, Z+6 ; 0x06 + 18f6: d7 81 ldd r29, Z+7 ; 0x07 + 18f8: 02 c0 rjmp .+4 ; 0x18fe + 18fa: c0 e0 ldi r28, 0x00 ; 0 + 18fc: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedTCB->xEventListItem ) ); + 18fe: 8e 01 movw r16, r28 + 1900: 04 5f subi r16, 0xF4 ; 244 + 1902: 1f 4f sbci r17, 0xFF ; 255 + 1904: c8 01 movw r24, r16 + 1906: 0e 94 14 11 call 0x2228 ; 0x2228 + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + 190a: 80 91 4d 01 lds r24, 0x014D + 190e: 81 11 cpse r24, r1 + 1910: 14 c0 rjmp .+40 ; 0x193a + { + vListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + 1912: 0a 50 subi r16, 0x0A ; 10 + 1914: 11 09 sbc r17, r1 + 1916: c8 01 movw r24, r16 + 1918: 0e 94 14 11 call 0x2228 ; 0x2228 + prvAddTaskToReadyQueue( pxUnblockedTCB ); + 191c: 9e 89 ldd r25, Y+22 ; 0x16 + 191e: 80 91 4f 01 lds r24, 0x014F + 1922: 89 17 cp r24, r25 + 1924: 10 f4 brcc .+4 ; 0x192a + 1926: 90 93 4f 01 sts 0x014F, r25 + 192a: b9 e0 ldi r27, 0x09 ; 9 + 192c: 9b 9f mul r25, r27 + 192e: c0 01 movw r24, r0 + 1930: 11 24 eor r1, r1 + 1932: b8 01 movw r22, r16 + 1934: 84 58 subi r24, 0x84 ; 132 + 1936: 9e 4f sbci r25, 0xFE ; 254 + 1938: 03 c0 rjmp .+6 ; 0x1940 + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + 193a: b8 01 movw r22, r16 + 193c: 8d e5 ldi r24, 0x5D ; 93 + 193e: 91 e0 ldi r25, 0x01 ; 1 + 1940: 0e 94 ba 10 call 0x2174 ; 0x2174 + } + + if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) + 1944: e0 91 47 01 lds r30, 0x0147 + 1948: f0 91 48 01 lds r31, 0x0148 + 194c: 81 e0 ldi r24, 0x01 ; 1 + 194e: 2e 89 ldd r18, Y+22 ; 0x16 + 1950: 96 89 ldd r25, Z+22 ; 0x16 + 1952: 29 17 cp r18, r25 + 1954: 08 f4 brcc .+2 ; 0x1958 + 1956: 80 e0 ldi r24, 0x00 ; 0 + { + xReturn = pdFALSE; + } + + return xReturn; +} + 1958: df 91 pop r29 + 195a: cf 91 pop r28 + 195c: 1f 91 pop r17 + 195e: 0f 91 pop r16 + 1960: 08 95 ret + +00001962 : +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) +{ + pxTimeOut->xOverflowCount = xNumOfOverflows; + 1962: 20 91 4a 01 lds r18, 0x014A + 1966: fc 01 movw r30, r24 + 1968: 20 83 st Z, r18 + pxTimeOut->xTimeOnEntering = xTickCount; + 196a: 20 91 51 01 lds r18, 0x0151 + 196e: 30 91 52 01 lds r19, 0x0152 + 1972: 32 83 std Z+2, r19 ; 0x02 + 1974: 21 83 std Z+1, r18 ; 0x01 + 1976: 08 95 ret + +00001978 : + +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + portENTER_CRITICAL(); + 1978: 0f b6 in r0, 0x3f ; 63 + 197a: f8 94 cli + 197c: 0f 92 push r0 + { + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + 197e: db 01 movw r26, r22 + 1980: 2d 91 ld r18, X+ + 1982: 3c 91 ld r19, X + 1984: 2f 3f cpi r18, 0xFF ; 255 + 1986: bf ef ldi r27, 0xFF ; 255 + 1988: 3b 07 cpc r19, r27 + 198a: 31 f1 breq .+76 ; 0x19d8 + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) ) + 198c: 50 91 4a 01 lds r21, 0x014A + 1990: fc 01 movw r30, r24 + 1992: 40 81 ld r20, Z + 1994: 01 80 ldd r0, Z+1 ; 0x01 + 1996: f2 81 ldd r31, Z+2 ; 0x02 + 1998: e0 2d mov r30, r0 + 199a: 54 17 cp r21, r20 + 199c: 39 f0 breq .+14 ; 0x19ac + 199e: 40 91 51 01 lds r20, 0x0151 + 19a2: 50 91 52 01 lds r21, 0x0152 + 19a6: 4e 17 cp r20, r30 + 19a8: 5f 07 cpc r21, r31 + 19aa: c0 f4 brcc .+48 ; 0x19dc + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait ) + 19ac: 40 91 51 01 lds r20, 0x0151 + 19b0: 50 91 52 01 lds r21, 0x0152 + 19b4: 4e 1b sub r20, r30 + 19b6: 5f 0b sbc r21, r31 + 19b8: 42 17 cp r20, r18 + 19ba: 53 07 cpc r21, r19 + 19bc: 78 f4 brcc .+30 ; 0x19dc + 19be: db 01 movw r26, r22 + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ); + 19c0: 40 91 51 01 lds r20, 0x0151 + 19c4: 50 91 52 01 lds r21, 0x0152 + 19c8: 4e 1b sub r20, r30 + 19ca: 5f 0b sbc r21, r31 + 19cc: 24 1b sub r18, r20 + 19ce: 35 0b sbc r19, r21 + 19d0: 2d 93 st X+, r18 + 19d2: 3c 93 st X, r19 + vTaskSetTimeOutState( pxTimeOut ); + 19d4: 0e 94 b1 0c call 0x1962 ; 0x1962 + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + 19d8: 80 e0 ldi r24, 0x00 ; 0 + 19da: 01 c0 rjmp .+2 ; 0x19de + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + 19dc: 81 e0 ldi r24, 0x01 ; 1 + else + { + xReturn = pdTRUE; + } + } + portEXIT_CRITICAL(); + 19de: 0f 90 pop r0 + 19e0: 0f be out 0x3f, r0 ; 63 + + return xReturn; +} + 19e2: 08 95 ret + +000019e4 : +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xMissedYield = pdTRUE; + 19e4: 81 e0 ldi r24, 0x01 ; 1 + 19e6: 80 93 4b 01 sts 0x014B, r24 + 19ea: 08 95 ret + +000019ec : + vPortFree( pxQueue ); +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) +{ + 19ec: cf 93 push r28 + 19ee: df 93 push r29 + 19f0: ec 01 movw r28, r24 + 19f2: 94 2f mov r25, r20 + if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) + 19f4: 8c 8d ldd r24, Y+28 ; 0x1c + 19f6: 88 23 and r24, r24 + 19f8: 99 f1 breq .+102 ; 0x1a60 + 19fa: 48 2f mov r20, r24 + 19fc: 50 e0 ldi r21, 0x00 ; 0 + pxQueue->pxMutexHolder = NULL; + } + } + #endif + } + else if( xPosition == queueSEND_TO_BACK ) + 19fe: 91 11 cpse r25, r1 + 1a00: 15 c0 rjmp .+42 ; 0x1a2c + { + memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + 1a02: 8c 81 ldd r24, Y+4 ; 0x04 + 1a04: 9d 81 ldd r25, Y+5 ; 0x05 + 1a06: 0e 94 ca 14 call 0x2994 ; 0x2994 + pxQueue->pcWriteTo += pxQueue->uxItemSize; + 1a0a: 2c 8d ldd r18, Y+28 ; 0x1c + 1a0c: 8c 81 ldd r24, Y+4 ; 0x04 + 1a0e: 9d 81 ldd r25, Y+5 ; 0x05 + 1a10: 82 0f add r24, r18 + 1a12: 91 1d adc r25, r1 + 1a14: 9d 83 std Y+5, r25 ; 0x05 + 1a16: 8c 83 std Y+4, r24 ; 0x04 + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) + 1a18: 2a 81 ldd r18, Y+2 ; 0x02 + 1a1a: 3b 81 ldd r19, Y+3 ; 0x03 + 1a1c: 82 17 cp r24, r18 + 1a1e: 93 07 cpc r25, r19 + 1a20: f8 f0 brcs .+62 ; 0x1a60 + { + pxQueue->pcWriteTo = pxQueue->pcHead; + 1a22: 88 81 ld r24, Y + 1a24: 99 81 ldd r25, Y+1 ; 0x01 + 1a26: 9d 83 std Y+5, r25 ; 0x05 + 1a28: 8c 83 std Y+4, r24 ; 0x04 + 1a2a: 1a c0 rjmp .+52 ; 0x1a60 + } + } + else + { + memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); + 1a2c: 8e 81 ldd r24, Y+6 ; 0x06 + 1a2e: 9f 81 ldd r25, Y+7 ; 0x07 + 1a30: 0e 94 ca 14 call 0x2994 ; 0x2994 + pxQueue->pcReadFrom -= pxQueue->uxItemSize; + 1a34: 8c 8d ldd r24, Y+28 ; 0x1c + 1a36: 90 e0 ldi r25, 0x00 ; 0 + 1a38: 91 95 neg r25 + 1a3a: 81 95 neg r24 + 1a3c: 91 09 sbc r25, r1 + 1a3e: 2e 81 ldd r18, Y+6 ; 0x06 + 1a40: 3f 81 ldd r19, Y+7 ; 0x07 + 1a42: 28 0f add r18, r24 + 1a44: 39 1f adc r19, r25 + 1a46: 3f 83 std Y+7, r19 ; 0x07 + 1a48: 2e 83 std Y+6, r18 ; 0x06 + if( pxQueue->pcReadFrom < pxQueue->pcHead ) + 1a4a: 48 81 ld r20, Y + 1a4c: 59 81 ldd r21, Y+1 ; 0x01 + 1a4e: 24 17 cp r18, r20 + 1a50: 35 07 cpc r19, r21 + 1a52: 30 f4 brcc .+12 ; 0x1a60 + { + pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + 1a54: 2a 81 ldd r18, Y+2 ; 0x02 + 1a56: 3b 81 ldd r19, Y+3 ; 0x03 + 1a58: 82 0f add r24, r18 + 1a5a: 93 1f adc r25, r19 + 1a5c: 9f 83 std Y+7, r25 ; 0x07 + 1a5e: 8e 83 std Y+6, r24 ; 0x06 + } + } + + ++( pxQueue->uxMessagesWaiting ); + 1a60: 8a 8d ldd r24, Y+26 ; 0x1a + 1a62: 8f 5f subi r24, 0xFF ; 255 + 1a64: 8a 8f std Y+26, r24 ; 0x1a +} + 1a66: df 91 pop r29 + 1a68: cf 91 pop r28 + 1a6a: 08 95 ret + +00001a6c : +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) +{ + 1a6c: fc 01 movw r30, r24 + 1a6e: cb 01 movw r24, r22 + if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) + 1a70: a0 81 ld r26, Z + 1a72: b1 81 ldd r27, Z+1 ; 0x01 + 1a74: 10 97 sbiw r26, 0x00 ; 0 + 1a76: 99 f0 breq .+38 ; 0x1a9e + { + pxQueue->pcReadFrom += pxQueue->uxItemSize; + 1a78: 44 8d ldd r20, Z+28 ; 0x1c + 1a7a: 50 e0 ldi r21, 0x00 ; 0 + 1a7c: 26 81 ldd r18, Z+6 ; 0x06 + 1a7e: 37 81 ldd r19, Z+7 ; 0x07 + 1a80: 24 0f add r18, r20 + 1a82: 35 1f adc r19, r21 + 1a84: 37 83 std Z+7, r19 ; 0x07 + 1a86: 26 83 std Z+6, r18 ; 0x06 + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + 1a88: 62 81 ldd r22, Z+2 ; 0x02 + 1a8a: 73 81 ldd r23, Z+3 ; 0x03 + 1a8c: 26 17 cp r18, r22 + 1a8e: 37 07 cpc r19, r23 + 1a90: 10 f0 brcs .+4 ; 0x1a96 + { + pxQueue->pcReadFrom = pxQueue->pcHead; + 1a92: b7 83 std Z+7, r27 ; 0x07 + 1a94: a6 83 std Z+6, r26 ; 0x06 + } + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + 1a96: 66 81 ldd r22, Z+6 ; 0x06 + 1a98: 77 81 ldd r23, Z+7 ; 0x07 + 1a9a: 0c 94 ca 14 jmp 0x2994 ; 0x2994 + 1a9e: 08 95 ret + +00001aa0 : + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( xQueueHandle pxQueue ) +{ + 1aa0: 0f 93 push r16 + 1aa2: 1f 93 push r17 + 1aa4: cf 93 push r28 + 1aa6: df 93 push r29 + 1aa8: ec 01 movw r28, r24 + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + 1aaa: 0f b6 in r0, 0x3f ; 63 + 1aac: f8 94 cli + 1aae: 0f 92 push r0 + blocked waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 1ab0: 8c 01 movw r16, r24 + 1ab2: 0f 5e subi r16, 0xEF ; 239 + 1ab4: 1f 4f sbci r17, 0xFF ; 255 + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + /* See if data was added to the queue while it was locked. */ + while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) + 1ab6: 9e 8d ldd r25, Y+30 ; 0x1e + 1ab8: 19 16 cp r1, r25 + 1aba: 6c f4 brge .+26 ; 0x1ad6 + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 1abc: 89 89 ldd r24, Y+17 ; 0x11 + 1abe: 88 23 and r24, r24 + 1ac0: 51 f0 breq .+20 ; 0x1ad6 + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 1ac2: c8 01 movw r24, r16 + 1ac4: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1ac8: 81 11 cpse r24, r1 + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + 1aca: 0e 94 f2 0c call 0x19e4 ; 0x19e4 + } + + --( pxQueue->xTxLock ); + 1ace: 9e 8d ldd r25, Y+30 ; 0x1e + 1ad0: 91 50 subi r25, 0x01 ; 1 + 1ad2: 9e 8f std Y+30, r25 ; 0x1e + 1ad4: f0 cf rjmp .-32 ; 0x1ab6 + { + break; + } + } + + pxQueue->xTxLock = queueUNLOCKED; + 1ad6: 8f ef ldi r24, 0xFF ; 255 + 1ad8: 8e 8f std Y+30, r24 ; 0x1e + } + taskEXIT_CRITICAL(); + 1ada: 0f 90 pop r0 + 1adc: 0f be out 0x3f, r0 ; 63 + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + 1ade: 0f b6 in r0, 0x3f ; 63 + 1ae0: f8 94 cli + 1ae2: 0f 92 push r0 + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 1ae4: 8e 01 movw r16, r28 + 1ae6: 08 5f subi r16, 0xF8 ; 248 + 1ae8: 1f 4f sbci r17, 0xFF ; 255 + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + 1aea: 9d 8d ldd r25, Y+29 ; 0x1d + 1aec: 19 16 cp r1, r25 + 1aee: 6c f4 brge .+26 ; 0x1b0a + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 1af0: 88 85 ldd r24, Y+8 ; 0x08 + 1af2: 88 23 and r24, r24 + 1af4: 51 f0 breq .+20 ; 0x1b0a + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 1af6: c8 01 movw r24, r16 + 1af8: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1afc: 81 11 cpse r24, r1 + { + vTaskMissedYield(); + 1afe: 0e 94 f2 0c call 0x19e4 ; 0x19e4 + } + + --( pxQueue->xRxLock ); + 1b02: 9d 8d ldd r25, Y+29 ; 0x1d + 1b04: 91 50 subi r25, 0x01 ; 1 + 1b06: 9d 8f std Y+29, r25 ; 0x1d + 1b08: f0 cf rjmp .-32 ; 0x1aea + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + 1b0a: 8f ef ldi r24, 0xFF ; 255 + 1b0c: 8d 8f std Y+29, r24 ; 0x1d + } + taskEXIT_CRITICAL(); + 1b0e: 0f 90 pop r0 + 1b10: 0f be out 0x3f, r0 ; 63 +} + 1b12: df 91 pop r29 + 1b14: cf 91 pop r28 + 1b16: 1f 91 pop r17 + 1b18: 0f 91 pop r16 + 1b1a: 08 95 ret + +00001b1c : +/*----------------------------------------------------------- + * PUBLIC QUEUE MANAGEMENT API documented in queue.h + *----------------------------------------------------------*/ + +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) +{ + 1b1c: cf 92 push r12 + 1b1e: df 92 push r13 + 1b20: ef 92 push r14 + 1b22: ff 92 push r15 + 1b24: 0f 93 push r16 + 1b26: 1f 93 push r17 + 1b28: cf 93 push r28 + 1b2a: df 93 push r29 +xQUEUE *pxNewQueue; +size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + 1b2c: 88 23 and r24, r24 + 1b2e: b1 f1 breq .+108 ; 0x1b9c + 1b30: f6 2e mov r15, r22 + 1b32: e8 2e mov r14, r24 + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + 1b34: 8f e1 ldi r24, 0x1F ; 31 + 1b36: 90 e0 ldi r25, 0x00 ; 0 + 1b38: 0e 94 02 13 call 0x2604 ; 0x2604 + 1b3c: ec 01 movw r28, r24 + if( pxNewQueue != NULL ) + 1b3e: 89 2b or r24, r25 + 1b40: 69 f1 breq .+90 ; 0x1b9c + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + 1b42: cf 2c mov r12, r15 + 1b44: d1 2c mov r13, r1 + 1b46: ef 9c mul r14, r15 + 1b48: 80 01 movw r16, r0 + 1b4a: 11 24 eor r1, r1 + + pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes ); + 1b4c: c8 01 movw r24, r16 + 1b4e: 01 96 adiw r24, 0x01 ; 1 + 1b50: 0e 94 02 13 call 0x2604 ; 0x2604 + 1b54: 99 83 std Y+1, r25 ; 0x01 + 1b56: 88 83 st Y, r24 + if( pxNewQueue->pcHead != NULL ) + 1b58: 00 97 sbiw r24, 0x00 ; 0 + 1b5a: e9 f0 breq .+58 ; 0x1b96 + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + 1b5c: 9c 01 movw r18, r24 + 1b5e: 20 0f add r18, r16 + 1b60: 31 1f adc r19, r17 + 1b62: 3b 83 std Y+3, r19 ; 0x03 + 1b64: 2a 83 std Y+2, r18 ; 0x02 + pxNewQueue->uxMessagesWaiting = 0; + 1b66: 1a 8e std Y+26, r1 ; 0x1a + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + 1b68: 9d 83 std Y+5, r25 ; 0x05 + 1b6a: 8c 83 std Y+4, r24 ; 0x04 + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + 1b6c: 0c 19 sub r16, r12 + 1b6e: 1d 09 sbc r17, r13 + 1b70: 08 0f add r16, r24 + 1b72: 19 1f adc r17, r25 + 1b74: 1f 83 std Y+7, r17 ; 0x07 + 1b76: 0e 83 std Y+6, r16 ; 0x06 + pxNewQueue->uxLength = uxQueueLength; + 1b78: eb 8e std Y+27, r14 ; 0x1b + pxNewQueue->uxItemSize = uxItemSize; + 1b7a: fc 8e std Y+28, r15 ; 0x1c + pxNewQueue->xRxLock = queueUNLOCKED; + 1b7c: 8f ef ldi r24, 0xFF ; 255 + 1b7e: 8d 8f std Y+29, r24 ; 0x1d + pxNewQueue->xTxLock = queueUNLOCKED; + 1b80: 8e 8f std Y+30, r24 ; 0x1e + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + 1b82: ce 01 movw r24, r28 + 1b84: 08 96 adiw r24, 0x08 ; 8 + 1b86: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + 1b8a: ce 01 movw r24, r28 + 1b8c: 41 96 adiw r24, 0x11 ; 17 + 1b8e: 0e 94 a8 10 call 0x2150 ; 0x2150 + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + 1b92: ce 01 movw r24, r28 + 1b94: 05 c0 rjmp .+10 ; 0x1ba0 + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + 1b96: ce 01 movw r24, r28 + 1b98: 0e 94 28 13 call 0x2650 ; 0x2650 + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; + 1b9c: 80 e0 ldi r24, 0x00 ; 0 + 1b9e: 90 e0 ldi r25, 0x00 ; 0 +} + 1ba0: df 91 pop r29 + 1ba2: cf 91 pop r28 + 1ba4: 1f 91 pop r17 + 1ba6: 0f 91 pop r16 + 1ba8: ff 90 pop r15 + 1baa: ef 90 pop r14 + 1bac: df 90 pop r13 + 1bae: cf 90 pop r12 + 1bb0: 08 95 ret + +00001bb2 : + +xQueueHandle xQueueCreateExternal( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, void *address ) +{ + 1bb2: ef 92 push r14 + 1bb4: ff 92 push r15 + 1bb6: 0f 93 push r16 + 1bb8: 1f 93 push r17 + 1bba: cf 93 push r28 + 1bbc: df 93 push r29 + xQUEUE *pxNewQueue; + //size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + 1bbe: 88 23 and r24, r24 + 1bc0: 89 f1 breq .+98 ; 0x1c24 + 1bc2: 8a 01 movw r16, r20 + 1bc4: f6 2e mov r15, r22 + 1bc6: e8 2e mov r14, r24 + { + pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); + 1bc8: 8f e1 ldi r24, 0x1F ; 31 + 1bca: 90 e0 ldi r25, 0x00 ; 0 + 1bcc: 0e 94 02 13 call 0x2604 ; 0x2604 + 1bd0: ec 01 movw r28, r24 + if( pxNewQueue != NULL ) + 1bd2: 00 97 sbiw r24, 0x00 ; 0 + 1bd4: 39 f1 breq .+78 ; 0x1c24 + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + //xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; + + pxNewQueue->pcHead = ( signed char * ) (address); + 1bd6: 19 83 std Y+1, r17 ; 0x01 + 1bd8: 08 83 st Y, r16 + if( pxNewQueue->pcHead != NULL ) + 1bda: 01 15 cp r16, r1 + 1bdc: 11 05 cpc r17, r1 + 1bde: 01 f1 breq .+64 ; 0x1c20 + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); + 1be0: ef 9c mul r14, r15 + 1be2: a0 01 movw r20, r0 + 1be4: 11 24 eor r1, r1 + 1be6: c8 01 movw r24, r16 + 1be8: 84 0f add r24, r20 + 1bea: 95 1f adc r25, r21 + 1bec: 9b 83 std Y+3, r25 ; 0x03 + 1bee: 8a 83 std Y+2, r24 ; 0x02 + pxNewQueue->uxMessagesWaiting = 0; + 1bf0: 1a 8e std Y+26, r1 ; 0x1a + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + 1bf2: 1d 83 std Y+5, r17 ; 0x05 + 1bf4: 0c 83 std Y+4, r16 ; 0x04 + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); + 1bf6: 4f 19 sub r20, r15 + 1bf8: 51 09 sbc r21, r1 + 1bfa: 04 0f add r16, r20 + 1bfc: 15 1f adc r17, r21 + 1bfe: 1f 83 std Y+7, r17 ; 0x07 + 1c00: 0e 83 std Y+6, r16 ; 0x06 + pxNewQueue->uxLength = uxQueueLength; + 1c02: eb 8e std Y+27, r14 ; 0x1b + pxNewQueue->uxItemSize = uxItemSize; + 1c04: fc 8e std Y+28, r15 ; 0x1c + pxNewQueue->xRxLock = queueUNLOCKED; + 1c06: 8f ef ldi r24, 0xFF ; 255 + 1c08: 8d 8f std Y+29, r24 ; 0x1d + pxNewQueue->xTxLock = queueUNLOCKED; + 1c0a: 8e 8f std Y+30, r24 ; 0x1e + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + 1c0c: ce 01 movw r24, r28 + 1c0e: 08 96 adiw r24, 0x08 ; 8 + 1c10: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + 1c14: ce 01 movw r24, r28 + 1c16: 41 96 adiw r24, 0x11 ; 17 + 1c18: 0e 94 a8 10 call 0x2150 ; 0x2150 + + traceQUEUE_CREATE( pxNewQueue ); + return pxNewQueue; + 1c1c: ce 01 movw r24, r28 + 1c1e: 04 c0 rjmp .+8 ; 0x1c28 + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + 1c20: 0e 94 28 13 call 0x2650 ; 0x2650 + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; + 1c24: 80 e0 ldi r24, 0x00 ; 0 + 1c26: 90 e0 ldi r25, 0x00 ; 0 +} + 1c28: df 91 pop r29 + 1c2a: cf 91 pop r28 + 1c2c: 1f 91 pop r17 + 1c2e: 0f 91 pop r16 + 1c30: ff 90 pop r15 + 1c32: ef 90 pop r14 + 1c34: 08 95 ret + +00001c36 : + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) +{ + 1c36: af 92 push r10 + 1c38: bf 92 push r11 + 1c3a: df 92 push r13 + 1c3c: ef 92 push r14 + 1c3e: ff 92 push r15 + 1c40: 0f 93 push r16 + 1c42: 1f 93 push r17 + 1c44: cf 93 push r28 + 1c46: df 93 push r29 + 1c48: 00 d0 rcall .+0 ; 0x1c4a + 1c4a: 00 d0 rcall .+0 ; 0x1c4c + 1c4c: 1f 92 push r1 + 1c4e: cd b7 in r28, 0x3d ; 61 + 1c50: de b7 in r29, 0x3e ; 62 + 1c52: 8c 01 movw r16, r24 + 1c54: 7b 01 movw r14, r22 + 1c56: 5d 83 std Y+5, r21 ; 0x05 + 1c58: 4c 83 std Y+4, r20 ; 0x04 + 1c5a: d2 2e mov r13, r18 +signed portBASE_TYPE xEntryTimeSet = pdFALSE; + 1c5c: 90 e0 ldi r25, 0x00 ; 0 + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + 1c5e: 58 01 movw r10, r16 + 1c60: 88 e0 ldi r24, 0x08 ; 8 + 1c62: a8 0e add r10, r24 + 1c64: b1 1c adc r11, r1 + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + 1c66: 0f b6 in r0, 0x3f ; 63 + 1c68: f8 94 cli + 1c6a: 0f 92 push r0 + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 1c6c: f8 01 movw r30, r16 + 1c6e: 22 8d ldd r18, Z+26 ; 0x1a + 1c70: 83 8d ldd r24, Z+27 ; 0x1b + 1c72: 28 17 cp r18, r24 + 1c74: a8 f4 brcc .+42 ; 0x1ca0 + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + 1c76: 4d 2d mov r20, r13 + 1c78: b7 01 movw r22, r14 + 1c7a: c8 01 movw r24, r16 + 1c7c: 0e 94 f6 0c call 0x19ec ; 0x19ec + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + 1c80: f8 01 movw r30, r16 + 1c82: 81 89 ldd r24, Z+17 ; 0x11 + 1c84: 88 23 and r24, r24 + 1c86: 41 f0 breq .+16 ; 0x1c98 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + 1c88: c8 01 movw r24, r16 + 1c8a: 41 96 adiw r24, 0x11 ; 17 + 1c8c: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1c90: 81 30 cpi r24, 0x01 ; 1 + 1c92: 11 f4 brne .+4 ; 0x1c98 + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + portYIELD_WITHIN_API(); + 1c94: 0e 94 df 13 call 0x27be ; 0x27be + } + } + + taskEXIT_CRITICAL(); + 1c98: 0f 90 pop r0 + 1c9a: 0f be out 0x3f, r0 ; 63 + + /* Return to the original privilege level before exiting the + function. */ + return pdPASS; + 1c9c: 81 e0 ldi r24, 0x01 ; 1 + 1c9e: 50 c0 rjmp .+160 ; 0x1d40 + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + 1ca0: 2c 81 ldd r18, Y+4 ; 0x04 + 1ca2: 3d 81 ldd r19, Y+5 ; 0x05 + 1ca4: 23 2b or r18, r19 + 1ca6: 19 f4 brne .+6 ; 0x1cae + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + 1ca8: 0f 90 pop r0 + 1caa: 0f be out 0x3f, r0 ; 63 + 1cac: 48 c0 rjmp .+144 ; 0x1d3e + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + 1cae: 91 11 cpse r25, r1 + 1cb0: 04 c0 rjmp .+8 ; 0x1cba + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + 1cb2: ce 01 movw r24, r28 + 1cb4: 01 96 adiw r24, 0x01 ; 1 + 1cb6: 0e 94 b1 0c call 0x1962 ; 0x1962 + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + 1cba: 0f 90 pop r0 + 1cbc: 0f be out 0x3f, r0 ; 63 + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + 1cbe: 0e 94 de 0a call 0x15bc ; 0x15bc + prvLockQueue( pxQueue ); + 1cc2: 0f b6 in r0, 0x3f ; 63 + 1cc4: f8 94 cli + 1cc6: 0f 92 push r0 + 1cc8: f8 01 movw r30, r16 + 1cca: 85 8d ldd r24, Z+29 ; 0x1d + 1ccc: 8f 3f cpi r24, 0xFF ; 255 + 1cce: 09 f4 brne .+2 ; 0x1cd2 + 1cd0: 15 8e std Z+29, r1 ; 0x1d + 1cd2: f8 01 movw r30, r16 + 1cd4: 86 8d ldd r24, Z+30 ; 0x1e + 1cd6: 8f 3f cpi r24, 0xFF ; 255 + 1cd8: 09 f4 brne .+2 ; 0x1cdc + 1cda: 16 8e std Z+30, r1 ; 0x1e + 1cdc: 0f 90 pop r0 + 1cde: 0f be out 0x3f, r0 ; 63 + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + 1ce0: be 01 movw r22, r28 + 1ce2: 6c 5f subi r22, 0xFC ; 252 + 1ce4: 7f 4f sbci r23, 0xFF ; 255 + 1ce6: ce 01 movw r24, r28 + 1ce8: 01 96 adiw r24, 0x01 ; 1 + 1cea: 0e 94 bc 0c call 0x1978 ; 0x1978 + 1cee: 81 11 cpse r24, r1 + 1cf0: 21 c0 rjmp .+66 ; 0x1d34 + +static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + 1cf2: 0f b6 in r0, 0x3f ; 63 + 1cf4: f8 94 cli + 1cf6: 0f 92 push r0 + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + 1cf8: f8 01 movw r30, r16 + 1cfa: 92 8d ldd r25, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 1cfc: 0f 90 pop r0 + 1cfe: 0f be out 0x3f, r0 ; 63 + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) ) + 1d00: 83 8d ldd r24, Z+27 ; 0x1b + 1d02: 98 13 cpse r25, r24 + 1d04: 11 c0 rjmp .+34 ; 0x1d28 + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + 1d06: 6c 81 ldd r22, Y+4 ; 0x04 + 1d08: 7d 81 ldd r23, Y+5 ; 0x05 + 1d0a: c5 01 movw r24, r10 + 1d0c: 0e 94 20 0c call 0x1840 ; 0x1840 + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + 1d10: c8 01 movw r24, r16 + 1d12: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( !xTaskResumeAll() ) + 1d16: 0e 94 64 0b call 0x16c8 ; 0x16c8 + 1d1a: 88 23 and r24, r24 + 1d1c: 11 f0 breq .+4 ; 0x1d22 + 1d1e: 91 e0 ldi r25, 0x01 ; 1 + 1d20: a2 cf rjmp .-188 ; 0x1c66 + { + portYIELD_WITHIN_API(); + 1d22: 0e 94 df 13 call 0x27be ; 0x27be + 1d26: fb cf rjmp .-10 ; 0x1d1e + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + 1d28: c8 01 movw r24, r16 + 1d2a: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + ( void ) xTaskResumeAll(); + 1d2e: 0e 94 64 0b call 0x16c8 ; 0x16c8 + 1d32: f5 cf rjmp .-22 ; 0x1d1e + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + 1d34: c8 01 movw r24, r16 + 1d36: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + ( void ) xTaskResumeAll(); + 1d3a: 0e 94 64 0b call 0x16c8 ; 0x16c8 + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + 1d3e: 80 e0 ldi r24, 0x00 ; 0 + } + } +} + 1d40: 0f 90 pop r0 + 1d42: 0f 90 pop r0 + 1d44: 0f 90 pop r0 + 1d46: 0f 90 pop r0 + 1d48: 0f 90 pop r0 + 1d4a: df 91 pop r29 + 1d4c: cf 91 pop r28 + 1d4e: 1f 91 pop r17 + 1d50: 0f 91 pop r16 + 1d52: ff 90 pop r15 + 1d54: ef 90 pop r14 + 1d56: df 90 pop r13 + 1d58: bf 90 pop r11 + 1d5a: af 90 pop r10 + 1d5c: 08 95 ret + +00001d5e : + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) +{ + 1d5e: 0f 93 push r16 + 1d60: 1f 93 push r17 + 1d62: cf 93 push r28 + 1d64: df 93 push r29 + 1d66: ec 01 movw r28, r24 + queue read, instead we return a flag to say whether a context switch is + required or not (i.e. has a task with a higher priority than us been woken + by this post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 1d68: 9a 8d ldd r25, Y+26 ; 0x1a + 1d6a: 8b 8d ldd r24, Y+27 ; 0x1b + 1d6c: 98 17 cp r25, r24 + 1d6e: c8 f4 brcc .+50 ; 0x1da2 + 1d70: 8a 01 movw r16, r20 + { + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + 1d72: 42 2f mov r20, r18 + 1d74: ce 01 movw r24, r28 + 1d76: 0e 94 f6 0c call 0x19ec ; 0x19ec + + /* If the queue is locked we do not alter the event list. This will + be done when the queue is unlocked later. */ + if( pxQueue->xTxLock == queueUNLOCKED ) + 1d7a: 8e 8d ldd r24, Y+30 ; 0x1e + 1d7c: 8f 3f cpi r24, 0xFF ; 255 + 1d7e: 69 f4 brne .+26 ; 0x1d9a + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 1d80: 89 89 ldd r24, Y+17 ; 0x11 + 1d82: 88 23 and r24, r24 + 1d84: 61 f0 breq .+24 ; 0x1d9e + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 1d86: ce 01 movw r24, r28 + 1d88: 41 96 adiw r24, 0x11 ; 17 + 1d8a: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1d8e: 88 23 and r24, r24 + 1d90: 31 f0 breq .+12 ; 0x1d9e + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + *pxHigherPriorityTaskWoken = pdTRUE; + 1d92: 81 e0 ldi r24, 0x01 ; 1 + 1d94: f8 01 movw r30, r16 + 1d96: 80 83 st Z, r24 + 1d98: 05 c0 rjmp .+10 ; 0x1da4 + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++( pxQueue->xTxLock ); + 1d9a: 8f 5f subi r24, 0xFF ; 255 + 1d9c: 8e 8f std Y+30, r24 ; 0x1e + } + + xReturn = pdPASS; + 1d9e: 81 e0 ldi r24, 0x01 ; 1 + 1da0: 01 c0 rjmp .+2 ; 0x1da4 + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + 1da2: 80 e0 ldi r24, 0x00 ; 0 + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} + 1da4: df 91 pop r29 + 1da6: cf 91 pop r28 + 1da8: 1f 91 pop r17 + 1daa: 0f 91 pop r16 + 1dac: 08 95 ret + +00001dae : +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) +{ + 1dae: af 92 push r10 + 1db0: bf 92 push r11 + 1db2: df 92 push r13 + 1db4: ef 92 push r14 + 1db6: ff 92 push r15 + 1db8: 0f 93 push r16 + 1dba: 1f 93 push r17 + 1dbc: cf 93 push r28 + 1dbe: df 93 push r29 + 1dc0: 00 d0 rcall .+0 ; 0x1dc2 + 1dc2: 00 d0 rcall .+0 ; 0x1dc4 + 1dc4: 1f 92 push r1 + 1dc6: cd b7 in r28, 0x3d ; 61 + 1dc8: de b7 in r29, 0x3e ; 62 + 1dca: 8c 01 movw r16, r24 + 1dcc: 7b 01 movw r14, r22 + 1dce: 5d 83 std Y+5, r21 ; 0x05 + 1dd0: 4c 83 std Y+4, r20 ; 0x04 + 1dd2: d2 2e mov r13, r18 +signed portBASE_TYPE xEntryTimeSet = pdFALSE; + 1dd4: 90 e0 ldi r25, 0x00 ; 0 + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + 1dd6: 58 01 movw r10, r16 + 1dd8: 81 e1 ldi r24, 0x11 ; 17 + 1dda: a8 0e add r10, r24 + 1ddc: b1 1c adc r11, r1 + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + 1dde: 0f b6 in r0, 0x3f ; 63 + 1de0: f8 94 cli + 1de2: 0f 92 push r0 + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 1de4: f8 01 movw r30, r16 + 1de6: 82 8d ldd r24, Z+26 ; 0x1a + 1de8: 88 23 and r24, r24 + 1dea: 39 f1 breq .+78 ; 0x1e3a + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + 1dec: a6 80 ldd r10, Z+6 ; 0x06 + 1dee: b7 80 ldd r11, Z+7 ; 0x07 + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + 1df0: b7 01 movw r22, r14 + 1df2: c8 01 movw r24, r16 + 1df4: 0e 94 36 0d call 0x1a6c ; 0x1a6c + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + 1df8: f8 01 movw r30, r16 + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + 1dfa: d1 10 cpse r13, r1 + 1dfc: 0f c0 rjmp .+30 ; 0x1e1c + { + traceQUEUE_RECEIVE( pxQueue ); + + /* We are actually removing data. */ + --( pxQueue->uxMessagesWaiting ); + 1dfe: 82 8d ldd r24, Z+26 ; 0x1a + 1e00: 81 50 subi r24, 0x01 ; 1 + 1e02: 82 8f std Z+26, r24 ; 0x1a + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + 1e04: 80 85 ldd r24, Z+8 ; 0x08 + 1e06: 88 23 and r24, r24 + 1e08: a1 f0 breq .+40 ; 0x1e32 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + 1e0a: c8 01 movw r24, r16 + 1e0c: 08 96 adiw r24, 0x08 ; 8 + 1e0e: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1e12: 81 30 cpi r24, 0x01 ; 1 + 1e14: 71 f4 brne .+28 ; 0x1e32 + { + portYIELD_WITHIN_API(); + 1e16: 0e 94 df 13 call 0x27be ; 0x27be + 1e1a: 0b c0 rjmp .+22 ; 0x1e32 + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + 1e1c: b7 82 std Z+7, r11 ; 0x07 + 1e1e: a6 82 std Z+6, r10 ; 0x06 + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 1e20: 81 89 ldd r24, Z+17 ; 0x11 + 1e22: 88 23 and r24, r24 + 1e24: 31 f0 breq .+12 ; 0x1e32 + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 1e26: c8 01 movw r24, r16 + 1e28: 41 96 adiw r24, 0x11 ; 17 + 1e2a: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1e2e: 81 11 cpse r24, r1 + 1e30: f2 cf rjmp .-28 ; 0x1e16 + } + } + + } + + taskEXIT_CRITICAL(); + 1e32: 0f 90 pop r0 + 1e34: 0f be out 0x3f, r0 ; 63 + return pdPASS; + 1e36: 81 e0 ldi r24, 0x01 ; 1 + 1e38: 4f c0 rjmp .+158 ; 0x1ed8 + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + 1e3a: 2c 81 ldd r18, Y+4 ; 0x04 + 1e3c: 3d 81 ldd r19, Y+5 ; 0x05 + 1e3e: 23 2b or r18, r19 + 1e40: 19 f4 brne .+6 ; 0x1e48 + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + 1e42: 0f 90 pop r0 + 1e44: 0f be out 0x3f, r0 ; 63 + 1e46: 47 c0 rjmp .+142 ; 0x1ed6 + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + 1e48: 91 11 cpse r25, r1 + 1e4a: 04 c0 rjmp .+8 ; 0x1e54 + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + 1e4c: ce 01 movw r24, r28 + 1e4e: 01 96 adiw r24, 0x01 ; 1 + 1e50: 0e 94 b1 0c call 0x1962 ; 0x1962 + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + 1e54: 0f 90 pop r0 + 1e56: 0f be out 0x3f, r0 ; 63 + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + 1e58: 0e 94 de 0a call 0x15bc ; 0x15bc + prvLockQueue( pxQueue ); + 1e5c: 0f b6 in r0, 0x3f ; 63 + 1e5e: f8 94 cli + 1e60: 0f 92 push r0 + 1e62: f8 01 movw r30, r16 + 1e64: 85 8d ldd r24, Z+29 ; 0x1d + 1e66: 8f 3f cpi r24, 0xFF ; 255 + 1e68: 09 f4 brne .+2 ; 0x1e6c + 1e6a: 15 8e std Z+29, r1 ; 0x1d + 1e6c: f8 01 movw r30, r16 + 1e6e: 86 8d ldd r24, Z+30 ; 0x1e + 1e70: 8f 3f cpi r24, 0xFF ; 255 + 1e72: 09 f4 brne .+2 ; 0x1e76 + 1e74: 16 8e std Z+30, r1 ; 0x1e + 1e76: 0f 90 pop r0 + 1e78: 0f be out 0x3f, r0 ; 63 + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + 1e7a: be 01 movw r22, r28 + 1e7c: 6c 5f subi r22, 0xFC ; 252 + 1e7e: 7f 4f sbci r23, 0xFF ; 255 + 1e80: ce 01 movw r24, r28 + 1e82: 01 96 adiw r24, 0x01 ; 1 + 1e84: 0e 94 bc 0c call 0x1978 ; 0x1978 + 1e88: 81 11 cpse r24, r1 + 1e8a: 20 c0 rjmp .+64 ; 0x1ecc + +static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + 1e8c: 0f b6 in r0, 0x3f ; 63 + 1e8e: f8 94 cli + 1e90: 0f 92 push r0 + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + 1e92: f8 01 movw r30, r16 + 1e94: 82 8d ldd r24, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 1e96: 0f 90 pop r0 + 1e98: 0f be out 0x3f, r0 ; 63 + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) ) + 1e9a: 81 11 cpse r24, r1 + 1e9c: 11 c0 rjmp .+34 ; 0x1ec0 + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + 1e9e: 6c 81 ldd r22, Y+4 ; 0x04 + 1ea0: 7d 81 ldd r23, Y+5 ; 0x05 + 1ea2: c5 01 movw r24, r10 + 1ea4: 0e 94 20 0c call 0x1840 ; 0x1840 + prvUnlockQueue( pxQueue ); + 1ea8: c8 01 movw r24, r16 + 1eaa: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + if( !xTaskResumeAll() ) + 1eae: 0e 94 64 0b call 0x16c8 ; 0x16c8 + 1eb2: 88 23 and r24, r24 + 1eb4: 11 f0 breq .+4 ; 0x1eba + 1eb6: 91 e0 ldi r25, 0x01 ; 1 + 1eb8: 92 cf rjmp .-220 ; 0x1dde + { + portYIELD_WITHIN_API(); + 1eba: 0e 94 df 13 call 0x27be ; 0x27be + 1ebe: fb cf rjmp .-10 ; 0x1eb6 + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + 1ec0: c8 01 movw r24, r16 + 1ec2: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + ( void ) xTaskResumeAll(); + 1ec6: 0e 94 64 0b call 0x16c8 ; 0x16c8 + 1eca: f5 cf rjmp .-22 ; 0x1eb6 + } + } + else + { + prvUnlockQueue( pxQueue ); + 1ecc: c8 01 movw r24, r16 + 1ece: 0e 94 50 0d call 0x1aa0 ; 0x1aa0 + ( void ) xTaskResumeAll(); + 1ed2: 0e 94 64 0b call 0x16c8 ; 0x16c8 + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + 1ed6: 80 e0 ldi r24, 0x00 ; 0 + } + } +} + 1ed8: 0f 90 pop r0 + 1eda: 0f 90 pop r0 + 1edc: 0f 90 pop r0 + 1ede: 0f 90 pop r0 + 1ee0: 0f 90 pop r0 + 1ee2: df 91 pop r29 + 1ee4: cf 91 pop r28 + 1ee6: 1f 91 pop r17 + 1ee8: 0f 91 pop r16 + 1eea: ff 90 pop r15 + 1eec: ef 90 pop r14 + 1eee: df 90 pop r13 + 1ef0: bf 90 pop r11 + 1ef2: af 90 pop r10 + 1ef4: 08 95 ret + +00001ef6 : +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) +{ + 1ef6: 0f 93 push r16 + 1ef8: 1f 93 push r17 + 1efa: cf 93 push r28 + 1efc: df 93 push r29 +unsigned portBASE_TYPE uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* We cannot block from an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 1efe: fc 01 movw r30, r24 + 1f00: 22 8d ldd r18, Z+26 ; 0x1a + 1f02: 22 23 and r18, r18 + 1f04: d9 f0 breq .+54 ; 0x1f3c + 1f06: 8a 01 movw r16, r20 + 1f08: ec 01 movw r28, r24 + { + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + 1f0a: 0e 94 36 0d call 0x1a6c ; 0x1a6c + --( pxQueue->uxMessagesWaiting ); + 1f0e: 8a 8d ldd r24, Y+26 ; 0x1a + 1f10: 81 50 subi r24, 0x01 ; 1 + 1f12: 8a 8f std Y+26, r24 ; 0x1a + + /* If the queue is locked we will not modify the event list. Instead + we update the lock count so the task that unlocks the queue will know + that an ISR has removed data while the queue was locked. */ + if( pxQueue->xRxLock == queueUNLOCKED ) + 1f14: 8d 8d ldd r24, Y+29 ; 0x1d + 1f16: 8f 3f cpi r24, 0xFF ; 255 + 1f18: 69 f4 brne .+26 ; 0x1f34 + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 1f1a: 88 85 ldd r24, Y+8 ; 0x08 + 1f1c: 88 23 and r24, r24 + 1f1e: 61 f0 breq .+24 ; 0x1f38 + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 1f20: ce 01 movw r24, r28 + 1f22: 08 96 adiw r24, 0x08 ; 8 + 1f24: 0e 94 6e 0c call 0x18dc ; 0x18dc + 1f28: 88 23 and r24, r24 + 1f2a: 31 f0 breq .+12 ; 0x1f38 + { + /* The task waiting has a higher priority than us so + force a context switch. */ + *pxTaskWoken = pdTRUE; + 1f2c: 81 e0 ldi r24, 0x01 ; 1 + 1f2e: f8 01 movw r30, r16 + 1f30: 80 83 st Z, r24 + 1f32: 05 c0 rjmp .+10 ; 0x1f3e + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++( pxQueue->xRxLock ); + 1f34: 8f 5f subi r24, 0xFF ; 255 + 1f36: 8d 8f std Y+29, r24 ; 0x1d + } + + xReturn = pdPASS; + 1f38: 81 e0 ldi r24, 0x01 ; 1 + 1f3a: 01 c0 rjmp .+2 ; 0x1f3e + } + else + { + xReturn = pdFAIL; + 1f3c: 80 e0 ldi r24, 0x00 ; 0 + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} + 1f3e: df 91 pop r29 + 1f40: cf 91 pop r28 + 1f42: 1f 91 pop r17 + 1f44: 0f 91 pop r16 + 1f46: 08 95 ret + +00001f48 : + +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + taskENTER_CRITICAL(); + 1f48: 0f b6 in r0, 0x3f ; 63 + 1f4a: f8 94 cli + 1f4c: 0f 92 push r0 + uxReturn = pxQueue->uxMessagesWaiting; + 1f4e: fc 01 movw r30, r24 + 1f50: 82 8d ldd r24, Z+26 ; 0x1a + taskEXIT_CRITICAL(); + 1f52: 0f 90 pop r0 + 1f54: 0f be out 0x3f, r0 ; 63 + + return uxReturn; +} + 1f56: 08 95 ret + +00001f58 : + +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + uxReturn = pxQueue->uxMessagesWaiting; + 1f58: fc 01 movw r30, r24 + 1f5a: 82 8d ldd r24, Z+26 ; 0x1a + + return uxReturn; +} + 1f5c: 08 95 ret + +00001f5e : +/*-----------------------------------------------------------*/ + +void vQueueDelete( xQueueHandle pxQueue ) +{ + 1f5e: cf 93 push r28 + 1f60: df 93 push r29 + 1f62: ec 01 movw r28, r24 + traceQUEUE_DELETE( pxQueue ); + vQueueUnregisterQueue( pxQueue ); + vPortFree( pxQueue->pcHead ); + 1f64: 88 81 ld r24, Y + 1f66: 99 81 ldd r25, Y+1 ; 0x01 + 1f68: 0e 94 28 13 call 0x2650 ; 0x2650 + vPortFree( pxQueue ); + 1f6c: ce 01 movw r24, r28 +} + 1f6e: df 91 pop r29 + 1f70: cf 91 pop r28 +void vQueueDelete( xQueueHandle pxQueue ) +{ + traceQUEUE_DELETE( pxQueue ); + vQueueUnregisterQueue( pxQueue ); + vPortFree( pxQueue->pcHead ); + vPortFree( pxQueue ); + 1f72: 0c 94 28 13 jmp 0x2650 ; 0x2650 + +00001f76 : + +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); + 1f76: fc 01 movw r30, r24 + 1f78: 92 8d ldd r25, Z+26 ; 0x1a + 1f7a: 81 e0 ldi r24, 0x01 ; 1 + 1f7c: 91 11 cpse r25, r1 + 1f7e: 80 e0 ldi r24, 0x00 ; 0 + + return xReturn; +} + 1f80: 08 95 ret + +00001f82 : + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) +{ + 1f82: fc 01 movw r30, r24 +signed portBASE_TYPE xReturn; + + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + 1f84: 22 8d ldd r18, Z+26 ; 0x1a + 1f86: 81 e0 ldi r24, 0x01 ; 1 + 1f88: 93 8d ldd r25, Z+27 ; 0x1b + 1f8a: 29 13 cpse r18, r25 + 1f8c: 80 e0 ldi r24, 0x00 ; 0 + + return xReturn; +} + 1f8e: 08 95 ret + +00001f90 : +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) +{ + 1f90: cf 93 push r28 + 1f92: df 93 push r29 + 1f94: ec 01 movw r28, r24 +signed portBASE_TYPE xReturn; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + 1f96: f8 94 cli + +static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + 1f98: 0f b6 in r0, 0x3f ; 63 + 1f9a: f8 94 cli + 1f9c: 0f 92 push r0 + xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); + 1f9e: 8a 8d ldd r24, Y+26 ; 0x1a + 1fa0: 9b 8d ldd r25, Y+27 ; 0x1b + taskEXIT_CRITICAL(); + 1fa2: 0f 90 pop r0 + 1fa4: 0f be out 0x3f, r0 ; 63 + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) ) + 1fa6: 89 13 cpse r24, r25 + 1fa8: 0f c0 rjmp .+30 ; 0x1fc8 + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( portTickType ) 0 ) + 1faa: 41 15 cp r20, r1 + 1fac: 51 05 cpc r21, r1 + 1fae: 49 f0 breq .+18 ; 0x1fc2 + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + 1fb0: be 01 movw r22, r28 + 1fb2: 68 5f subi r22, 0xF8 ; 248 + 1fb4: 7f 4f sbci r23, 0xFF ; 255 + 1fb6: ca 01 movw r24, r20 + 1fb8: 0e 94 9f 11 call 0x233e ; 0x233e + portENABLE_INTERRUPTS(); + 1fbc: 78 94 sei + return errQUEUE_BLOCKED; + 1fbe: 8c ef ldi r24, 0xFC ; 252 + 1fc0: 1c c0 rjmp .+56 ; 0x1ffa + } + else + { + portENABLE_INTERRUPTS(); + 1fc2: 78 94 sei + return errQUEUE_FULL; + 1fc4: 80 e0 ldi r24, 0x00 ; 0 + 1fc6: 19 c0 rjmp .+50 ; 0x1ffa + } + } + } + portENABLE_INTERRUPTS(); + 1fc8: 78 94 sei + + portNOP(); + 1fca: 00 00 nop + + portDISABLE_INTERRUPTS(); + 1fcc: f8 94 cli + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 1fce: 8a 8d ldd r24, Y+26 ; 0x1a + 1fd0: 89 17 cp r24, r25 + 1fd2: 88 f4 brcc .+34 ; 0x1ff6 + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + 1fd4: 40 e0 ldi r20, 0x00 ; 0 + 1fd6: ce 01 movw r24, r28 + 1fd8: 0e 94 f6 0c call 0x19ec ; 0x19ec + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 1fdc: 89 89 ldd r24, Y+17 ; 0x11 + 1fde: 81 11 cpse r24, r1 + 1fe0: 02 c0 rjmp .+4 ; 0x1fe6 + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + 1fe2: 81 e0 ldi r24, 0x01 ; 1 + 1fe4: 09 c0 rjmp .+18 ; 0x1ff8 + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 1fe6: ce 01 movw r24, r28 + 1fe8: 41 96 adiw r24, 0x11 ; 17 + 1fea: 0e 94 d7 12 call 0x25ae ; 0x25ae + 1fee: 88 23 and r24, r24 + 1ff0: c1 f3 breq .-16 ; 0x1fe2 + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + 1ff2: 8b ef ldi r24, 0xFB ; 251 + 1ff4: 01 c0 rjmp .+2 ; 0x1ff8 + } + } + } + else + { + xReturn = errQUEUE_FULL; + 1ff6: 80 e0 ldi r24, 0x00 ; 0 + } + } + portENABLE_INTERRUPTS(); + 1ff8: 78 94 sei + + return xReturn; +} + 1ffa: df 91 pop r29 + 1ffc: cf 91 pop r28 + 1ffe: 08 95 ret + +00002000 : +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) +{ + 2000: cf 93 push r28 + 2002: df 93 push r29 + 2004: ec 01 movw r28, r24 + 2006: fb 01 movw r30, r22 +signed portBASE_TYPE xReturn; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + 2008: f8 94 cli + { + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) + 200a: 8a 8d ldd r24, Y+26 ; 0x1a + 200c: 81 11 cpse r24, r1 + 200e: 0f c0 rjmp .+30 ; 0x202e + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( portTickType ) 0 ) + 2010: 41 15 cp r20, r1 + 2012: 51 05 cpc r21, r1 + 2014: 49 f0 breq .+18 ; 0x2028 + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + 2016: be 01 movw r22, r28 + 2018: 6f 5e subi r22, 0xEF ; 239 + 201a: 7f 4f sbci r23, 0xFF ; 255 + 201c: ca 01 movw r24, r20 + 201e: 0e 94 9f 11 call 0x233e ; 0x233e + portENABLE_INTERRUPTS(); + 2022: 78 94 sei + return errQUEUE_BLOCKED; + 2024: 8c ef ldi r24, 0xFC ; 252 + 2026: 31 c0 rjmp .+98 ; 0x208a + } + else + { + portENABLE_INTERRUPTS(); + 2028: 78 94 sei + return errQUEUE_FULL; + 202a: 80 e0 ldi r24, 0x00 ; 0 + 202c: 2e c0 rjmp .+92 ; 0x208a + } + } + } + portENABLE_INTERRUPTS(); + 202e: 78 94 sei + + portNOP(); + 2030: 00 00 nop + + portDISABLE_INTERRUPTS(); + 2032: f8 94 cli + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 2034: 8a 8d ldd r24, Y+26 ; 0x1a + 2036: 88 23 and r24, r24 + 2038: 31 f1 breq .+76 ; 0x2086 + { + /* Data is available from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + 203a: 4c 8d ldd r20, Y+28 ; 0x1c + 203c: 50 e0 ldi r21, 0x00 ; 0 + 203e: 2e 81 ldd r18, Y+6 ; 0x06 + 2040: 3f 81 ldd r19, Y+7 ; 0x07 + 2042: 24 0f add r18, r20 + 2044: 35 1f adc r19, r21 + 2046: 3f 83 std Y+7, r19 ; 0x07 + 2048: 2e 83 std Y+6, r18 ; 0x06 + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + 204a: 8a 81 ldd r24, Y+2 ; 0x02 + 204c: 9b 81 ldd r25, Y+3 ; 0x03 + 204e: 28 17 cp r18, r24 + 2050: 39 07 cpc r19, r25 + 2052: 20 f0 brcs .+8 ; 0x205c + { + pxQueue->pcReadFrom = pxQueue->pcHead; + 2054: 88 81 ld r24, Y + 2056: 99 81 ldd r25, Y+1 ; 0x01 + 2058: 9f 83 std Y+7, r25 ; 0x07 + 205a: 8e 83 std Y+6, r24 ; 0x06 + } + --( pxQueue->uxMessagesWaiting ); + 205c: 9a 8d ldd r25, Y+26 ; 0x1a + 205e: 91 50 subi r25, 0x01 ; 1 + 2060: 9a 8f std Y+26, r25 ; 0x1a + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + 2062: 6e 81 ldd r22, Y+6 ; 0x06 + 2064: 7f 81 ldd r23, Y+7 ; 0x07 + 2066: cf 01 movw r24, r30 + 2068: 0e 94 ca 14 call 0x2994 ; 0x2994 + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 206c: 88 85 ldd r24, Y+8 ; 0x08 + 206e: 81 11 cpse r24, r1 + 2070: 02 c0 rjmp .+4 ; 0x2076 + pxQueue->pcReadFrom = pxQueue->pcHead; + } + --( pxQueue->uxMessagesWaiting ); + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + 2072: 81 e0 ldi r24, 0x01 ; 1 + 2074: 09 c0 rjmp .+18 ; 0x2088 + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 2076: ce 01 movw r24, r28 + 2078: 08 96 adiw r24, 0x08 ; 8 + 207a: 0e 94 d7 12 call 0x25ae ; 0x25ae + 207e: 88 23 and r24, r24 + 2080: c1 f3 breq .-16 ; 0x2072 + { + xReturn = errQUEUE_YIELD; + 2082: 8b ef ldi r24, 0xFB ; 251 + 2084: 01 c0 rjmp .+2 ; 0x2088 + } + } + } + else + { + xReturn = pdFAIL; + 2086: 80 e0 ldi r24, 0x00 ; 0 + } + } + portENABLE_INTERRUPTS(); + 2088: 78 94 sei + + return xReturn; +} + 208a: df 91 pop r29 + 208c: cf 91 pop r28 + 208e: 08 95 ret + +00002090 : + + + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) +{ + 2090: 0f 93 push r16 + 2092: 1f 93 push r17 + 2094: cf 93 push r28 + 2096: 8c 01 movw r16, r24 + 2098: c4 2f mov r28, r20 + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + 209a: fc 01 movw r30, r24 + 209c: 92 8d ldd r25, Z+26 ; 0x1a + 209e: 83 8d ldd r24, Z+27 ; 0x1b + 20a0: 98 17 cp r25, r24 + 20a2: 10 f0 brcs .+4 ; 0x20a8 + 20a4: 4c 2f mov r20, r28 + 20a6: 12 c0 rjmp .+36 ; 0x20cc + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + 20a8: 40 e0 ldi r20, 0x00 ; 0 + 20aa: c8 01 movw r24, r16 + 20ac: 0e 94 f6 0c call 0x19ec ; 0x19ec + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( !xCoRoutinePreviouslyWoken ) + 20b0: c1 11 cpse r28, r1 + 20b2: f8 cf rjmp .-16 ; 0x20a4 + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) + 20b4: f8 01 movw r30, r16 + 20b6: 81 89 ldd r24, Z+17 ; 0x11 + 20b8: 88 23 and r24, r24 + 20ba: 39 f0 breq .+14 ; 0x20ca + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + 20bc: c8 01 movw r24, r16 + 20be: 41 96 adiw r24, 0x11 ; 17 + 20c0: 0e 94 d7 12 call 0x25ae ; 0x25ae + 20c4: 41 e0 ldi r20, 0x01 ; 1 + 20c6: 81 11 cpse r24, r1 + 20c8: 01 c0 rjmp .+2 ; 0x20cc + 20ca: 40 e0 ldi r20, 0x00 ; 0 + } + } + } + + return xCoRoutinePreviouslyWoken; +} + 20cc: 84 2f mov r24, r20 + 20ce: cf 91 pop r28 + 20d0: 1f 91 pop r17 + 20d2: 0f 91 pop r16 + 20d4: 08 95 ret + +000020d6 : +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken ) +{ + 20d6: 0f 93 push r16 + 20d8: 1f 93 push r17 + 20da: cf 93 push r28 + 20dc: df 93 push r29 + 20de: fc 01 movw r30, r24 +signed portBASE_TYPE xReturn; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + 20e0: 82 8d ldd r24, Z+26 ; 0x1a + 20e2: 88 23 and r24, r24 + 20e4: 79 f1 breq .+94 ; 0x2144 + { + /* Copy the data from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + 20e6: 24 8d ldd r18, Z+28 ; 0x1c + 20e8: 30 e0 ldi r19, 0x00 ; 0 + 20ea: a6 81 ldd r26, Z+6 ; 0x06 + 20ec: b7 81 ldd r27, Z+7 ; 0x07 + 20ee: a2 0f add r26, r18 + 20f0: b3 1f adc r27, r19 + 20f2: b7 83 std Z+7, r27 ; 0x07 + 20f4: a6 83 std Z+6, r26 ; 0x06 + if( pxQueue->pcReadFrom >= pxQueue->pcTail ) + 20f6: 82 81 ldd r24, Z+2 ; 0x02 + 20f8: 93 81 ldd r25, Z+3 ; 0x03 + 20fa: a8 17 cp r26, r24 + 20fc: b9 07 cpc r27, r25 + 20fe: 20 f0 brcs .+8 ; 0x2108 + { + pxQueue->pcReadFrom = pxQueue->pcHead; + 2100: 80 81 ld r24, Z + 2102: 91 81 ldd r25, Z+1 ; 0x01 + 2104: 97 83 std Z+7, r25 ; 0x07 + 2106: 86 83 std Z+6, r24 ; 0x06 + 2108: 8a 01 movw r16, r20 + 210a: cb 01 movw r24, r22 + 210c: ef 01 movw r28, r30 + } + --( pxQueue->uxMessagesWaiting ); + 210e: 42 8d ldd r20, Z+26 ; 0x1a + 2110: 41 50 subi r20, 0x01 ; 1 + 2112: 42 8f std Z+26, r20 ; 0x1a + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + 2114: 66 81 ldd r22, Z+6 ; 0x06 + 2116: 77 81 ldd r23, Z+7 ; 0x07 + 2118: a9 01 movw r20, r18 + 211a: 0e 94 ca 14 call 0x2994 ; 0x2994 + + if( !( *pxCoRoutineWoken ) ) + 211e: f8 01 movw r30, r16 + 2120: 80 81 ld r24, Z + 2122: 88 23 and r24, r24 + 2124: 11 f0 breq .+4 ; 0x212a + *pxCoRoutineWoken = pdTRUE; + } + } + } + + xReturn = pdPASS; + 2126: 81 e0 ldi r24, 0x01 ; 1 + 2128: 0e c0 rjmp .+28 ; 0x2146 + --( pxQueue->uxMessagesWaiting ); + memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( !( *pxCoRoutineWoken ) ) + { + if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) + 212a: 88 85 ldd r24, Y+8 ; 0x08 + 212c: 88 23 and r24, r24 + 212e: d9 f3 breq .-10 ; 0x2126 + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + 2130: ce 01 movw r24, r28 + 2132: 08 96 adiw r24, 0x08 ; 8 + 2134: 0e 94 d7 12 call 0x25ae ; 0x25ae + 2138: 88 23 and r24, r24 + 213a: a9 f3 breq .-22 ; 0x2126 + { + *pxCoRoutineWoken = pdTRUE; + 213c: 81 e0 ldi r24, 0x01 ; 1 + 213e: f8 01 movw r30, r16 + 2140: 80 83 st Z, r24 + 2142: 01 c0 rjmp .+2 ; 0x2146 + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + 2144: 80 e0 ldi r24, 0x00 ; 0 + } + + return xReturn; +} + 2146: df 91 pop r29 + 2148: cf 91 pop r28 + 214a: 1f 91 pop r17 + 214c: 0f 91 pop r16 + 214e: 08 95 ret + +00002150 : +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( xList *pxList ) +{ + 2150: fc 01 movw r30, r24 + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); + 2152: 03 96 adiw r24, 0x03 ; 3 + 2154: 92 83 std Z+2, r25 ; 0x02 + 2156: 81 83 std Z+1, r24 ; 0x01 + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + 2158: 2f ef ldi r18, 0xFF ; 255 + 215a: 3f ef ldi r19, 0xFF ; 255 + 215c: 34 83 std Z+4, r19 ; 0x04 + 215e: 23 83 std Z+3, r18 ; 0x03 + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); + 2160: 96 83 std Z+6, r25 ; 0x06 + 2162: 85 83 std Z+5, r24 ; 0x05 + pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd ); + 2164: 90 87 std Z+8, r25 ; 0x08 + 2166: 87 83 std Z+7, r24 ; 0x07 + + pxList->uxNumberOfItems = 0; + 2168: 10 82 st Z, r1 + 216a: 08 95 ret + +0000216c : +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( xListItem *pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; + 216c: fc 01 movw r30, r24 + 216e: 11 86 std Z+9, r1 ; 0x09 + 2170: 10 86 std Z+8, r1 ; 0x08 + 2172: 08 95 ret + +00002174 : +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ) +{ + 2174: cf 93 push r28 + 2176: df 93 push r29 + 2178: dc 01 movw r26, r24 + 217a: fb 01 movw r30, r22 + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by + the pxIndex member. */ + pxIndex = pxList->pxIndex; + 217c: 11 96 adiw r26, 0x01 ; 1 + 217e: 2d 91 ld r18, X+ + 2180: 3c 91 ld r19, X + 2182: 12 97 sbiw r26, 0x02 ; 2 + + pxNewListItem->pxNext = pxIndex->pxNext; + 2184: e9 01 movw r28, r18 + 2186: 8a 81 ldd r24, Y+2 ; 0x02 + 2188: 9b 81 ldd r25, Y+3 ; 0x03 + 218a: 93 83 std Z+3, r25 ; 0x03 + 218c: 82 83 std Z+2, r24 ; 0x02 + pxNewListItem->pxPrevious = pxList->pxIndex; + 218e: 35 83 std Z+5, r19 ; 0x05 + 2190: 24 83 std Z+4, r18 ; 0x04 + pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + 2192: 8a 81 ldd r24, Y+2 ; 0x02 + 2194: 9b 81 ldd r25, Y+3 ; 0x03 + 2196: ec 01 movw r28, r24 + 2198: 7d 83 std Y+5, r23 ; 0x05 + 219a: 6c 83 std Y+4, r22 ; 0x04 + pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem; + 219c: e9 01 movw r28, r18 + 219e: 7b 83 std Y+3, r23 ; 0x03 + 21a0: 6a 83 std Y+2, r22 ; 0x02 + pxList->pxIndex = ( volatile xListItem * ) pxNewListItem; + 21a2: 12 96 adiw r26, 0x02 ; 2 + 21a4: 7c 93 st X, r23 + 21a6: 6e 93 st -X, r22 + 21a8: 11 97 sbiw r26, 0x01 ; 1 + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + 21aa: b1 87 std Z+9, r27 ; 0x09 + 21ac: a0 87 std Z+8, r26 ; 0x08 + + ( pxList->uxNumberOfItems )++; + 21ae: 8c 91 ld r24, X + 21b0: 8f 5f subi r24, 0xFF ; 255 + 21b2: 8c 93 st X, r24 +} + 21b4: df 91 pop r29 + 21b6: cf 91 pop r28 + 21b8: 08 95 ret + +000021ba : +/*-----------------------------------------------------------*/ + +void vListInsert( xList *pxList, xListItem *pxNewListItem ) +{ + 21ba: cf 93 push r28 + 21bc: df 93 push r29 + 21be: ac 01 movw r20, r24 + 21c0: db 01 movw r26, r22 +volatile xListItem *pxIterator; +portTickType xValueOfInsertion; + + /* Insert the new list item into the list, sorted in ulListItem order. */ + xValueOfInsertion = pxNewListItem->xItemValue; + 21c2: 8d 91 ld r24, X+ + 21c4: 9c 91 ld r25, X + 21c6: 11 97 sbiw r26, 0x01 ; 1 + are stored in ready lists (all of which have the same ulListItem value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + 21c8: 8f 3f cpi r24, 0xFF ; 255 + 21ca: 2f ef ldi r18, 0xFF ; 255 + 21cc: 92 07 cpc r25, r18 + 21ce: 21 f4 brne .+8 ; 0x21d8 + { + pxIterator = pxList->xListEnd.pxPrevious; + 21d0: ea 01 movw r28, r20 + 21d2: ef 81 ldd r30, Y+7 ; 0x07 + 21d4: f8 85 ldd r31, Y+8 ; 0x08 + 21d6: 0e c0 rjmp .+28 ; 0x21f4 + } + else + { + for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) + 21d8: fa 01 movw r30, r20 + 21da: 33 96 adiw r30, 0x03 ; 3 + 21dc: 22 81 ldd r18, Z+2 ; 0x02 + 21de: 33 81 ldd r19, Z+3 ; 0x03 + 21e0: e9 01 movw r28, r18 + 21e2: 28 81 ld r18, Y + 21e4: 39 81 ldd r19, Y+1 ; 0x01 + 21e6: 82 17 cp r24, r18 + 21e8: 93 07 cpc r25, r19 + 21ea: 20 f0 brcs .+8 ; 0x21f4 + 21ec: 02 80 ldd r0, Z+2 ; 0x02 + 21ee: f3 81 ldd r31, Z+3 ; 0x03 + 21f0: e0 2d mov r30, r0 + 21f2: f4 cf rjmp .-24 ; 0x21dc + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + 21f4: 82 81 ldd r24, Z+2 ; 0x02 + 21f6: 93 81 ldd r25, Z+3 ; 0x03 + 21f8: 13 96 adiw r26, 0x03 ; 3 + 21fa: 9c 93 st X, r25 + 21fc: 8e 93 st -X, r24 + 21fe: 12 97 sbiw r26, 0x02 ; 2 + pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + 2200: ec 01 movw r28, r24 + 2202: bd 83 std Y+5, r27 ; 0x05 + 2204: ac 83 std Y+4, r26 ; 0x04 + pxNewListItem->pxPrevious = pxIterator; + 2206: 15 96 adiw r26, 0x05 ; 5 + 2208: fc 93 st X, r31 + 220a: ee 93 st -X, r30 + 220c: 14 97 sbiw r26, 0x04 ; 4 + pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem; + 220e: b3 83 std Z+3, r27 ; 0x03 + 2210: a2 83 std Z+2, r26 ; 0x02 + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + 2212: 19 96 adiw r26, 0x09 ; 9 + 2214: 5c 93 st X, r21 + 2216: 4e 93 st -X, r20 + 2218: 18 97 sbiw r26, 0x08 ; 8 + + ( pxList->uxNumberOfItems )++; + 221a: fa 01 movw r30, r20 + 221c: 80 81 ld r24, Z + 221e: 8f 5f subi r24, 0xFF ; 255 + 2220: 80 83 st Z, r24 +} + 2222: df 91 pop r29 + 2224: cf 91 pop r28 + 2226: 08 95 ret + +00002228 : +/*-----------------------------------------------------------*/ + +void vListRemove( xListItem *pxItemToRemove ) +{ + 2228: cf 93 push r28 + 222a: df 93 push r29 + 222c: fc 01 movw r30, r24 +xList * pxList; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + 222e: a2 81 ldd r26, Z+2 ; 0x02 + 2230: b3 81 ldd r27, Z+3 ; 0x03 + 2232: 84 81 ldd r24, Z+4 ; 0x04 + 2234: 95 81 ldd r25, Z+5 ; 0x05 + 2236: 15 96 adiw r26, 0x05 ; 5 + 2238: 9c 93 st X, r25 + 223a: 8e 93 st -X, r24 + 223c: 14 97 sbiw r26, 0x04 ; 4 + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + 223e: c4 81 ldd r28, Z+4 ; 0x04 + 2240: d5 81 ldd r29, Z+5 ; 0x05 + 2242: bb 83 std Y+3, r27 ; 0x03 + 2244: aa 83 std Y+2, r26 ; 0x02 + + /* The list item knows which list it is in. Obtain the list from the list + item. */ + pxList = ( xList * ) pxItemToRemove->pvContainer; + 2246: a0 85 ldd r26, Z+8 ; 0x08 + 2248: b1 85 ldd r27, Z+9 ; 0x09 + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + 224a: 11 96 adiw r26, 0x01 ; 1 + 224c: 8d 91 ld r24, X+ + 224e: 9c 91 ld r25, X + 2250: 12 97 sbiw r26, 0x02 ; 2 + 2252: 8e 17 cp r24, r30 + 2254: 9f 07 cpc r25, r31 + 2256: 21 f4 brne .+8 ; 0x2260 + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + 2258: 12 96 adiw r26, 0x02 ; 2 + 225a: dc 93 st X, r29 + 225c: ce 93 st -X, r28 + 225e: 11 97 sbiw r26, 0x01 ; 1 + } + + pxItemToRemove->pvContainer = NULL; + 2260: 11 86 std Z+9, r1 ; 0x09 + 2262: 10 86 std Z+8, r1 ; 0x08 + ( pxList->uxNumberOfItems )--; + 2264: 8c 91 ld r24, X + 2266: 81 50 subi r24, 0x01 ; 1 + 2268: 8c 93 st X, r24 +} + 226a: df 91 pop r29 + 226c: cf 91 pop r28 + 226e: 08 95 ret + +00002270 : +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) +{ + 2270: ef 92 push r14 + 2272: ff 92 push r15 + 2274: 0f 93 push r16 + 2276: 1f 93 push r17 + 2278: cf 93 push r28 + 227a: df 93 push r29 + 227c: 7c 01 movw r14, r24 + 227e: 14 2f mov r17, r20 +signed portBASE_TYPE xReturn; +corCRCB *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); + 2280: 8a e1 ldi r24, 0x1A ; 26 + 2282: 90 e0 ldi r25, 0x00 ; 0 + 2284: 0e 94 02 13 call 0x2604 ; 0x2604 + 2288: ec 01 movw r28, r24 + if( pxCoRoutine ) + 228a: 89 2b or r24, r25 + 228c: 09 f4 brne .+2 ; 0x2290 + 228e: 4f c0 rjmp .+158 ; 0x232e + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + 2290: 80 91 a0 01 lds r24, 0x01A0 + 2294: 90 91 a1 01 lds r25, 0x01A1 + 2298: 89 2b or r24, r25 + 229a: 01 f5 brne .+64 ; 0x22dc + { + pxCurrentCoRoutine = pxCoRoutine; + 229c: d0 93 a1 01 sts 0x01A1, r29 + 22a0: c0 93 a0 01 sts 0x01A0, r28 +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + 22a4: 88 ec ldi r24, 0xC8 ; 200 + 22a6: 91 e0 ldi r25, 0x01 ; 1 + 22a8: 0e 94 a8 10 call 0x2150 ; 0x2150 + } + + vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); + 22ac: 8f eb ldi r24, 0xBF ; 191 + 22ae: 91 e0 ldi r25, 0x01 ; 1 + 22b0: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); + 22b4: 86 eb ldi r24, 0xB6 ; 182 + 22b6: 91 e0 ldi r25, 0x01 ; 1 + 22b8: 0e 94 a8 10 call 0x2150 ; 0x2150 + vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); + 22bc: 89 ea ldi r24, 0xA9 ; 169 + 22be: 91 e0 ldi r25, 0x01 ; 1 + 22c0: 0e 94 a8 10 call 0x2150 ; 0x2150 + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + 22c4: 8f eb ldi r24, 0xBF ; 191 + 22c6: 91 e0 ldi r25, 0x01 ; 1 + 22c8: 90 93 b5 01 sts 0x01B5, r25 + 22cc: 80 93 b4 01 sts 0x01B4, r24 + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; + 22d0: 86 eb ldi r24, 0xB6 ; 182 + 22d2: 91 e0 ldi r25, 0x01 ; 1 + 22d4: 90 93 b3 01 sts 0x01B3, r25 + 22d8: 80 93 b2 01 sts 0x01B2, r24 + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + 22dc: 19 8e std Y+25, r1 ; 0x19 + 22de: 18 8e std Y+24, r1 ; 0x18 + pxCoRoutine->uxPriority = uxPriority; + 22e0: 1e 8a std Y+22, r1 ; 0x16 + pxCoRoutine->uxIndex = uxIndex; + 22e2: 1f 8b std Y+23, r17 ; 0x17 + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + 22e4: fe 01 movw r30, r28 + 22e6: e1 92 st Z+, r14 + 22e8: f1 92 st Z+, r15 + 22ea: 8f 01 movw r16, r30 + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + 22ec: cf 01 movw r24, r30 + 22ee: 0e 94 b6 10 call 0x216c ; 0x216c + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + 22f2: ce 01 movw r24, r28 + 22f4: 0c 96 adiw r24, 0x0c ; 12 + 22f6: 0e 94 b6 10 call 0x216c ; 0x216c + + /* Set the co-routine control block as a link back from the xListItem. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + 22fa: d9 87 std Y+9, r29 ; 0x09 + 22fc: c8 87 std Y+8, r28 ; 0x08 + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + 22fe: db 8b std Y+19, r29 ; 0x13 + 2300: ca 8b std Y+18, r28 ; 0x12 + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + 2302: 84 e0 ldi r24, 0x04 ; 4 + 2304: 90 e0 ldi r25, 0x00 ; 0 + 2306: 9d 87 std Y+13, r25 ; 0x0d + 2308: 8c 87 std Y+12, r24 ; 0x0c + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + 230a: 9e 89 ldd r25, Y+22 ; 0x16 + 230c: 80 91 a8 01 lds r24, 0x01A8 + 2310: 89 17 cp r24, r25 + 2312: 10 f4 brcc .+4 ; 0x2318 + 2314: 90 93 a8 01 sts 0x01A8, r25 + 2318: f9 e0 ldi r31, 0x09 ; 9 + 231a: 9f 9f mul r25, r31 + 231c: c0 01 movw r24, r0 + 231e: 11 24 eor r1, r1 + 2320: b8 01 movw r22, r16 + 2322: 88 53 subi r24, 0x38 ; 56 + 2324: 9e 4f sbci r25, 0xFE ; 254 + 2326: 0e 94 ba 10 call 0x2174 ; 0x2174 + + xReturn = pdPASS; + 232a: 81 e0 ldi r24, 0x01 ; 1 + 232c: 01 c0 rjmp .+2 ; 0x2330 + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + 232e: 8f ef ldi r24, 0xFF ; 255 + } + + return xReturn; +} + 2330: df 91 pop r29 + 2332: cf 91 pop r28 + 2334: 1f 91 pop r17 + 2336: 0f 91 pop r16 + 2338: ff 90 pop r15 + 233a: ef 90 pop r14 + 233c: 08 95 ret + +0000233e : +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) +{ + 233e: 0f 93 push r16 + 2340: 1f 93 push r17 + 2342: cf 93 push r28 + 2344: df 93 push r29 + 2346: 8b 01 movw r16, r22 +portTickType xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + 2348: c0 91 a6 01 lds r28, 0x01A6 + 234c: d0 91 a7 01 lds r29, 0x01A7 + 2350: c8 0f add r28, r24 + 2352: d9 1f adc r29, r25 + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 2354: 80 91 a0 01 lds r24, 0x01A0 + 2358: 90 91 a1 01 lds r25, 0x01A1 + 235c: 02 96 adiw r24, 0x02 ; 2 + 235e: 0e 94 14 11 call 0x2228 ; 0x2228 + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + 2362: e0 91 a0 01 lds r30, 0x01A0 + 2366: f0 91 a1 01 lds r31, 0x01A1 + 236a: d3 83 std Z+3, r29 ; 0x03 + 236c: c2 83 std Z+2, r28 ; 0x02 + + if( xTimeToWake < xCoRoutineTickCount ) + 236e: 80 91 a6 01 lds r24, 0x01A6 + 2372: 90 91 a7 01 lds r25, 0x01A7 + 2376: bf 01 movw r22, r30 + 2378: 6e 5f subi r22, 0xFE ; 254 + 237a: 7f 4f sbci r23, 0xFF ; 255 + 237c: c8 17 cp r28, r24 + 237e: d9 07 cpc r29, r25 + 2380: 28 f4 brcc .+10 ; 0x238c + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 2382: 80 91 b2 01 lds r24, 0x01B2 + 2386: 90 91 b3 01 lds r25, 0x01B3 + 238a: 04 c0 rjmp .+8 ; 0x2394 + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + 238c: 80 91 b4 01 lds r24, 0x01B4 + 2390: 90 91 b5 01 lds r25, 0x01B5 + 2394: 0e 94 dd 10 call 0x21ba ; 0x21ba + } + + if( pxEventList ) + 2398: 01 15 cp r16, r1 + 239a: 11 05 cpc r17, r1 + 239c: 69 f0 breq .+26 ; 0x23b8 + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + 239e: 60 91 a0 01 lds r22, 0x01A0 + 23a2: 70 91 a1 01 lds r23, 0x01A1 + 23a6: 64 5f subi r22, 0xF4 ; 244 + 23a8: 7f 4f sbci r23, 0xFF ; 255 + 23aa: c8 01 movw r24, r16 + } +} + 23ac: df 91 pop r29 + 23ae: cf 91 pop r28 + 23b0: 1f 91 pop r17 + 23b2: 0f 91 pop r16 + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + 23b4: 0c 94 dd 10 jmp 0x21ba ; 0x21ba + } +} + 23b8: df 91 pop r29 + 23ba: cf 91 pop r28 + 23bc: 1f 91 pop r17 + 23be: 0f 91 pop r16 + 23c0: 08 95 ret + +000023c2 : + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + 23c2: ff 92 push r15 + 23c4: 0f 93 push r16 + 23c6: 1f 93 push r17 + 23c8: cf 93 push r28 + 23ca: df 93 push r29 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + 23cc: 99 e0 ldi r25, 0x09 ; 9 + 23ce: f9 2e mov r15, r25 +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) ) + 23d0: 80 91 a9 01 lds r24, 0x01A9 + 23d4: 88 23 and r24, r24 + 23d6: 49 f1 breq .+82 ; 0x242a + { + corCRCB *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + 23d8: f8 94 cli + { + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + 23da: 80 91 a9 01 lds r24, 0x01A9 + 23de: 88 23 and r24, r24 + 23e0: 39 f0 breq .+14 ; 0x23f0 + 23e2: e0 91 ae 01 lds r30, 0x01AE + 23e6: f0 91 af 01 lds r31, 0x01AF + 23ea: c6 81 ldd r28, Z+6 ; 0x06 + 23ec: d7 81 ldd r29, Z+7 ; 0x07 + 23ee: 02 c0 rjmp .+4 ; 0x23f4 + 23f0: c0 e0 ldi r28, 0x00 ; 0 + 23f2: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + 23f4: ce 01 movw r24, r28 + 23f6: 0c 96 adiw r24, 0x0c ; 12 + 23f8: 0e 94 14 11 call 0x2228 ; 0x2228 + } + portENABLE_INTERRUPTS(); + 23fc: 78 94 sei + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + 23fe: 8e 01 movw r16, r28 + 2400: 0e 5f subi r16, 0xFE ; 254 + 2402: 1f 4f sbci r17, 0xFF ; 255 + 2404: c8 01 movw r24, r16 + 2406: 0e 94 14 11 call 0x2228 ; 0x2228 + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + 240a: 9e 89 ldd r25, Y+22 ; 0x16 + 240c: 80 91 a8 01 lds r24, 0x01A8 + 2410: 89 17 cp r24, r25 + 2412: 10 f4 brcc .+4 ; 0x2418 + 2414: 90 93 a8 01 sts 0x01A8, r25 + 2418: f9 9e mul r15, r25 + 241a: c0 01 movw r24, r0 + 241c: 11 24 eor r1, r1 + 241e: b8 01 movw r22, r16 + 2420: 88 53 subi r24, 0x38 ; 56 + 2422: 9e 4f sbci r25, 0xFE ; 254 + 2424: 0e 94 ba 10 call 0x2174 ; 0x2174 + 2428: d3 cf rjmp .-90 ; 0x23d0 + +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + 242a: 0e 94 e4 0a call 0x15c8 ; 0x15c8 + 242e: 20 91 a4 01 lds r18, 0x01A4 + 2432: 30 91 a5 01 lds r19, 0x01A5 + 2436: 82 1b sub r24, r18 + 2438: 93 0b sbc r25, r19 + 243a: 90 93 a3 01 sts 0x01A3, r25 + 243e: 80 93 a2 01 sts 0x01A2, r24 + vListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + 2442: 89 e0 ldi r24, 0x09 ; 9 + 2444: f8 2e mov r15, r24 +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + 2446: 20 91 a2 01 lds r18, 0x01A2 + 244a: 30 91 a3 01 lds r19, 0x01A3 + 244e: 80 91 a6 01 lds r24, 0x01A6 + 2452: 90 91 a7 01 lds r25, 0x01A7 + 2456: 21 15 cp r18, r1 + 2458: 31 05 cpc r19, r1 + 245a: 09 f4 brne .+2 ; 0x245e + 245c: 56 c0 rjmp .+172 ; 0x250a + { + xCoRoutineTickCount++; + 245e: 01 96 adiw r24, 0x01 ; 1 + 2460: 90 93 a7 01 sts 0x01A7, r25 + 2464: 80 93 a6 01 sts 0x01A6, r24 + xPassedTicks--; + 2468: 21 50 subi r18, 0x01 ; 1 + 246a: 31 09 sbc r19, r1 + 246c: 30 93 a3 01 sts 0x01A3, r19 + 2470: 20 93 a2 01 sts 0x01A2, r18 + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + 2474: 89 2b or r24, r25 + 2476: 09 f0 breq .+2 ; 0x247a + 2478: 40 c0 rjmp .+128 ; 0x24fa + { + xList * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + 247a: 80 91 b4 01 lds r24, 0x01B4 + 247e: 90 91 b5 01 lds r25, 0x01B5 + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + 2482: 20 91 b2 01 lds r18, 0x01B2 + 2486: 30 91 b3 01 lds r19, 0x01B3 + 248a: 30 93 b5 01 sts 0x01B5, r19 + 248e: 20 93 b4 01 sts 0x01B4, r18 + pxOverflowDelayedCoRoutineList = pxTemp; + 2492: 90 93 b3 01 sts 0x01B3, r25 + 2496: 80 93 b2 01 sts 0x01B2, r24 + 249a: 2f c0 rjmp .+94 ; 0x24fa + } + + /* See if this tick has made a timeout expire. */ + while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) + 249c: 05 80 ldd r0, Z+5 ; 0x05 + 249e: f6 81 ldd r31, Z+6 ; 0x06 + 24a0: e0 2d mov r30, r0 + 24a2: c6 81 ldd r28, Z+6 ; 0x06 + 24a4: d7 81 ldd r29, Z+7 ; 0x07 + 24a6: 20 97 sbiw r28, 0x00 ; 0 + 24a8: 71 f2 breq .-100 ; 0x2446 + { + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + 24aa: 20 91 a6 01 lds r18, 0x01A6 + 24ae: 30 91 a7 01 lds r19, 0x01A7 + 24b2: 8a 81 ldd r24, Y+2 ; 0x02 + 24b4: 9b 81 ldd r25, Y+3 ; 0x03 + 24b6: 28 17 cp r18, r24 + 24b8: 39 07 cpc r19, r25 + 24ba: 28 f2 brcs .-118 ; 0x2446 + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + 24bc: f8 94 cli + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + vListRemove( &( pxCRCB->xGenericListItem ) ); + 24be: 8e 01 movw r16, r28 + 24c0: 0e 5f subi r16, 0xFE ; 254 + 24c2: 1f 4f sbci r17, 0xFF ; 255 + 24c4: c8 01 movw r24, r16 + 24c6: 0e 94 14 11 call 0x2228 ; 0x2228 + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + 24ca: 8c 89 ldd r24, Y+20 ; 0x14 + 24cc: 9d 89 ldd r25, Y+21 ; 0x15 + 24ce: 89 2b or r24, r25 + 24d0: 21 f0 breq .+8 ; 0x24da + { + vListRemove( &( pxCRCB->xEventListItem ) ); + 24d2: ce 01 movw r24, r28 + 24d4: 0c 96 adiw r24, 0x0c ; 12 + 24d6: 0e 94 14 11 call 0x2228 ; 0x2228 + } + } + portENABLE_INTERRUPTS(); + 24da: 78 94 sei + + prvAddCoRoutineToReadyQueue( pxCRCB ); + 24dc: 9e 89 ldd r25, Y+22 ; 0x16 + 24de: 80 91 a8 01 lds r24, 0x01A8 + 24e2: 89 17 cp r24, r25 + 24e4: 10 f4 brcc .+4 ; 0x24ea + 24e6: 90 93 a8 01 sts 0x01A8, r25 + 24ea: f9 9e mul r15, r25 + 24ec: c0 01 movw r24, r0 + 24ee: 11 24 eor r1, r1 + 24f0: b8 01 movw r22, r16 + 24f2: 88 53 subi r24, 0x38 ; 56 + 24f4: 9e 4f sbci r25, 0xFE ; 254 + 24f6: 0e 94 ba 10 call 0x2174 ; 0x2174 + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) + 24fa: e0 91 b4 01 lds r30, 0x01B4 + 24fe: f0 91 b5 01 lds r31, 0x01B5 + 2502: 80 81 ld r24, Z + 2504: 81 11 cpse r24, r1 + 2506: ca cf rjmp .-108 ; 0x249c + 2508: 9e cf rjmp .-196 ; 0x2446 + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; + 250a: 90 93 a5 01 sts 0x01A5, r25 + 250e: 80 93 a4 01 sts 0x01A4, r24 + 2512: 80 91 a8 01 lds r24, 0x01A8 + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + 2516: 69 e0 ldi r22, 0x09 ; 9 + 2518: 48 2f mov r20, r24 + 251a: 50 e0 ldi r21, 0x00 ; 0 + 251c: 64 9f mul r22, r20 + 251e: 90 01 movw r18, r0 + 2520: 65 9f mul r22, r21 + 2522: 30 0d add r19, r0 + 2524: 11 24 eor r1, r1 + 2526: f9 01 movw r30, r18 + 2528: e8 53 subi r30, 0x38 ; 56 + 252a: fe 4f sbci r31, 0xFE ; 254 + 252c: 90 81 ld r25, Z + 252e: 91 11 cpse r25, r1 + 2530: 0c c0 rjmp .+24 ; 0x254a + { + if( uxTopCoRoutineReadyPriority == 0 ) + 2532: 81 11 cpse r24, r1 + 2534: 08 c0 rjmp .+16 ; 0x2546 + 2536: 10 92 a8 01 sts 0x01A8, r1 + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} + 253a: df 91 pop r29 + 253c: cf 91 pop r28 + 253e: 1f 91 pop r17 + 2540: 0f 91 pop r16 + 2542: ff 90 pop r15 + 2544: 08 95 ret + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + 2546: 81 50 subi r24, 0x01 ; 1 + 2548: e7 cf rjmp .-50 ; 0x2518 + 254a: 80 93 a8 01 sts 0x01A8, r24 + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + 254e: a1 81 ldd r26, Z+1 ; 0x01 + 2550: b2 81 ldd r27, Z+2 ; 0x02 + 2552: 12 96 adiw r26, 0x02 ; 2 + 2554: 0d 90 ld r0, X+ + 2556: bc 91 ld r27, X + 2558: a0 2d mov r26, r0 + 255a: b2 83 std Z+2, r27 ; 0x02 + 255c: a1 83 std Z+1, r26 ; 0x01 + 255e: 25 53 subi r18, 0x35 ; 53 + 2560: 3e 4f sbci r19, 0xFE ; 254 + 2562: a2 17 cp r26, r18 + 2564: b3 07 cpc r27, r19 + 2566: 31 f4 brne .+12 ; 0x2574 + 2568: 12 96 adiw r26, 0x02 ; 2 + 256a: 8d 91 ld r24, X+ + 256c: 9c 91 ld r25, X + 256e: 13 97 sbiw r26, 0x03 ; 3 + 2570: 92 83 std Z+2, r25 ; 0x02 + 2572: 81 83 std Z+1, r24 ; 0x01 + 2574: 89 e0 ldi r24, 0x09 ; 9 + 2576: 84 9f mul r24, r20 + 2578: f0 01 movw r30, r0 + 257a: 85 9f mul r24, r21 + 257c: f0 0d add r31, r0 + 257e: 11 24 eor r1, r1 + 2580: e8 53 subi r30, 0x38 ; 56 + 2582: fe 4f sbci r31, 0xFE ; 254 + 2584: 01 80 ldd r0, Z+1 ; 0x01 + 2586: f2 81 ldd r31, Z+2 ; 0x02 + 2588: e0 2d mov r30, r0 + 258a: 86 81 ldd r24, Z+6 ; 0x06 + 258c: 97 81 ldd r25, Z+7 ; 0x07 + 258e: 90 93 a1 01 sts 0x01A1, r25 + 2592: 80 93 a0 01 sts 0x01A0, r24 + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + 2596: dc 01 movw r26, r24 + 2598: ed 91 ld r30, X+ + 259a: fc 91 ld r31, X + 259c: 11 97 sbiw r26, 0x01 ; 1 + 259e: 57 96 adiw r26, 0x17 ; 23 + 25a0: 6c 91 ld r22, X + + return; +} + 25a2: df 91 pop r29 + 25a4: cf 91 pop r28 + 25a6: 1f 91 pop r17 + 25a8: 0f 91 pop r16 + 25aa: ff 90 pop r15 + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + 25ac: 09 94 ijmp + +000025ae : + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) +{ + 25ae: 0f 93 push r16 + 25b0: 1f 93 push r17 + 25b2: cf 93 push r28 + 25b4: df 93 push r29 +corCRCB *pxUnblockedCRCB; +signed portBASE_TYPE xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. */ + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + 25b6: dc 01 movw r26, r24 + 25b8: 2c 91 ld r18, X + 25ba: 22 23 and r18, r18 + 25bc: 39 f0 breq .+14 ; 0x25cc + 25be: 15 96 adiw r26, 0x05 ; 5 + 25c0: ed 91 ld r30, X+ + 25c2: fc 91 ld r31, X + 25c4: 16 97 sbiw r26, 0x06 ; 6 + 25c6: c6 81 ldd r28, Z+6 ; 0x06 + 25c8: d7 81 ldd r29, Z+7 ; 0x07 + 25ca: 02 c0 rjmp .+4 ; 0x25d0 + 25cc: c0 e0 ldi r28, 0x00 ; 0 + 25ce: d0 e0 ldi r29, 0x00 ; 0 + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + 25d0: 8e 01 movw r16, r28 + 25d2: 04 5f subi r16, 0xF4 ; 244 + 25d4: 1f 4f sbci r17, 0xFF ; 255 + 25d6: c8 01 movw r24, r16 + 25d8: 0e 94 14 11 call 0x2228 ; 0x2228 + vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + 25dc: b8 01 movw r22, r16 + 25de: 89 ea ldi r24, 0xA9 ; 169 + 25e0: 91 e0 ldi r25, 0x01 ; 1 + 25e2: 0e 94 ba 10 call 0x2174 ; 0x2174 + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + 25e6: e0 91 a0 01 lds r30, 0x01A0 + 25ea: f0 91 a1 01 lds r31, 0x01A1 + 25ee: 81 e0 ldi r24, 0x01 ; 1 + 25f0: 2e 89 ldd r18, Y+22 ; 0x16 + 25f2: 96 89 ldd r25, Z+22 ; 0x16 + 25f4: 29 17 cp r18, r25 + 25f6: 08 f4 brcc .+2 ; 0x25fa + 25f8: 80 e0 ldi r24, 0x00 ; 0 + { + xReturn = pdFALSE; + } + + return xReturn; +} + 25fa: df 91 pop r29 + 25fc: cf 91 pop r28 + 25fe: 1f 91 pop r17 + 2600: 0f 91 pop r16 + 2602: 08 95 ret + +00002604 : + +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ + 2604: 0f 93 push r16 + 2606: 1f 93 push r17 + 2608: cf 93 push r28 + 260a: df 93 push r29 + 260c: 8c 01 movw r16, r24 + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + #endif + + vTaskSuspendAll(); + 260e: 0e 94 de 0a call 0x15bc ; 0x15bc + { + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) && + 2612: c0 91 d1 01 lds r28, 0x01D1 + 2616: d0 91 d2 01 lds r29, 0x01D2 + 261a: c8 01 movw r24, r16 + 261c: 8c 0f add r24, r28 + 261e: 9d 1f adc r25, r29 + 2620: 8e 3e cpi r24, 0xEE ; 238 + 2622: 22 e0 ldi r18, 0x02 ; 2 + 2624: 92 07 cpc r25, r18 + 2626: 50 f4 brcc .+20 ; 0x263c + 2628: c8 17 cp r28, r24 + 262a: d9 07 cpc r29, r25 + 262c: 38 f4 brcc .+14 ; 0x263c + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + 262e: cd 52 subi r28, 0x2D ; 45 + 2630: de 4f sbci r29, 0xFE ; 254 + xNextFreeByte += xWantedSize; + 2632: 90 93 d2 01 sts 0x01D2, r25 + 2636: 80 93 d1 01 sts 0x01D1, r24 + 263a: 02 c0 rjmp .+4 ; 0x2640 +static size_t xNextFreeByte = ( size_t ) 0; +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; + 263c: c0 e0 ldi r28, 0x00 ; 0 + 263e: d0 e0 ldi r29, 0x00 ; 0 + block. */ + pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); + xNextFreeByte += xWantedSize; + } + } + xTaskResumeAll(); + 2640: 0e 94 64 0b call 0x16c8 ; 0x16c8 + } + } + #endif + + return pvReturn; +} + 2644: ce 01 movw r24, r28 + 2646: df 91 pop r29 + 2648: cf 91 pop r28 + 264a: 1f 91 pop r17 + 264c: 0f 91 pop r16 + 264e: 08 95 ret + +00002650 : +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + 2650: 08 95 ret + +00002652 : +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; + 2652: 10 92 d2 01 sts 0x01D2, r1 + 2656: 10 92 d1 01 sts 0x01D1, r1 + 265a: 08 95 ret + +0000265c : +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configTOTAL_HEAP_SIZE - xNextFreeByte ); + 265c: 20 91 d1 01 lds r18, 0x01D1 + 2660: 30 91 d2 01 lds r19, 0x01D2 +} + 2664: 8e ee ldi r24, 0xEE ; 238 + 2666: 92 e0 ldi r25, 0x02 ; 2 + 2668: 82 1b sub r24, r18 + 266a: 93 0b sbc r25, r19 + 266c: 08 95 ret + +0000266e : +unsigned portSHORT usAddress; + + /* Place a few bytes of known values on the bottom of the stack. + This is just useful for debugging. */ + + *pxTopOfStack = 0x11; + 266e: 31 e1 ldi r19, 0x11 ; 17 + 2670: fc 01 movw r30, r24 + 2672: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = 0x22; + 2674: 31 97 sbiw r30, 0x01 ; 1 + 2676: 22 e2 ldi r18, 0x22 ; 34 + 2678: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = 0x33; + 267a: 31 97 sbiw r30, 0x01 ; 1 + 267c: a3 e3 ldi r26, 0x33 ; 51 + 267e: a0 83 st Z, r26 + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* The start of the task code will be popped off the stack last, so place + it on first. */ + usAddress = ( unsigned portSHORT ) pxCode; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 2680: 31 97 sbiw r30, 0x01 ; 1 + 2682: 60 83 st Z, r22 + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 2684: 31 97 sbiw r30, 0x01 ; 1 + 2686: 70 83 st Z, r23 + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + portSAVE_CONTEXT places the flags on the stack immediately after r0 + to ensure the interrupts get disabled as soon as possible, and so ensuring + the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */ + 2688: 31 97 sbiw r30, 0x01 ; 1 + 268a: 10 82 st Z, r1 + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + 268c: 31 97 sbiw r30, 0x01 ; 1 + 268e: 60 e8 ldi r22, 0x80 ; 128 + 2690: 60 83 st Z, r22 + pxTopOfStack--; + + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */ + 2692: 31 97 sbiw r30, 0x01 ; 1 + 2694: 10 82 st Z, r1 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */ + 2696: 31 97 sbiw r30, 0x01 ; 1 + 2698: 62 e0 ldi r22, 0x02 ; 2 + 269a: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */ + 269c: 31 97 sbiw r30, 0x01 ; 1 + 269e: 63 e0 ldi r22, 0x03 ; 3 + 26a0: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */ + 26a2: 31 97 sbiw r30, 0x01 ; 1 + 26a4: 64 e0 ldi r22, 0x04 ; 4 + 26a6: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */ + 26a8: 31 97 sbiw r30, 0x01 ; 1 + 26aa: 65 e0 ldi r22, 0x05 ; 5 + 26ac: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */ + 26ae: 31 97 sbiw r30, 0x01 ; 1 + 26b0: 66 e0 ldi r22, 0x06 ; 6 + 26b2: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */ + 26b4: 31 97 sbiw r30, 0x01 ; 1 + 26b6: 67 e0 ldi r22, 0x07 ; 7 + 26b8: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */ + 26ba: 31 97 sbiw r30, 0x01 ; 1 + 26bc: 68 e0 ldi r22, 0x08 ; 8 + 26be: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */ + 26c0: 31 97 sbiw r30, 0x01 ; 1 + 26c2: 69 e0 ldi r22, 0x09 ; 9 + 26c4: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */ + 26c6: 31 97 sbiw r30, 0x01 ; 1 + 26c8: 60 e1 ldi r22, 0x10 ; 16 + 26ca: 60 83 st Z, r22 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */ + 26cc: 31 97 sbiw r30, 0x01 ; 1 + 26ce: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */ + 26d0: 31 97 sbiw r30, 0x01 ; 1 + 26d2: 32 e1 ldi r19, 0x12 ; 18 + 26d4: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */ + 26d6: 31 97 sbiw r30, 0x01 ; 1 + 26d8: 33 e1 ldi r19, 0x13 ; 19 + 26da: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */ + 26dc: 31 97 sbiw r30, 0x01 ; 1 + 26de: 34 e1 ldi r19, 0x14 ; 20 + 26e0: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */ + 26e2: 31 97 sbiw r30, 0x01 ; 1 + 26e4: 35 e1 ldi r19, 0x15 ; 21 + 26e6: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */ + 26e8: 31 97 sbiw r30, 0x01 ; 1 + 26ea: 36 e1 ldi r19, 0x16 ; 22 + 26ec: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */ + 26ee: 31 97 sbiw r30, 0x01 ; 1 + 26f0: 37 e1 ldi r19, 0x17 ; 23 + 26f2: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */ + 26f4: 31 97 sbiw r30, 0x01 ; 1 + 26f6: 38 e1 ldi r19, 0x18 ; 24 + 26f8: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */ + 26fa: 31 97 sbiw r30, 0x01 ; 1 + 26fc: 39 e1 ldi r19, 0x19 ; 25 + 26fe: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */ + 2700: 31 97 sbiw r30, 0x01 ; 1 + 2702: 30 e2 ldi r19, 0x20 ; 32 + 2704: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */ + 2706: 31 97 sbiw r30, 0x01 ; 1 + 2708: 31 e2 ldi r19, 0x21 ; 33 + 270a: 30 83 st Z, r19 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */ + 270c: 31 97 sbiw r30, 0x01 ; 1 + 270e: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */ + 2710: 31 97 sbiw r30, 0x01 ; 1 + 2712: 23 e2 ldi r18, 0x23 ; 35 + 2714: 20 83 st Z, r18 + pxTopOfStack--; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( unsigned portSHORT ) pvParameters; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 2716: 31 97 sbiw r30, 0x01 ; 1 + 2718: 40 83 st Z, r20 + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); + 271a: 31 97 sbiw r30, 0x01 ; 1 + 271c: 50 83 st Z, r21 + pxTopOfStack--; + + *pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */ + 271e: 31 97 sbiw r30, 0x01 ; 1 + 2720: 26 e2 ldi r18, 0x26 ; 38 + 2722: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */ + 2724: 31 97 sbiw r30, 0x01 ; 1 + 2726: 27 e2 ldi r18, 0x27 ; 39 + 2728: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */ + 272a: 31 97 sbiw r30, 0x01 ; 1 + 272c: 28 e2 ldi r18, 0x28 ; 40 + 272e: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */ + 2730: 31 97 sbiw r30, 0x01 ; 1 + 2732: 29 e2 ldi r18, 0x29 ; 41 + 2734: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */ + 2736: 31 97 sbiw r30, 0x01 ; 1 + 2738: 20 e3 ldi r18, 0x30 ; 48 + 273a: 20 83 st Z, r18 + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */ + 273c: 31 97 sbiw r30, 0x01 ; 1 + 273e: 21 e3 ldi r18, 0x31 ; 49 + 2740: 20 83 st Z, r18 + pxTopOfStack--; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} + 2742: 86 97 sbiw r24, 0x26 ; 38 + 2744: 08 95 ret + +00002746 : + /* Setup compare match value for compare match A. Interrupts are disabled + before this is called so we need not worry here. */ + ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + ulCompareMatch >>= 8; + ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff ); + OCR1AH = ucHighByte; + 2746: 88 e0 ldi r24, 0x08 ; 8 + 2748: 80 93 89 00 sts 0x0089, r24 + OCR1AL = ucLowByte; + 274c: 8f ef ldi r24, 0xFF ; 255 + 274e: 80 93 88 00 sts 0x0088, r24 + + /* Setup clock source and compare match behaviour. */ + ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64; + TCCR1B = ucLowByte; + 2752: 8b e0 ldi r24, 0x0B ; 11 + 2754: 80 93 81 00 sts 0x0081, r24 + + /* Enable the interrupt - this is okay as interrupt are currently globally + disabled. */ + ucLowByte = TIMSK1; + 2758: ef e6 ldi r30, 0x6F ; 111 + 275a: f0 e0 ldi r31, 0x00 ; 0 + 275c: 80 81 ld r24, Z + ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE; + 275e: 82 60 ori r24, 0x02 ; 2 + TIMSK1 = ucLowByte; + 2760: 80 83 st Z, r24 +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + 2762: a0 91 47 01 lds r26, 0x0147 + 2766: b0 91 48 01 lds r27, 0x0148 + 276a: cd 91 ld r28, X+ + 276c: cd bf out 0x3d, r28 ; 61 + 276e: dd 91 ld r29, X+ + 2770: de bf out 0x3e, r29 ; 62 + 2772: ff 91 pop r31 + 2774: ef 91 pop r30 + 2776: df 91 pop r29 + 2778: cf 91 pop r28 + 277a: bf 91 pop r27 + 277c: af 91 pop r26 + 277e: 9f 91 pop r25 + 2780: 8f 91 pop r24 + 2782: 7f 91 pop r23 + 2784: 6f 91 pop r22 + 2786: 5f 91 pop r21 + 2788: 4f 91 pop r20 + 278a: 3f 91 pop r19 + 278c: 2f 91 pop r18 + 278e: 1f 91 pop r17 + 2790: 0f 91 pop r16 + 2792: ff 90 pop r15 + 2794: ef 90 pop r14 + 2796: df 90 pop r13 + 2798: cf 90 pop r12 + 279a: bf 90 pop r11 + 279c: af 90 pop r10 + 279e: 9f 90 pop r9 + 27a0: 8f 90 pop r8 + 27a2: 7f 90 pop r7 + 27a4: 6f 90 pop r6 + 27a6: 5f 90 pop r5 + 27a8: 4f 90 pop r4 + 27aa: 3f 90 pop r3 + 27ac: 2f 90 pop r2 + 27ae: 1f 90 pop r1 + 27b0: 0f 90 pop r0 + 27b2: 0f be out 0x3f, r0 ; 63 + 27b4: 0f 90 pop r0 + + /* Simulate a function call end as generated by the compiler. We will now + jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + 27b6: 08 95 ret + + /* Should not get here. */ + return pdTRUE; +} + 27b8: 81 e0 ldi r24, 0x01 ; 1 + 27ba: 08 95 ret + +000027bc : +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + 27bc: 08 95 ret + +000027be : + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__ ( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + 27be: 0f 92 push r0 + 27c0: 0f b6 in r0, 0x3f ; 63 + 27c2: f8 94 cli + 27c4: 0f 92 push r0 + 27c6: 1f 92 push r1 + 27c8: 11 24 eor r1, r1 + 27ca: 2f 92 push r2 + 27cc: 3f 92 push r3 + 27ce: 4f 92 push r4 + 27d0: 5f 92 push r5 + 27d2: 6f 92 push r6 + 27d4: 7f 92 push r7 + 27d6: 8f 92 push r8 + 27d8: 9f 92 push r9 + 27da: af 92 push r10 + 27dc: bf 92 push r11 + 27de: cf 92 push r12 + 27e0: df 92 push r13 + 27e2: ef 92 push r14 + 27e4: ff 92 push r15 + 27e6: 0f 93 push r16 + 27e8: 1f 93 push r17 + 27ea: 2f 93 push r18 + 27ec: 3f 93 push r19 + 27ee: 4f 93 push r20 + 27f0: 5f 93 push r21 + 27f2: 6f 93 push r22 + 27f4: 7f 93 push r23 + 27f6: 8f 93 push r24 + 27f8: 9f 93 push r25 + 27fa: af 93 push r26 + 27fc: bf 93 push r27 + 27fe: cf 93 push r28 + 2800: df 93 push r29 + 2802: ef 93 push r30 + 2804: ff 93 push r31 + 2806: a0 91 47 01 lds r26, 0x0147 + 280a: b0 91 48 01 lds r27, 0x0148 + 280e: 0d b6 in r0, 0x3d ; 61 + 2810: 0d 92 st X+, r0 + 2812: 0e b6 in r0, 0x3e ; 62 + 2814: 0d 92 st X+, r0 + vTaskSwitchContext(); + 2816: 0e 94 d6 0b call 0x17ac ; 0x17ac + portRESTORE_CONTEXT(); + 281a: a0 91 47 01 lds r26, 0x0147 + 281e: b0 91 48 01 lds r27, 0x0148 + 2822: cd 91 ld r28, X+ + 2824: cd bf out 0x3d, r28 ; 61 + 2826: dd 91 ld r29, X+ + 2828: de bf out 0x3e, r29 ; 62 + 282a: ff 91 pop r31 + 282c: ef 91 pop r30 + 282e: df 91 pop r29 + 2830: cf 91 pop r28 + 2832: bf 91 pop r27 + 2834: af 91 pop r26 + 2836: 9f 91 pop r25 + 2838: 8f 91 pop r24 + 283a: 7f 91 pop r23 + 283c: 6f 91 pop r22 + 283e: 5f 91 pop r21 + 2840: 4f 91 pop r20 + 2842: 3f 91 pop r19 + 2844: 2f 91 pop r18 + 2846: 1f 91 pop r17 + 2848: 0f 91 pop r16 + 284a: ff 90 pop r15 + 284c: ef 90 pop r14 + 284e: df 90 pop r13 + 2850: cf 90 pop r12 + 2852: bf 90 pop r11 + 2854: af 90 pop r10 + 2856: 9f 90 pop r9 + 2858: 8f 90 pop r8 + 285a: 7f 90 pop r7 + 285c: 6f 90 pop r6 + 285e: 5f 90 pop r5 + 2860: 4f 90 pop r4 + 2862: 3f 90 pop r3 + 2864: 2f 90 pop r2 + 2866: 1f 90 pop r1 + 2868: 0f 90 pop r0 + 286a: 0f be out 0x3f, r0 ; 63 + 286c: 0f 90 pop r0 + + asm volatile ( "ret" ); + 286e: 08 95 ret + +00002870 : + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + 2870: 0f 92 push r0 + 2872: 0f b6 in r0, 0x3f ; 63 + 2874: f8 94 cli + 2876: 0f 92 push r0 + 2878: 1f 92 push r1 + 287a: 11 24 eor r1, r1 + 287c: 2f 92 push r2 + 287e: 3f 92 push r3 + 2880: 4f 92 push r4 + 2882: 5f 92 push r5 + 2884: 6f 92 push r6 + 2886: 7f 92 push r7 + 2888: 8f 92 push r8 + 288a: 9f 92 push r9 + 288c: af 92 push r10 + 288e: bf 92 push r11 + 2890: cf 92 push r12 + 2892: df 92 push r13 + 2894: ef 92 push r14 + 2896: ff 92 push r15 + 2898: 0f 93 push r16 + 289a: 1f 93 push r17 + 289c: 2f 93 push r18 + 289e: 3f 93 push r19 + 28a0: 4f 93 push r20 + 28a2: 5f 93 push r21 + 28a4: 6f 93 push r22 + 28a6: 7f 93 push r23 + 28a8: 8f 93 push r24 + 28aa: 9f 93 push r25 + 28ac: af 93 push r26 + 28ae: bf 93 push r27 + 28b0: cf 93 push r28 + 28b2: df 93 push r29 + 28b4: ef 93 push r30 + 28b6: ff 93 push r31 + 28b8: a0 91 47 01 lds r26, 0x0147 + 28bc: b0 91 48 01 lds r27, 0x0148 + 28c0: 0d b6 in r0, 0x3d ; 61 + 28c2: 0d 92 st X+, r0 + 28c4: 0e b6 in r0, 0x3e ; 62 + 28c6: 0d 92 st X+, r0 + vTaskIncrementTick(); + 28c8: 0e 94 f1 0a call 0x15e2 ; 0x15e2 + vTaskSwitchContext(); + 28cc: 0e 94 d6 0b call 0x17ac ; 0x17ac + portRESTORE_CONTEXT(); + 28d0: a0 91 47 01 lds r26, 0x0147 + 28d4: b0 91 48 01 lds r27, 0x0148 + 28d8: cd 91 ld r28, X+ + 28da: cd bf out 0x3d, r28 ; 61 + 28dc: dd 91 ld r29, X+ + 28de: de bf out 0x3e, r29 ; 62 + 28e0: ff 91 pop r31 + 28e2: ef 91 pop r30 + 28e4: df 91 pop r29 + 28e6: cf 91 pop r28 + 28e8: bf 91 pop r27 + 28ea: af 91 pop r26 + 28ec: 9f 91 pop r25 + 28ee: 8f 91 pop r24 + 28f0: 7f 91 pop r23 + 28f2: 6f 91 pop r22 + 28f4: 5f 91 pop r21 + 28f6: 4f 91 pop r20 + 28f8: 3f 91 pop r19 + 28fa: 2f 91 pop r18 + 28fc: 1f 91 pop r17 + 28fe: 0f 91 pop r16 + 2900: ff 90 pop r15 + 2902: ef 90 pop r14 + 2904: df 90 pop r13 + 2906: cf 90 pop r12 + 2908: bf 90 pop r11 + 290a: af 90 pop r10 + 290c: 9f 90 pop r9 + 290e: 8f 90 pop r8 + 2910: 7f 90 pop r7 + 2912: 6f 90 pop r6 + 2914: 5f 90 pop r5 + 2916: 4f 90 pop r4 + 2918: 3f 90 pop r3 + 291a: 2f 90 pop r2 + 291c: 1f 90 pop r1 + 291e: 0f 90 pop r0 + 2920: 0f be out 0x3f, r0 ; 63 + 2922: 0f 90 pop r0 + + asm volatile ( "ret" ); + 2924: 08 95 ret + +00002926 <__vector_11>: + 2926: 0e 94 38 14 call 0x2870 ; 0x2870 + 292a: 18 95 reti + +0000292c
: +extern xQueueHandle xCharsForTx; + +xQueueHandle xRoleta[2]; + +portSHORT main( void ) +{ + 292c: cf 93 push r28 + 292e: df 93 push r29 +//prvIncrementResetCount(); + + hardwareInit(); + 2930: 0e 94 3e 08 call 0x107c ; 0x107c + xSerialPortInitMinimal(16); + 2934: 80 e1 ldi r24, 0x10 ; 16 + 2936: 0e 94 7c 07 call 0xef8 ; 0xef8 + + xRoleta[0] = xQueueCreate(4, 1); + 293a: 61 e0 ldi r22, 0x01 ; 1 + 293c: 84 e0 ldi r24, 0x04 ; 4 + 293e: 0e 94 8e 0d call 0x1b1c ; 0x1b1c + 2942: c2 ec ldi r28, 0xC2 ; 194 + 2944: d4 e0 ldi r29, 0x04 ; 4 + 2946: 99 83 std Y+1, r25 ; 0x01 + 2948: 88 83 st Y, r24 + xRoleta[1] = xQueueCreate(4, 1); + 294a: 61 e0 ldi r22, 0x01 ; 1 + 294c: 84 e0 ldi r24, 0x04 ; 4 + 294e: 0e 94 8e 0d call 0x1b1c ; 0x1b1c + 2952: 9b 83 std Y+3, r25 ; 0x03 + 2954: 8a 83 std Y+2, r24 ; 0x02 + + xCoRoutineCreate(vProtocol, 0, 0); + 2956: 40 e0 ldi r20, 0x00 ; 0 + 2958: 60 e0 ldi r22, 0x00 ; 0 + 295a: 8c ea ldi r24, 0xAC ; 172 + 295c: 91 e0 ldi r25, 0x01 ; 1 + 295e: 0e 94 38 11 call 0x2270 ; 0x2270 + xCoRoutineCreate(vKlawisze, 0, 0); + 2962: 40 e0 ldi r20, 0x00 ; 0 + 2964: 60 e0 ldi r22, 0x00 ; 0 + 2966: 8a ee ldi r24, 0xEA ; 234 + 2968: 90 e0 ldi r25, 0x00 ; 0 + 296a: 0e 94 38 11 call 0x2270 ; 0x2270 + xCoRoutineCreate(vRoleta, 0, 0); + 296e: 40 e0 ldi r20, 0x00 ; 0 + 2970: 60 e0 ldi r22, 0x00 ; 0 + 2972: 83 e5 ldi r24, 0x53 ; 83 + 2974: 90 e0 ldi r25, 0x00 ; 0 + 2976: 0e 94 38 11 call 0x2270 ; 0x2270 + xCoRoutineCreate(vRoleta, 0, 1); + 297a: 41 e0 ldi r20, 0x01 ; 1 + 297c: 60 e0 ldi r22, 0x00 ; 0 + 297e: 83 e5 ldi r24, 0x53 ; 83 + 2980: 90 e0 ldi r25, 0x00 ; 0 + 2982: 0e 94 38 11 call 0x2270 ; 0x2270 + + vTaskStartScheduler(); + 2986: 0e 94 a7 0a call 0x154e ; 0x154e + return 0; +} + 298a: 80 e0 ldi r24, 0x00 ; 0 + 298c: 90 e0 ldi r25, 0x00 ; 0 + 298e: df 91 pop r29 + 2990: cf 91 pop r28 + 2992: 08 95 ret + +00002994 : + 2994: fb 01 movw r30, r22 + 2996: dc 01 movw r26, r24 + 2998: 02 c0 rjmp .+4 ; 0x299e + 299a: 01 90 ld r0, Z+ + 299c: 0d 92 st X+, r0 + 299e: 41 50 subi r20, 0x01 ; 1 + 29a0: 50 40 sbci r21, 0x00 ; 0 + 29a2: d8 f7 brcc .-10 ; 0x299a + 29a4: 08 95 ret + +000029a6 : + 29a6: dc 01 movw r26, r24 + 29a8: 01 c0 rjmp .+2 ; 0x29ac + 29aa: 6d 93 st X+, r22 + 29ac: 41 50 subi r20, 0x01 ; 1 + 29ae: 50 40 sbci r21, 0x00 ; 0 + 29b0: e0 f7 brcc .-8 ; 0x29aa + 29b2: 08 95 ret + +000029b4 <_exit>: + 29b4: f8 94 cli + +000029b6 <__stop_program>: + 29b6: ff cf rjmp .-2 ; 0x29b6 <__stop_program> diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.sym b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.sym new file mode 100644 index 0000000..826d666 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/firmware.sym @@ -0,0 +1,246 @@ +00000000 W __heap_end +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 W __vector_default +00000000 T __vectors +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +00000068 T __ctors_end +00000068 T __ctors_start +00000068 T __dtors_end +00000068 T __dtors_start +00000068 W __init +00000068 T __trampolines_end +00000068 T __trampolines_start +00000074 T __do_copy_data +0000008a T __do_clear_bss +00000092 t .do_clear_bss_loop +00000094 t .do_clear_bss_start +000000a2 T __bad_interrupt +000000a2 W __vector_1 +000000a2 W __vector_10 +000000a2 W __vector_12 +000000a2 W __vector_13 +000000a2 W __vector_14 +000000a2 W __vector_15 +000000a2 W __vector_16 +000000a2 W __vector_17 +000000a2 W __vector_2 +000000a2 W __vector_21 +000000a2 W __vector_22 +000000a2 W __vector_23 +000000a2 W __vector_24 +000000a2 W __vector_25 +000000a2 W __vector_3 +000000a2 W __vector_4 +000000a2 W __vector_5 +000000a2 W __vector_6 +000000a2 W __vector_7 +000000a2 W __vector_8 +000000a2 W __vector_9 +000000a6 t vRoleta +000001d4 t vKlawisze +0000031e T vApplicationIdleHook +00000324 t _crc_xmodem_update +00000358 T vProtocol +000004ff W __stack +00000ef8 T xSerialPortInitMinimal +00000f60 T __vector_18 +00000fce T __vector_19 +00001052 T __vector_20 +0000107c T hardwareInit +000010aa T roleta1wGore +000010b0 T roleta1wDol +000010b6 T roleta1Stop +000010be T roleta2wGore +000010c4 T roletawGore +000010d0 T roleta2wDol +000010d6 T roletawDol +000010e2 T roleta2Stop +000010e8 T roletaStop +000010f4 T Led1On +000010f8 T Led1Toggle +00001102 T Led1Off +00001106 T Led2On +0000110a T Led2Toggle +00001114 T Led2Off +00001118 T czytKlawiszRol1wGore +0000111e T czytKlawiszRol1wDol +00001124 T czytKlawiszRol2wGore +0000112a T czytKlawiszRol2wDol +00001130 T automatStanowKlawiszy +000011ea t prvIdleTask +000011f0 T xTaskGenericCreate +000013ba T vTaskSuspend +00001434 T xTaskIsTaskSuspended +00001458 T vTaskResume +000014d0 T xTaskResumeFromISR +0000154e T vTaskStartScheduler +000015b2 T vTaskEndScheduler +000015bc T vTaskSuspendAll +000015c8 T xTaskGetTickCount +000015dc T uxTaskGetNumberOfTasks +000015e2 T vTaskIncrementTick +000016c8 T xTaskResumeAll +000017ac T vTaskSwitchContext +00001840 T vTaskPlaceOnEventList +000018dc T xTaskRemoveFromEventList +00001962 T vTaskSetTimeOutState +00001978 T xTaskCheckForTimeOut +000019e4 T vTaskMissedYield +000019ec t prvCopyDataToQueue +00001a6c t prvCopyDataFromQueue +00001aa0 t prvUnlockQueue +00001b1c T xQueueCreate +00001bb2 T xQueueCreateExternal +00001c36 T xQueueGenericSend +00001d5e T xQueueGenericSendFromISR +00001dae T xQueueGenericReceive +00001ef6 T xQueueReceiveFromISR +00001f48 T uxQueueMessagesWaiting +00001f58 T uxQueueMessagesWaitingFromISR +00001f5e T vQueueDelete +00001f76 T xQueueIsQueueEmptyFromISR +00001f82 T xQueueIsQueueFullFromISR +00001f90 T xQueueCRSend +00002000 T xQueueCRReceive +00002090 T xQueueCRSendFromISR +000020d6 T xQueueCRReceiveFromISR +00002150 T vListInitialise +0000216c T vListInitialiseItem +00002174 T vListInsertEnd +000021ba T vListInsert +00002228 T vListRemove +00002270 T xCoRoutineCreate +0000233e T vCoRoutineAddToDelayedList +000023c2 T vCoRoutineSchedule +000025ae T xCoRoutineRemoveFromEventList +00002604 T pvPortMalloc +00002650 T vPortFree +00002652 T vPortInitialiseBlocks +0000265c T xPortGetFreeHeapSize +0000266e T pxPortInitialiseStack +00002746 T xPortStartScheduler +000027bc T vPortEndScheduler +000027be T vPortYield +00002870 T vPortYieldFromTick +00002926 T __vector_11 +0000292c T main +00002994 T memcpy +000029a6 T memset +000029b4 W exit +000029b4 T _exit +000029b6 t __stop_program +000029b8 A __data_load_start +000029b8 T _etext +000029ca A __data_load_end +00800100 D bHelloResp +00800100 D __data_start +00800112 B __bss_start +00800112 D __data_end +00800112 D _edata +00800112 B roleta2 +00800117 B roleta1 +0080011c b xResult.2181 +0080011d b xResult.2196 +0080011f b rozkaz.2194 +00800121 b czasAkcji.2195 +00800125 b rezultat.2192 +00800126 b lOdebrDanych.2191 +00800127 b dobryAdres.2190 +00800128 b xResult.2189 +00800129 b znak.2188 +0080012a b stan.2187 +0080012b b crc +0080012d b crcHi +0080012e b crcLo +0080012f b xHigherPriorityTaskWoken +00800130 b xSemaphore +00800132 b wiadomosc +00800133 b bDane +00800141 b dlDanych +00800142 b kodRozkazu +00800143 b xCharsForTx +00800145 b xRxedChars +00800147 B pxCurrentTCB +00800149 b uxTaskNumber +0080014a b xNumOfOverflows +0080014b b xMissedYield +0080014c b uxMissedTicks +0080014d b uxSchedulerSuspended +0080014e b xSchedulerRunning +0080014f b uxTopReadyPriority +00800150 b uxTopUsedPriority +00800151 b xTickCount +00800153 b uxCurrentNumberOfTasks +00800154 b xSuspendedTaskList +0080015d b xPendingReadyList +00800166 b pxOverflowDelayedTaskList +00800168 b pxDelayedTaskList +0080016a b xDelayedTaskList2 +00800173 b xDelayedTaskList1 +0080017c b pxReadyTasksLists +008001a0 B pxCurrentCoRoutine +008001a2 b xPassedTicks +008001a4 b xLastTickCount +008001a6 b xCoRoutineTickCount +008001a8 b uxTopCoRoutineReadyPriority +008001a9 b xPendingReadyCoRoutineList +008001b2 b pxOverflowDelayedCoRoutineList +008001b4 b pxDelayedCoRoutineList +008001b6 b xDelayedCoRoutineList2 +008001bf b xDelayedCoRoutineList1 +008001c8 b pxReadyCoRoutineLists +008001d1 b xNextFreeByte +008001d3 b xHeap +008004c1 B adres +008004c2 B xRoleta +008004c6 B __bss_end +008004c6 N _end +00810000 N __eeprom_end diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.sh b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.sh new file mode 100755 index 0000000..f40b1d2 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.sh @@ -0,0 +1,16 @@ +#!/usr/bin/expect -f + +set dev "/dev/rs485tty" +set file "./rtosdemo.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" +send "bootaa" +expect "C" +send_user "Starting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.txt b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.txt new file mode 100644 index 0000000..876fc37 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/flash.txt @@ -0,0 +1,16 @@ +#!/usr/bin/expect -f + +set dev "/dev/rs485tty" +set file "./rtosdemo.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" +send "boot\0x1F\0xE0" +expect "C" +send_user "Starting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.c b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.c new file mode 100644 index 0000000..a948d54 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.c @@ -0,0 +1,127 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - P3 , 1 - P2 , 2 - P1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - KlRolety1Up, 3 - klRolety1Down + PORTC = 0x3F; //4 - KlRolety2Up, 5 - KlRolety2Down + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - Led1, 6 - Led2, 7 - P4) + /*Ustalanie adresu + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = (PINB & 0x38) >> 1; + adres |= (PINC & 0x03); +} + +void roletawGore(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wGore(); + else + roleta2wGore(); +} + +void roletawDol(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wDol(); + else + roleta2wDol(); +} + +void roletaStop(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1Stop(); + else + roleta2Stop(); +} + +inline void roleta1wGore(void) +{ + PORTB &= ~0x02; + PORTB |= 0x04; +} + +inline void roleta1wDol(void) +{ + PORTB &= ~0x04; + PORTB |= 0x02; +} + +inline void roleta1Stop(void) +{ + PORTB &= ~0x06; +} + +inline void roleta2wGore(void) +{ + PORTD &= ~0x80; + PORTB |= 0x01; +} + +inline void roleta2wDol(void) +{ + PORTB &= ~0x01; + PORTD |= 0x80; +} + +inline void roleta2Stop(void) +{ + PORTB &= ~0x01; + PORTD &= ~0x80; +} + +inline void Led1On(void) +{ + PORTD |= 0x20; +} + +inline void Led1Toggle(void) +{ + PORTD ^= 0x20; +} + +inline void Led1Off(void) +{ + PORTD &= ~0x20; +} + +inline void Led2On(void) +{ + PORTD |= 0x40; +} + +inline void Led2Toggle(void) +{ + PORTD ^= 0x40; +} + +inline void Led2Off(void) +{ + PORTD &= ~0x40; +} + +inline char czytKlawiszRol1wGore(void) +{ + return PINC & 0x04; +} + +inline char czytKlawiszRol1wDol(void) +{ + return PINC & 0x08; +} + +inline char czytKlawiszRol2wGore(void) +{ + return PINC & 0x10; +} + +inline char czytKlawiszRol2wDol(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.h b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.h new file mode 100644 index 0000000..0540a4c --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.h @@ -0,0 +1,102 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" +#include "../../Lib/include/protocol1.h" + +#define TxStart() (PORTD |= 0x0C) +#define TxStop() (PORTD &= 0xF3) + +extern uint8_t adres; +extern char bHelloResp[]; + +/** + * Inicjalizacja sprzętu + */ +void hardwareInit(void); + +void roletawGore(uint8_t nrRolety); +void roletaStop(uint8_t nrRolety); +void roletawDol(uint8_t nrRolety); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 1 + */ +void roleta1wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 1 + */ +void roleta1wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 1 + */ +void roleta1Stop(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 2 + */ +void roleta2wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 2 + */ +void roleta2wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 2 + */ +void roleta2Stop(void); + +/** + * Zapalenie diody kontrolej 1 + */ +void Led1On(void); + +/** + * Zmiana stanu diody kontrolej 1 + */ +void Led1Toggle(void); + +/** + * Gaszenie diody kontrolej 1 + */ +void Led1Off(void); + +/** + * Zapalenie diody kontrolej 2 + */ +void Led2On(void); + +/** + * Zmiana stanu diody kontrolej 2 + */ +void Led2Toggle(void); + +/** + * Gaszenie diody kontrolej 2 + */ +void Led2Off(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 1 + */ +char czytKlawiszRol1wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 1 + */ +char czytKlawiszRol1wDol(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 2 + */ +char czytKlawiszRol2wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 2 + */ +char czytKlawiszRol2wDol(void); +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.lst b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.lst new file mode 100644 index 0000000..9794aaf --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/hardware.lst @@ -0,0 +1,525 @@ + 1 .file "hardware.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 168 .global hardwareInit + 170 hardwareInit: + 171 .stabd 46,0,0 + 1:hardware.c **** #include "hardware.h" + 2:hardware.c **** + 3:hardware.c **** + 4:hardware.c **** void hardwareInit(void) + 5:hardware.c **** { + 173 .LM0: + 174 .LFBB1: + 175 /* prologue: function */ + 176 /* frame size = 0 */ + 177 /* stack size = 0 */ + 178 .L__stack_usage = 0 + 6:hardware.c **** DDRB = 0x07; //0 - P3 , 1 - P2 , 2 - P1 + 180 .LM1: + 181 0000 87E0 ldi r24,lo8(7) + 182 0002 84B9 out 0x4,r24 + 7:hardware.c **** PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + 184 .LM2: + 185 0004 88E3 ldi r24,lo8(56) + 186 0006 85B9 out 0x5,r24 + 8:hardware.c **** DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - KlRolety1Up, 3 - klRolety1Down + 188 .LM3: + 189 0008 17B8 out 0x7,__zero_reg__ + 9:hardware.c **** PORTC = 0x3F; //4 - KlRolety2Up, 5 - KlRolety2Down + 191 .LM4: + 192 000a 8FE3 ldi r24,lo8(63) + 193 000c 88B9 out 0x8,r24 + 10:hardware.c **** DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + 195 .LM5: + 196 000e 8EEE ldi r24,lo8(-18) + 197 0010 8AB9 out 0xa,r24 + 11:hardware.c **** PORTD = 0x00; //5 - Led1, 6 - Led2, 7 - P4) + 199 .LM6: + 200 0012 1BB8 out 0xb,__zero_reg__ + 12:hardware.c **** /*Ustalanie adresu + 13:hardware.c **** bit 7, 6 = 0 dla sterowników rolet i światła + 14:hardware.c **** */ + 15:hardware.c **** adres = (PINB & 0x38) >> 1; + 202 .LM7: + 203 0014 83B1 in r24,0x3 + 204 0016 8873 andi r24,lo8(56) + 205 0018 90E0 ldi r25,0 + 206 001a 9595 asr r25 + 207 001c 8795 ror r24 + 208 001e 8093 0000 sts adres,r24 + 16:hardware.c **** adres |= (PINC & 0x03); + 210 .LM8: + 211 0022 96B1 in r25,0x6 + 212 0024 9370 andi r25,lo8(3) + 213 0026 892B or r24,r25 + 214 0028 8093 0000 sts adres,r24 + 215 002c 0895 ret + 217 .Lscope1: + 219 .stabd 78,0,0 + 221 .global roleta1wGore + 223 roleta1wGore: + 224 .stabd 46,0,0 + 17:hardware.c **** } + 18:hardware.c **** + 19:hardware.c **** void roletawGore(uint8_t nrRolety) + 20:hardware.c **** { + 21:hardware.c **** if (nrRolety == 0) + 22:hardware.c **** roleta1wGore(); + 23:hardware.c **** else + 24:hardware.c **** roleta2wGore(); + 25:hardware.c **** } + 26:hardware.c **** + 27:hardware.c **** void roletawDol(uint8_t nrRolety) + 28:hardware.c **** { + 29:hardware.c **** if (nrRolety == 0) + 30:hardware.c **** roleta1wDol(); + 31:hardware.c **** else + 32:hardware.c **** roleta2wDol(); + 33:hardware.c **** } + 34:hardware.c **** + 35:hardware.c **** void roletaStop(uint8_t nrRolety) + 36:hardware.c **** { + 37:hardware.c **** if (nrRolety == 0) + 38:hardware.c **** roleta1Stop(); + 39:hardware.c **** else + 40:hardware.c **** roleta2Stop(); + 41:hardware.c **** } + 42:hardware.c **** + 43:hardware.c **** inline void roleta1wGore(void) + 44:hardware.c **** { + 226 .LM9: + 227 .LFBB2: + 228 /* prologue: function */ + 229 /* frame size = 0 */ + 230 /* stack size = 0 */ + 231 .L__stack_usage = 0 + 45:hardware.c **** PORTB &= ~0x02; + 233 .LM10: + 234 002e 2998 cbi 0x5,1 + 46:hardware.c **** PORTB |= 0x04; + 236 .LM11: + 237 0030 2A9A sbi 0x5,2 + 238 0032 0895 ret + 240 .Lscope2: + 242 .stabd 78,0,0 + 244 .global roleta1wDol + 246 roleta1wDol: + 247 .stabd 46,0,0 + 47:hardware.c **** } + 48:hardware.c **** + 49:hardware.c **** inline void roleta1wDol(void) + 50:hardware.c **** { + 249 .LM12: + 250 .LFBB3: + 251 /* prologue: function */ + 252 /* frame size = 0 */ + 253 /* stack size = 0 */ + 254 .L__stack_usage = 0 + 51:hardware.c **** PORTB &= ~0x04; + 256 .LM13: + 257 0034 2A98 cbi 0x5,2 + 52:hardware.c **** PORTB |= 0x02; + 259 .LM14: + 260 0036 299A sbi 0x5,1 + 261 0038 0895 ret + 263 .Lscope3: + 265 .stabd 78,0,0 + 267 .global roleta1Stop + 269 roleta1Stop: + 270 .stabd 46,0,0 + 53:hardware.c **** } + 54:hardware.c **** + 55:hardware.c **** inline void roleta1Stop(void) + 56:hardware.c **** { + 272 .LM15: + 273 .LFBB4: + 274 /* prologue: function */ + 275 /* frame size = 0 */ + 276 /* stack size = 0 */ + 277 .L__stack_usage = 0 + 57:hardware.c **** PORTB &= ~0x06; + 279 .LM16: + 280 003a 85B1 in r24,0x5 + 281 003c 897F andi r24,lo8(-7) + 282 003e 85B9 out 0x5,r24 + 283 0040 0895 ret + 285 .Lscope4: + 287 .stabd 78,0,0 + 289 .global roleta2wGore + 291 roleta2wGore: + 292 .stabd 46,0,0 + 58:hardware.c **** } + 59:hardware.c **** + 60:hardware.c **** inline void roleta2wGore(void) + 61:hardware.c **** { + 294 .LM17: + 295 .LFBB5: + 296 /* prologue: function */ + 297 /* frame size = 0 */ + 298 /* stack size = 0 */ + 299 .L__stack_usage = 0 + 62:hardware.c **** PORTD &= ~0x80; + 301 .LM18: + 302 0042 5F98 cbi 0xb,7 + 63:hardware.c **** PORTB |= 0x01; + 304 .LM19: + 305 0044 289A sbi 0x5,0 + 306 0046 0895 ret + 308 .Lscope5: + 310 .stabd 78,0,0 + 313 .global roletawGore + 315 roletawGore: + 316 .stabd 46,0,0 + 20:hardware.c **** if (nrRolety == 0) + 318 .LM20: + 319 .LFBB6: + 320 /* prologue: function */ + 321 /* frame size = 0 */ + 322 /* stack size = 0 */ + 323 .L__stack_usage = 0 + 21:hardware.c **** roleta1wGore(); + 325 .LM21: + 326 0048 8111 cpse r24,__zero_reg__ + 327 004a 00C0 rjmp .L7 + 22:hardware.c **** else + 329 .LM22: + 330 004c 0C94 0000 jmp roleta1wGore + 331 .L7: + 24:hardware.c **** } + 333 .LM23: + 334 0050 0C94 0000 jmp roleta2wGore + 336 .Lscope6: + 338 .stabd 78,0,0 + 340 .global roleta2wDol + 342 roleta2wDol: + 343 .stabd 46,0,0 + 64:hardware.c **** } + 65:hardware.c **** + 66:hardware.c **** inline void roleta2wDol(void) + 67:hardware.c **** { + 345 .LM24: + 346 .LFBB7: + 347 /* prologue: function */ + 348 /* frame size = 0 */ + 349 /* stack size = 0 */ + 350 .L__stack_usage = 0 + 68:hardware.c **** PORTB &= ~0x01; + 352 .LM25: + 353 0054 2898 cbi 0x5,0 + 69:hardware.c **** PORTD |= 0x80; + 355 .LM26: + 356 0056 5F9A sbi 0xb,7 + 357 0058 0895 ret + 359 .Lscope7: + 361 .stabd 78,0,0 + 364 .global roletawDol + 366 roletawDol: + 367 .stabd 46,0,0 + 28:hardware.c **** if (nrRolety == 0) + 369 .LM27: + 370 .LFBB8: + 371 /* prologue: function */ + 372 /* frame size = 0 */ + 373 /* stack size = 0 */ + 374 .L__stack_usage = 0 + 29:hardware.c **** roleta1wDol(); + 376 .LM28: + 377 005a 8111 cpse r24,__zero_reg__ + 378 005c 00C0 rjmp .L11 + 30:hardware.c **** else + 380 .LM29: + 381 005e 0C94 0000 jmp roleta1wDol + 382 .L11: + 32:hardware.c **** } + 384 .LM30: + 385 0062 0C94 0000 jmp roleta2wDol + 387 .Lscope8: + 389 .stabd 78,0,0 + 391 .global roleta2Stop + 393 roleta2Stop: + 394 .stabd 46,0,0 + 70:hardware.c **** } + 71:hardware.c **** + 72:hardware.c **** inline void roleta2Stop(void) + 73:hardware.c **** { + 396 .LM31: + 397 .LFBB9: + 398 /* prologue: function */ + 399 /* frame size = 0 */ + 400 /* stack size = 0 */ + 401 .L__stack_usage = 0 + 74:hardware.c **** PORTB &= ~0x01; + 403 .LM32: + 404 0066 2898 cbi 0x5,0 + 75:hardware.c **** PORTD &= ~0x80; + 406 .LM33: + 407 0068 5F98 cbi 0xb,7 + 408 006a 0895 ret + 410 .Lscope9: + 412 .stabd 78,0,0 + 415 .global roletaStop + 417 roletaStop: + 418 .stabd 46,0,0 + 36:hardware.c **** if (nrRolety == 0) + 420 .LM34: + 421 .LFBB10: + 422 /* prologue: function */ + 423 /* frame size = 0 */ + 424 /* stack size = 0 */ + 425 .L__stack_usage = 0 + 37:hardware.c **** roleta1Stop(); + 427 .LM35: + 428 006c 8111 cpse r24,__zero_reg__ + 429 006e 00C0 rjmp .L14 + 38:hardware.c **** else + 431 .LM36: + 432 0070 0C94 0000 jmp roleta1Stop + 433 .L14: + 40:hardware.c **** } + 435 .LM37: + 436 0074 0C94 0000 jmp roleta2Stop + 438 .Lscope10: + 440 .stabd 78,0,0 + 442 .global Led1On + 444 Led1On: + 445 .stabd 46,0,0 + 76:hardware.c **** } + 77:hardware.c **** + 78:hardware.c **** inline void Led1On(void) + 79:hardware.c **** { + 447 .LM38: + 448 .LFBB11: + 449 /* prologue: function */ + 450 /* frame size = 0 */ + 451 /* stack size = 0 */ + 452 .L__stack_usage = 0 + 80:hardware.c **** PORTD |= 0x20; + 454 .LM39: + 455 0078 5D9A sbi 0xb,5 + 456 007a 0895 ret + 458 .Lscope11: + 460 .stabd 78,0,0 + 462 .global Led1Toggle + 464 Led1Toggle: + 465 .stabd 46,0,0 + 81:hardware.c **** } + 82:hardware.c **** + 83:hardware.c **** inline void Led1Toggle(void) + 84:hardware.c **** { + 467 .LM40: + 468 .LFBB12: + 469 /* prologue: function */ + 470 /* frame size = 0 */ + 471 /* stack size = 0 */ + 472 .L__stack_usage = 0 + 85:hardware.c **** PORTD ^= 0x20; + 474 .LM41: + 475 007c 9BB1 in r25,0xb + 476 007e 80E2 ldi r24,lo8(32) + 477 0080 8927 eor r24,r25 + 478 0082 8BB9 out 0xb,r24 + 479 0084 0895 ret + 481 .Lscope12: + 483 .stabd 78,0,0 + 485 .global Led1Off + 487 Led1Off: + 488 .stabd 46,0,0 + 86:hardware.c **** } + 87:hardware.c **** + 88:hardware.c **** inline void Led1Off(void) + 89:hardware.c **** { + 490 .LM42: + 491 .LFBB13: + 492 /* prologue: function */ + 493 /* frame size = 0 */ + 494 /* stack size = 0 */ + 495 .L__stack_usage = 0 + 90:hardware.c **** PORTD &= ~0x20; + 497 .LM43: + 498 0086 5D98 cbi 0xb,5 + 499 0088 0895 ret + 501 .Lscope13: + 503 .stabd 78,0,0 + 505 .global Led2On + 507 Led2On: + 508 .stabd 46,0,0 + 91:hardware.c **** } + 92:hardware.c **** + 93:hardware.c **** inline void Led2On(void) + 94:hardware.c **** { + 510 .LM44: + 511 .LFBB14: + 512 /* prologue: function */ + 513 /* frame size = 0 */ + 514 /* stack size = 0 */ + 515 .L__stack_usage = 0 + 95:hardware.c **** PORTD |= 0x40; + 517 .LM45: + 518 008a 5E9A sbi 0xb,6 + 519 008c 0895 ret + 521 .Lscope14: + 523 .stabd 78,0,0 + 525 .global Led2Toggle + 527 Led2Toggle: + 528 .stabd 46,0,0 + 96:hardware.c **** } + 97:hardware.c **** + 98:hardware.c **** inline void Led2Toggle(void) + 99:hardware.c **** { + 530 .LM46: + 531 .LFBB15: + 532 /* prologue: function */ + 533 /* frame size = 0 */ + 534 /* stack size = 0 */ + 535 .L__stack_usage = 0 + 100:hardware.c **** PORTD ^= 0x40; + 537 .LM47: + 538 008e 9BB1 in r25,0xb + 539 0090 80E4 ldi r24,lo8(64) + 540 0092 8927 eor r24,r25 + 541 0094 8BB9 out 0xb,r24 + 542 0096 0895 ret + 544 .Lscope15: + 546 .stabd 78,0,0 + 548 .global Led2Off + 550 Led2Off: + 551 .stabd 46,0,0 + 101:hardware.c **** } + 102:hardware.c **** + 103:hardware.c **** inline void Led2Off(void) + 104:hardware.c **** { + 553 .LM48: + 554 .LFBB16: + 555 /* prologue: function */ + 556 /* frame size = 0 */ + 557 /* stack size = 0 */ + 558 .L__stack_usage = 0 + 105:hardware.c **** PORTD &= ~0x40; + 560 .LM49: + 561 0098 5E98 cbi 0xb,6 + 562 009a 0895 ret + 564 .Lscope16: + 566 .stabd 78,0,0 + 568 .global czytKlawiszRol1wGore + 570 czytKlawiszRol1wGore: + 571 .stabd 46,0,0 + 106:hardware.c **** } + 107:hardware.c **** + 108:hardware.c **** inline char czytKlawiszRol1wGore(void) + 109:hardware.c **** { + 573 .LM50: + 574 .LFBB17: + 575 /* prologue: function */ + 576 /* frame size = 0 */ + 577 /* stack size = 0 */ + 578 .L__stack_usage = 0 + 110:hardware.c **** return PINC & 0x04; + 580 .LM51: + 581 009c 86B1 in r24,0x6 + 111:hardware.c **** } + 583 .LM52: + 584 009e 8470 andi r24,lo8(4) + 585 00a0 0895 ret + 587 .Lscope17: + 589 .stabd 78,0,0 + 591 .global czytKlawiszRol1wDol + 593 czytKlawiszRol1wDol: + 594 .stabd 46,0,0 + 112:hardware.c **** + 113:hardware.c **** inline char czytKlawiszRol1wDol(void) + 114:hardware.c **** { + 596 .LM53: + 597 .LFBB18: + 598 /* prologue: function */ + 599 /* frame size = 0 */ + 600 /* stack size = 0 */ + 601 .L__stack_usage = 0 + 115:hardware.c **** return PINC & 0x08; + 603 .LM54: + 604 00a2 86B1 in r24,0x6 + 116:hardware.c **** } + 606 .LM55: + 607 00a4 8870 andi r24,lo8(8) + 608 00a6 0895 ret + 610 .Lscope18: + 612 .stabd 78,0,0 + 614 .global czytKlawiszRol2wGore + 616 czytKlawiszRol2wGore: + 617 .stabd 46,0,0 + 117:hardware.c **** + 118:hardware.c **** inline char czytKlawiszRol2wGore(void) + 119:hardware.c **** { + 619 .LM56: + 620 .LFBB19: + 621 /* prologue: function */ + 622 /* frame size = 0 */ + 623 /* stack size = 0 */ + 624 .L__stack_usage = 0 + 120:hardware.c **** return PINC & 0x10; + 626 .LM57: + 627 00a8 86B1 in r24,0x6 + 121:hardware.c **** } + 629 .LM58: + 630 00aa 8071 andi r24,lo8(16) + 631 00ac 0895 ret + 633 .Lscope19: + 635 .stabd 78,0,0 + 637 .global czytKlawiszRol2wDol + 639 czytKlawiszRol2wDol: + 640 .stabd 46,0,0 + 122:hardware.c **** + 123:hardware.c **** inline char czytKlawiszRol2wDol(void) + 124:hardware.c **** { + 642 .LM59: + 643 .LFBB20: + 644 /* prologue: function */ + 645 /* frame size = 0 */ + 646 /* stack size = 0 */ + 647 .L__stack_usage = 0 + 125:hardware.c **** return PINC & 0x20; + 649 .LM60: + 650 00ae 86B1 in r24,0x6 + 126:hardware.c **** } + 652 .LM61: + 653 00b0 8072 andi r24,lo8(32) + 654 00b2 0895 ret + 656 .Lscope20: + 658 .stabd 78,0,0 + 660 .Letext0: + 661 .ident "GCC: (GNU) 4.9.2" +DEFINED SYMBOLS + *ABS*:0000000000000000 hardware.c + /tmp/ccgxkPb0.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccgxkPb0.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccgxkPb0.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccgxkPb0.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccgxkPb0.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccgxkPb0.s:170 .text:0000000000000000 hardwareInit + /tmp/ccgxkPb0.s:223 .text:000000000000002e roleta1wGore + /tmp/ccgxkPb0.s:246 .text:0000000000000034 roleta1wDol + /tmp/ccgxkPb0.s:269 .text:000000000000003a roleta1Stop + /tmp/ccgxkPb0.s:291 .text:0000000000000042 roleta2wGore + /tmp/ccgxkPb0.s:315 .text:0000000000000048 roletawGore + /tmp/ccgxkPb0.s:342 .text:0000000000000054 roleta2wDol + /tmp/ccgxkPb0.s:366 .text:000000000000005a roletawDol + /tmp/ccgxkPb0.s:393 .text:0000000000000066 roleta2Stop + /tmp/ccgxkPb0.s:417 .text:000000000000006c roletaStop + /tmp/ccgxkPb0.s:444 .text:0000000000000078 Led1On + /tmp/ccgxkPb0.s:464 .text:000000000000007c Led1Toggle + /tmp/ccgxkPb0.s:487 .text:0000000000000086 Led1Off + /tmp/ccgxkPb0.s:507 .text:000000000000008a Led2On + /tmp/ccgxkPb0.s:527 .text:000000000000008e Led2Toggle + /tmp/ccgxkPb0.s:550 .text:0000000000000098 Led2Off + /tmp/ccgxkPb0.s:570 .text:000000000000009c czytKlawiszRol1wGore + /tmp/ccgxkPb0.s:593 .text:00000000000000a2 czytKlawiszRol1wDol + /tmp/ccgxkPb0.s:616 .text:00000000000000a8 czytKlawiszRol2wGore + /tmp/ccgxkPb0.s:639 .text:00000000000000ae czytKlawiszRol2wDol + +UNDEFINED SYMBOLS +adres diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.c b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.c new file mode 100644 index 0000000..117bc6a --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.c @@ -0,0 +1,184 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + +/** + * Proces odpowiedzialny za obsługę klawiszy + * @param pvParameters ignorowane parametry + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Proces odpowiedzialny za obsługę rolety + * @param pvParameters ignorowane parametry + */ +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +static void prvIncrementResetCount( void ); + +void vApplicationIdleHook( void ); + + +/*-----------------------------------------------------------*/ + +/* Device address on RS 485 bus */ +uint8_t adres; +char bHelloResp[HELLO_RESP_LEN+HDR_LEN] = {SYNC, 0, rHELLO, HELLO_RESP_LEN, 'r', 0, 'v', '0', '.', '5', '1'}; + +t_stan_klawiszy roleta1 = {0, 0, 0, 0, bezczynny}; +t_stan_klawiszy roleta2 = {0, 0, 0, 0, bezczynny}; + +extern xQueueHandle xRxedChars; +extern xQueueHandle xCharsForTx; + +xQueueHandle xRoleta[2]; + +portSHORT main( void ) +{ +//prvIncrementResetCount(); + + hardwareInit(); + xSerialPortInitMinimal(16); + + xRoleta[0] = xQueueCreate(4, 1); + xRoleta[1] = xQueueCreate(4, 1); + + xCoRoutineCreate(vProtocol, 0, 0); + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vRoleta, 0, 0); + xCoRoutineCreate(vRoleta, 0, 1); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + static portBASE_TYPE xResult; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + } + wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta2)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + } + } + crEND(); +} + +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + static uint8_t rozkaz[2]; + static uint16_t czasAkcji[2]; + czasAkcji[uxIndex] = portMAX_DELAY; + static portBASE_TYPE xResult[2]; + crSTART( xHandle ); + for (;;) + { + crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz[uxIndex], czasAkcji[uxIndex], &xResult[uxIndex]); + + if (xResult[uxIndex] == pdTRUE) + { + uint8_t tmp = rozkaz[uxIndex] & 0x3F; + if (tmp == 0) + czasAkcji[uxIndex] = portMAX_DELAY; + else + czasAkcji[uxIndex] = tmp*20; + if (rozkaz[uxIndex] & 0x40) + { + roletaStop(uxIndex); + } + else + { + if (rozkaz[uxIndex] & 0x80) + roletawGore(uxIndex); + else + roletawDol(uxIndex); + } + } + else + { + czasAkcji[uxIndex] = portMAX_DELAY; + roletaStop(uxIndex); + } + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +#if 0 +static void prvIncrementResetCount( void ) +{ + unsigned portCHAR ucCount; + eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); + ucCount++; + eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); +} +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.h b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.h new file mode 100644 index 0000000..088190b --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.h @@ -0,0 +1,28 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" +#include "automat.h" +#include "../../Lib/include/protocol1.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.lst b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.lst new file mode 100644 index 0000000..d831d14 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/main.lst @@ -0,0 +1,752 @@ + 1 .file "main.c" + 2 __SP_H__ = 0x3e + 3 __SP_L__ = 0x3d + 4 __SREG__ = 0x3f + 5 __tmp_reg__ = 0 + 6 __zero_reg__ = 1 + 9 .text + 10 .Ltext0: + 171 vRoleta: + 172 .stabd 46,0,0 + 1:main.c **** /* + 2:main.c **** FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + 3:main.c **** + 4:main.c **** This file is part of the FreeRTOS.org distribution. + 5:main.c **** + 6:main.c **** FreeRTOS.org is free software; you can redistribute it and/or modify it + 7:main.c **** under the terms of the GNU General Public License (version 2) as published + 8:main.c **** by the Free Software Foundation and modified by the FreeRTOS exception. + 9:main.c **** + 10:main.c **** FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + 11:main.c **** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + 12:main.c **** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + 13:main.c **** more details. + 14:main.c **** + 15:main.c **** You should have received a copy of the GNU General Public License along + 16:main.c **** with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + 17:main.c **** Temple Place, Suite 330, Boston, MA 02111-1307 USA. + 18:main.c **** + 19:main.c **** A special exception to the GPL is included to allow you to distribute a + 20:main.c **** combined work that includes FreeRTOS.org without being obliged to provide + 21:main.c **** the source code for any proprietary components. See the licensing section + 22:main.c **** of http://www.FreeRTOS.org for full details. + 23:main.c **** + 24:main.c **** + 25:main.c **** *************************************************************************** + 26:main.c **** * * + 27:main.c **** * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + 28:main.c **** * * + 29:main.c **** * This is a concise, step by step, 'hands on' guide that describes both * + 30:main.c **** * general multitasking concepts and FreeRTOS specifics. It presents and * + 31:main.c **** * explains numerous examples that are written using the FreeRTOS API. * + 32:main.c **** * Full source code for all the examples is provided in an accompanying * + 33:main.c **** * .zip file. * + 34:main.c **** * * + 35:main.c **** *************************************************************************** + 36:main.c **** + 37:main.c **** 1 tab == 4 spaces! + 38:main.c **** + 39:main.c **** Please ensure to read the configuration and relevant port sections of the + 40:main.c **** online documentation. + 41:main.c **** + 42:main.c **** http://www.FreeRTOS.org - Documentation, latest information, license and + 43:main.c **** contact details. + 44:main.c **** + 45:main.c **** http://www.SafeRTOS.com - A version that is certified for use in safety + 46:main.c **** critical systems. + 47:main.c **** + 48:main.c **** http://www.OpenRTOS.com - Commercial support, development, porting, + 49:main.c **** licensing and training services. + 50:main.c **** */ + 51:main.c **** + 52:main.c **** #include "main.h" + 53:main.c **** + 54:main.c **** /** + 55:main.c **** * Proces odpowiedzialny za obsługę klawiszy + 56:main.c **** * @param pvParameters ignorowane parametry + 57:main.c **** */ + 58:main.c **** static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + 59:main.c **** + 60:main.c **** /** + 61:main.c **** * Proces odpowiedzialny za obsługę rolety + 62:main.c **** * @param pvParameters ignorowane parametry + 63:main.c **** */ + 64:main.c **** static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + 65:main.c **** + 66:main.c **** static void prvIncrementResetCount( void ); + 67:main.c **** + 68:main.c **** void vApplicationIdleHook( void ); + 69:main.c **** + 70:main.c **** + 71:main.c **** /*-----------------------------------------------------------*/ + 72:main.c **** + 73:main.c **** /* Device address on RS 485 bus */ + 74:main.c **** uint8_t adres; + 75:main.c **** char bHelloResp[HELLO_RESP_LEN+HDR_LEN] = {SYNC, 0, rHELLO, HELLO_RESP_LEN, 'r', 0, 'v', '0', '.', + 76:main.c **** + 77:main.c **** t_stan_klawiszy roleta1 = {0, 0, 0, 0, bezczynny}; + 78:main.c **** t_stan_klawiszy roleta2 = {0, 0, 0, 0, bezczynny}; + 79:main.c **** + 80:main.c **** extern xQueueHandle xRxedChars; + 81:main.c **** extern xQueueHandle xCharsForTx; + 82:main.c **** + 83:main.c **** xQueueHandle xRoleta[2]; + 84:main.c **** + 85:main.c **** portSHORT main( void ) + 86:main.c **** { + 87:main.c **** //prvIncrementResetCount(); + 88:main.c **** + 89:main.c **** hardwareInit(); + 90:main.c **** xSerialPortInitMinimal(16); + 91:main.c **** + 92:main.c **** xRoleta[0] = xQueueCreate(4, 1); + 93:main.c **** xRoleta[1] = xQueueCreate(4, 1); + 94:main.c **** + 95:main.c **** xCoRoutineCreate(vProtocol, 0, 0); + 96:main.c **** xCoRoutineCreate(vKlawisze, 0, 0); + 97:main.c **** xCoRoutineCreate(vRoleta, 0, 0); + 98:main.c **** xCoRoutineCreate(vRoleta, 0, 1); + 99:main.c **** + 100:main.c **** vTaskStartScheduler(); + 101:main.c **** return 0; + 102:main.c **** } + 103:main.c **** /*-----------------------------------------------------------*/ + 104:main.c **** + 105:main.c **** static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) + 106:main.c **** { + 107:main.c **** (void) uxIndex; + 108:main.c **** static portBASE_TYPE xResult; + 109:main.c **** + 110:main.c **** crSTART( xHandle ); + 111:main.c **** for( ;; ) + 112:main.c **** { + 113:main.c **** crDELAY( xHandle, 1); + 114:main.c **** uint8_t wiadomosc; + 115:main.c **** wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &ro + 116:main.c **** if (wiadomosc) + 117:main.c **** { + 118:main.c **** crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + 119:main.c **** } + 120:main.c **** wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &rol + 121:main.c **** if (wiadomosc) + 122:main.c **** { + 123:main.c **** crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + 124:main.c **** } + 125:main.c **** } + 126:main.c **** crEND(); + 127:main.c **** } + 128:main.c **** + 129:main.c **** static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) + 130:main.c **** { + 174 .LM0: + 175 .LFBB1: + 176 0000 CF92 push r12 + 177 0002 DF92 push r13 + 178 0004 FF92 push r15 + 179 0006 0F93 push r16 + 180 0008 1F93 push r17 + 181 000a CF93 push r28 + 182 000c DF93 push r29 + 183 /* prologue: function */ + 184 /* frame size = 0 */ + 185 /* stack size = 7 */ + 186 .L__stack_usage = 7 + 187 000e 6C01 movw r12,r24 + 188 0010 F62E mov r15,r22 + 131:main.c **** static uint8_t rozkaz[2]; + 132:main.c **** static uint16_t czasAkcji[2]; + 133:main.c **** czasAkcji[uxIndex] = portMAX_DELAY; + 190 .LM1: + 191 0012 C62F mov r28,r22 + 192 0014 D0E0 ldi r29,0 + 193 0016 8E01 movw r16,r28 + 194 0018 000F lsl r16 + 195 001a 111F rol r17 + 196 001c F801 movw r30,r16 + 197 001e E050 subi r30,lo8(-(czasAkcji.2195)) + 198 0020 F040 sbci r31,hi8(-(czasAkcji.2195)) + 199 0022 8FEF ldi r24,lo8(-1) + 200 0024 9FEF ldi r25,lo8(-1) + 201 0026 9183 std Z+1,r25 + 202 0028 8083 st Z,r24 + 134:main.c **** static portBASE_TYPE xResult[2]; + 135:main.c **** crSTART( xHandle ); + 204 .LM2: + 205 002a F601 movw r30,r12 + 206 002c 808D ldd r24,Z+24 + 207 002e 918D ldd r25,Z+25 + 208 0030 8431 cpi r24,20 + 209 0032 F1E0 ldi r31,1 + 210 0034 9F07 cpc r25,r31 + 211 0036 01F0 breq .L3 + 212 0038 8531 cpi r24,21 + 213 003a 21E0 ldi r18,1 + 214 003c 9207 cpc r25,r18 + 215 003e 01F0 breq .L4 + 216 0040 892B or r24,r25 + 217 0042 01F0 breq .+2 + 218 0044 00C0 rjmp .L1 + 219 .L5: + 136:main.c **** for (;;) + 137:main.c **** { + 138:main.c **** crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz[uxIndex], czasAkcji[uxIndex], &xResult[uxInd + 221 .LM3: + 222 0046 F801 movw r30,r16 + 223 0048 E050 subi r30,lo8(-(czasAkcji.2195)) + 224 004a F040 sbci r31,hi8(-(czasAkcji.2195)) + 225 004c 4081 ld r20,Z + 226 004e 5181 ldd r21,Z+1 + 227 0050 BE01 movw r22,r28 + 228 0052 6050 subi r22,lo8(-(rozkaz.2194)) + 229 0054 7040 sbci r23,hi8(-(rozkaz.2194)) + 230 0056 F801 movw r30,r16 + 231 0058 E050 subi r30,lo8(-(xRoleta)) + 232 005a F040 sbci r31,hi8(-(xRoleta)) + 233 005c 8081 ld r24,Z + 234 005e 9181 ldd r25,Z+1 + 235 0060 0E94 0000 call xQueueCRReceive + 236 0064 FE01 movw r30,r28 + 237 0066 E050 subi r30,lo8(-(xResult.2196)) + 238 0068 F040 sbci r31,hi8(-(xResult.2196)) + 239 006a 8083 st Z,r24 + 240 006c 8C3F cpi r24,lo8(-4) + 241 006e 01F4 brne .L6 + 243 .LM4: + 244 0070 84E1 ldi r24,lo8(20) + 245 0072 91E0 ldi r25,lo8(1) + 246 0074 00C0 rjmp .L18 + 247 .L3: + 249 .LM5: + 250 0076 40E0 ldi r20,0 + 251 0078 50E0 ldi r21,0 + 252 007a BE01 movw r22,r28 + 253 007c 6050 subi r22,lo8(-(rozkaz.2194)) + 254 007e 7040 sbci r23,hi8(-(rozkaz.2194)) + 255 0080 F801 movw r30,r16 + 256 0082 E050 subi r30,lo8(-(xRoleta)) + 257 0084 F040 sbci r31,hi8(-(xRoleta)) + 258 0086 8081 ld r24,Z + 259 0088 9181 ldd r25,Z+1 + 260 008a 0E94 0000 call xQueueCRReceive + 261 008e FE01 movw r30,r28 + 262 0090 E050 subi r30,lo8(-(xResult.2196)) + 263 0092 F040 sbci r31,hi8(-(xResult.2196)) + 264 0094 8083 st Z,r24 + 265 .L6: + 267 .LM6: + 268 0096 FE01 movw r30,r28 + 269 0098 E050 subi r30,lo8(-(xResult.2196)) + 270 009a F040 sbci r31,hi8(-(xResult.2196)) + 271 009c 8081 ld r24,Z + 272 009e 8B3F cpi r24,lo8(-5) + 273 00a0 01F4 brne .L7 + 275 .LM7: + 276 00a2 85E1 ldi r24,lo8(21) + 277 00a4 91E0 ldi r25,lo8(1) + 278 .L18: + 279 00a6 F601 movw r30,r12 + 280 00a8 918F std Z+25,r25 + 281 00aa 808F std Z+24,r24 + 282 00ac 00C0 rjmp .L1 + 283 .L4: + 285 .LM8: + 286 00ae 81E0 ldi r24,lo8(1) + 287 00b0 FE01 movw r30,r28 + 288 00b2 E050 subi r30,lo8(-(xResult.2196)) + 289 00b4 F040 sbci r31,hi8(-(xResult.2196)) + 290 00b6 8083 st Z,r24 + 291 .L7: + 139:main.c **** + 140:main.c **** if (xResult[uxIndex] == pdTRUE) + 293 .LM9: + 294 00b8 FE01 movw r30,r28 + 295 00ba E050 subi r30,lo8(-(xResult.2196)) + 296 00bc F040 sbci r31,hi8(-(xResult.2196)) + 297 00be 8081 ld r24,Z + 298 00c0 8130 cpi r24,lo8(1) + 299 00c2 01F4 brne .L8 + 300 .LBB2: + 141:main.c **** { + 142:main.c **** uint8_t tmp = rozkaz[uxIndex] & 0x3F; + 302 .LM10: + 303 00c4 FE01 movw r30,r28 + 304 00c6 E050 subi r30,lo8(-(rozkaz.2194)) + 305 00c8 F040 sbci r31,hi8(-(rozkaz.2194)) + 306 00ca 8081 ld r24,Z + 307 00cc 282F mov r18,r24 + 308 00ce 2F73 andi r18,lo8(63) + 143:main.c **** if (tmp == 0) + 310 .LM11: + 311 00d0 01F4 brne .L9 + 144:main.c **** czasAkcji[uxIndex] = portMAX_DELAY; + 313 .LM12: + 314 00d2 2FEF ldi r18,lo8(-1) + 315 00d4 3FEF ldi r19,lo8(-1) + 316 00d6 F801 movw r30,r16 + 317 00d8 E050 subi r30,lo8(-(czasAkcji.2195)) + 318 00da F040 sbci r31,hi8(-(czasAkcji.2195)) + 319 00dc 00C0 rjmp .L17 + 320 .L9: + 145:main.c **** else + 146:main.c **** czasAkcji[uxIndex] = tmp*20; + 322 .LM13: + 323 00de F801 movw r30,r16 + 324 00e0 E050 subi r30,lo8(-(czasAkcji.2195)) + 325 00e2 F040 sbci r31,hi8(-(czasAkcji.2195)) + 326 00e4 94E1 ldi r25,lo8(20) + 327 00e6 299F mul r18,r25 + 328 00e8 9001 movw r18,r0 + 329 00ea 1124 clr __zero_reg__ + 330 .L17: + 331 00ec 3183 std Z+1,r19 + 332 00ee 2083 st Z,r18 + 147:main.c **** if (rozkaz[uxIndex] & 0x40) + 334 .LM14: + 335 00f0 86FD sbrc r24,6 + 336 00f2 00C0 rjmp .L16 + 148:main.c **** { + 149:main.c **** roletaStop(uxIndex); + 150:main.c **** } + 151:main.c **** else + 152:main.c **** { + 153:main.c **** if (rozkaz[uxIndex] & 0x80) + 338 .LM15: + 339 00f4 87FF sbrs r24,7 + 340 00f6 00C0 rjmp .L12 + 154:main.c **** roletawGore(uxIndex); + 342 .LM16: + 343 00f8 8F2D mov r24,r15 + 344 00fa 0E94 0000 call roletawGore + 345 00fe 00C0 rjmp .L5 + 346 .L12: + 155:main.c **** else + 156:main.c **** roletawDol(uxIndex); + 348 .LM17: + 349 0100 8F2D mov r24,r15 + 350 0102 0E94 0000 call roletawDol + 351 0106 00C0 rjmp .L5 + 352 .L8: + 353 .LBE2: + 157:main.c **** } + 158:main.c **** } + 159:main.c **** else + 160:main.c **** { + 161:main.c **** czasAkcji[uxIndex] = portMAX_DELAY; + 355 .LM18: + 356 0108 8FEF ldi r24,lo8(-1) + 357 010a 9FEF ldi r25,lo8(-1) + 358 010c F801 movw r30,r16 + 359 010e E050 subi r30,lo8(-(czasAkcji.2195)) + 360 0110 F040 sbci r31,hi8(-(czasAkcji.2195)) + 361 0112 9183 std Z+1,r25 + 362 0114 8083 st Z,r24 + 363 .L16: + 162:main.c **** roletaStop(uxIndex); + 365 .LM19: + 366 0116 8F2D mov r24,r15 + 367 0118 0E94 0000 call roletaStop + 368 011c 00C0 rjmp .L5 + 369 .L1: + 370 /* epilogue start */ + 163:main.c **** } + 164:main.c **** } + 165:main.c **** crEND(); + 166:main.c **** } + 372 .LM20: + 373 011e DF91 pop r29 + 374 0120 CF91 pop r28 + 375 0122 1F91 pop r17 + 376 0124 0F91 pop r16 + 377 0126 FF90 pop r15 + 378 0128 DF90 pop r13 + 379 012a CF90 pop r12 + 380 012c 0895 ret + 390 .Lscope1: + 392 .stabd 78,0,0 + 397 vKlawisze: + 398 .stabd 46,0,0 + 106:main.c **** (void) uxIndex; + 400 .LM21: + 401 .LFBB2: + 402 012e 0F93 push r16 + 403 0130 1F93 push r17 + 404 0132 CF93 push r28 + 405 0134 DF93 push r29 + 406 0136 00D0 rcall . + 407 0138 CDB7 in r28,__SP_L__ + 408 013a DEB7 in r29,__SP_H__ + 409 /* prologue: function */ + 410 /* frame size = 2 */ + 411 /* stack size = 6 */ + 412 .L__stack_usage = 6 + 413 013c 8C01 movw r16,r24 + 110:main.c **** for( ;; ) + 415 .LM22: + 416 013e FC01 movw r30,r24 + 417 0140 208D ldd r18,Z+24 + 418 0142 318D ldd r19,Z+25 + 419 0144 2C3E cpi r18,-20 + 420 0146 3105 cpc r19,__zero_reg__ + 421 0148 01F4 brne .+2 + 422 014a 00C0 rjmp .L22 + 423 014c 00F4 brsh .L23 + 424 014e 2115 cp r18,__zero_reg__ + 425 0150 3105 cpc r19,__zero_reg__ + 426 0152 01F0 breq .L24 + 427 0154 223E cpi r18,-30 + 428 0156 3105 cpc r19,__zero_reg__ + 429 0158 01F0 breq .L25 + 430 015a 00C0 rjmp .L20 + 431 .L23: + 432 015c 263F cpi r18,-10 + 433 015e 3105 cpc r19,__zero_reg__ + 434 0160 01F4 brne .+2 + 435 0162 00C0 rjmp .L26 + 436 0164 273F cpi r18,-9 + 437 0166 3105 cpc r19,__zero_reg__ + 438 0168 01F4 brne .+2 + 439 016a 00C0 rjmp .L27 + 440 016c 2D3E cpi r18,-19 + 441 016e 3105 cpc r19,__zero_reg__ + 442 0170 01F0 breq .+2 + 443 0172 00C0 rjmp .L20 + 444 .LBB3: + 118:main.c **** } + 446 .LM23: + 447 0174 81E0 ldi r24,lo8(1) + 448 0176 8093 0000 sts xResult.2181,r24 + 449 017a 00C0 rjmp .L31 + 450 .L25: + 115:main.c **** if (wiadomosc) + 452 .LM24: + 453 017c 0E94 0000 call czytKlawiszRol1wDol + 454 0180 8A83 std Y+2,r24 + 455 0182 0E94 0000 call czytKlawiszRol1wGore + 456 0186 40E0 ldi r20,lo8(roleta1) + 457 0188 50E0 ldi r21,hi8(roleta1) + 458 018a 6A81 ldd r22,Y+2 + 459 018c 0E94 0000 call automatStanowKlawiszy + 460 0190 8983 std Y+1,r24 + 116:main.c **** { + 462 .LM25: + 463 0192 8111 cpse r24,__zero_reg__ + 464 0194 00C0 rjmp .L42 + 465 .L31: + 120:main.c **** if (wiadomosc) + 467 .LM26: + 468 0196 0E94 0000 call czytKlawiszRol2wDol + 469 019a 8A83 std Y+2,r24 + 470 019c 0E94 0000 call czytKlawiszRol2wGore + 471 01a0 40E0 ldi r20,lo8(roleta2) + 472 01a2 50E0 ldi r21,hi8(roleta2) + 473 01a4 6A81 ldd r22,Y+2 + 474 01a6 0E94 0000 call automatStanowKlawiszy + 475 01aa 8983 std Y+1,r24 + 121:main.c **** { + 477 .LM27: + 478 01ac 8111 cpse r24,__zero_reg__ + 479 01ae 00C0 rjmp .L43 + 480 .L24: + 113:main.c **** uint8_t wiadomosc; + 482 .LM28: + 483 01b0 60E0 ldi r22,0 + 484 01b2 70E0 ldi r23,0 + 485 01b4 81E0 ldi r24,lo8(1) + 486 01b6 90E0 ldi r25,0 + 487 01b8 0E94 0000 call vCoRoutineAddToDelayedList + 488 01bc 82EE ldi r24,lo8(-30) + 489 01be 90E0 ldi r25,0 + 490 01c0 00C0 rjmp .L41 + 491 .L42: + 118:main.c **** } + 493 .LM29: + 494 01c2 4AE0 ldi r20,lo8(10) + 495 01c4 50E0 ldi r21,0 + 496 01c6 BE01 movw r22,r28 + 497 01c8 6F5F subi r22,-1 + 498 01ca 7F4F sbci r23,-1 + 499 01cc 8091 0000 lds r24,xRoleta + 500 01d0 9091 0000 lds r25,xRoleta+1 + 501 01d4 0E94 0000 call xQueueCRSend + 502 01d8 8093 0000 sts xResult.2181,r24 + 503 01dc 8C3F cpi r24,lo8(-4) + 504 01de 01F4 brne .L32 + 118:main.c **** } + 506 .LM30: + 507 01e0 8CEE ldi r24,lo8(-20) + 508 01e2 90E0 ldi r25,0 + 509 01e4 00C0 rjmp .L41 + 510 .L22: + 118:main.c **** } + 512 .LM31: + 513 01e6 40E0 ldi r20,0 + 514 01e8 50E0 ldi r21,0 + 515 01ea BE01 movw r22,r28 + 516 01ec 6F5F subi r22,-1 + 517 01ee 7F4F sbci r23,-1 + 518 01f0 8091 0000 lds r24,xRoleta + 519 01f4 9091 0000 lds r25,xRoleta+1 + 520 01f8 0E94 0000 call xQueueCRSend + 521 01fc 8093 0000 sts xResult.2181,r24 + 522 .L32: + 118:main.c **** } + 524 .LM32: + 525 0200 8091 0000 lds r24,xResult.2181 + 526 0204 8B3F cpi r24,lo8(-5) + 527 0206 01F4 brne .L31 + 118:main.c **** } + 529 .LM33: + 530 0208 8DEE ldi r24,lo8(-19) + 531 020a 90E0 ldi r25,0 + 532 020c 00C0 rjmp .L41 + 533 .L43: + 123:main.c **** } + 535 .LM34: + 536 020e 4AE0 ldi r20,lo8(10) + 537 0210 50E0 ldi r21,0 + 538 0212 BE01 movw r22,r28 + 539 0214 6F5F subi r22,-1 + 540 0216 7F4F sbci r23,-1 + 541 0218 8091 0000 lds r24,xRoleta+2 + 542 021c 9091 0000 lds r25,xRoleta+2+1 + 543 0220 0E94 0000 call xQueueCRSend + 544 0224 8093 0000 sts xResult.2181,r24 + 545 0228 8C3F cpi r24,lo8(-4) + 546 022a 01F4 brne .L36 + 123:main.c **** } + 548 .LM35: + 549 022c 86EF ldi r24,lo8(-10) + 550 022e 90E0 ldi r25,0 + 551 0230 00C0 rjmp .L41 + 552 .L26: + 123:main.c **** } + 554 .LM36: + 555 0232 40E0 ldi r20,0 + 556 0234 50E0 ldi r21,0 + 557 0236 BE01 movw r22,r28 + 558 0238 6F5F subi r22,-1 + 559 023a 7F4F sbci r23,-1 + 560 023c 8091 0000 lds r24,xRoleta+2 + 561 0240 9091 0000 lds r25,xRoleta+2+1 + 562 0244 0E94 0000 call xQueueCRSend + 563 0248 8093 0000 sts xResult.2181,r24 + 564 .L36: + 123:main.c **** } + 566 .LM37: + 567 024c 8091 0000 lds r24,xResult.2181 + 568 0250 8B3F cpi r24,lo8(-5) + 569 0252 01F0 breq .+2 + 570 0254 00C0 rjmp .L24 + 123:main.c **** } + 572 .LM38: + 573 0256 87EF ldi r24,lo8(-9) + 574 0258 90E0 ldi r25,0 + 575 .L41: + 576 025a F801 movw r30,r16 + 577 025c 918F std Z+25,r25 + 578 025e 808F std Z+24,r24 + 579 0260 00C0 rjmp .L20 + 580 .L27: + 123:main.c **** } + 582 .LM39: + 583 0262 81E0 ldi r24,lo8(1) + 584 0264 8093 0000 sts xResult.2181,r24 + 585 .LBE3: + 125:main.c **** crEND(); + 587 .LM40: + 588 0268 00C0 rjmp .L24 + 589 .L20: + 590 /* epilogue start */ + 127:main.c **** + 592 .LM41: + 593 026a 0F90 pop __tmp_reg__ + 594 026c 0F90 pop __tmp_reg__ + 595 026e DF91 pop r29 + 596 0270 CF91 pop r28 + 597 0272 1F91 pop r17 + 598 0274 0F91 pop r16 + 599 0276 0895 ret + 607 .Lscope2: + 609 .stabd 78,0,0 + 610 .section .text.startup,"ax",@progbits + 612 .global main + 614 main: + 615 .stabd 46,0,0 + 86:main.c **** //prvIncrementResetCount(); + 617 .LM42: + 618 .LFBB3: + 619 0000 CF93 push r28 + 620 0002 DF93 push r29 + 621 /* prologue: function */ + 622 /* frame size = 0 */ + 623 /* stack size = 2 */ + 624 .L__stack_usage = 2 + 89:main.c **** xSerialPortInitMinimal(16); + 626 .LM43: + 627 0004 0E94 0000 call hardwareInit + 90:main.c **** + 629 .LM44: + 630 0008 80E1 ldi r24,lo8(16) + 631 000a 0E94 0000 call xSerialPortInitMinimal + 92:main.c **** xRoleta[1] = xQueueCreate(4, 1); + 633 .LM45: + 634 000e 61E0 ldi r22,lo8(1) + 635 0010 84E0 ldi r24,lo8(4) + 636 0012 0E94 0000 call xQueueCreate + 637 0016 C0E0 ldi r28,lo8(xRoleta) + 638 0018 D0E0 ldi r29,hi8(xRoleta) + 639 001a 9983 std Y+1,r25 + 640 001c 8883 st Y,r24 + 93:main.c **** + 642 .LM46: + 643 001e 61E0 ldi r22,lo8(1) + 644 0020 84E0 ldi r24,lo8(4) + 645 0022 0E94 0000 call xQueueCreate + 646 0026 9B83 std Y+3,r25 + 647 0028 8A83 std Y+2,r24 + 95:main.c **** xCoRoutineCreate(vKlawisze, 0, 0); + 649 .LM47: + 650 002a 40E0 ldi r20,0 + 651 002c 60E0 ldi r22,0 + 652 002e 80E0 ldi r24,lo8(gs(vProtocol)) + 653 0030 90E0 ldi r25,hi8(gs(vProtocol)) + 654 0032 0E94 0000 call xCoRoutineCreate + 96:main.c **** xCoRoutineCreate(vRoleta, 0, 0); + 656 .LM48: + 657 0036 40E0 ldi r20,0 + 658 0038 60E0 ldi r22,0 + 659 003a 80E0 ldi r24,lo8(gs(vKlawisze)) + 660 003c 90E0 ldi r25,hi8(gs(vKlawisze)) + 661 003e 0E94 0000 call xCoRoutineCreate + 97:main.c **** xCoRoutineCreate(vRoleta, 0, 1); + 663 .LM49: + 664 0042 40E0 ldi r20,0 + 665 0044 60E0 ldi r22,0 + 666 0046 80E0 ldi r24,lo8(gs(vRoleta)) + 667 0048 90E0 ldi r25,hi8(gs(vRoleta)) + 668 004a 0E94 0000 call xCoRoutineCreate + 98:main.c **** + 670 .LM50: + 671 004e 41E0 ldi r20,lo8(1) + 672 0050 60E0 ldi r22,0 + 673 0052 80E0 ldi r24,lo8(gs(vRoleta)) + 674 0054 90E0 ldi r25,hi8(gs(vRoleta)) + 675 0056 0E94 0000 call xCoRoutineCreate + 100:main.c **** return 0; + 677 .LM51: + 678 005a 0E94 0000 call vTaskStartScheduler + 102:main.c **** /*-----------------------------------------------------------*/ + 680 .LM52: + 681 005e 80E0 ldi r24,0 + 682 0060 90E0 ldi r25,0 + 683 /* epilogue start */ + 684 0062 DF91 pop r29 + 685 0064 CF91 pop r28 + 686 0066 0895 ret + 688 .Lscope3: + 690 .stabd 78,0,0 + 691 .text + 693 .global vApplicationIdleHook + 695 vApplicationIdleHook: + 696 .stabd 46,0,0 + 167:main.c **** + 168:main.c **** void vApplicationIdleHook( void ) + 169:main.c **** { + 698 .LM53: + 699 .LFBB4: + 700 /* prologue: function */ + 701 /* frame size = 0 */ + 702 /* stack size = 0 */ + 703 .L__stack_usage = 0 + 704 .L46: + 170:main.c **** for( ;; ) + 171:main.c **** { + 172:main.c **** vCoRoutineSchedule(); + 706 .LM54: + 707 0278 0E94 0000 call vCoRoutineSchedule + 173:main.c **** } + 709 .LM55: + 710 027c 00C0 rjmp .L46 + 712 .Lscope4: + 714 .stabd 78,0,0 + 715 .local xResult.2181 + 716 .comm xResult.2181,1,1 + 717 .local xResult.2196 + 718 .comm xResult.2196,2,1 + 719 .local rozkaz.2194 + 720 .comm rozkaz.2194,2,1 + 721 .local czasAkcji.2195 + 722 .comm czasAkcji.2195,4,1 + 723 .comm xRoleta,4,1 + 724 .global roleta2 + 725 .section .bss + 728 roleta2: + 729 0000 0000 0000 .zero 5 + 729 00 + 730 .global roleta1 + 733 roleta1: + 734 0005 0000 0000 .zero 5 + 734 00 + 735 .global bHelloResp + 736 .data + 739 bHelloResp: + 740 0000 5A .byte 90 + 741 0001 00 .byte 0 + 742 0002 82 .byte -126 + 743 0003 08 .byte 8 + 744 0004 72 .byte 114 + 745 0005 00 .byte 0 + 746 0006 76 .byte 118 + 747 0007 30 .byte 48 + 748 0008 2E .byte 46 + 749 0009 35 .byte 53 + 750 000a 31 .byte 49 + 751 000b 00 .zero 1 + 752 .comm adres,1,1 + 758 .text + 760 .Letext0: + 761 .ident "GCC: (GNU) 4.9.2" + 762 .global __do_copy_data + 763 .global __do_clear_bss +DEFINED SYMBOLS + *ABS*:0000000000000000 main.c + /tmp/ccKfiRID.s:2 *ABS*:000000000000003e __SP_H__ + /tmp/ccKfiRID.s:3 *ABS*:000000000000003d __SP_L__ + /tmp/ccKfiRID.s:4 *ABS*:000000000000003f __SREG__ + /tmp/ccKfiRID.s:5 *ABS*:0000000000000000 __tmp_reg__ + /tmp/ccKfiRID.s:6 *ABS*:0000000000000001 __zero_reg__ + /tmp/ccKfiRID.s:171 .text:0000000000000000 vRoleta + /tmp/ccKfiRID.s:720 .bss:000000000000000f czasAkcji.2195 + /tmp/ccKfiRID.s:718 .bss:000000000000000d rozkaz.2194 + *COM*:0000000000000004 xRoleta + /tmp/ccKfiRID.s:716 .bss:000000000000000b xResult.2196 + /tmp/ccKfiRID.s:397 .text:000000000000012e vKlawisze + .bss:000000000000000a xResult.2181 + /tmp/ccKfiRID.s:733 .bss:0000000000000005 roleta1 + /tmp/ccKfiRID.s:728 .bss:0000000000000000 roleta2 + /tmp/ccKfiRID.s:614 .text.startup:0000000000000000 main + /tmp/ccKfiRID.s:695 .text:0000000000000278 vApplicationIdleHook + /tmp/ccKfiRID.s:739 .data:0000000000000000 bHelloResp + *COM*:0000000000000001 adres + +UNDEFINED SYMBOLS +xQueueCRReceive +roletawGore +roletawDol +roletaStop +czytKlawiszRol1wDol +czytKlawiszRol1wGore +automatStanowKlawiszy +czytKlawiszRol2wDol +czytKlawiszRol2wGore +vCoRoutineAddToDelayedList +xQueueCRSend +hardwareInit +xSerialPortInitMinimal +xQueueCreate +vProtocol +xCoRoutineCreate +vTaskStartScheduler +vCoRoutineSchedule +__do_copy_data +__do_clear_bss diff --git a/Projects/DidacticSystem/Adam/RollerBlinderRelayer/serial.c b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/serial.c new file mode 100644 index 0000000..ea614cd --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderRelayer/serial.c @@ -0,0 +1,445 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 2 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +//#define debug 1 + +/*-----------------------------------------------------------*/ + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + + +static volatile uint8_t kodRozkazu; +static volatile uint8_t dlDanych; +static uint8_t bDane[MAX_DATA_LEN]; + +static uint8_t wiadomosc; + + +static xSemaphoreHandle xSemaphore; +static portBASE_TYPE xHigherPriorityTaskWoken; + +static uint8_t crcLo; +static uint8_t crcHi; +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + { + case rOpuscRolete1: + wiadomosc = 0x3F; + wysylac = 2; + break; + + case rOpuscRolete2: + wiadomosc = 0x3F; + wysylac = 3; + break; + + case rPodniesRolete1: + wiadomosc = 0xBF; + wysylac = 2; + break; + + case rPodniesRolete2: + wiadomosc = 0xBF; + wysylac = 3; + break; + + case rZatrzymajRolete1: + wiadomosc = 0x40; + wysylac = 2; + break; + + case rZatrzymajRolete2: + wiadomosc = 0x40; + wysylac = 3; + break; + + case rPING: + wysylac = 1; + break; + case rHELLO: + wysylac = 4; + break; + case rFLASH: + wysylac = 1; + break; + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + static t_serialState stan; + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + +/* + for ( ;; ) + { + static uint8_t tmp = 'C'; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1On(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1Off(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + } +*/ + for( ;; ) + { + if (stan == s_sync) + { + znak=0; + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + if ((xResult == pdPASS) && (znak == SYNC)) + { + stan = s_addr; + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + stan = s_rozkaz; + crc = _crc_xmodem_update(crc, znak); + if (znak == adres) + dobryAdres = 1; + else + dobryAdres = 0; + } + else + { + stan = s_sync; + } + } + if (stan == s_rozkaz) + { + Led1On(); + Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, kodRozkazu); + stan = s_len; + } + else + { + stan = s_sync; + } + } + if (stan == s_len) + { + Led1Off(); + Led2On(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, dlDanych); + lOdebrDanych = 0; + stan = s_dane; + Led1On(); + Led2On(); + } + else + { + stan = s_sync; + } + } + if (stan == s_dane) + { + if (lOdebrDanych == dlDanych) + { + stan = s_CRC_HI; + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, znak); + if (lOdebrDanych < MAX_DATA_LEN) + bDane[lOdebrDanych] = znak; + lOdebrDanych++; + } + else + { + Led1Off(); + stan = s_sync; + } + } + } + if (stan == s_CRC_HI) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + if (xResult == pdPASS) + { + stan = s_CRC_LO; + } + else + { + Led1Off(); + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + if (xResult == pdPASS) + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + { + Led1Off(); + stan = s_sync; + } + else + { + stan = s_CRC_OK; + } + } + } + if (stan == s_CRC_OK) + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + if (rezultat == 1) + { + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(0, temp); + + //ADRES 0x00 adres mastera + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + + if (kodRozkazu == rFLASH) + { + Led1On(); + Led2On(); + crDELAY(xHandle, 10); + Led1Off(); + Led2Off(); + (*((void(*)(void))BOOT_START))(); //reboot + } + } + else if (rezultat == 2) + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 3) + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 4) + { + //SYNC + crc = 0; + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + Led1Off(); + Led2Off(); + stan = s_sync; + } + else //Zły adres + { + if (kodRozkazu == rFLASH) + { + DISABLE_RX(); + Led1On(); + Led2On(); + //TODO disable RX buffer + crDELAY(xHandle, 1000); + ENABLE_RX(); + } + Led1Off(); + stan = s_sync; + } + } + } + crEND(); +} + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + UBRR0L = 3; + UBRR0H = 0; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1< + 40:/usr/lib/avr/include/util/crc16.h **** + 41:/usr/lib/avr/include/util/crc16.h **** /** \file */ + 42:/usr/lib/avr/include/util/crc16.h **** /** \defgroup util_crc : CRC Computations + 43:/usr/lib/avr/include/util/crc16.h **** \code#include \endcode + 44:/usr/lib/avr/include/util/crc16.h **** + 45:/usr/lib/avr/include/util/crc16.h **** This header file provides a optimized inline functions for calculating + 46:/usr/lib/avr/include/util/crc16.h **** cyclic redundancy checks (CRC) using common polynomials. + 47:/usr/lib/avr/include/util/crc16.h **** + 48:/usr/lib/avr/include/util/crc16.h **** \par References: + 49:/usr/lib/avr/include/util/crc16.h **** + 50:/usr/lib/avr/include/util/crc16.h **** \par + 51:/usr/lib/avr/include/util/crc16.h **** + 52:/usr/lib/avr/include/util/crc16.h **** See the Dallas Semiconductor app note 27 for 8051 assembler example and + 53:/usr/lib/avr/include/util/crc16.h **** general CRC optimization suggestions. The table on the last page of the + 54:/usr/lib/avr/include/util/crc16.h **** app note is the key to understanding these implementations. + 55:/usr/lib/avr/include/util/crc16.h **** + 56:/usr/lib/avr/include/util/crc16.h **** \par + 57:/usr/lib/avr/include/util/crc16.h **** + 58:/usr/lib/avr/include/util/crc16.h **** Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e + 59:/usr/lib/avr/include/util/crc16.h **** Embedded \e Systems \e Programming. This may be difficult to find, but it + 60:/usr/lib/avr/include/util/crc16.h **** explains CRC's in very clear and concise terms. Well worth the effort to + 61:/usr/lib/avr/include/util/crc16.h **** obtain a copy. + 62:/usr/lib/avr/include/util/crc16.h **** + 63:/usr/lib/avr/include/util/crc16.h **** A typical application would look like: + 64:/usr/lib/avr/include/util/crc16.h **** + 65:/usr/lib/avr/include/util/crc16.h **** \code + 66:/usr/lib/avr/include/util/crc16.h **** // Dallas iButton test vector. + 67:/usr/lib/avr/include/util/crc16.h **** uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; + 68:/usr/lib/avr/include/util/crc16.h **** + 69:/usr/lib/avr/include/util/crc16.h **** int + 70:/usr/lib/avr/include/util/crc16.h **** checkcrc(void) + 71:/usr/lib/avr/include/util/crc16.h **** { + 72:/usr/lib/avr/include/util/crc16.h **** uint8_t crc = 0, i; + 73:/usr/lib/avr/include/util/crc16.h **** + 74:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < sizeof serno / sizeof serno[0]; i++) + 75:/usr/lib/avr/include/util/crc16.h **** crc = _crc_ibutton_update(crc, serno[i]); + 76:/usr/lib/avr/include/util/crc16.h **** + 77:/usr/lib/avr/include/util/crc16.h **** return crc; // must be 0 + 78:/usr/lib/avr/include/util/crc16.h **** } + 79:/usr/lib/avr/include/util/crc16.h **** \endcode + 80:/usr/lib/avr/include/util/crc16.h **** */ + 81:/usr/lib/avr/include/util/crc16.h **** + 82:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 83:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-16 calculation. + 84:/usr/lib/avr/include/util/crc16.h **** + 85:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ 86:/usr/lib/avr/include/util/crc16.h **** Initial value: 0xffff + 87:/usr/lib/avr/include/util/crc16.h **** + 88:/usr/lib/avr/include/util/crc16.h **** This CRC is normally used in disk-drive controllers. + 89:/usr/lib/avr/include/util/crc16.h **** + 90:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 91:/usr/lib/avr/include/util/crc16.h **** + 92:/usr/lib/avr/include/util/crc16.h **** \code + 93:/usr/lib/avr/include/util/crc16.h **** uint16_t + 94:/usr/lib/avr/include/util/crc16.h **** crc16_update(uint16_t crc, uint8_t a) + 95:/usr/lib/avr/include/util/crc16.h **** { + 96:/usr/lib/avr/include/util/crc16.h **** int i; + 97:/usr/lib/avr/include/util/crc16.h **** + 98:/usr/lib/avr/include/util/crc16.h **** crc ^= a; + 99:/usr/lib/avr/include/util/crc16.h **** for (i = 0; i < 8; ++i) + 100:/usr/lib/avr/include/util/crc16.h **** { + 101:/usr/lib/avr/include/util/crc16.h **** if (crc & 1) + 102:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1) ^ 0xA001; + 103:/usr/lib/avr/include/util/crc16.h **** else + 104:/usr/lib/avr/include/util/crc16.h **** crc = (crc >> 1); + 105:/usr/lib/avr/include/util/crc16.h **** } + 106:/usr/lib/avr/include/util/crc16.h **** + 107:/usr/lib/avr/include/util/crc16.h **** return crc; + 108:/usr/lib/avr/include/util/crc16.h **** } + 109:/usr/lib/avr/include/util/crc16.h **** + 110:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 111:/usr/lib/avr/include/util/crc16.h **** + 112:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 113:/usr/lib/avr/include/util/crc16.h **** _crc16_update(uint16_t __crc, uint8_t __data) + 114:/usr/lib/avr/include/util/crc16.h **** { + 115:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp; + 116:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; + 117:/usr/lib/avr/include/util/crc16.h **** + 118:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 119:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%2" "\n\t" + 120:/usr/lib/avr/include/util/crc16.h **** "mov %1,%A0" "\n\t" + 121:/usr/lib/avr/include/util/crc16.h **** "swap %1" "\n\t" + 122:/usr/lib/avr/include/util/crc16.h **** "eor %1,%A0" "\n\t" + 123:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 124:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 125:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 126:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 127:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%1" "\n\t" + 128:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 129:/usr/lib/avr/include/util/crc16.h **** "eor %1,__tmp_reg__" "\n\t" + 130:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x07" "\n\t" + 131:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%A0" "\n\t" + 132:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%B0" "\n\t" + 133:/usr/lib/avr/include/util/crc16.h **** "lsr %1" "\n\t" + 134:/usr/lib/avr/include/util/crc16.h **** "ror __tmp_reg__" "\n\t" + 135:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 136:/usr/lib/avr/include/util/crc16.h **** "mov %B0,__tmp_reg__" "\n\t" + 137:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" "\n\t" + 138:/usr/lib/avr/include/util/crc16.h **** "lsr __tmp_reg__" "\n\t" + 139:/usr/lib/avr/include/util/crc16.h **** "ror %1" "\n\t" + 140:/usr/lib/avr/include/util/crc16.h **** "eor %B0,__tmp_reg__" "\n\t" + 141:/usr/lib/avr/include/util/crc16.h **** "eor %A0,%1" + 142:/usr/lib/avr/include/util/crc16.h **** : "=r" (__ret), "=d" (__tmp) + 143:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 144:/usr/lib/avr/include/util/crc16.h **** : "r0" + 145:/usr/lib/avr/include/util/crc16.h **** ); + 146:/usr/lib/avr/include/util/crc16.h **** return __ret; + 147:/usr/lib/avr/include/util/crc16.h **** } + 148:/usr/lib/avr/include/util/crc16.h **** + 149:/usr/lib/avr/include/util/crc16.h **** /** \ingroup util_crc + 150:/usr/lib/avr/include/util/crc16.h **** Optimized CRC-XMODEM calculation. + 151:/usr/lib/avr/include/util/crc16.h **** + 152:/usr/lib/avr/include/util/crc16.h **** Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ 153:/usr/lib/avr/include/util/crc16.h **** Initial value: 0x0 + 154:/usr/lib/avr/include/util/crc16.h **** + 155:/usr/lib/avr/include/util/crc16.h **** This is the CRC used by the Xmodem-CRC protocol. + 156:/usr/lib/avr/include/util/crc16.h **** + 157:/usr/lib/avr/include/util/crc16.h **** The following is the equivalent functionality written in C. + 158:/usr/lib/avr/include/util/crc16.h **** + 159:/usr/lib/avr/include/util/crc16.h **** \code + 160:/usr/lib/avr/include/util/crc16.h **** uint16_t + 161:/usr/lib/avr/include/util/crc16.h **** crc_xmodem_update (uint16_t crc, uint8_t data) + 162:/usr/lib/avr/include/util/crc16.h **** { + 163:/usr/lib/avr/include/util/crc16.h **** int i; + 164:/usr/lib/avr/include/util/crc16.h **** + 165:/usr/lib/avr/include/util/crc16.h **** crc = crc ^ ((uint16_t)data << 8); + 166:/usr/lib/avr/include/util/crc16.h **** for (i=0; i<8; i++) + 167:/usr/lib/avr/include/util/crc16.h **** { + 168:/usr/lib/avr/include/util/crc16.h **** if (crc & 0x8000) + 169:/usr/lib/avr/include/util/crc16.h **** crc = (crc << 1) ^ 0x1021; + 170:/usr/lib/avr/include/util/crc16.h **** else + 171:/usr/lib/avr/include/util/crc16.h **** crc <<= 1; + 172:/usr/lib/avr/include/util/crc16.h **** } + 173:/usr/lib/avr/include/util/crc16.h **** + 174:/usr/lib/avr/include/util/crc16.h **** return crc; + 175:/usr/lib/avr/include/util/crc16.h **** } + 176:/usr/lib/avr/include/util/crc16.h **** \endcode */ + 177:/usr/lib/avr/include/util/crc16.h **** + 178:/usr/lib/avr/include/util/crc16.h **** static __inline__ uint16_t + 179:/usr/lib/avr/include/util/crc16.h **** _crc_xmodem_update(uint16_t __crc, uint8_t __data) + 180:/usr/lib/avr/include/util/crc16.h **** { + 176 .LM0: + 177 .LFBB1: + 178 /* prologue: function */ + 179 /* frame size = 0 */ + 180 /* stack size = 0 */ + 181 .L__stack_usage = 0 + 181:/usr/lib/avr/include/util/crc16.h **** uint16_t __ret; /* %B0:%A0 (alias for __crc) */ + 182:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp1; /* %1 */ + 183:/usr/lib/avr/include/util/crc16.h **** uint8_t __tmp2; /* %2 */ + 184:/usr/lib/avr/include/util/crc16.h **** /* %3 __data */ + 185:/usr/lib/avr/include/util/crc16.h **** + 186:/usr/lib/avr/include/util/crc16.h **** __asm__ __volatile__ ( + 187:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%3" "\n\t" /* crc.hi ^ data */ + 188:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%B0" "\n\t" + 189:/usr/lib/avr/include/util/crc16.h **** "swap __tmp_reg__" "\n\t" /* swap(crc.hi ^ data) */ + 190:/usr/lib/avr/include/util/crc16.h **** + 191:/usr/lib/avr/include/util/crc16.h **** /* Calculate the ret.lo of the CRC. */ + 192:/usr/lib/avr/include/util/crc16.h **** "mov %1,__tmp_reg__" "\n\t" + 193:/usr/lib/avr/include/util/crc16.h **** "andi %1,0x0f" "\n\t" + 194:/usr/lib/avr/include/util/crc16.h **** "eor %1,%B0" "\n\t" + 195:/usr/lib/avr/include/util/crc16.h **** "mov %2,%B0" "\n\t" + 196:/usr/lib/avr/include/util/crc16.h **** "eor %2,__tmp_reg__" "\n\t" + 197:/usr/lib/avr/include/util/crc16.h **** "lsl %2" "\n\t" + 198:/usr/lib/avr/include/util/crc16.h **** "andi %2,0xe0" "\n\t" + 199:/usr/lib/avr/include/util/crc16.h **** "eor %1,%2" "\n\t" /* __tmp1 is now ret.lo. */ + 200:/usr/lib/avr/include/util/crc16.h **** + 201:/usr/lib/avr/include/util/crc16.h **** /* Calculate the ret.hi of the CRC. */ + 202:/usr/lib/avr/include/util/crc16.h **** "mov %2,__tmp_reg__" "\n\t" + 203:/usr/lib/avr/include/util/crc16.h **** "eor %2,%B0" "\n\t" + 204:/usr/lib/avr/include/util/crc16.h **** "andi %2,0xf0" "\n\t" + 205:/usr/lib/avr/include/util/crc16.h **** "lsr %2" "\n\t" + 206:/usr/lib/avr/include/util/crc16.h **** "mov __tmp_reg__,%B0" "\n\t" + 207:/usr/lib/avr/include/util/crc16.h **** "lsl __tmp_reg__" "\n\t" + 208:/usr/lib/avr/include/util/crc16.h **** "rol %2" "\n\t" + 209:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 210:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 211:/usr/lib/avr/include/util/crc16.h **** "lsr %B0" "\n\t" + 212:/usr/lib/avr/include/util/crc16.h **** "andi %B0,0x1f" "\n\t" + 213:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%2" "\n\t" + 214:/usr/lib/avr/include/util/crc16.h **** "eor %B0,%A0" "\n\t" /* ret.hi is now ready. */ + 215:/usr/lib/avr/include/util/crc16.h **** "mov %A0,%1" "\n\t" /* ret.lo is now ready. */ + 216:/usr/lib/avr/include/util/crc16.h **** : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2) + 217:/usr/lib/avr/include/util/crc16.h **** : "r" (__data), "0" (__crc) + 218:/usr/lib/avr/include/util/crc16.h **** : "r0" + 219:/usr/lib/avr/include/util/crc16.h **** ); + 220:/usr/lib/avr/include/util/crc16.h **** return __ret; + 221:/usr/lib/avr/include/util/crc16.h **** } + 183 .LM1: + 184 /* #APP */ + 185 ; 186 "/usr/lib/avr/include/util/crc16.h" 1 + 186 0000 9627 eor r25,r22 + 187 0002 092E mov __tmp_reg__,r25 + 188 0004 0294 swap __tmp_reg__ + 189 0006 202D mov r18,__tmp_reg__ + 190 0008 2F70 andi r18,0x0f + 191 000a 2927 eor r18,r25 + 192 000c 692F mov r22,r25 + 193 000e 6025 eor r22,__tmp_reg__ + 194 0010 660F lsl r22 + 195 0012 607E andi r22,0xe0 + 196 0014 2627 eor r18,r22 + 197 0016 602D mov r22,__tmp_reg__ + 198 0018 6927 eor r22,r25 + 199 001a 607F andi r22,0xf0 + 200 001c 6695 lsr r22 + 201 001e 092E mov __tmp_reg__,r25 + 202 0020 000C lsl __tmp_reg__ + 203 0022 661F rol r22 + 204 0024 9695 lsr r25 + 205 0026 9695 lsr r25 + 206 0028 9695 lsr r25 + 207 002a 9F71 andi r25,0x1f + 208 002c 9627 eor r25,r22 + 209 002e 9827 eor r25,r24 + 210 0030 822F mov r24,r18 + 211 + 212 ; 0 "" 2 + 213 /* #NOAPP */ + 214 0032 0895 ret + 216 .Lscope1: + 218 .stabd 78,0,0 + 222 .global vProtocol + 224 vProtocol: + 225 .stabd 46,0,0 + 227 .Ltext2: + 1:serial.c **** /* + 2:serial.c **** FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + 3:serial.c **** + 4:serial.c **** This file is part of the FreeRTOS.org distribution. + 5:serial.c **** + 6:serial.c **** FreeRTOS.org is free software; you can redistribute it and/or modify it + 7:serial.c **** under the terms of the GNU General Public License (version 2) as published + 8:serial.c **** by the Free Software Foundation and modified by the FreeRTOS exception. + 9:serial.c **** + 10:serial.c **** FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + 11:serial.c **** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + 12:serial.c **** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + 13:serial.c **** more details. + 14:serial.c **** + 15:serial.c **** You should have received a copy of the GNU General Public License along + 16:serial.c **** with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + 17:serial.c **** Temple Place, Suite 330, Boston, MA 02111-1307 USA. + 18:serial.c **** + 19:serial.c **** A special exception to the GPL is included to allow you to distribute a + 20:serial.c **** combined work that includes FreeRTOS.org without being obliged to provide + 21:serial.c **** the source code for any proprietary components. See the licensing section + 22:serial.c **** of http://www.FreeRTOS.org for full details. + 23:serial.c **** + 24:serial.c **** + 25:serial.c **** *************************************************************************** + 26:serial.c **** * * + 27:serial.c **** * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + 28:serial.c **** * * + 29:serial.c **** * This is a concise, step by step, 'hands on' guide that describes both * + 30:serial.c **** * general multitasking concepts and FreeRTOS specifics. It presents and * + 31:serial.c **** * explains numerous examples that are written using the FreeRTOS API. * + 32:serial.c **** * Full source code for all the examples is provided in an accompanying * + 33:serial.c **** * .zip file. * + 34:serial.c **** * * + 35:serial.c **** *************************************************************************** + 36:serial.c **** + 37:serial.c **** 1 tab == 2 spaces! + 38:serial.c **** + 39:serial.c **** Please ensure to read the configuration and relevant port sections of the + 40:serial.c **** online documentation. + 41:serial.c **** + 42:serial.c **** http://www.FreeRTOS.org - Documentation, latest information, license and + 43:serial.c **** contact details. + 44:serial.c **** + 45:serial.c **** http://www.SafeRTOS.com - A version that is certified for use in safety + 46:serial.c **** critical systems. + 47:serial.c **** + 48:serial.c **** http://www.OpenRTOS.com - Commercial support, development, porting, + 49:serial.c **** licensing and training services. + 50:serial.c **** */ + 51:serial.c **** #include + 52:serial.c **** #include + 53:serial.c **** #include "FreeRTOS.h" + 54:serial.c **** #include "queue.h" + 55:serial.c **** #include "task.h" + 56:serial.c **** #include "serial.h" + 57:serial.c **** #include "hardware.h" + 58:serial.c **** + 59:serial.c **** //#define debug 1 + 60:serial.c **** + 61:serial.c **** /*-----------------------------------------------------------*/ + 62:serial.c **** + 63:serial.c **** static xQueueHandle xRxedChars; + 64:serial.c **** static xQueueHandle xCharsForTx; + 65:serial.c **** + 66:serial.c **** + 67:serial.c **** static volatile uint8_t kodRozkazu; + 68:serial.c **** static volatile uint8_t dlDanych; + 69:serial.c **** static uint8_t bDane[MAX_DATA_LEN]; + 70:serial.c **** + 71:serial.c **** static uint8_t wiadomosc; + 72:serial.c **** + 73:serial.c **** + 74:serial.c **** static xSemaphoreHandle xSemaphore; + 75:serial.c **** static portBASE_TYPE xHigherPriorityTaskWoken; + 76:serial.c **** + 77:serial.c **** static uint8_t crcLo; + 78:serial.c **** static uint8_t crcHi; + 79:serial.c **** static uint16_t crc; + 80:serial.c **** + 81:serial.c **** static uint8_t wykonajRozkaz(void) + 82:serial.c **** { + 83:serial.c **** // static portBASE_TYPE xResult; + 84:serial.c **** uint8_t wysylac = 0; + 85:serial.c **** + 86:serial.c **** switch (kodRozkazu) + 87:serial.c **** { + 88:serial.c **** case rOpuscRolete1: + 89:serial.c **** wiadomosc = 0x3F; + 90:serial.c **** wysylac = 2; + 91:serial.c **** break; + 92:serial.c **** + 93:serial.c **** case rOpuscRolete2: + 94:serial.c **** wiadomosc = 0x3F; + 95:serial.c **** wysylac = 3; + 96:serial.c **** break; + 97:serial.c **** + 98:serial.c **** case rPodniesRolete1: + 99:serial.c **** wiadomosc = 0xBF; + 100:serial.c **** wysylac = 2; + 101:serial.c **** break; + 102:serial.c **** + 103:serial.c **** case rPodniesRolete2: + 104:serial.c **** wiadomosc = 0xBF; + 105:serial.c **** wysylac = 3; + 106:serial.c **** break; + 107:serial.c **** + 108:serial.c **** case rZatrzymajRolete1: + 109:serial.c **** wiadomosc = 0x40; + 110:serial.c **** wysylac = 2; + 111:serial.c **** break; + 112:serial.c **** + 113:serial.c **** case rZatrzymajRolete2: + 114:serial.c **** wiadomosc = 0x40; + 115:serial.c **** wysylac = 3; + 116:serial.c **** break; + 117:serial.c **** + 118:serial.c **** case rPING: + 119:serial.c **** wysylac = 1; + 120:serial.c **** break; + 121:serial.c **** case rHELLO: + 122:serial.c **** wysylac = 4; + 123:serial.c **** break; + 124:serial.c **** case rFLASH: + 125:serial.c **** wysylac = 1; + 126:serial.c **** break; + 127:serial.c **** } + 128:serial.c **** return wysylac; + 129:serial.c **** } + 130:serial.c **** + 131:serial.c **** void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) + 132:serial.c **** { + 229 .LM2: + 230 .LFBB2: + 231 0034 FF92 push r15 + 232 0036 0F93 push r16 + 233 0038 1F93 push r17 + 234 003a CF93 push r28 + 235 003c DF93 push r29 + 236 003e 1F92 push __zero_reg__ + 237 0040 CDB7 in r28,__SP_L__ + 238 0042 DEB7 in r29,__SP_H__ + 239 /* prologue: function */ + 240 /* frame size = 1 */ + 241 /* stack size = 6 */ + 242 .L__stack_usage = 6 + 243 0044 8C01 movw r16,r24 + 133:serial.c **** (void) uxIndex; + 134:serial.c **** + 135:serial.c **** crSTART( xHandle ); + 245 .LM3: + 246 0046 FC01 movw r30,r24 + 247 0048 208D ldd r18,Z+24 + 248 004a 318D ldd r19,Z+25 + 249 004c 2535 cpi r18,85 + 250 004e F2E0 ldi r31,2 + 251 0050 3F07 cpc r19,r31 + 252 0052 01F4 brne .+2 + 253 0054 00C0 rjmp .L4 + 254 0056 00F0 brlo .+2 + 255 0058 00C0 rjmp .L5 + 256 005a 223D cpi r18,-46 + 257 005c E1E0 ldi r30,1 + 258 005e 3E07 cpc r19,r30 + 259 0060 01F4 brne .+2 + 260 0062 00C0 rjmp .L6 + 261 0064 00F0 brlo .+2 + 262 0066 00C0 rjmp .L7 + 263 0068 2136 cpi r18,97 + 264 006a 81E0 ldi r24,1 + 265 006c 3807 cpc r19,r24 + 266 006e 01F4 brne .+2 + 267 0070 00C0 rjmp .L8 + 268 0072 00F4 brsh .L9 + 269 0074 2C34 cpi r18,76 + 270 0076 F1E0 ldi r31,1 + 271 0078 3F07 cpc r19,r31 + 272 007a 01F4 brne .+2 + 273 007c 00C0 rjmp .L10 + 274 007e 00F4 brsh .L11 + 275 0080 232B or r18,r19 + 276 0082 01F4 brne .+2 + 277 0084 00C0 rjmp .L12 + 278 0086 00C0 rjmp .L2 + 279 .L11: + 280 0088 2D34 cpi r18,77 + 281 008a E1E0 ldi r30,1 + 282 008c 3E07 cpc r19,r30 + 283 008e 01F4 brne .+2 + 284 0090 00C0 rjmp .L13 + 285 0092 2036 cpi r18,96 + 286 0094 3140 sbci r19,1 + 287 0096 01F0 breq .+2 + 288 0098 00C0 rjmp .L2 + 289 .LBB9: + 136:serial.c **** static t_serialState stan; + 137:serial.c **** static uint8_t znak; + 138:serial.c **** static portBASE_TYPE xResult; + 139:serial.c **** static uint8_t dobryAdres; + 140:serial.c **** static uint8_t lOdebrDanych; + 141:serial.c **** static uint8_t rezultat; + 142:serial.c **** stan = s_sync; + 143:serial.c **** + 144:serial.c **** /* + 145:serial.c **** for ( ;; ) + 146:serial.c **** { + 147:serial.c **** static uint8_t tmp = 'C'; + 148:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + 149:serial.c **** Led1On(); + 150:serial.c **** TxStart(); + 151:serial.c **** vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + 152:serial.c **** crDELAY(xHandle, 100); + 153:serial.c **** + 154:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + 155:serial.c **** Led1Off(); + 156:serial.c **** TxStart(); + 157:serial.c **** vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + 158:serial.c **** crDELAY(xHandle, 100); + 159:serial.c **** } + 160:serial.c **** */ + 161:serial.c **** for( ;; ) + 162:serial.c **** { + 163:serial.c **** if (stan == s_sync) + 164:serial.c **** { + 165:serial.c **** znak=0; + 166:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + 167:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 168:serial.c **** { + 169:serial.c **** stan = s_addr; + 170:serial.c **** //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + 171:serial.c **** crc = _crc_xmodem_update(0, znak); + 172:serial.c **** } + 173:serial.c **** } + 174:serial.c **** if (stan == s_addr) + 175:serial.c **** { + 176:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 291 .LM4: + 292 009a 40E0 ldi r20,0 + 293 009c 50E0 ldi r21,0 + 294 009e 60E0 ldi r22,lo8(znak.2188) + 295 00a0 70E0 ldi r23,hi8(znak.2188) + 296 00a2 8091 0000 lds r24,xRxedChars + 297 00a6 9091 0000 lds r25,xRxedChars+1 + 298 00aa 0E94 0000 call xQueueCRReceive + 299 00ae 8093 0000 sts xResult.2189,r24 + 300 00b2 00C0 rjmp .L66 + 301 .L9: + 302 .LBE9: + 135:serial.c **** static t_serialState stan; + 304 .LM5: + 305 00b4 2738 cpi r18,-121 + 306 00b6 81E0 ldi r24,1 + 307 00b8 3807 cpc r19,r24 + 308 00ba 01F4 brne .+2 + 309 00bc 00C0 rjmp .L15 + 310 00be 00F4 brsh .L16 + 311 00c0 2638 cpi r18,-122 + 312 00c2 3140 sbci r19,1 + 313 00c4 01F0 breq .+2 + 314 00c6 00C0 rjmp .L2 + 315 .LBB24: + 177:serial.c **** if (xResult == pdPASS) + 178:serial.c **** { + 179:serial.c **** stan = s_rozkaz; + 180:serial.c **** crc = _crc_xmodem_update(crc, znak); + 181:serial.c **** if (znak == adres) + 182:serial.c **** dobryAdres = 1; + 183:serial.c **** else + 184:serial.c **** dobryAdres = 0; + 185:serial.c **** } + 186:serial.c **** else + 187:serial.c **** { + 188:serial.c **** stan = s_sync; + 189:serial.c **** } + 190:serial.c **** } + 191:serial.c **** if (stan == s_rozkaz) + 192:serial.c **** { + 193:serial.c **** Led1On(); + 194:serial.c **** Led2Off(); + 195:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + 317 .LM6: + 318 00c8 40E0 ldi r20,0 + 319 00ca 50E0 ldi r21,0 + 320 00cc 60E0 ldi r22,lo8(kodRozkazu) + 321 00ce 70E0 ldi r23,hi8(kodRozkazu) + 322 00d0 8091 0000 lds r24,xRxedChars + 323 00d4 9091 0000 lds r25,xRxedChars+1 + 324 00d8 0E94 0000 call xQueueCRReceive + 325 00dc 8093 0000 sts xResult.2189,r24 + 326 00e0 00C0 rjmp .L71 + 327 .L16: + 328 .LBE24: + 135:serial.c **** static t_serialState stan; + 330 .LM7: + 331 00e2 243A cpi r18,-92 + 332 00e4 81E0 ldi r24,1 + 333 00e6 3807 cpc r19,r24 + 334 00e8 01F4 brne .+2 + 335 00ea 00C0 rjmp .L18 + 336 00ec 253A cpi r18,-91 + 337 00ee 3140 sbci r19,1 + 338 00f0 01F0 breq .+2 + 339 00f2 00C0 rjmp .L2 + 340 .LBB25: + 196:serial.c **** if (xResult == pdPASS) + 197:serial.c **** { + 198:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 199:serial.c **** stan = s_len; + 200:serial.c **** } + 201:serial.c **** else + 202:serial.c **** { + 203:serial.c **** stan = s_sync; + 204:serial.c **** } + 205:serial.c **** } + 206:serial.c **** if (stan == s_len) + 207:serial.c **** { + 208:serial.c **** Led1Off(); + 209:serial.c **** Led2On(); + 210:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + 342 .LM8: + 343 00f4 81E0 ldi r24,lo8(1) + 344 00f6 8093 0000 sts xResult.2189,r24 + 345 00fa 00C0 rjmp .L76 + 346 .L7: + 347 .LBE25: + 135:serial.c **** static t_serialState stan; + 349 .LM9: + 350 00fc 2F30 cpi r18,15 + 351 00fe F2E0 ldi r31,2 + 352 0100 3F07 cpc r19,r31 + 353 0102 01F4 brne .+2 + 354 0104 00C0 rjmp .L20 + 355 0106 00F4 brsh .L21 + 356 0108 243F cpi r18,-12 + 357 010a E1E0 ldi r30,1 + 358 010c 3E07 cpc r19,r30 + 359 010e 01F4 brne .+2 + 360 0110 00C0 rjmp .L22 + 361 0112 00F4 brsh .L23 + 362 0114 233D cpi r18,-45 + 363 0116 3140 sbci r19,1 + 364 0118 01F0 breq .+2 + 365 011a 00C0 rjmp .L2 + 366 .LBB26: + 211:serial.c **** if (xResult == pdPASS) + 212:serial.c **** { + 213:serial.c **** crc = _crc_xmodem_update(crc, dlDanych); + 214:serial.c **** lOdebrDanych = 0; + 215:serial.c **** stan = s_dane; + 216:serial.c **** Led1On(); + 217:serial.c **** Led2On(); + 218:serial.c **** } + 219:serial.c **** else + 220:serial.c **** { + 221:serial.c **** stan = s_sync; + 222:serial.c **** } + 223:serial.c **** } + 224:serial.c **** if (stan == s_dane) + 225:serial.c **** { + 226:serial.c **** if (lOdebrDanych == dlDanych) + 227:serial.c **** { + 228:serial.c **** stan = s_CRC_HI; + 229:serial.c **** } + 230:serial.c **** else + 231:serial.c **** { + 232:serial.c **** //Led2Off(); + 233:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + 368 .LM10: + 369 011c 81E0 ldi r24,lo8(1) + 370 011e 8093 0000 sts xResult.2189,r24 + 371 0122 00C0 rjmp .L81 + 372 .L23: + 373 .LBE26: + 135:serial.c **** static t_serialState stan; + 375 .LM11: + 376 0124 253F cpi r18,-11 + 377 0126 E1E0 ldi r30,1 + 378 0128 3E07 cpc r19,r30 + 379 012a 01F4 brne .+2 + 380 012c 00C0 rjmp .L25 + 381 012e 2E30 cpi r18,14 + 382 0130 3240 sbci r19,2 + 383 0132 01F0 breq .+2 + 384 0134 00C0 rjmp .L2 + 385 .LBB27: + 234:serial.c **** if (xResult == pdPASS) + 235:serial.c **** { + 236:serial.c **** crc = _crc_xmodem_update(crc, znak); + 237:serial.c **** if (lOdebrDanych < MAX_DATA_LEN) + 238:serial.c **** bDane[lOdebrDanych] = znak; + 239:serial.c **** lOdebrDanych++; + 240:serial.c **** } + 241:serial.c **** else + 242:serial.c **** { + 243:serial.c **** Led1Off(); + 244:serial.c **** stan = s_sync; + 245:serial.c **** } + 246:serial.c **** } + 247:serial.c **** } + 248:serial.c **** if (stan == s_CRC_HI) + 249:serial.c **** { + 250:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + 251:serial.c **** if (xResult == pdPASS) + 252:serial.c **** { + 253:serial.c **** stan = s_CRC_LO; + 254:serial.c **** } + 255:serial.c **** else + 256:serial.c **** { + 257:serial.c **** Led1Off(); + 258:serial.c **** stan = s_sync; + 259:serial.c **** } + 260:serial.c **** } + 261:serial.c **** if (stan == s_CRC_LO) + 262:serial.c **** { + 263:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + 387 .LM12: + 388 0136 40E0 ldi r20,0 + 389 0138 50E0 ldi r21,0 + 390 013a 60E0 ldi r22,lo8(crcLo) + 391 013c 70E0 ldi r23,hi8(crcLo) + 392 013e 8091 0000 lds r24,xRxedChars + 393 0142 9091 0000 lds r25,xRxedChars+1 + 394 0146 0E94 0000 call xQueueCRReceive + 395 014a 8093 0000 sts xResult.2189,r24 + 396 014e 00C0 rjmp .L90 + 397 .L21: + 398 .LBE27: + 135:serial.c **** static t_serialState stan; + 400 .LM13: + 401 0150 2C34 cpi r18,76 + 402 0152 82E0 ldi r24,2 + 403 0154 3807 cpc r19,r24 + 404 0156 01F4 brne .+2 + 405 0158 00C0 rjmp .L27 + 406 015a 00F4 brsh .L28 + 407 015c 2234 cpi r18,66 + 408 015e F2E0 ldi r31,2 + 409 0160 3F07 cpc r19,r31 + 410 0162 01F4 brne .+2 + 411 0164 00C0 rjmp .L29 + 412 0166 2334 cpi r18,67 + 413 0168 3240 sbci r19,2 + 414 016a 01F0 breq .+2 + 415 016c 00C0 rjmp .L2 + 416 .LBB28: + 417 .LBB10: + 264:serial.c **** if (xResult == pdPASS) + 265:serial.c **** { + 266:serial.c **** if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + 267:serial.c **** { + 268:serial.c **** Led1Off(); + 269:serial.c **** stan = s_sync; + 270:serial.c **** } + 271:serial.c **** else + 272:serial.c **** { + 273:serial.c **** stan = s_CRC_OK; + 274:serial.c **** } + 275:serial.c **** } + 276:serial.c **** } + 277:serial.c **** if (stan == s_CRC_OK) + 278:serial.c **** { + 279:serial.c **** if (dobryAdres == 1) + 280:serial.c **** { + 281:serial.c **** if (lOdebrDanych > MAX_DATA_LEN) + 282:serial.c **** lOdebrDanych = MAX_DATA_LEN; + 283:serial.c **** rezultat = wykonajRozkaz(); + 284:serial.c **** if (rezultat == 1) + 285:serial.c **** { + 286:serial.c **** //SYNC + 287:serial.c **** uint8_t temp; + 288:serial.c **** temp = SYNC; + 289:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + 419 .LM14: + 420 016e 81E0 ldi r24,lo8(1) + 421 0170 8093 0000 sts xResult.2189,r24 + 422 0174 00C0 rjmp .L113 + 423 .L28: + 424 .LBE10: + 425 .LBE28: + 135:serial.c **** static t_serialState stan; + 427 .LM15: + 428 0176 2D34 cpi r18,77 + 429 0178 E2E0 ldi r30,2 + 430 017a 3E07 cpc r19,r30 + 431 017c 01F4 brne .+2 + 432 017e 00C0 rjmp .L31 + 433 0180 2435 cpi r18,84 + 434 0182 3240 sbci r19,2 + 435 0184 01F0 breq .+2 + 436 0186 00C0 rjmp .L2 + 437 .LBB29: + 438 .LBB12: + 290:serial.c **** crc = _crc_xmodem_update(0, temp); + 291:serial.c **** + 292:serial.c **** //ADRES 0x00 adres mastera + 293:serial.c **** temp = 0x00; + 294:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + 295:serial.c **** crc = _crc_xmodem_update(crc, temp); + 296:serial.c **** + 297:serial.c **** //Rozkaz + 298:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + 440 .LM16: + 441 0188 40E0 ldi r20,0 + 442 018a 50E0 ldi r21,0 + 443 018c 60E0 ldi r22,lo8(kodRozkazu) + 444 018e 70E0 ldi r23,hi8(kodRozkazu) + 445 0190 8091 0000 lds r24,xCharsForTx + 446 0194 9091 0000 lds r25,xCharsForTx+1 + 447 0198 0E94 0000 call xQueueCRSend + 448 019c 8093 0000 sts xResult.2189,r24 + 449 01a0 00C0 rjmp .L116 + 450 .L5: + 451 .LBE12: + 452 .LBE29: + 135:serial.c **** static t_serialState stan; + 454 .LM17: + 455 01a2 2E39 cpi r18,-98 + 456 01a4 82E0 ldi r24,2 + 457 01a6 3807 cpc r19,r24 + 458 01a8 01F4 brne .+2 + 459 01aa 00C0 rjmp .L33 + 460 01ac 00F0 brlo .+2 + 461 01ae 00C0 rjmp .L34 + 462 01b0 2237 cpi r18,114 + 463 01b2 F2E0 ldi r31,2 + 464 01b4 3F07 cpc r19,r31 + 465 01b6 01F4 brne .+2 + 466 01b8 00C0 rjmp .L35 + 467 01ba 00F4 brsh .L36 + 468 01bc 2D35 cpi r18,93 + 469 01be E2E0 ldi r30,2 + 470 01c0 3E07 cpc r19,r30 + 471 01c2 01F4 brne .+2 + 472 01c4 00C0 rjmp .L37 + 473 01c6 00F4 brsh .L38 + 474 01c8 2C35 cpi r18,92 + 475 01ca 3240 sbci r19,2 + 476 01cc 01F0 breq .+2 + 477 01ce 00C0 rjmp .L2 + 478 .LBB30: + 479 .LBB13: + 299:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 300:serial.c **** + 301:serial.c **** //Długość danych + 302:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + 481 .LM18: + 482 01d0 40E0 ldi r20,0 + 483 01d2 50E0 ldi r21,0 + 484 01d4 60E0 ldi r22,lo8(lOdebrDanych.2191) + 485 01d6 70E0 ldi r23,hi8(lOdebrDanych.2191) + 486 01d8 8091 0000 lds r24,xCharsForTx + 487 01dc 9091 0000 lds r25,xCharsForTx+1 + 488 01e0 0E94 0000 call xQueueCRSend + 489 01e4 8093 0000 sts xResult.2189,r24 + 490 01e8 00C0 rjmp .L118 + 491 .L38: + 492 .LBE13: + 493 .LBE30: + 135:serial.c **** static t_serialState stan; + 495 .LM19: + 496 01ea 2836 cpi r18,104 + 497 01ec E2E0 ldi r30,2 + 498 01ee 3E07 cpc r19,r30 + 499 01f0 01F4 brne .+2 + 500 01f2 00C0 rjmp .L40 + 501 01f4 2936 cpi r18,105 + 502 01f6 3240 sbci r19,2 + 503 01f8 01F0 breq .+2 + 504 01fa 00C0 rjmp .L2 + 505 .LBB31: + 506 .LBB14: + 303:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 304:serial.c **** + 305:serial.c **** //Dane + 306:serial.c **** for (temp = 0; temp < lOdebrDanych; temp++) + 307:serial.c **** { + 308:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + 508 .LM20: + 509 01fc 81E0 ldi r24,lo8(1) + 510 01fe 8093 0000 sts xResult.2189,r24 + 511 0202 00C0 rjmp .L122 + 512 .L36: + 513 .LBE14: + 514 .LBE31: + 135:serial.c **** static t_serialState stan; + 516 .LM21: + 517 0204 2637 cpi r18,118 + 518 0206 82E0 ldi r24,2 + 519 0208 3807 cpc r19,r24 + 520 020a 01F4 brne .+2 + 521 020c 00C0 rjmp .L42 + 522 020e 00F4 brsh .L43 + 523 0210 2337 cpi r18,115 + 524 0212 3240 sbci r19,2 + 525 0214 01F0 breq .+2 + 526 0216 00C0 rjmp .L2 + 527 .LBB32: + 528 .LBB15: + 309:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 310:serial.c **** } + 311:serial.c **** + 312:serial.c **** temp = (uint8_t)(crc>>8); + 313:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 530 .LM22: + 531 0218 81E0 ldi r24,lo8(1) + 532 021a 8093 0000 sts xResult.2189,r24 + 533 021e 00C0 rjmp .L125 + 534 .L43: + 535 .LBE15: + 536 .LBE32: + 135:serial.c **** static t_serialState stan; + 538 .LM23: + 539 0220 2737 cpi r18,119 + 540 0222 82E0 ldi r24,2 + 541 0224 3807 cpc r19,r24 + 542 0226 01F4 brne .+2 + 543 0228 00C0 rjmp .L45 + 544 022a 2E38 cpi r18,-114 + 545 022c 3240 sbci r19,2 + 546 022e 01F0 breq .+2 + 547 0230 00C0 rjmp .L2 + 548 .LBB33: + 549 .LBB16: + 314:serial.c **** temp = (uint8_t)(crc & 0xFF); + 315:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 316:serial.c **** + 317:serial.c **** if (xResult == pdPASS) + 318:serial.c **** { + 319:serial.c **** TxStart(); + 320:serial.c **** } + 321:serial.c **** vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nada + 322:serial.c **** + 323:serial.c **** if (kodRozkazu == rFLASH) + 324:serial.c **** { + 325:serial.c **** Led1On(); + 326:serial.c **** Led2On(); + 327:serial.c **** crDELAY(xHandle, 10); + 328:serial.c **** Led1Off(); + 551 .LM24: + 552 0232 0E94 0000 call Led1Off + 329:serial.c **** Led2Off(); + 554 .LM25: + 555 0236 0E94 0000 call Led2Off + 330:serial.c **** (*((void(*)(void))BOOT_START))(); //reboot + 557 .LM26: + 558 023a E0E0 ldi r30,0 + 559 023c FCE1 ldi r31,lo8(28) + 560 023e 0995 icall + 561 0240 00C0 rjmp .L130 + 562 .L34: + 563 .LBE16: + 564 .LBE33: + 135:serial.c **** static t_serialState stan; + 566 .LM27: + 567 0242 2D3B cpi r18,-67 + 568 0244 F2E0 ldi r31,2 + 569 0246 3F07 cpc r19,r31 + 570 0248 01F4 brne .+2 + 571 024a 00C0 rjmp .L47 + 572 024c 00F4 brsh .L48 + 573 024e 263A cpi r18,-90 + 574 0250 E2E0 ldi r30,2 + 575 0252 3E07 cpc r19,r30 + 576 0254 01F4 brne .+2 + 577 0256 00C0 rjmp .L49 + 578 0258 00F4 brsh .L50 + 579 025a 2F39 cpi r18,-97 + 580 025c 3240 sbci r19,2 + 581 025e 01F0 breq .L52 + 582 0260 00C0 rjmp .L2 + 583 .L50: + 584 0262 273A cpi r18,-89 + 585 0264 E2E0 ldi r30,2 + 586 0266 3E07 cpc r19,r30 + 587 0268 01F0 breq .L52 + 588 026a 2C3B cpi r18,-68 + 589 026c 3240 sbci r19,2 + 590 026e 01F0 breq .+2 + 591 0270 00C0 rjmp .L2 + 592 .LBB34: + 593 .LBB17: + 331:serial.c **** } + 332:serial.c **** } + 333:serial.c **** else if (rezultat == 2) + 334:serial.c **** { + 335:serial.c **** crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + 336:serial.c **** } + 337:serial.c **** else if (rezultat == 3) + 338:serial.c **** { + 339:serial.c **** crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + 340:serial.c **** } + 341:serial.c **** else if (rezultat == 4) + 342:serial.c **** { + 343:serial.c **** //SYNC + 344:serial.c **** crc = 0; + 345:serial.c **** uint8_t temp; + 346:serial.c **** + 347:serial.c **** //Dane + 348:serial.c **** for (temp = 0; temp < 11; temp++) + 349:serial.c **** { + 350:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + 595 .LM28: + 596 0272 6981 ldd r22,Y+1 + 597 0274 70E0 ldi r23,0 + 598 0276 6050 subi r22,lo8(-(bHelloResp)) + 599 0278 7040 sbci r23,hi8(-(bHelloResp)) + 600 027a 40E0 ldi r20,0 + 601 027c 50E0 ldi r21,0 + 602 027e 8091 0000 lds r24,xCharsForTx + 603 0282 9091 0000 lds r25,xCharsForTx+1 + 604 0286 0E94 0000 call xQueueCRSend + 605 028a 8093 0000 sts xResult.2189,r24 + 606 028e 00C0 rjmp .L137 + 607 .L48: + 608 .LBE17: + 609 .LBE34: + 135:serial.c **** static t_serialState stan; + 611 .LM29: + 612 0290 2A3C cpi r18,-54 + 613 0292 82E0 ldi r24,2 + 614 0294 3807 cpc r19,r24 + 615 0296 01F4 brne .+2 + 616 0298 00C0 rjmp .L54 + 617 029a 00F4 brsh .L55 + 618 029c 263C cpi r18,-58 + 619 029e F2E0 ldi r31,2 + 620 02a0 3F07 cpc r19,r31 + 621 02a2 01F4 brne .+2 + 622 02a4 00C0 rjmp .L56 + 623 02a6 273C cpi r18,-57 + 624 02a8 3240 sbci r19,2 + 625 02aa 01F0 breq .+2 + 626 02ac 00C0 rjmp .L2 + 627 .LBB35: + 628 .LBB19: + 351:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 352:serial.c **** } + 353:serial.c **** + 354:serial.c **** temp = (uint8_t)(crc>>8); + 355:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 630 .LM30: + 631 02ae 81E0 ldi r24,lo8(1) + 632 02b0 8093 0000 sts xResult.2189,r24 + 633 02b4 00C0 rjmp .L142 + 634 .L55: + 635 .LBE19: + 636 .LBE35: + 135:serial.c **** static t_serialState stan; + 638 .LM31: + 639 02b6 2B3C cpi r18,-53 + 640 02b8 E2E0 ldi r30,2 + 641 02ba 3E07 cpc r19,r30 + 642 02bc 01F4 brne .+2 + 643 02be 00C0 rjmp .L58 + 644 02c0 223F cpi r18,-14 + 645 02c2 3240 sbci r19,2 + 646 02c4 01F0 breq .+2 + 647 02c6 00C0 rjmp .L2 + 648 .LBB36: + 356:serial.c **** temp = (uint8_t)(crc & 0xFF); + 357:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 358:serial.c **** + 359:serial.c **** if (xResult == pdPASS) + 360:serial.c **** { + 361:serial.c **** TxStart(); + 362:serial.c **** } + 363:serial.c **** vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nada + 364:serial.c **** } + 365:serial.c **** Led1Off(); + 366:serial.c **** Led2Off(); + 367:serial.c **** stan = s_sync; + 368:serial.c **** } + 369:serial.c **** else //Zły adres + 370:serial.c **** { + 371:serial.c **** if (kodRozkazu == rFLASH) + 372:serial.c **** { + 373:serial.c **** DISABLE_RX(); + 374:serial.c **** Led1On(); + 375:serial.c **** Led2On(); + 376:serial.c **** //TODO disable RX buffer + 377:serial.c **** crDELAY(xHandle, 1000); + 378:serial.c **** ENABLE_RX(); + 650 .LM32: + 651 02c8 8091 C100 lds r24,193 + 652 02cc 8061 ori r24,lo8(16) + 653 02ce 8093 C100 sts 193,r24 + 654 02d2 00C0 rjmp .L146 + 655 .L52: + 339:serial.c **** } + 657 .LM33: + 658 02d4 81E0 ldi r24,lo8(1) + 659 02d6 8093 0000 sts xResult.2189,r24 + 660 .L130: + 365:serial.c **** Led2Off(); + 662 .LM34: + 663 02da 0E94 0000 call Led1Off + 366:serial.c **** stan = s_sync; + 665 .LM35: + 666 02de 0E94 0000 call Led2Off + 667 .L12: + 142:serial.c **** + 669 .LM36: + 670 02e2 1092 0000 sts stan.2187,__zero_reg__ + 671 .L95: + 163:serial.c **** { + 673 .LM37: + 674 02e6 8091 0000 lds r24,stan.2187 + 675 02ea 8111 cpse r24,__zero_reg__ + 676 02ec 00C0 rjmp .L61 + 165:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + 678 .LM38: + 679 02ee 1092 0000 sts znak.2188,__zero_reg__ + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 681 .LM39: + 682 02f2 4FEF ldi r20,lo8(-1) + 683 02f4 5FEF ldi r21,lo8(-1) + 684 02f6 60E0 ldi r22,lo8(znak.2188) + 685 02f8 70E0 ldi r23,hi8(znak.2188) + 686 02fa 8091 0000 lds r24,xRxedChars + 687 02fe 9091 0000 lds r25,xRxedChars+1 + 688 0302 0E94 0000 call xQueueCRReceive + 689 0306 8093 0000 sts xResult.2189,r24 + 690 030a 8C3F cpi r24,lo8(-4) + 691 030c 01F4 brne .L62 + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 693 .LM40: + 694 030e 8CE4 ldi r24,lo8(76) + 695 0310 91E0 ldi r25,lo8(1) + 696 0312 00C0 rjmp .L150 + 697 .L10: + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 699 .LM41: + 700 0314 40E0 ldi r20,0 + 701 0316 50E0 ldi r21,0 + 702 0318 60E0 ldi r22,lo8(znak.2188) + 703 031a 70E0 ldi r23,hi8(znak.2188) + 704 031c 8091 0000 lds r24,xRxedChars + 705 0320 9091 0000 lds r25,xRxedChars+1 + 706 0324 0E94 0000 call xQueueCRReceive + 707 0328 8093 0000 sts xResult.2189,r24 + 708 .L62: + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 710 .LM42: + 711 032c 8091 0000 lds r24,xResult.2189 + 712 0330 8B3F cpi r24,lo8(-5) + 713 0332 01F4 brne .L63 + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 715 .LM43: + 716 0334 8DE4 ldi r24,lo8(77) + 717 0336 91E0 ldi r25,lo8(1) + 718 0338 00C0 rjmp .L150 + 719 .L13: + 166:serial.c **** if ((xResult == pdPASS) && (znak == SYNC)) + 721 .LM44: + 722 033a 81E0 ldi r24,lo8(1) + 723 033c 8093 0000 sts xResult.2189,r24 + 724 .L63: + 167:serial.c **** { + 726 .LM45: + 727 0340 8091 0000 lds r24,xResult.2189 + 728 0344 8130 cpi r24,lo8(1) + 729 0346 01F4 brne .L61 + 167:serial.c **** { + 731 .LM46: + 732 0348 9091 0000 lds r25,znak.2188 + 733 034c 9A35 cpi r25,lo8(90) + 734 034e 01F4 brne .L61 + 169:serial.c **** //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + 736 .LM47: + 737 0350 8093 0000 sts stan.2187,r24 + 171:serial.c **** } + 739 .LM48: + 740 0354 6AE5 ldi r22,lo8(90) + 741 0356 80E0 ldi r24,0 + 742 0358 90E0 ldi r25,0 + 743 035a 0E94 0000 call _crc_xmodem_update + 744 035e 9093 0000 sts crc+1,r25 + 745 0362 8093 0000 sts crc,r24 + 746 .L61: + 174:serial.c **** { + 748 .LM49: + 749 0366 8091 0000 lds r24,stan.2187 + 750 036a 8130 cpi r24,lo8(1) + 751 036c 01F4 brne .L65 + 176:serial.c **** if (xResult == pdPASS) + 753 .LM50: + 754 036e 41E0 ldi r20,lo8(1) + 755 0370 50E0 ldi r21,0 + 756 0372 60E0 ldi r22,lo8(znak.2188) + 757 0374 70E0 ldi r23,hi8(znak.2188) + 758 0376 8091 0000 lds r24,xRxedChars + 759 037a 9091 0000 lds r25,xRxedChars+1 + 760 037e 0E94 0000 call xQueueCRReceive + 761 0382 8093 0000 sts xResult.2189,r24 + 762 0386 8C3F cpi r24,lo8(-4) + 763 0388 01F4 brne .L66 + 176:serial.c **** if (xResult == pdPASS) + 765 .LM51: + 766 038a 80E6 ldi r24,lo8(96) + 767 038c 91E0 ldi r25,lo8(1) + 768 038e 00C0 rjmp .L150 + 769 .L66: + 176:serial.c **** if (xResult == pdPASS) + 771 .LM52: + 772 0390 8091 0000 lds r24,xResult.2189 + 773 0394 8B3F cpi r24,lo8(-5) + 774 0396 01F4 brne .L67 + 176:serial.c **** if (xResult == pdPASS) + 776 .LM53: + 777 0398 81E6 ldi r24,lo8(97) + 778 039a 91E0 ldi r25,lo8(1) + 779 039c 00C0 rjmp .L150 + 780 .L8: + 176:serial.c **** if (xResult == pdPASS) + 782 .LM54: + 783 039e 81E0 ldi r24,lo8(1) + 784 03a0 8093 0000 sts xResult.2189,r24 + 785 .L67: + 177:serial.c **** { + 787 .LM55: + 788 03a4 F090 0000 lds r15,xResult.2189 + 789 03a8 F1E0 ldi r31,lo8(1) + 790 03aa FF12 cpse r15,r31 + 791 03ac 00C0 rjmp .L68 + 179:serial.c **** crc = _crc_xmodem_update(crc, znak); + 793 .LM56: + 794 03ae 82E0 ldi r24,lo8(2) + 795 03b0 8093 0000 sts stan.2187,r24 + 180:serial.c **** if (znak == adres) + 797 .LM57: + 798 03b4 6091 0000 lds r22,znak.2188 + 799 03b8 8091 0000 lds r24,crc + 800 03bc 9091 0000 lds r25,crc+1 + 801 03c0 0E94 0000 call _crc_xmodem_update + 802 03c4 9093 0000 sts crc+1,r25 + 803 03c8 8093 0000 sts crc,r24 + 181:serial.c **** dobryAdres = 1; + 805 .LM58: + 806 03cc 9091 0000 lds r25,znak.2188 + 807 03d0 8091 0000 lds r24,adres + 808 03d4 9813 cpse r25,r24 + 809 03d6 00C0 rjmp .L69 + 182:serial.c **** else + 811 .LM59: + 812 03d8 F092 0000 sts dobryAdres.2190,r15 + 813 03dc 00C0 rjmp .L65 + 814 .L69: + 184:serial.c **** } + 816 .LM60: + 817 03de 1092 0000 sts dobryAdres.2190,__zero_reg__ + 818 03e2 00C0 rjmp .L65 + 819 .L68: + 188:serial.c **** } + 821 .LM61: + 822 03e4 1092 0000 sts stan.2187,__zero_reg__ + 823 .L65: + 191:serial.c **** { + 825 .LM62: + 826 03e8 8091 0000 lds r24,stan.2187 + 827 03ec 8230 cpi r24,lo8(2) + 828 03ee 01F4 brne .L70 + 193:serial.c **** Led2Off(); + 830 .LM63: + 831 03f0 0E94 0000 call Led1On + 194:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + 833 .LM64: + 834 03f4 0E94 0000 call Led2Off + 195:serial.c **** if (xResult == pdPASS) + 836 .LM65: + 837 03f8 41E0 ldi r20,lo8(1) + 838 03fa 50E0 ldi r21,0 + 839 03fc 60E0 ldi r22,lo8(kodRozkazu) + 840 03fe 70E0 ldi r23,hi8(kodRozkazu) + 841 0400 8091 0000 lds r24,xRxedChars + 842 0404 9091 0000 lds r25,xRxedChars+1 + 843 0408 0E94 0000 call xQueueCRReceive + 844 040c 8093 0000 sts xResult.2189,r24 + 845 0410 8C3F cpi r24,lo8(-4) + 846 0412 01F4 brne .L71 + 195:serial.c **** if (xResult == pdPASS) + 848 .LM66: + 849 0414 86E8 ldi r24,lo8(-122) + 850 0416 91E0 ldi r25,lo8(1) + 851 0418 00C0 rjmp .L150 + 852 .L71: + 195:serial.c **** if (xResult == pdPASS) + 854 .LM67: + 855 041a 8091 0000 lds r24,xResult.2189 + 856 041e 8B3F cpi r24,lo8(-5) + 857 0420 01F4 brne .L72 + 195:serial.c **** if (xResult == pdPASS) + 859 .LM68: + 860 0422 87E8 ldi r24,lo8(-121) + 861 0424 91E0 ldi r25,lo8(1) + 862 0426 00C0 rjmp .L150 + 863 .L15: + 195:serial.c **** if (xResult == pdPASS) + 865 .LM69: + 866 0428 81E0 ldi r24,lo8(1) + 867 042a 8093 0000 sts xResult.2189,r24 + 868 .L72: + 196:serial.c **** { + 870 .LM70: + 871 042e 8091 0000 lds r24,xResult.2189 + 872 0432 8130 cpi r24,lo8(1) + 873 0434 01F4 brne .L73 + 198:serial.c **** stan = s_len; + 875 .LM71: + 876 0436 6091 0000 lds r22,kodRozkazu + 877 043a 8091 0000 lds r24,crc + 878 043e 9091 0000 lds r25,crc+1 + 879 0442 0E94 0000 call _crc_xmodem_update + 880 0446 9093 0000 sts crc+1,r25 + 881 044a 8093 0000 sts crc,r24 + 199:serial.c **** } + 883 .LM72: + 884 044e 83E0 ldi r24,lo8(3) + 885 0450 8093 0000 sts stan.2187,r24 + 886 0454 00C0 rjmp .L70 + 887 .L73: + 203:serial.c **** } + 889 .LM73: + 890 0456 1092 0000 sts stan.2187,__zero_reg__ + 891 .L70: + 206:serial.c **** { + 893 .LM74: + 894 045a 8091 0000 lds r24,stan.2187 + 895 045e 8330 cpi r24,lo8(3) + 896 0460 01F0 breq .+2 + 897 0462 00C0 rjmp .L74 + 208:serial.c **** Led2On(); + 899 .LM75: + 900 0464 0E94 0000 call Led1Off + 209:serial.c **** crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + 902 .LM76: + 903 0468 0E94 0000 call Led2On + 210:serial.c **** if (xResult == pdPASS) + 905 .LM77: + 906 046c 41E0 ldi r20,lo8(1) + 907 046e 50E0 ldi r21,0 + 908 0470 60E0 ldi r22,lo8(dlDanych) + 909 0472 70E0 ldi r23,hi8(dlDanych) + 910 0474 8091 0000 lds r24,xRxedChars + 911 0478 9091 0000 lds r25,xRxedChars+1 + 912 047c 0E94 0000 call xQueueCRReceive + 913 0480 8093 0000 sts xResult.2189,r24 + 914 0484 8C3F cpi r24,lo8(-4) + 915 0486 01F4 brne .L75 + 210:serial.c **** if (xResult == pdPASS) + 917 .LM78: + 918 0488 84EA ldi r24,lo8(-92) + 919 048a 91E0 ldi r25,lo8(1) + 920 048c 00C0 rjmp .L150 + 921 .L18: + 210:serial.c **** if (xResult == pdPASS) + 923 .LM79: + 924 048e 40E0 ldi r20,0 + 925 0490 50E0 ldi r21,0 + 926 0492 60E0 ldi r22,lo8(dlDanych) + 927 0494 70E0 ldi r23,hi8(dlDanych) + 928 0496 8091 0000 lds r24,xRxedChars + 929 049a 9091 0000 lds r25,xRxedChars+1 + 930 049e 0E94 0000 call xQueueCRReceive + 931 04a2 8093 0000 sts xResult.2189,r24 + 932 .L75: + 210:serial.c **** if (xResult == pdPASS) + 934 .LM80: + 935 04a6 8091 0000 lds r24,xResult.2189 + 936 04aa 8B3F cpi r24,lo8(-5) + 937 04ac 01F4 brne .L76 + 210:serial.c **** if (xResult == pdPASS) + 939 .LM81: + 940 04ae 85EA ldi r24,lo8(-91) + 941 04b0 91E0 ldi r25,lo8(1) + 942 04b2 00C0 rjmp .L150 + 943 .L76: + 211:serial.c **** { + 945 .LM82: + 946 04b4 8091 0000 lds r24,xResult.2189 + 947 04b8 8130 cpi r24,lo8(1) + 948 04ba 01F4 brne .L77 + 213:serial.c **** lOdebrDanych = 0; + 950 .LM83: + 951 04bc 6091 0000 lds r22,dlDanych + 952 04c0 8091 0000 lds r24,crc + 953 04c4 9091 0000 lds r25,crc+1 + 954 04c8 0E94 0000 call _crc_xmodem_update + 955 04cc 9093 0000 sts crc+1,r25 + 956 04d0 8093 0000 sts crc,r24 + 214:serial.c **** stan = s_dane; + 958 .LM84: + 959 04d4 1092 0000 sts lOdebrDanych.2191,__zero_reg__ + 215:serial.c **** Led1On(); + 961 .LM85: + 962 04d8 84E0 ldi r24,lo8(4) + 963 04da 8093 0000 sts stan.2187,r24 + 216:serial.c **** Led2On(); + 965 .LM86: + 966 04de 0E94 0000 call Led1On + 217:serial.c **** } + 968 .LM87: + 969 04e2 0E94 0000 call Led2On + 970 04e6 00C0 rjmp .L74 + 971 .L77: + 221:serial.c **** } + 973 .LM88: + 974 04e8 1092 0000 sts stan.2187,__zero_reg__ + 975 .L74: + 224:serial.c **** { + 977 .LM89: + 978 04ec 8091 0000 lds r24,stan.2187 + 979 04f0 8430 cpi r24,lo8(4) + 980 04f2 01F0 breq .+2 + 981 04f4 00C0 rjmp .L78 + 226:serial.c **** { + 983 .LM90: + 984 04f6 8091 0000 lds r24,dlDanych + 985 04fa 9091 0000 lds r25,lOdebrDanych.2191 + 986 04fe 9813 cpse r25,r24 + 987 0500 00C0 rjmp .L79 + 228:serial.c **** } + 989 .LM91: + 990 0502 85E0 ldi r24,lo8(5) + 991 0504 8093 0000 sts stan.2187,r24 + 992 0508 00C0 rjmp .L78 + 993 .L79: + 233:serial.c **** if (xResult == pdPASS) + 995 .LM92: + 996 050a 41E0 ldi r20,lo8(1) + 997 050c 50E0 ldi r21,0 + 998 050e 60E0 ldi r22,lo8(znak.2188) + 999 0510 70E0 ldi r23,hi8(znak.2188) + 1000 0512 8091 0000 lds r24,xRxedChars + 1001 0516 9091 0000 lds r25,xRxedChars+1 + 1002 051a 0E94 0000 call xQueueCRReceive + 1003 051e 8093 0000 sts xResult.2189,r24 + 1004 0522 8C3F cpi r24,lo8(-4) + 1005 0524 01F4 brne .L80 + 233:serial.c **** if (xResult == pdPASS) + 1007 .LM93: + 1008 0526 82ED ldi r24,lo8(-46) + 1009 0528 91E0 ldi r25,lo8(1) + 1010 052a 00C0 rjmp .L150 + 1011 .L6: + 233:serial.c **** if (xResult == pdPASS) + 1013 .LM94: + 1014 052c 40E0 ldi r20,0 + 1015 052e 50E0 ldi r21,0 + 1016 0530 60E0 ldi r22,lo8(znak.2188) + 1017 0532 70E0 ldi r23,hi8(znak.2188) + 1018 0534 8091 0000 lds r24,xRxedChars + 1019 0538 9091 0000 lds r25,xRxedChars+1 + 1020 053c 0E94 0000 call xQueueCRReceive + 1021 0540 8093 0000 sts xResult.2189,r24 + 1022 .L80: + 233:serial.c **** if (xResult == pdPASS) + 1024 .LM95: + 1025 0544 8091 0000 lds r24,xResult.2189 + 1026 0548 8B3F cpi r24,lo8(-5) + 1027 054a 01F4 brne .L81 + 233:serial.c **** if (xResult == pdPASS) + 1029 .LM96: + 1030 054c 83ED ldi r24,lo8(-45) + 1031 054e 91E0 ldi r25,lo8(1) + 1032 0550 00C0 rjmp .L150 + 1033 .L81: + 234:serial.c **** { + 1035 .LM97: + 1036 0552 8091 0000 lds r24,xResult.2189 + 1037 0556 8130 cpi r24,lo8(1) + 1038 0558 01F4 brne .L82 + 236:serial.c **** if (lOdebrDanych < MAX_DATA_LEN) + 1040 .LM98: + 1041 055a 6091 0000 lds r22,znak.2188 + 1042 055e 8091 0000 lds r24,crc + 1043 0562 9091 0000 lds r25,crc+1 + 1044 0566 0E94 0000 call _crc_xmodem_update + 1045 056a 9093 0000 sts crc+1,r25 + 1046 056e 8093 0000 sts crc,r24 + 237:serial.c **** bDane[lOdebrDanych] = znak; + 1048 .LM99: + 1049 0572 8091 0000 lds r24,lOdebrDanych.2191 + 1050 0576 8E30 cpi r24,lo8(14) + 1051 0578 00F4 brsh .L83 + 238:serial.c **** lOdebrDanych++; + 1053 .LM100: + 1054 057a E82F mov r30,r24 + 1055 057c F0E0 ldi r31,0 + 1056 057e E050 subi r30,lo8(-(bDane)) + 1057 0580 F040 sbci r31,hi8(-(bDane)) + 1058 0582 9091 0000 lds r25,znak.2188 + 1059 0586 9083 st Z,r25 + 1060 .L83: + 239:serial.c **** } + 1062 .LM101: + 1063 0588 8F5F subi r24,lo8(-(1)) + 1064 058a 8093 0000 sts lOdebrDanych.2191,r24 + 1065 058e 00C0 rjmp .L78 + 1066 .L82: + 243:serial.c **** stan = s_sync; + 1068 .LM102: + 1069 0590 0E94 0000 call Led1Off + 244:serial.c **** } + 1071 .LM103: + 1072 0594 1092 0000 sts stan.2187,__zero_reg__ + 1073 .L78: + 248:serial.c **** { + 1075 .LM104: + 1076 0598 8091 0000 lds r24,stan.2187 + 1077 059c 8530 cpi r24,lo8(5) + 1078 059e 01F4 brne .L84 + 250:serial.c **** if (xResult == pdPASS) + 1080 .LM105: + 1081 05a0 41E0 ldi r20,lo8(1) + 1082 05a2 50E0 ldi r21,0 + 1083 05a4 60E0 ldi r22,lo8(crcHi) + 1084 05a6 70E0 ldi r23,hi8(crcHi) + 1085 05a8 8091 0000 lds r24,xRxedChars + 1086 05ac 9091 0000 lds r25,xRxedChars+1 + 1087 05b0 0E94 0000 call xQueueCRReceive + 1088 05b4 8093 0000 sts xResult.2189,r24 + 1089 05b8 8C3F cpi r24,lo8(-4) + 1090 05ba 01F4 brne .L85 + 250:serial.c **** if (xResult == pdPASS) + 1092 .LM106: + 1093 05bc 84EF ldi r24,lo8(-12) + 1094 05be 91E0 ldi r25,lo8(1) + 1095 05c0 00C0 rjmp .L150 + 1096 .L22: + 250:serial.c **** if (xResult == pdPASS) + 1098 .LM107: + 1099 05c2 40E0 ldi r20,0 + 1100 05c4 50E0 ldi r21,0 + 1101 05c6 60E0 ldi r22,lo8(crcHi) + 1102 05c8 70E0 ldi r23,hi8(crcHi) + 1103 05ca 8091 0000 lds r24,xRxedChars + 1104 05ce 9091 0000 lds r25,xRxedChars+1 + 1105 05d2 0E94 0000 call xQueueCRReceive + 1106 05d6 8093 0000 sts xResult.2189,r24 + 1107 .L85: + 250:serial.c **** if (xResult == pdPASS) + 1109 .LM108: + 1110 05da 8091 0000 lds r24,xResult.2189 + 1111 05de 8B3F cpi r24,lo8(-5) + 1112 05e0 01F4 brne .L86 + 250:serial.c **** if (xResult == pdPASS) + 1114 .LM109: + 1115 05e2 85EF ldi r24,lo8(-11) + 1116 05e4 91E0 ldi r25,lo8(1) + 1117 05e6 00C0 rjmp .L150 + 1118 .L25: + 250:serial.c **** if (xResult == pdPASS) + 1120 .LM110: + 1121 05e8 81E0 ldi r24,lo8(1) + 1122 05ea 8093 0000 sts xResult.2189,r24 + 1123 .L86: + 251:serial.c **** { + 1125 .LM111: + 1126 05ee 8091 0000 lds r24,xResult.2189 + 1127 05f2 8130 cpi r24,lo8(1) + 1128 05f4 01F4 brne .L87 + 253:serial.c **** } + 1130 .LM112: + 1131 05f6 86E0 ldi r24,lo8(6) + 1132 05f8 8093 0000 sts stan.2187,r24 + 1133 05fc 00C0 rjmp .L84 + 1134 .L87: + 257:serial.c **** stan = s_sync; + 1136 .LM113: + 1137 05fe 0E94 0000 call Led1Off + 258:serial.c **** } + 1139 .LM114: + 1140 0602 1092 0000 sts stan.2187,__zero_reg__ + 1141 .L84: + 261:serial.c **** { + 1143 .LM115: + 1144 0606 8091 0000 lds r24,stan.2187 + 1145 060a 8630 cpi r24,lo8(6) + 1146 060c 01F4 brne .L89 + 263:serial.c **** if (xResult == pdPASS) + 1148 .LM116: + 1149 060e 41E0 ldi r20,lo8(1) + 1150 0610 50E0 ldi r21,0 + 1151 0612 60E0 ldi r22,lo8(crcLo) + 1152 0614 70E0 ldi r23,hi8(crcLo) + 1153 0616 8091 0000 lds r24,xRxedChars + 1154 061a 9091 0000 lds r25,xRxedChars+1 + 1155 061e 0E94 0000 call xQueueCRReceive + 1156 0622 8093 0000 sts xResult.2189,r24 + 1157 0626 8C3F cpi r24,lo8(-4) + 1158 0628 01F4 brne .L90 + 263:serial.c **** if (xResult == pdPASS) + 1160 .LM117: + 1161 062a 8EE0 ldi r24,lo8(14) + 1162 062c 92E0 ldi r25,lo8(2) + 1163 062e 00C0 rjmp .L150 + 1164 .L90: + 263:serial.c **** if (xResult == pdPASS) + 1166 .LM118: + 1167 0630 8091 0000 lds r24,xResult.2189 + 1168 0634 8B3F cpi r24,lo8(-5) + 1169 0636 01F4 brne .L91 + 263:serial.c **** if (xResult == pdPASS) + 1171 .LM119: + 1172 0638 8FE0 ldi r24,lo8(15) + 1173 063a 92E0 ldi r25,lo8(2) + 1174 063c 00C0 rjmp .L150 + 1175 .L20: + 263:serial.c **** if (xResult == pdPASS) + 1177 .LM120: + 1178 063e 81E0 ldi r24,lo8(1) + 1179 0640 8093 0000 sts xResult.2189,r24 + 1180 .L91: + 264:serial.c **** { + 1182 .LM121: + 1183 0644 8091 0000 lds r24,xResult.2189 + 1184 0648 8130 cpi r24,lo8(1) + 1185 064a 01F4 brne .L89 + 266:serial.c **** { + 1187 .LM122: + 1188 064c 8091 0000 lds r24,crc + 1189 0650 9091 0000 lds r25,crc+1 + 1190 0654 2091 0000 lds r18,crcHi + 1191 0658 2913 cpse r18,r25 + 1192 065a 00C0 rjmp .L93 + 266:serial.c **** { + 1194 .LM123: + 1195 065c 9091 0000 lds r25,crcLo + 1196 0660 9817 cp r25,r24 + 1197 0662 01F0 breq .L94 + 1198 .L93: + 268:serial.c **** stan = s_sync; + 1200 .LM124: + 1201 0664 0E94 0000 call Led1Off + 269:serial.c **** } + 1203 .LM125: + 1204 0668 1092 0000 sts stan.2187,__zero_reg__ + 1205 066c 00C0 rjmp .L89 + 1206 .L94: + 273:serial.c **** } + 1208 .LM126: + 1209 066e 87E0 ldi r24,lo8(7) + 1210 0670 8093 0000 sts stan.2187,r24 + 1211 .L89: + 277:serial.c **** { + 1213 .LM127: + 1214 0674 8091 0000 lds r24,stan.2187 + 1215 0678 8730 cpi r24,lo8(7) + 1216 067a 01F0 breq .+2 + 1217 067c 00C0 rjmp .L95 + 279:serial.c **** { + 1219 .LM128: + 1220 067e 8091 0000 lds r24,dobryAdres.2190 + 1221 0682 8130 cpi r24,lo8(1) + 1222 0684 01F0 breq .+2 + 1223 0686 00C0 rjmp .L96 + 281:serial.c **** lOdebrDanych = MAX_DATA_LEN; + 1225 .LM129: + 1226 0688 8091 0000 lds r24,lOdebrDanych.2191 + 1227 068c 8F30 cpi r24,lo8(15) + 1228 068e 00F0 brlo .L97 + 282:serial.c **** rezultat = wykonajRozkaz(); + 1230 .LM130: + 1231 0690 8EE0 ldi r24,lo8(14) + 1232 0692 8093 0000 sts lOdebrDanych.2191,r24 + 1233 .L97: + 1234 .LBB20: + 1235 .LBB21: + 86:serial.c **** { + 1237 .LM131: + 1238 0696 8091 0000 lds r24,kodRozkazu + 1239 069a 8033 cpi r24,lo8(48) + 1240 069c 01F0 breq .L99 + 1241 069e 00F4 brsh .L100 + 1242 06a0 8131 cpi r24,lo8(17) + 1243 06a2 01F0 breq .L101 + 1244 06a4 00F4 brsh .L102 + 1245 06a6 8031 cpi r24,lo8(16) + 1246 06a8 01F4 brne .L147 + 89:serial.c **** wysylac = 2; + 1248 .LM132: + 1249 06aa 8FE3 ldi r24,lo8(63) + 1250 06ac 00C0 rjmp .L148 + 1251 .L102: + 86:serial.c **** { + 1253 .LM133: + 1254 06ae 8032 cpi r24,lo8(32) + 1255 06b0 01F0 breq .L104 + 1256 06b2 8132 cpi r24,lo8(33) + 1257 06b4 01F4 brne .L147 + 104:serial.c **** wysylac = 3; + 1259 .LM134: + 1260 06b6 8FEB ldi r24,lo8(-65) + 1261 06b8 00C0 rjmp .L149 + 1262 .L100: + 86:serial.c **** { + 1264 .LM135: + 1265 06ba 8238 cpi r24,lo8(-126) + 1266 06bc 00F4 brsh .L106 + 1267 06be 8038 cpi r24,lo8(-128) + 1268 06c0 00F4 brsh .L107 + 1269 06c2 8133 cpi r24,lo8(49) + 1270 06c4 01F4 brne .L147 + 114:serial.c **** wysylac = 3; + 1272 .LM136: + 1273 06c6 80E4 ldi r24,lo8(64) + 1274 06c8 00C0 rjmp .L149 + 1275 .L106: + 86:serial.c **** { + 1277 .LM137: + 1278 06ca 8238 cpi r24,lo8(-126) + 1279 06cc 01F4 brne .L147 + 122:serial.c **** break; + 1281 .LM138: + 1282 06ce 84E0 ldi r24,lo8(4) + 1283 06d0 00C0 rjmp .L98 + 1284 .L107: + 119:serial.c **** break; + 1286 .LM139: + 1287 06d2 81E0 ldi r24,lo8(1) + 1288 06d4 00C0 rjmp .L98 + 1289 .L101: + 94:serial.c **** wysylac = 3; + 1291 .LM140: + 1292 06d6 8FE3 ldi r24,lo8(63) + 1293 06d8 00C0 rjmp .L149 + 1294 .L104: + 99:serial.c **** wysylac = 2; + 1296 .LM141: + 1297 06da 8FEB ldi r24,lo8(-65) + 1298 .L148: + 1299 06dc 8093 0000 sts wiadomosc,r24 + 100:serial.c **** break; + 1301 .LM142: + 1302 06e0 82E0 ldi r24,lo8(2) + 1303 06e2 00C0 rjmp .L98 + 1304 .L149: + 104:serial.c **** wysylac = 3; + 1306 .LM143: + 1307 06e4 8093 0000 sts wiadomosc,r24 + 105:serial.c **** break; + 1309 .LM144: + 1310 06e8 83E0 ldi r24,lo8(3) + 1311 06ea 00C0 rjmp .L98 + 1312 .L99: + 109:serial.c **** wysylac = 2; + 1314 .LM145: + 1315 06ec 80E4 ldi r24,lo8(64) + 1316 06ee 00C0 rjmp .L148 + 1317 .L147: + 84:serial.c **** + 1319 .LM146: + 1320 06f0 80E0 ldi r24,0 + 1321 .L98: + 1322 .LBE21: + 1323 .LBE20: + 283:serial.c **** if (rezultat == 1) + 1325 .LM147: + 1326 06f2 8093 0000 sts rezultat.2192,r24 + 284:serial.c **** { + 1328 .LM148: + 1329 06f6 8130 cpi r24,lo8(1) + 1330 06f8 01F0 breq .+2 + 1331 06fa 00C0 rjmp .L110 + 1332 .LBB22: + 288:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + 1334 .LM149: + 1335 06fc 8AE5 ldi r24,lo8(90) + 1336 06fe 8983 std Y+1,r24 + 289:serial.c **** crc = _crc_xmodem_update(0, temp); + 1338 .LM150: + 1339 0700 40E0 ldi r20,0 + 1340 0702 50E0 ldi r21,0 + 1341 0704 BE01 movw r22,r28 + 1342 0706 6F5F subi r22,-1 + 1343 0708 7F4F sbci r23,-1 + 1344 070a 8091 0000 lds r24,xCharsForTx + 1345 070e 9091 0000 lds r25,xCharsForTx+1 + 1346 0712 0E94 0000 call xQueueCRSend + 1347 0716 8093 0000 sts xResult.2189,r24 + 1348 071a 8C3F cpi r24,lo8(-4) + 1349 071c 01F4 brne .L111 + 289:serial.c **** crc = _crc_xmodem_update(0, temp); + 1351 .LM151: + 1352 071e 82E4 ldi r24,lo8(66) + 1353 0720 92E0 ldi r25,lo8(2) + 1354 0722 00C0 rjmp .L150 + 1355 .L29: + 289:serial.c **** crc = _crc_xmodem_update(0, temp); + 1357 .LM152: + 1358 0724 40E0 ldi r20,0 + 1359 0726 50E0 ldi r21,0 + 1360 0728 BE01 movw r22,r28 + 1361 072a 6F5F subi r22,-1 + 1362 072c 7F4F sbci r23,-1 + 1363 072e 8091 0000 lds r24,xCharsForTx + 1364 0732 9091 0000 lds r25,xCharsForTx+1 + 1365 0736 0E94 0000 call xQueueCRSend + 1366 073a 8093 0000 sts xResult.2189,r24 + 1367 .L111: + 289:serial.c **** crc = _crc_xmodem_update(0, temp); + 1369 .LM153: + 1370 073e 8091 0000 lds r24,xResult.2189 + 1371 0742 8B3F cpi r24,lo8(-5) + 1372 0744 01F4 brne .L113 + 289:serial.c **** crc = _crc_xmodem_update(0, temp); + 1374 .LM154: + 1375 0746 83E4 ldi r24,lo8(67) + 1376 0748 92E0 ldi r25,lo8(2) + 1377 074a 00C0 rjmp .L150 + 1378 .L113: + 290:serial.c **** + 1380 .LM155: + 1381 074c 6981 ldd r22,Y+1 + 1382 074e 80E0 ldi r24,0 + 1383 0750 90E0 ldi r25,0 + 1384 0752 0E94 0000 call _crc_xmodem_update + 1385 0756 9093 0000 sts crc+1,r25 + 1386 075a 8093 0000 sts crc,r24 + 293:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + 1388 .LM156: + 1389 075e 1982 std Y+1,__zero_reg__ + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1391 .LM157: + 1392 0760 40E0 ldi r20,0 + 1393 0762 50E0 ldi r21,0 + 1394 0764 BE01 movw r22,r28 + 1395 0766 6F5F subi r22,-1 + 1396 0768 7F4F sbci r23,-1 + 1397 076a 8091 0000 lds r24,xCharsForTx + 1398 076e 9091 0000 lds r25,xCharsForTx+1 + 1399 0772 0E94 0000 call xQueueCRSend + 1400 0776 8093 0000 sts xResult.2189,r24 + 1401 077a 8C3F cpi r24,lo8(-4) + 1402 077c 01F4 brne .L114 + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1404 .LM158: + 1405 077e 8CE4 ldi r24,lo8(76) + 1406 0780 92E0 ldi r25,lo8(2) + 1407 0782 00C0 rjmp .L150 + 1408 .L27: + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1410 .LM159: + 1411 0784 40E0 ldi r20,0 + 1412 0786 50E0 ldi r21,0 + 1413 0788 BE01 movw r22,r28 + 1414 078a 6F5F subi r22,-1 + 1415 078c 7F4F sbci r23,-1 + 1416 078e 8091 0000 lds r24,xCharsForTx + 1417 0792 9091 0000 lds r25,xCharsForTx+1 + 1418 0796 0E94 0000 call xQueueCRSend + 1419 079a 8093 0000 sts xResult.2189,r24 + 1420 .L114: + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1422 .LM160: + 1423 079e 8091 0000 lds r24,xResult.2189 + 1424 07a2 8B3F cpi r24,lo8(-5) + 1425 07a4 01F4 brne .L115 + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1427 .LM161: + 1428 07a6 8DE4 ldi r24,lo8(77) + 1429 07a8 92E0 ldi r25,lo8(2) + 1430 07aa 00C0 rjmp .L150 + 1431 .L31: + 294:serial.c **** crc = _crc_xmodem_update(crc, temp); + 1433 .LM162: + 1434 07ac 81E0 ldi r24,lo8(1) + 1435 07ae 8093 0000 sts xResult.2189,r24 + 1436 .L115: + 295:serial.c **** + 1438 .LM163: + 1439 07b2 6981 ldd r22,Y+1 + 1440 07b4 8091 0000 lds r24,crc + 1441 07b8 9091 0000 lds r25,crc+1 + 1442 07bc 0E94 0000 call _crc_xmodem_update + 1443 07c0 9093 0000 sts crc+1,r25 + 1444 07c4 8093 0000 sts crc,r24 + 298:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 1446 .LM164: + 1447 07c8 40E0 ldi r20,0 + 1448 07ca 50E0 ldi r21,0 + 1449 07cc 60E0 ldi r22,lo8(kodRozkazu) + 1450 07ce 70E0 ldi r23,hi8(kodRozkazu) + 1451 07d0 8091 0000 lds r24,xCharsForTx + 1452 07d4 9091 0000 lds r25,xCharsForTx+1 + 1453 07d8 0E94 0000 call xQueueCRSend + 1454 07dc 8093 0000 sts xResult.2189,r24 + 1455 07e0 8C3F cpi r24,lo8(-4) + 1456 07e2 01F4 brne .L116 + 298:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 1458 .LM165: + 1459 07e4 84E5 ldi r24,lo8(84) + 1460 07e6 92E0 ldi r25,lo8(2) + 1461 07e8 00C0 rjmp .L150 + 1462 .L116: + 298:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 1464 .LM166: + 1465 07ea 8091 0000 lds r24,xResult.2189 + 1466 07ee 8B3F cpi r24,lo8(-5) + 1467 07f0 01F4 brne .L117 + 298:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 1469 .LM167: + 1470 07f2 85E5 ldi r24,lo8(85) + 1471 07f4 92E0 ldi r25,lo8(2) + 1472 07f6 00C0 rjmp .L150 + 1473 .L4: + 298:serial.c **** crc = _crc_xmodem_update(crc, kodRozkazu); + 1475 .LM168: + 1476 07f8 81E0 ldi r24,lo8(1) + 1477 07fa 8093 0000 sts xResult.2189,r24 + 1478 .L117: + 299:serial.c **** + 1480 .LM169: + 1481 07fe 6091 0000 lds r22,kodRozkazu + 1482 0802 8091 0000 lds r24,crc + 1483 0806 9091 0000 lds r25,crc+1 + 1484 080a 0E94 0000 call _crc_xmodem_update + 1485 080e 9093 0000 sts crc+1,r25 + 1486 0812 8093 0000 sts crc,r24 + 302:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 1488 .LM170: + 1489 0816 40E0 ldi r20,0 + 1490 0818 50E0 ldi r21,0 + 1491 081a 60E0 ldi r22,lo8(lOdebrDanych.2191) + 1492 081c 70E0 ldi r23,hi8(lOdebrDanych.2191) + 1493 081e 8091 0000 lds r24,xCharsForTx + 1494 0822 9091 0000 lds r25,xCharsForTx+1 + 1495 0826 0E94 0000 call xQueueCRSend + 1496 082a 8093 0000 sts xResult.2189,r24 + 1497 082e 8C3F cpi r24,lo8(-4) + 1498 0830 01F4 brne .L118 + 302:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 1500 .LM171: + 1501 0832 8CE5 ldi r24,lo8(92) + 1502 0834 92E0 ldi r25,lo8(2) + 1503 0836 00C0 rjmp .L150 + 1504 .L118: + 302:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 1506 .LM172: + 1507 0838 8091 0000 lds r24,xResult.2189 + 1508 083c 8B3F cpi r24,lo8(-5) + 1509 083e 01F4 brne .L119 + 302:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 1511 .LM173: + 1512 0840 8DE5 ldi r24,lo8(93) + 1513 0842 92E0 ldi r25,lo8(2) + 1514 0844 00C0 rjmp .L150 + 1515 .L37: + 302:serial.c **** crc = _crc_xmodem_update(crc, lOdebrDanych); + 1517 .LM174: + 1518 0846 81E0 ldi r24,lo8(1) + 1519 0848 8093 0000 sts xResult.2189,r24 + 1520 .L119: + 303:serial.c **** + 1522 .LM175: + 1523 084c 6091 0000 lds r22,lOdebrDanych.2191 + 1524 0850 8091 0000 lds r24,crc + 1525 0854 9091 0000 lds r25,crc+1 + 1526 0858 0E94 0000 call _crc_xmodem_update + 1527 085c 9093 0000 sts crc+1,r25 + 1528 0860 8093 0000 sts crc,r24 + 306:serial.c **** { + 1530 .LM176: + 1531 0864 1982 std Y+1,__zero_reg__ + 1532 0866 00C0 rjmp .L120 + 1533 .L40: + 308:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 1535 .LM177: + 1536 0868 6981 ldd r22,Y+1 + 1537 086a 70E0 ldi r23,0 + 1538 086c 6050 subi r22,lo8(-(bDane)) + 1539 086e 7040 sbci r23,hi8(-(bDane)) + 1540 0870 40E0 ldi r20,0 + 1541 0872 50E0 ldi r21,0 + 1542 0874 8091 0000 lds r24,xCharsForTx + 1543 0878 9091 0000 lds r25,xCharsForTx+1 + 1544 087c 0E94 0000 call xQueueCRSend + 1545 0880 8093 0000 sts xResult.2189,r24 + 1546 .L121: + 308:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 1548 .LM178: + 1549 0884 8091 0000 lds r24,xResult.2189 + 1550 0888 8B3F cpi r24,lo8(-5) + 1551 088a 01F4 brne .L122 + 308:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 1553 .LM179: + 1554 088c 89E6 ldi r24,lo8(105) + 1555 088e 92E0 ldi r25,lo8(2) + 1556 0890 00C0 rjmp .L150 + 1557 .L122: + 309:serial.c **** } + 1559 .LM180: + 1560 0892 E981 ldd r30,Y+1 + 1561 0894 F0E0 ldi r31,0 + 1562 0896 E050 subi r30,lo8(-(bDane)) + 1563 0898 F040 sbci r31,hi8(-(bDane)) + 1564 089a 6081 ld r22,Z + 1565 089c 8091 0000 lds r24,crc + 1566 08a0 9091 0000 lds r25,crc+1 + 1567 08a4 0E94 0000 call _crc_xmodem_update + 1568 08a8 9093 0000 sts crc+1,r25 + 1569 08ac 8093 0000 sts crc,r24 + 306:serial.c **** { + 1571 .LM181: + 1572 08b0 8981 ldd r24,Y+1 + 1573 08b2 8F5F subi r24,lo8(-(1)) + 1574 08b4 8983 std Y+1,r24 + 1575 .L120: + 306:serial.c **** { + 1577 .LM182: + 1578 08b6 6981 ldd r22,Y+1 + 1579 08b8 2091 0000 lds r18,lOdebrDanych.2191 + 1580 08bc 8091 0000 lds r24,xCharsForTx + 1581 08c0 9091 0000 lds r25,xCharsForTx+1 + 1582 08c4 6217 cp r22,r18 + 1583 08c6 00F4 brsh .L152 + 308:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 1585 .LM183: + 1586 08c8 70E0 ldi r23,0 + 1587 08ca 6050 subi r22,lo8(-(bDane)) + 1588 08cc 7040 sbci r23,hi8(-(bDane)) + 1589 08ce 41E0 ldi r20,lo8(1) + 1590 08d0 50E0 ldi r21,0 + 1591 08d2 0E94 0000 call xQueueCRSend + 1592 08d6 8093 0000 sts xResult.2189,r24 + 1593 08da 8C3F cpi r24,lo8(-4) + 1594 08dc 01F4 brne .L121 + 308:serial.c **** crc = _crc_xmodem_update(crc, bDane[temp]); + 1596 .LM184: + 1597 08de 88E6 ldi r24,lo8(104) + 1598 08e0 92E0 ldi r25,lo8(2) + 1599 08e2 00C0 rjmp .L150 + 1600 .L152: + 312:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 1602 .LM185: + 1603 08e4 2091 0000 lds r18,crc+1 + 1604 08e8 2983 std Y+1,r18 + 313:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1606 .LM186: + 1607 08ea 41E0 ldi r20,lo8(1) + 1608 08ec 50E0 ldi r21,0 + 1609 08ee BE01 movw r22,r28 + 1610 08f0 6F5F subi r22,-1 + 1611 08f2 7F4F sbci r23,-1 + 1612 08f4 0E94 0000 call xQueueCRSend + 1613 08f8 8093 0000 sts xResult.2189,r24 + 1614 08fc 8C3F cpi r24,lo8(-4) + 1615 08fe 01F4 brne .L124 + 313:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1617 .LM187: + 1618 0900 82E7 ldi r24,lo8(114) + 1619 0902 92E0 ldi r25,lo8(2) + 1620 0904 00C0 rjmp .L150 + 1621 .L35: + 313:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1623 .LM188: + 1624 0906 40E0 ldi r20,0 + 1625 0908 50E0 ldi r21,0 + 1626 090a BE01 movw r22,r28 + 1627 090c 6F5F subi r22,-1 + 1628 090e 7F4F sbci r23,-1 + 1629 0910 8091 0000 lds r24,xCharsForTx + 1630 0914 9091 0000 lds r25,xCharsForTx+1 + 1631 0918 0E94 0000 call xQueueCRSend + 1632 091c 8093 0000 sts xResult.2189,r24 + 1633 .L124: + 313:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1635 .LM189: + 1636 0920 8091 0000 lds r24,xResult.2189 + 1637 0924 8B3F cpi r24,lo8(-5) + 1638 0926 01F4 brne .L125 + 313:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1640 .LM190: + 1641 0928 83E7 ldi r24,lo8(115) + 1642 092a 92E0 ldi r25,lo8(2) + 1643 092c 00C0 rjmp .L150 + 1644 .L125: + 314:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 1646 .LM191: + 1647 092e 8091 0000 lds r24,crc + 1648 0932 8983 std Y+1,r24 + 315:serial.c **** + 1650 .LM192: + 1651 0934 41E0 ldi r20,lo8(1) + 1652 0936 50E0 ldi r21,0 + 1653 0938 BE01 movw r22,r28 + 1654 093a 6F5F subi r22,-1 + 1655 093c 7F4F sbci r23,-1 + 1656 093e 8091 0000 lds r24,xCharsForTx + 1657 0942 9091 0000 lds r25,xCharsForTx+1 + 1658 0946 0E94 0000 call xQueueCRSend + 1659 094a 8093 0000 sts xResult.2189,r24 + 1660 094e 8C3F cpi r24,lo8(-4) + 1661 0950 01F4 brne .L126 + 315:serial.c **** + 1663 .LM193: + 1664 0952 86E7 ldi r24,lo8(118) + 1665 0954 92E0 ldi r25,lo8(2) + 1666 0956 00C0 rjmp .L150 + 1667 .L42: + 315:serial.c **** + 1669 .LM194: + 1670 0958 40E0 ldi r20,0 + 1671 095a 50E0 ldi r21,0 + 1672 095c BE01 movw r22,r28 + 1673 095e 6F5F subi r22,-1 + 1674 0960 7F4F sbci r23,-1 + 1675 0962 8091 0000 lds r24,xCharsForTx + 1676 0966 9091 0000 lds r25,xCharsForTx+1 + 1677 096a 0E94 0000 call xQueueCRSend + 1678 096e 8093 0000 sts xResult.2189,r24 + 1679 .L126: + 315:serial.c **** + 1681 .LM195: + 1682 0972 8091 0000 lds r24,xResult.2189 + 1683 0976 8B3F cpi r24,lo8(-5) + 1684 0978 01F4 brne .L127 + 315:serial.c **** + 1686 .LM196: + 1687 097a 87E7 ldi r24,lo8(119) + 1688 097c 92E0 ldi r25,lo8(2) + 1689 097e 00C0 rjmp .L150 + 1690 .L45: + 315:serial.c **** + 1692 .LM197: + 1693 0980 81E0 ldi r24,lo8(1) + 1694 0982 8093 0000 sts xResult.2189,r24 + 1695 .L127: + 317:serial.c **** { + 1697 .LM198: + 1698 0986 8091 0000 lds r24,xResult.2189 + 1699 098a 8130 cpi r24,lo8(1) + 1700 098c 01F4 brne .L128 + 319:serial.c **** } + 1702 .LM199: + 1703 098e 8BB1 in r24,0xb + 1704 0990 8C60 ori r24,lo8(12) + 1705 0992 8BB9 out 0xb,r24 + 1706 .L128: + 1707 .LBB11: + 321:serial.c **** + 1709 .LM200: + 1710 0994 8091 C100 lds r24,193 + 1711 0998 8062 ori r24,lo8(32) + 1712 099a 8093 C100 sts 193,r24 + 1713 .LBE11: + 323:serial.c **** { + 1715 .LM201: + 1716 099e 8091 0000 lds r24,kodRozkazu + 1717 09a2 8138 cpi r24,lo8(-127) + 1718 09a4 01F0 breq .+2 + 1719 09a6 00C0 rjmp .L130 + 325:serial.c **** Led2On(); + 1721 .LM202: + 1722 09a8 0E94 0000 call Led1On + 326:serial.c **** crDELAY(xHandle, 10); + 1724 .LM203: + 1725 09ac 0E94 0000 call Led2On + 327:serial.c **** Led1Off(); + 1727 .LM204: + 1728 09b0 60E0 ldi r22,0 + 1729 09b2 70E0 ldi r23,0 + 1730 09b4 8AE0 ldi r24,lo8(10) + 1731 09b6 90E0 ldi r25,0 + 1732 09b8 0E94 0000 call vCoRoutineAddToDelayedList + 1733 09bc 8EE8 ldi r24,lo8(-114) + 1734 09be 92E0 ldi r25,lo8(2) + 1735 09c0 00C0 rjmp .L150 + 1736 .L110: + 1737 .LBE22: + 333:serial.c **** { + 1739 .LM205: + 1740 09c2 8230 cpi r24,lo8(2) + 1741 09c4 01F4 brne .L131 + 335:serial.c **** } + 1743 .LM206: + 1744 09c6 40E0 ldi r20,0 + 1745 09c8 50E0 ldi r21,0 + 1746 09ca 60E0 ldi r22,lo8(wiadomosc) + 1747 09cc 70E0 ldi r23,hi8(wiadomosc) + 1748 09ce 8091 0000 lds r24,xRoleta + 1749 09d2 9091 0000 lds r25,xRoleta+1 + 1750 09d6 0E94 0000 call xQueueCRSend + 1751 09da 8093 0000 sts xResult.2189,r24 + 1752 09de 8C3F cpi r24,lo8(-4) + 1753 09e0 01F4 brne .L132 + 335:serial.c **** } + 1755 .LM207: + 1756 09e2 8EE9 ldi r24,lo8(-98) + 1757 09e4 92E0 ldi r25,lo8(2) + 1758 09e6 00C0 rjmp .L150 + 1759 .L33: + 335:serial.c **** } + 1761 .LM208: + 1762 09e8 40E0 ldi r20,0 + 1763 09ea 50E0 ldi r21,0 + 1764 09ec 60E0 ldi r22,lo8(wiadomosc) + 1765 09ee 70E0 ldi r23,hi8(wiadomosc) + 1766 09f0 8091 0000 lds r24,xRoleta + 1767 09f4 9091 0000 lds r25,xRoleta+1 + 1768 09f8 0E94 0000 call xQueueCRSend + 1769 09fc 8093 0000 sts xResult.2189,r24 + 1770 .L132: + 335:serial.c **** } + 1772 .LM209: + 1773 0a00 8091 0000 lds r24,xResult.2189 + 1774 0a04 8B3F cpi r24,lo8(-5) + 1775 0a06 01F0 breq .+2 + 1776 0a08 00C0 rjmp .L130 + 335:serial.c **** } + 1778 .LM210: + 1779 0a0a 8FE9 ldi r24,lo8(-97) + 1780 0a0c 92E0 ldi r25,lo8(2) + 1781 0a0e 00C0 rjmp .L150 + 1782 .L131: + 337:serial.c **** { + 1784 .LM211: + 1785 0a10 8330 cpi r24,lo8(3) + 1786 0a12 01F4 brne .L134 + 339:serial.c **** } + 1788 .LM212: + 1789 0a14 40E0 ldi r20,0 + 1790 0a16 50E0 ldi r21,0 + 1791 0a18 60E0 ldi r22,lo8(wiadomosc) + 1792 0a1a 70E0 ldi r23,hi8(wiadomosc) + 1793 0a1c 8091 0000 lds r24,xRoleta+2 + 1794 0a20 9091 0000 lds r25,xRoleta+2+1 + 1795 0a24 0E94 0000 call xQueueCRSend + 1796 0a28 8093 0000 sts xResult.2189,r24 + 1797 0a2c 8C3F cpi r24,lo8(-4) + 1798 0a2e 01F4 brne .L135 + 339:serial.c **** } + 1800 .LM213: + 1801 0a30 86EA ldi r24,lo8(-90) + 1802 0a32 92E0 ldi r25,lo8(2) + 1803 0a34 00C0 rjmp .L150 + 1804 .L49: + 339:serial.c **** } + 1806 .LM214: + 1807 0a36 40E0 ldi r20,0 + 1808 0a38 50E0 ldi r21,0 + 1809 0a3a 60E0 ldi r22,lo8(wiadomosc) + 1810 0a3c 70E0 ldi r23,hi8(wiadomosc) + 1811 0a3e 8091 0000 lds r24,xRoleta+2 + 1812 0a42 9091 0000 lds r25,xRoleta+2+1 + 1813 0a46 0E94 0000 call xQueueCRSend + 1814 0a4a 8093 0000 sts xResult.2189,r24 + 1815 .L135: + 339:serial.c **** } + 1817 .LM215: + 1818 0a4e 8091 0000 lds r24,xResult.2189 + 1819 0a52 8B3F cpi r24,lo8(-5) + 1820 0a54 01F0 breq .+2 + 1821 0a56 00C0 rjmp .L130 + 339:serial.c **** } + 1823 .LM216: + 1824 0a58 87EA ldi r24,lo8(-89) + 1825 0a5a 92E0 ldi r25,lo8(2) + 1826 0a5c 00C0 rjmp .L150 + 1827 .L134: + 341:serial.c **** { + 1829 .LM217: + 1830 0a5e 8430 cpi r24,lo8(4) + 1831 0a60 01F0 breq .+2 + 1832 0a62 00C0 rjmp .L130 + 1833 .LBB23: + 344:serial.c **** uint8_t temp; + 1835 .LM218: + 1836 0a64 1092 0000 sts crc+1,__zero_reg__ + 1837 0a68 1092 0000 sts crc,__zero_reg__ + 348:serial.c **** { + 1839 .LM219: + 1840 0a6c 1982 std Y+1,__zero_reg__ + 1841 0a6e 00C0 rjmp .L136 + 1842 .L137: + 350:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 1844 .LM220: + 1845 0a70 8091 0000 lds r24,xResult.2189 + 1846 0a74 8B3F cpi r24,lo8(-5) + 1847 0a76 01F4 brne .L139 + 350:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 1849 .LM221: + 1850 0a78 8DEB ldi r24,lo8(-67) + 1851 0a7a 92E0 ldi r25,lo8(2) + 1852 0a7c 00C0 rjmp .L150 + 1853 .L47: + 350:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 1855 .LM222: + 1856 0a7e 81E0 ldi r24,lo8(1) + 1857 0a80 8093 0000 sts xResult.2189,r24 + 1858 .L139: + 351:serial.c **** } + 1860 .LM223: + 1861 0a84 E981 ldd r30,Y+1 + 1862 0a86 F0E0 ldi r31,0 + 1863 0a88 E050 subi r30,lo8(-(bHelloResp)) + 1864 0a8a F040 sbci r31,hi8(-(bHelloResp)) + 1865 0a8c 6081 ld r22,Z + 1866 0a8e 8091 0000 lds r24,crc + 1867 0a92 9091 0000 lds r25,crc+1 + 1868 0a96 0E94 0000 call _crc_xmodem_update + 1869 0a9a 9093 0000 sts crc+1,r25 + 1870 0a9e 8093 0000 sts crc,r24 + 348:serial.c **** { + 1872 .LM224: + 1873 0aa2 8981 ldd r24,Y+1 + 1874 0aa4 8F5F subi r24,lo8(-(1)) + 1875 0aa6 8983 std Y+1,r24 + 1876 .L136: + 348:serial.c **** { + 1878 .LM225: + 1879 0aa8 6981 ldd r22,Y+1 + 1880 0aaa 8091 0000 lds r24,xCharsForTx + 1881 0aae 9091 0000 lds r25,xCharsForTx+1 + 1882 0ab2 6B30 cpi r22,lo8(11) + 1883 0ab4 00F4 brsh .L153 + 350:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 1885 .LM226: + 1886 0ab6 70E0 ldi r23,0 + 1887 0ab8 6050 subi r22,lo8(-(bHelloResp)) + 1888 0aba 7040 sbci r23,hi8(-(bHelloResp)) + 1889 0abc 41E0 ldi r20,lo8(1) + 1890 0abe 50E0 ldi r21,0 + 1891 0ac0 0E94 0000 call xQueueCRSend + 1892 0ac4 8093 0000 sts xResult.2189,r24 + 1893 0ac8 8C3F cpi r24,lo8(-4) + 1894 0aca 01F4 brne .L137 + 350:serial.c **** crc = _crc_xmodem_update(crc, bHelloResp[temp]); + 1896 .LM227: + 1897 0acc 8CEB ldi r24,lo8(-68) + 1898 0ace 92E0 ldi r25,lo8(2) + 1899 0ad0 00C0 rjmp .L150 + 1900 .L153: + 354:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 1902 .LM228: + 1903 0ad2 2091 0000 lds r18,crc+1 + 1904 0ad6 2983 std Y+1,r18 + 355:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1906 .LM229: + 1907 0ad8 41E0 ldi r20,lo8(1) + 1908 0ada 50E0 ldi r21,0 + 1909 0adc BE01 movw r22,r28 + 1910 0ade 6F5F subi r22,-1 + 1911 0ae0 7F4F sbci r23,-1 + 1912 0ae2 0E94 0000 call xQueueCRSend + 1913 0ae6 8093 0000 sts xResult.2189,r24 + 1914 0aea 8C3F cpi r24,lo8(-4) + 1915 0aec 01F4 brne .L141 + 355:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1917 .LM230: + 1918 0aee 86EC ldi r24,lo8(-58) + 1919 0af0 92E0 ldi r25,lo8(2) + 1920 0af2 00C0 rjmp .L150 + 1921 .L56: + 355:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1923 .LM231: + 1924 0af4 40E0 ldi r20,0 + 1925 0af6 50E0 ldi r21,0 + 1926 0af8 BE01 movw r22,r28 + 1927 0afa 6F5F subi r22,-1 + 1928 0afc 7F4F sbci r23,-1 + 1929 0afe 8091 0000 lds r24,xCharsForTx + 1930 0b02 9091 0000 lds r25,xCharsForTx+1 + 1931 0b06 0E94 0000 call xQueueCRSend + 1932 0b0a 8093 0000 sts xResult.2189,r24 + 1933 .L141: + 355:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1935 .LM232: + 1936 0b0e 8091 0000 lds r24,xResult.2189 + 1937 0b12 8B3F cpi r24,lo8(-5) + 1938 0b14 01F4 brne .L142 + 355:serial.c **** temp = (uint8_t)(crc & 0xFF); + 1940 .LM233: + 1941 0b16 87EC ldi r24,lo8(-57) + 1942 0b18 92E0 ldi r25,lo8(2) + 1943 0b1a 00C0 rjmp .L150 + 1944 .L142: + 356:serial.c **** crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + 1946 .LM234: + 1947 0b1c 8091 0000 lds r24,crc + 1948 0b20 8983 std Y+1,r24 + 357:serial.c **** + 1950 .LM235: + 1951 0b22 41E0 ldi r20,lo8(1) + 1952 0b24 50E0 ldi r21,0 + 1953 0b26 BE01 movw r22,r28 + 1954 0b28 6F5F subi r22,-1 + 1955 0b2a 7F4F sbci r23,-1 + 1956 0b2c 8091 0000 lds r24,xCharsForTx + 1957 0b30 9091 0000 lds r25,xCharsForTx+1 + 1958 0b34 0E94 0000 call xQueueCRSend + 1959 0b38 8093 0000 sts xResult.2189,r24 + 1960 0b3c 8C3F cpi r24,lo8(-4) + 1961 0b3e 01F4 brne .L143 + 357:serial.c **** + 1963 .LM236: + 1964 0b40 8AEC ldi r24,lo8(-54) + 1965 0b42 92E0 ldi r25,lo8(2) + 1966 0b44 00C0 rjmp .L150 + 1967 .L54: + 357:serial.c **** + 1969 .LM237: + 1970 0b46 40E0 ldi r20,0 + 1971 0b48 50E0 ldi r21,0 + 1972 0b4a BE01 movw r22,r28 + 1973 0b4c 6F5F subi r22,-1 + 1974 0b4e 7F4F sbci r23,-1 + 1975 0b50 8091 0000 lds r24,xCharsForTx + 1976 0b54 9091 0000 lds r25,xCharsForTx+1 + 1977 0b58 0E94 0000 call xQueueCRSend + 1978 0b5c 8093 0000 sts xResult.2189,r24 + 1979 .L143: + 357:serial.c **** + 1981 .LM238: + 1982 0b60 8091 0000 lds r24,xResult.2189 + 1983 0b64 8B3F cpi r24,lo8(-5) + 1984 0b66 01F4 brne .L144 + 357:serial.c **** + 1986 .LM239: + 1987 0b68 8BEC ldi r24,lo8(-53) + 1988 0b6a 92E0 ldi r25,lo8(2) + 1989 0b6c 00C0 rjmp .L150 + 1990 .L58: + 357:serial.c **** + 1992 .LM240: + 1993 0b6e 81E0 ldi r24,lo8(1) + 1994 0b70 8093 0000 sts xResult.2189,r24 + 1995 .L144: + 359:serial.c **** { + 1997 .LM241: + 1998 0b74 8091 0000 lds r24,xResult.2189 + 1999 0b78 8130 cpi r24,lo8(1) + 2000 0b7a 01F4 brne .L145 + 361:serial.c **** } + 2002 .LM242: + 2003 0b7c 8BB1 in r24,0xb + 2004 0b7e 8C60 ori r24,lo8(12) + 2005 0b80 8BB9 out 0xb,r24 + 2006 .L145: + 2007 .LBB18: + 363:serial.c **** } + 2009 .LM243: + 2010 0b82 8091 C100 lds r24,193 + 2011 0b86 8062 ori r24,lo8(32) + 2012 0b88 8093 C100 sts 193,r24 + 2013 .LBE18: + 2014 0b8c 00C0 rjmp .L130 + 2015 .L96: + 2016 .LBE23: + 371:serial.c **** { + 2018 .LM244: + 2019 0b8e 8091 0000 lds r24,kodRozkazu + 2020 0b92 8138 cpi r24,lo8(-127) + 2021 0b94 01F4 brne .L146 + 373:serial.c **** Led1On(); + 2023 .LM245: + 2024 0b96 8091 C100 lds r24,193 + 2025 0b9a 8F7E andi r24,lo8(-17) + 2026 0b9c 8093 C100 sts 193,r24 + 374:serial.c **** Led2On(); + 2028 .LM246: + 2029 0ba0 0E94 0000 call Led1On + 375:serial.c **** //TODO disable RX buffer + 2031 .LM247: + 2032 0ba4 0E94 0000 call Led2On + 377:serial.c **** ENABLE_RX(); + 2034 .LM248: + 2035 0ba8 60E0 ldi r22,0 + 2036 0baa 70E0 ldi r23,0 + 2037 0bac 88EE ldi r24,lo8(-24) + 2038 0bae 93E0 ldi r25,lo8(3) + 2039 0bb0 0E94 0000 call vCoRoutineAddToDelayedList + 2040 0bb4 82EF ldi r24,lo8(-14) + 2041 0bb6 92E0 ldi r25,lo8(2) + 2042 .L150: + 2043 0bb8 F801 movw r30,r16 + 2044 0bba 918F std Z+25,r25 + 2045 0bbc 808F std Z+24,r24 + 2046 0bbe 00C0 rjmp .L2 + 2047 .L146: + 379:serial.c **** } + 380:serial.c **** Led1Off(); + 2049 .LM249: + 2050 0bc0 0E94 0000 call Led1Off + 2051 0bc4 00C0 rjmp .L12 + 2052 .L2: + 2053 /* epilogue start */ + 2054 .LBE36: + 381:serial.c **** stan = s_sync; + 382:serial.c **** } + 383:serial.c **** } + 384:serial.c **** } + 385:serial.c **** crEND(); + 386:serial.c **** } + 2056 .LM250: + 2057 0bc6 0F90 pop __tmp_reg__ + 2058 0bc8 DF91 pop r29 + 2059 0bca CF91 pop r28 + 2060 0bcc 1F91 pop r17 + 2061 0bce 0F91 pop r16 + 2062 0bd0 FF90 pop r15 + 2063 0bd2 0895 ret + 2210 .Lscope2: + 2212 .stabd 78,0,0 + 2215 .global xSerialPortInitMinimal + 2217 xSerialPortInitMinimal: + 2218 .stabd 46,0,0 + 387:serial.c **** + 388:serial.c **** void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) + 389:serial.c **** { + 2220 .LM251: + 2221 .LFBB3: + 2222 0bd4 CF93 push r28 + 2223 /* prologue: function */ + 2224 /* frame size = 0 */ + 2225 /* stack size = 1 */ + 2226 .L__stack_usage = 1 + 2227 0bd6 C82F mov r28,r24 + 390:serial.c **** portENTER_CRITICAL(); + 2229 .LM252: + 2230 /* #APP */ + 2231 ; 390 "serial.c" 1 + 2232 0bd8 0FB6 in __tmp_reg__, __SREG__ + 2233 ; 0 "" 2 + 2234 ; 390 "serial.c" 1 + 2235 0bda F894 cli + 2236 ; 0 "" 2 + 2237 ; 390 "serial.c" 1 + 2238 0bdc 0F92 push __tmp_reg__ + 2239 ; 0 "" 2 + 391:serial.c **** { + 392:serial.c **** /* Create the queues used by the com test task. */ + 393:serial.c **** xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) + 2241 .LM253: + 2242 /* #NOAPP */ + 2243 0bde 61E0 ldi r22,lo8(1) + 2244 0be0 0E94 0000 call xQueueCreate + 2245 0be4 9093 0000 sts xRxedChars+1,r25 + 2246 0be8 8093 0000 sts xRxedChars,r24 + 394:serial.c **** xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) + 2248 .LM254: + 2249 0bec 61E0 ldi r22,lo8(1) + 2250 0bee 8C2F mov r24,r28 + 2251 0bf0 0E94 0000 call xQueueCreate + 2252 0bf4 9093 0000 sts xCharsForTx+1,r25 + 2253 0bf8 8093 0000 sts xCharsForTx,r24 + 395:serial.c **** + 396:serial.c **** UBRR0L = 3; + 2255 .LM255: + 2256 0bfc 83E0 ldi r24,lo8(3) + 2257 0bfe 8093 C400 sts 196,r24 + 397:serial.c **** UBRR0H = 0; + 2259 .LM256: + 2260 0c02 1092 C500 sts 197,__zero_reg__ + 398:serial.c **** + 399:serial.c **** /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx + 400:serial.c **** UCSR0B = ((1< $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +#AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PROGRAMMER = avrispmkII +AVRDUDE_PORT = usb +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m -U efuse:w:0x00:m + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVR_DUDE_WRITE_FUSES) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) bootloader.elf dep/* bootloader.hex bootloader.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/bootloader.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/bootloader.c new file mode 100644 index 0000000..662f96a --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/bootloader.c @@ -0,0 +1,385 @@ +/* + Project: AVR Rs485 bootloader + Base on + Project: AVR Universal BootLoader + Author: Shaoziyang + Shaoziyang@gmail.com + http://avrubd.googlepages.com + + Author: Adam Kaliszan + adam.kaliszan@gmail.com + + File: bootldr.c + main program code + + Version: 0.9 + + Date: 2010.4 +*/ + +#include "bootloader.h" + +uint8_t helloBuf[] = {SYNC, 0, rHELLO, 8, 0x00 , 0x00, 0x00, 'b', '0', '.', '7', '0'}; //rHELLO response +uint8_t pingBuf[HDR_LEN+PROT_BUF_LEN] = {SYNC, 0, rPING, 8}; //rPING response +uint8_t noCommandBuf[] = {SYNC, 0, rUNKNOWN, 0}; //unknown command response + +uint8_t buf[BUFSIZE]; // xModem receive buffer +uint8_t bufptr; +uint8_t pagptr; +uint8_t ch; +uint8_t cl; +uint16_t FlashAddr; +uint8_t cnt; + +uint8_t tmp; +uint8_t adres; // Adres urządzenia zczytany na starcie +stanAutomatu_t stan; // Stan automatu +uint16_t crc; // Crc +uint16_t crcObl; // Crc +uint8_t protAddr; // Odebrany adres w magistrali Rs485 +uint8_t protRozkaz; // Odebrany kod rozkazu +uint8_t protDlDanych; // Odebrana inf. o długości pola danych +uint8_t protBuf[PROT_BUF_LEN]; // Odebrane dane do rozkazu +uint8_t protCrcHi; // Odebrany bardziej znaczący bajt CRC +uint8_t protCrcLo; // Odebrany mniej znaczący bajt CRC +uint8_t protDaneWsk; // Licznik odebranych danych + + +inline void write_one_page(unsigned char *buf) //Uaktualnianie strony z pamięcią flash +{ + boot_page_erase(FlashAddr); //Kasowanie strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji + + uint16_t *tmpPtr = (uint16_t *)(buf); //kompilator musi być little bit endian + for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2) + { + boot_page_fill(pagptr, *tmpPtr); //brzydkie rzutowanie 2X uint8_t na uint16_t + tmpPtr++; //wskaźnik zwiększa się o 2 + } + boot_page_write(FlashAddr); //Zapis strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji +} + +//send data to comport +void WriteCom(unsigned char dat) +{ + RS485Enable(); + UDRREG(COMPORTNo) = dat; + while(!(UCSR0A & (1<>8)); + WriteCom((uint8_t)(crc & 0xFF)); + crc=0; +} + + +void wykonajRozkaz(void) +{ + uint8_t tmpCrcLo = (uint8_t)(crcObl & 0xFF); + uint8_t tmpCrcHi = (uint8_t)(crcObl >>8); + + resetStateMachine(); + if ((tmpCrcHi != protCrcHi) ||(tmpCrcLo != protCrcLo)) + { + return; + } + stan = sync; +//cnt = TimeOutCnt; + if (adres != protAddr) + { + if (protRozkaz == rFLASH) + { + waitAndQuit(); + } + return; + } + if (protRozkaz == rFLASH) + { + stan = xModem; + return; + } + if (protRozkaz == rHELLO) + { + sendBuf(helloBuf, HDR_LEN+8); + return; + } + if (protRozkaz == rPING) + { + if (protDlDanych > PROT_BUF_LEN) + protDlDanych = PROT_BUF_LEN; + pingBuf[3] = protDlDanych; + for (tmp=0; tmp>1); + + //initialize serial port UART0 + UCSR0A = 0; + UCSR0B = (1 << RXENBIT(COMPORTNo))|(1 << TXENBIT(COMPORTNo)); + UCSR0C = (1 << USEURSEL)|(1 << UCSZ01)|(1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 3; + + cnt = TimeOutCnt; // Timeout (wg. częstotliwości zegara 1Hz) + cl = 0; // Liczba poprawnych liter od hasła + + +//Wykonywanie poleceń. Tryb bootloadera. + while(stan != xModem) // Czekanie aż zostanie odebrany rozkaz rozpoczęcia transmisji xModemowej + { + if(TIFRREG & (1< + break; + } + + //begin xModem transmission - receive data + packNO = 1; + bufptr = 0; + cnt = 0; + FlashAddr = 0; + while(1) + { + ch = ReadCom_withLimitedWaiting(); // get package number + cl = ~ReadCom_withLimitedWaiting(); + if ((packNO == ch) && (packNO == cl)) + { + uint16_t crc = 0; // start calculate CRC + for(li = 0; li < BUFFERSIZE; li++) // receive a full data frame + { + tmp = ReadCom_withLimitedWaiting(); // read from uart + buf[bufptr++] = tmp; // write to temporary buffer + crc = _crc_xmodem_update(crc, tmp); // calculate CRC + } + crch = ReadCom_withLimitedWaiting(); // get checksum Hi + crcl = ReadCom_withLimitedWaiting(); // get checksum Lo + ch = crc / 256; + cl = crc % 256; + if ((crch == ch) && (crcl == cl)) + { + PORTD |= (uint8_t)(0x40); + packNO++; + while(bufptr > 0) // receive one frame, write multi pages + { + write_one_page(&buf[BUFSIZE - bufptr]); + FlashAddr += SPM_PAGESIZE; // modify Flash page address + bufptr -= SPM_PAGESIZE; + if (FlashAddr >= 2*BootStart) // BootStart is word number (not byte number) + quit(); + } + WriteCom(XMODEM_ACK); // All OK send ACK + cnt = 0; + } + else //CRC + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + } + else //PackNo + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + //too much error, update abort + if(cnt > 3) + { + PORTD |= (uint8_t)(0x20); + break; + } + tmp = ReadCom_withLimitedWaiting(); + + if (tmp == XMODEM_EOT) + break; + } + WriteCom(XMODEM_NAK); + + quit(); + return 0; +} + +//! quit boot mode and jump to user's application +void quit(void) +{ + boot_rww_enable(); //enable application section + (*((void(*)(void))PROG_START))(); //jump +} + +//! wait 1 minute and jump to user's application +void waitAndQuit(void) +{ +// PORTD = 0x20; //LED 1 and 2 on + cnt=120; + while(1) + { + if(TIFRREG & (1< + +#include +#include +#include +#include + +#include "../../../freeRtos/Lib/include/protocol1.h" +#include "../../../freeRtos/Lib/include/xModemCommands.h" + +#define PROT_BUF_LEN 32 /// Rs485 rec buffer length + + +#ifndef F_CPU ///system clock(Hz) +#define F_CPU 7372800UL +#endif + +#define PROG_START 0x0000 /// User's application start address +#define BootStart 0x1C00 /// Boot section address start + +#define BUFFERSIZE 128 /// Xmodem buffer length +#define BAUDRATE 115200 /// Rs485 baudrate + + +#define timeclk 500 /// basic timer interval(ms) +#define TimeOutCnt 10 /// max wait for password time = TimeOutCnt * timeclk +#define TimeOutCntC 40 /// numbers of sending C char for start xModem + + +#define COMPORTNo 0 /// comport number: 0/1/2.. + +#define RS485RXDis 2 /// Pin that disables Rs485 receiver +#define RS485TXEn 3 /// Pin that enables Rs485 transmitter +#define LEDPORTNo 5 /// Pin that is connected to the diode 1 +#define LED2PORTNo 6 /// Pin that is connected to the diode 2 + + +#define RS485Enable() (PORTD |= 0x08) +#define RS485Disable() (PORTD &= 0xF7) + +//receive buffer' size will not smaller than SPM_PAGESIZE +#if BUFFERSIZE < SPM_PAGESIZE +#define BUFSIZE SPM_PAGESIZE +#else +#define BUFSIZE BUFFERSIZE +#endif + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE +#if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#else +#if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + +//check baudrate register error +//mocro below maybe not same in different C compiler +#define FreqTemp (16UL * BAUDRATE * (((F_CPU * 10) / (16 * BAUDRATE) + 5)/ 10)) +#if ((FreqTemp * 50) > (51 * F_CPU) || (FreqTemp * 50) < (49 * F_CPU)) +#error "BaudRate error > 2% ! Please check BaudRate and F_CPU value." +#endif + +#define True 1 +#define False 0 +#define TRUE 1 +#define FALSE 0 + +//internal use macro +#define CONCAT(a, b) a ## b +#define CONCAT3(a, b, c) a ## b ## c + +//register of PORT and bit define +#define PORTREG(No) CONCAT(PORT, No) +#define PINREG(No) CONCAT(PIN, No) +#define UDRREG(No) CONCAT(UDR, No) +#define DDRREG(No) CONCAT(DDR, No) +#define TXCBIT(No) CONCAT(TXC, No) +#define RXCBIT(No) CONCAT(RXC, No) +#define RXENBIT(No) CONCAT(RXEN, No) +#define TXENBIT(No) CONCAT(TXEN, No) +#define URSELBIT(No) CONCAT(URSEL, No) + +//some kind of AVR need URSEL define when comport initialize +#define USEURSEL 0 + + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + + + +//#define DataInCom() (UCSRAREG(COMPORTNo) & (1 << RXCBIT(COMPORTNo))) +#define DataInCom() (UCSR0A & (1 << RXC0)) +#define ReadCom() UDR0 + +//@{ +/** + * Stan automatu: + * sync, addr, rozkaz, dlDanych, dane, crcHi, crcLo, xModem + */ +enum stanAutomatu +{ + sync, + addr, + rozkaz, + dlDanych, + dane, + crcHi, + crcLo, + xModem +}; +typedef enum stanAutomatu stanAutomatu_t; + +/** + * Leave bootloader mode + */ +void quit(void) __attribute__((noreturn)); + +/** + * Wait for a tame of different device flashing and leave next bootloader mode + */ +void waitAndQuit(void) __attribute__((noreturn)); + +uint8_t ReadCom_withLimitedWaiting(void); + +//@} +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/falsh.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/falsh.h new file mode 100644 index 0000000..775b916 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/falsh.h @@ -0,0 +1,8 @@ +#ifndef FLASSH_H +#define FLASSH_H + +#include +#include + + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/flash.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/flash.c new file mode 100644 index 0000000..eeb5942 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/flash.c @@ -0,0 +1,4 @@ +#include "falsh.h" + + + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/serial.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/serial.c new file mode 100644 index 0000000..e69de29 diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/serial.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/serial.h new file mode 100644 index 0000000..1e578fd --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Bootloader/serial.h @@ -0,0 +1,8 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#define RS485Enable() (PORTD |= 0x08) +#define RS485Disable() (PORTD &= 0xF7) + + +#endif /* SERIAL_H */ diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/CMakeLists.txt b/Projects/DidacticSystem/Adam/RollerBlinderTriac/CMakeLists.txt new file mode 100644 index 0000000..93ae9cf --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/CMakeLists.txt @@ -0,0 +1,86 @@ +cmake_minimum_required(VERSION 2.8) +PROJECT("Moduł wykonawczy triaki") +SET(CMAKE_SYSTEM_NAME "Moduł wykonawczy triaki") + +SET(CMAKE_C_COMPILER avr-gcc) +SET(CMAKE_CXX_COMPILER avr-g++) + +SET(MCU atmega168) +#SET(PROGRAMMER_DEV /dev/avrStk500v2prog) +SET(PROGRAMMER_DEV usb) + +SET(IMAGENAME "firmware") + + +SET(${CMAKE_SYSTEM_NAME}_BINARY_DIR "./build") + + +SET(TARGET_NAME ${IMAGENAME}) + + +SET(SOURCE_DIR "../../freeRtos/Source") +SET(LIB_DIR "../../freeRtos/Lib") +SET(LIB_NET_DIR "../../freeRtos/Lib/net") +SET(PORT_DIR "../../freeRtos/portable/GCC/ATMega168") +SET(PORT_MEM "../../freeRtos/portable/MemMang") + +include_directories("./" "${SOURCE_DIR}/include" "${LIB_DIR}/include" "${LIB_NET_DIR}/include" "${PORT_DIR}") + +SET(CSTANDARD "-std=gnu99") +SET(CDEBUG "-gstabs") +SET(CWARN "-Wall -Wstrict-prototypes") +SET(CTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums") +SET(COPT "-Os") +SET(CINCS "-I. -I${SOURCE_DIR}/include -I${LIB_DIR}/include -I${LIB_NET_DIR}/include") +SET(CMCU "-mmcu=${MCU}") +SET(CDEFS "-DF_CPU=7372800") + + +SET(CFLAGS "${CMCU} ${CDEBUG} ${CDEFS} ${CINCS} ${COPT} ${CWARN} ${CSTANDARD} ${CEXTRA} -Wl,-Map=${IMAGENAME}.map,--cref -lm") +SET(CXXFLAGS "${CMCU} ${CDEFS} ${CINCS} ${COPT}") + +SET(CMAKE_C_FLAGS ${CFLAGS}) +SET(CMAKE_CXX_FLAGS ${CXXFLAGS}) +SET(FORMAT "ihex") + + +add_executable(${IMAGENAME}.elf + main.c automat.c hardware.c serial.c + ${SOURCE_DIR}/tasks.c ${SOURCE_DIR}/queue.c ${SOURCE_DIR}/list.c ${SOURCE_DIR}/croutine.c + ${PORT_MEM}/heap_avr.c + ${PORT_DIR}/port.c ) + + +add_custom_target(FreeRtos DEPENDS + ${SOURCE_DIR}/include/FreeRTOS.h + ${SOURCE_DIR}/include/semphr.h + ${SOURCE_DIR}/include/portable.h + ${SOURCE_DIR}/list.c ${SOURCE_DIR}/include/list.h + ${SOURCE_DIR}/queue.c ${SOURCE_DIR}/include/queue.h + ${SOURCE_DIR}/tasks.c ${SOURCE_DIR}/include/task.h + ${LIB_DIR}/queueStream.c ${LIB_DIR}/include/queueStream.h # obsługa strumienia FILE na potrzeby biblioteki libc + ) + +ADD_CUSTOM_COMMAND( + OUTPUT ${IMAGENAME}.hex + COMMENT "Create hex file" + COMMAND avr-objcopy -O ${FORMAT} -R .eeprom ${IMAGENAME}.elf ${IMAGENAME}.hex + DEPENDS ${IMAGENAME}.elf +) + +ADD_CUSTOM_COMMAND( + OUTPUT ${IMAGENAME}.eep + COMMENT "Create eep file" + COMMAND avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ${FORMAT} ${IMAGENAME}.elf ${IMAGENAME}.eep + DEPENDS ${IMAGENAME}.hex +) + +add_custom_target(install + COMMAND @avr-size -A ${IMAGENAME}.elf + COMMAND avrdude -p ${MCU} -P ${PROGRAMMER_DEV} -c stk500v2 -U flash:w:${IMAGENAME}.hex -U eeprom:w:${IMAGENAME}.eep + COMMENT "Programming device" + DEPENDS ${IMAGENAME}.elf + DEPENDS ${IMAGENAME}.hex + DEPENDS ${IMAGENAME}.eep + COMMENT "Upload firmware to microcontroller" +) diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/FreeRTOSConfig.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/FreeRTOSConfig.h new file mode 100644 index 0000000..53a4f99 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 1 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 200 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 700 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/Makefile b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Makefile new file mode 100644 index 0000000..a69d578 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/Makefile @@ -0,0 +1,405 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = EMTriacFirmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +PORT_DIR = ../../freeRtos/portable/GCC/ATMega168 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +serial.c \ +hardware.c\ +automat.c\ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = avrispmkII +AVRDUDE_PORT = usb # Stk500v2 on dedicated PCB +#AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/ModWykonawczyTriaki.kdev4 b/Projects/DidacticSystem/Adam/RollerBlinderTriac/ModWykonawczyTriaki.kdev4 new file mode 100644 index 0000000..833d014 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/ModWykonawczyTriaki.kdev4 @@ -0,0 +1,3 @@ +[Project] +Manager=KDevCMakeManager +Name=ModWykonawczyTriaki diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.c new file mode 100644 index 0000000..49a8622 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.c @@ -0,0 +1,88 @@ +#include "automat.h" + +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + + if (klGoraOff) + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + stan->klGora_off++; + } + else + { + if (stan->klGora_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_gore; + wiadomosc = 0xBF; + } + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + stan->klGora_off = 0; + } + + if (klDolOff) + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klDol_on = 0; + stan->klDol_off++; + } + else + { + if (stan->klDol_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_dol; + wiadomosc = 0x3F; + } + } + if (stan->klDol_on == T_START_CONT) + { + stan->czynnosc = w_dol; + } + stan->klDol_on++; + stan->klDol_off = 0; + } + + if (stan->klDol_on == 255) + stan->klDol_on = 254; + if (stan->klGora_on == 255) + stan->klGora_on = 254; + + if (stan->klDol_off == 255) + stan->klDol_off = 254; + if (stan->klGora_off == 255) + stan->klGora_off = 254; + + return wiadomosc; +} diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.h new file mode 100644 index 0000000..702de30 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/automat.h @@ -0,0 +1,29 @@ +#ifndef AUTOMAT_H +#define AUTOMAT_H + +#include "main.h" + + +typedef enum +{ + bezczynny, + do_konca_w_gore, + do_konca_w_dol, + w_gore, + w_dol +} t_czynnosc; + +typedef struct +{ + uint8_t klGora_on; + uint8_t klDol_on; + + uint8_t klGora_off; + uint8_t klDol_off; + t_czynnosc czynnosc; +} +t_stan_klawiszy; + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan); + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/flash.txt b/Projects/DidacticSystem/Adam/RollerBlinderTriac/flash.txt new file mode 100644 index 0000000..876fc37 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/flash.txt @@ -0,0 +1,16 @@ +#!/usr/bin/expect -f + +set dev "/dev/rs485tty" +set file "./rtosdemo.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" +send "boot\0x1F\0xE0" +expect "C" +send_user "Starting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.c new file mode 100644 index 0000000..0d73105 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.c @@ -0,0 +1,162 @@ +#include "hardware.h" + +void hardwareInit(void) +{ + DDRB = 0x01; + PORTB = 0x3E; //3 - Adr2, 4 - Adr3, 5 - Adr4 + DDRC = 0x3C; + PORTC = 0x03; + DDRD = 0x0A; //0 - RXD, 1 - TXD, 3 - TxEn, 6 - + PORTD = 0x00; + /*Ustalanie adresu + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = PINC & 0x03; + adres |= ((PINB & 0x38)>>1); +} + +void roleta1wGore(void) +{ + PORTC &= ~0x20; + PORTC |= 0x01; +} + +void roleta1wDol(void) +{ + PORTC &= ~0x10; + PORTC |= 0x20; +} + +void roleta1Stop(void) +{ + PORTC &= ~0x30; +} + +uint8_t czytKlawiszRol1wGore(void) +{ + return PIND & 0x40; +} + +uint8_t czytKlawiszRol1wDol(void) +{ + return PIND & 0x80; +} + +void roleta2wGore(void) +{ + PORTC &= ~0x08; + PORTC |= 0x04; +} + +void roleta2wDol(void) +{ + PORTC &= ~0x08; + PORTC |= 0x04; +} + +void roleta2Stop(void) +{ + PORTC &= ~0x0C; +} + +uint8_t czytKlawiszRol2wGore(void) +{ + return PINB & 0x02; +} + +uint8_t czytKlawiszRol2wDol(void) +{ + return PINB & 0x04; +} + +void wczytajUstawienia(uint8_t konfiguracja) +{ + if (konfiguracja & 0x80) + sterowanie[1].wlaczona = 1; + else + { + sterowanie[1].wlaczona = 0; + roleta1Stop(); + } + + if (konfiguracja & 0x08) + sterowanie[0].wlaczona = 1; + else + { + sterowanie[0].wlaczona = 0; + roleta2Stop(); + } + + sterowanie[0].stop = roleta1Stop; + sterowanie[1].stop = roleta2Stop; + + if (konfiguracja & 0x44 == 0) + { + if (konfiguracja & 0x01) + { + sterowanie[0].czytKlawiszGora = czytKlawiszRol1wGore; + sterowanie[0].czytKlawiszDol = czytKlawiszRol1wDol; + } + else + { + sterowanie[0].czytKlawiszGora = czytKlawiszRol1wDol; + sterowanie[0].czytKlawiszDol = czytKlawiszRol1wGore; + } + if (konfiguracja & 0x10) + { + sterowanie[1].czytKlawiszGora = czytKlawiszRol2wGore; + sterowanie[1].czytKlawiszDol = czytKlawiszRol2wDol; + } + else + { + sterowanie[1].czytKlawiszGora = czytKlawiszRol2wDol; + sterowanie[1].czytKlawiszDol = czytKlawiszRol2wGore; + } + } + else + { + if (konfiguracja & 0x01) + { + sterowanie[0].czytKlawiszGora = czytKlawiszRol2wGore; + sterowanie[0].czytKlawiszDol = czytKlawiszRol2wDol; + } + else + { + sterowanie[0].czytKlawiszGora = czytKlawiszRol2wDol; + sterowanie[0].czytKlawiszDol = czytKlawiszRol2wGore; + } + if (konfiguracja & 0x10) + { + sterowanie[1].czytKlawiszGora = czytKlawiszRol1wGore; + sterowanie[1].czytKlawiszDol = czytKlawiszRol1wDol; + } + else + { + sterowanie[1].czytKlawiszGora = czytKlawiszRol1wDol; + sterowanie[1].czytKlawiszDol = czytKlawiszRol1wGore; + } + } + + if (konfiguracja & 0x02) + { + sterowanie[0].gora = roleta1wGore; + sterowanie[0].dol = roleta1wDol; + } + else + { + sterowanie[0].gora = roleta1wDol; + sterowanie[0].dol = roleta1wGore; + } + + if (konfiguracja & 0x20) + { + sterowanie[1].gora = roleta2wGore; + sterowanie[1].dol = roleta2wDol; + } + else + { + sterowanie[1].gora = roleta2wDol; + sterowanie[1].dol = roleta2wGore; + } +} + diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.h new file mode 100644 index 0000000..91d6bf4 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/hardware.h @@ -0,0 +1,131 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" + + +/* + * Opis sprzętu. + * PORTB + * - PB0 - sterowanie przekaźnikiem (tylko dla wersji z 2 triakami) + * - PB1 - Kl2G (Klawisz roleta 2 góra) + * - PB2 - Kl2D (Klawisz roleta 2 dół) + * - PB3 - ADDR 2 + * - PB4 - ADDR 3 + * - PB5 - ADDR 4 + * PORTC + * - PC0 - Addr 0 + * - PC1 - Addr 1 + * - PC2 - Triak 3 (Roleta 2 góra) + * - PC3 - Triak 4 (Roleta 2 dół) + * - PC4 - Triak 1 (Roleta 1 góra) + * - PC5 - Triak 2 (Roleta 1 dół) + * PORTD + * - PD0 - RxD + * - PD1 - TxD + * - PD3 - TxEN + * - PD6 - Kl1G (Klawisz roleta 1 góra) + * - PD7 - Kl1D (Klawisz roleta 1 dół) + */ + +#define TxStart() (PORTD |= 0x08) +#define TxStop() (PORTD &= 0xF7) + +#if X2 +#define POWER_ON +#define POWER_OFF +#else +#define POWER_ON PORTB |= 0x01; +#define POWER_OFF PORTB &= (~0x01); +#endif + +struct funkcje +{ + uint8_t wlaczona; + void (*stop)(void); + void (*gora)(void); + void (*dol)(void); + uint8_t (*czytKlawiszGora)(void); + uint8_t (*czytKlawiszDol)(void); +}; + + +extern uint8_t adres; +extern uint8_t settings; +extern char bHelloResp[]; +struct funkcje sterowanie[2]; + +/** + * Inicjalizacja sprzętu + */ +void hardwareInit(void); + +/** + * Wczytuje ustawienia + * @param konfiguracja Roleta 1 (bity 3-0), Roleta 2 (bity 7-4) + * - bit 7 (3) - włączona obsługa rolety 2 (1) + * - bit 6 (2) - zamiana klawiszy rolet roletę 1 obsługują klawisze od rolety 2 i odwrotnie + * - bit 5 (1) - odwrócenie faz silnika w rolecie 2 (1) + * - bit 4 (0) - odwrócenie klawisze góra/dół w rolecie 2 (1) + */ +void wczytajUstawienia(uint8_t konfiguracja); + + +/** + * Włącznenie triaka - rozpoczęcie podnoszenia rolety 1 + */ +void roleta1wGore(void); + +/** + * Włącznenie triaka - rozpoczęcie podnoszenia rolety 2 + */ +void roleta2wGore(void); + +/** + * Włącznenie triaka - rozpoczęcie opuszczania rolety 1 + */ +void roleta1wDol(void); + +/** + * Włącznenie triaka - rozpoczęcie opuszczania rolety 2 + */ +void roleta2wDol(void); + +/** + * Wyłącznenie triaków - zatrzymanie rolety 1 + */ +void roleta1Stop(void); + +/** + * Wyłącznenie triaków - zatrzymanie rolety 2 + */ +void roleta2Stop(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 1 + */ +uint8_t czytKlawiszRol1wGore(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 2 + */ +uint8_t czytKlawiszRol2wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 1 + */ +uint8_t czytKlawiszRol1wDol(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 2 + */ +uint8_t czytKlawiszRol2wDol(void); + + +void powerOn(void); +void powerOff(void); + + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.c new file mode 100644 index 0000000..d4b9185 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.c @@ -0,0 +1,214 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" +#include +#include "hardware.h" + + +/** + * Proces odpowiedzialny za obsługę klawiszy + * @param pvParameters ignorowane parametry + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Proces odpowiedzialny za obsługę rolety + * @param pvParameters ignorowane parametry + */ +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +#if DO_INCR_RST +static void prvIncrementResetCount( void ) +{ + unsigned portCHAR ucCount; + eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); + ucCount++; + eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); +} +#endif + +void vApplicationIdleHook( void ); + + +/*-----------------------------------------------------------*/ + +/* Device address on RS 485 bus */ + +uint8_t settingsEep EEMEM = 0x88; +uint8_t adres; +char bHelloResp[HELLO_RESP_LEN+HDR_LEN] = {SYNC, 0, rHELLO, HELLO_RESP_LEN, 0, 0, 0, 'v', '0', '.', '0', '2'}; + +t_stan_klawiszy roleta[2] = {{0, 0, 0, 0, bezczynny}, {0, 0, 0, 0, bezczynny}}; + +extern xQueueHandle xRxedChars; +extern xQueueHandle xCharsForTx; +extern struct funkcje sterowanie[2]; + +xQueueHandle xRoleta[2]; + +portSHORT main( void ) +{ +#if DO_INCR_RST + prvIncrementResetCount(); +#endif + hardwareInit(); + + + wczytajUstawienia(settings); + settings = eeprom_read_byte(&settingsEep); + + POWER_ON + + xSerialPortInitMinimal(32); + + xRoleta[0] = xQueueCreate(4, 1); +#if X2 + xRoleta[1] = xQueueCreate(4, 1); +#endif + xCoRoutineCreate(vProtocol, 0, 0); + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vRoleta, 0, 0); +#if X2 + xCoRoutineCreate(vRoleta, 0, 1); +#endif + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + static portBASE_TYPE xResult; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta[0])); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + } +#if X2 + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta[1])); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + } +#endif + } + crEND(); +} + +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + static uint8_t rozkaz; + static uint16_t czasAkcji; + static portBASE_TYPE xResult; + czasAkcji = portMAX_DELAY; + + crSTART( xHandle ); + for (;;) + { + crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz, czasAkcji, &xResult); + + if (xResult == pdTRUE) + { + uint8_t tmp = rozkaz & 0x3F; + if (tmp == 0) + czasAkcji = portMAX_DELAY; + else + czasAkcji = tmp*20; + if (rozkaz & 0x40) + { + sterowanie[uxIndex].stop(); + } + else + { + sterowanie[uxIndex].stop(); + + bHelloResp[HDR_LEN+2] + crDELAY(xHandle, 10); + bHelloResp[HDR_LEN+uxIndex] &= 0x3F; + + if (rozkaz & 0x80) + { + bHelloResp[HDR_LEN+uxIndex] |= 0x80; + sterowanie[uxIndex].gora(); + } + else + { + bHelloResp[HDR_LEN+uxIndex] |= 0x40; + sterowanie[uxIndex].dol(); + } + } + } + else + { + bHelloResp[HDR_LEN+uxIndex] &= 0x3F; + czasAkcji = portMAX_DELAY; + sterowanie[uxIndex].stop(); + } + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.h b/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.h new file mode 100644 index 0000000..387d264 --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/main.h @@ -0,0 +1,35 @@ +#ifndef MAIN_H +#define MAIN_H + +#define X2 1 + + +#include +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" +#include "automat.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define DO_INCR_RST 0 + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + +uint8_t settings; + +#endif diff --git a/Projects/DidacticSystem/Adam/RollerBlinderTriac/serial.c b/Projects/DidacticSystem/Adam/RollerBlinderTriac/serial.c new file mode 100644 index 0000000..b87c87a --- /dev/null +++ b/Projects/DidacticSystem/Adam/RollerBlinderTriac/serial.c @@ -0,0 +1,373 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "../../freeRtos/Lib/include/protocol1.h" +#include "hardware.h" + +//#define debug 1 + +/*-----------------------------------------------------------*/ + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + + +static volatile uint8_t kodRozkazu; +static volatile uint8_t dlDanych; +static uint8_t bDane[MAX_DATA_LEN]; + +static uint8_t wiadomosc; + + +static xSemaphoreHandle xSemaphore; + +static uint8_t crcLo; +static uint8_t crcHi; +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + { + case rOpuscRolete1: + wiadomosc = 0x3F; + wysylac = 2; + break; + + case rOpuscRolete2: +#if X2 + wiadomosc = 0x3F; + wysylac = 3; +#endif + break; + + case rPodniesRolete1: + wiadomosc = 0xBF; + wysylac = 2; + break; + + case rPodniesRolete2: +#if X2 + wiadomosc = 0xBF; + wysylac = 3; +#endif + break; + + case rZatrzymajRolete1: + wiadomosc = 0x40; + wysylac = 2; + break; + + case rZatrzymajRolete2: +#if X2 + wiadomosc = 0x40; + wysylac = 3; +#endif + break; + + case rPING: + wysylac = 1; + break; + case rHELLO: + wysylac = 4; + break; + case rFLASH: + wysylac = 1; + break; + + case rUstaw: + wczytajUstawienia(bDane[0]); + settings = bDane[0]; + break; + + case rZapiszUstawienia: + eeprom_write_byte(&settingsEep, settings); + break; + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + static t_serialState stan; + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + + for( ;; ) + { + if (stan == s_sync) + { + znak=0; + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + if ((xResult == pdPASS) && (znak == SYNC)) + { + stan = s_addr; + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + stan = s_rozkaz; + crc = _crc_xmodem_update(crc, znak); + if (znak == adres) + dobryAdres = 1; + else + dobryAdres = 0; + } + else + { + stan = s_sync; + } + } + if (stan == s_rozkaz) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, kodRozkazu); + stan = s_len; + } + else + { + stan = s_sync; + } + } + if (stan == s_len) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, dlDanych); + lOdebrDanych = 0; + stan = s_dane; + } + else + { + stan = s_sync; + } + } + if (stan == s_dane) + { + if (lOdebrDanych == dlDanych) + { + stan = s_CRC_HI; + } + else + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, znak); + if (lOdebrDanych < MAX_DATA_LEN) + bDane[lOdebrDanych] = znak; + lOdebrDanych++; + } + else + { + stan = s_sync; + } + } + } + if (stan == s_CRC_HI) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + if (xResult == pdPASS) + { + stan = s_CRC_LO; + } + else + { + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + if (xResult == pdPASS) + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + { + stan = s_sync; + } + else + { + stan = s_CRC_OK; + } + } + } + if (stan == s_CRC_OK) + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + if (rezultat == 1) + { + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(0, temp); + + //ADRES 0x00 adres mastera + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + + if (kodRozkazu == rFLASH) + { + (*((void(*)(void))BOOT_START))(); //reboot + } + } + else if (rezultat == 2) + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + } +#if X2 + else if (rezultat == 3) + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + } +#endif + else if (rezultat == 4) + { + //SYNC + crc = 0; + uint8_t temp; + + //Dane + bHelloResp[HDR_LEN+2] = settings; + for (temp = 0; temp < HELLO_RESP_LEN+HDR_LEN; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + stan = s_sync; + } + else //Zły adres + { + if (kodRozkazu == rFLASH) + { + DISABLE_RX(); + crDELAY(xHandle, 1000); + ENABLE_RX(); + } + stan = s_sync; + } + } + } + crEND(); +} + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + UBRR0L = 3; + UBRR0H = 0; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1< + + + + + diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/FreeRTOSConfig.h b/Projects/DidacticSystem/Labs/AcutatorCoroutines/FreeRTOSConfig.h new file mode 100644 index 0000000..a76f2ab --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/Makefile b/Projects/DidacticSystem/Labs/AcutatorCoroutines/Makefile new file mode 100644 index 0000000..8d95b84 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/Makefile @@ -0,0 +1,409 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTOS_SRC_DIR = ../../../../FreeRtosCore/Source +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega168 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang + +SRC = \ +main.c \ +hardware.c\ +$(RTOS_SRC_DIR)/tasks.c \ +$(RTOS_SRC_DIR)/queue.c \ +$(RTOS_SRC_DIR)/list.c \ +$(RTOS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#serial.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTOS_SRC_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.c b/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.c new file mode 100644 index 0000000..4179bdb --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.c @@ -0,0 +1,160 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - Led3 , 1 - Led2 , 2 - Led1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - Key1, 3 - Key2 + PORTC = 0x3F; //4 - Key3, 5 - Key4 + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - ExtLed1, 6 - ExtLed2, 7 - Led4) +} + +void ledOn(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1on(); + break; + case 1: + led2on(); + break; + case 2: + led3on(); + break; + case 3: + led4on(); + break; + default: + break; + } +} + +void ledOff(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1off(); + break; + case 1: + led2off(); + break; + case 2: + led3off(); + break; + case 3: + led4off(); + break; + default: + break; + } +} +void ledToggle(uint8_t ledNo) +{ + switch (ledNo) + { + case 0: + led1toggle(); + break; + case 1: + led2toggle(); + break; + case 2: + led3toggle(); + break; + case 3: + led4toggle(); + break; + default: + break; + } +} + +char readKey(uint8_t keyNo) +{ + switch (keyNo) + { + case 0: return readKey1(); + case 1: return readKey2(); + case 2: return readKey3(); + case 3: return readKey4(); + default: return 1; + } +} + +inline void led1on(void) +{ + PORTB |= 0x04; +} +inline void led1off(void) +{ + PORTB &= ~0x04; +} +inline void led1toggle(void) +{ + PORTB ^= 0x04; +} + +inline void led2on(void) +{ + PORTB |= 0x02; +} +inline void led2off(void) +{ + PORTB &= ~0x02; +} +inline void led2toggle(void) +{ + PORTB ^= 0x02; +} + +inline void led3on(void) +{ + PORTB |= 0x01; +} +inline void led3off(void) +{ + PORTB &= ~0x01; +} +inline void led3toggle(void) +{ + PORTB ^= 0x01; +} + +inline void led4on(void) +{ + PORTD |= 0x80; +} +inline void led4off(void) +{ + PORTD &= ~0x80; +} +inline void led4toggle(void) +{ + PORTD ^= 0x80; +} + + +inline char readKey1(void) +{ + return PINC & 0x04; +} + +inline char readKey2(void) +{ + return PINC & 0x08; +} + +inline char readKey3(void) +{ + return PINC & 0x10; +} + +inline char readKey4(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.h b/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.h new file mode 100644 index 0000000..caf98a2 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/hardware.h @@ -0,0 +1,123 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" + +#define TxStart() (PORTD |= 0x0C) +#define TxStop() (PORTD &= 0xF3) + +extern uint8_t address; +extern char bHelloResp[]; + +/** + * Herdware initialization + */ +void hardwareInit(void); + +/** + * Switch on specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOn(uint8_t ledNo); + +/** + * Switch off specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOff(uint8_t ledNo); + +/** + * Toggle specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledToggle(uint8_t ledNo); + +/** + * Reads specyfied key state + * @param keyNo - key number (0-3) + * @return 0 - key pressed, > 0 key is not pressed + */ +char readKey(uint8_t keyNo); + +/** + * Switch on (enable) Led 1 + */ +void led1on(void); + +/** + * Switch off (disable) Led 1 + */ +void led1off(void); + +/** + * Toggle (change state) Led 1 + */ +void led1toggle(void); + +/** + * Read key #1 + */ +char readKey1(void); + +/** + * Switch on (enable) Led 2 + */ +void led2on(void); + +/** + * Switch off (disable) Led 2 + */ +void led2off(void); + +/** + * Toggle (change state) Led 2 + */ +void led2toggle(void); + +/** + * Read key #2 + */ +char readKey2(void); + +/** + * Switch on (enable) Led 3 + */ +void led3on(void); + +/** + * Switch off (disable) Led 3 + */ +void led3off(void); + +/** + * Toggle (change state) Led 3 + */ +void led3toggle(void); + +/** + * Read key #3 + */ +char readKey3(void); + +/** + * Switch on (enable) Led 4 + */ +void led4on(void); + +/** + * Switch off (disable) Led 4 + */ +void led4off(void); + +/** + * Toggle (change state) Led 4 + */ +void led4toggle(void); + +/** + * Read key #4 + */ +char readKey4(void); + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.c b/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.c new file mode 100644 index 0000000..74b7fcb --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.c @@ -0,0 +1,73 @@ +#include "main.h" + +/** + * Korutyna odpowiedzialna za sprawdzanie stanu przycisków. + * @param xHandle uchwyt do korutyny umożliwiający zastosowanie makr. Programista nie może go używać bezpośrednio. + * @param uxIndex indeks korutyny. Umożliwia wykonywanie tej samej funkcji przez kilka korutyn. + * W przypadku tej funkcji, parametr nie jest wykorzystywany. + * By uniknąć ostrzeżeń, należy na początku funkcji wpisać (void) uxIndex; + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Korutyna odpowiedzialna za sterowanie diodami. + * @param xHandle uchwyt do korutyny umożliwiający zastosowanie makr. Programista nie może go używać bezpośrednio. + * @param uxIndex indeks korutyny. Umożliwia wykonywanie tej samej funkcji przez kilka korutyn. W zależności od indeksu korytyna może sterować inną diodą + */ +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Funkcja wykonywana w procesie bezczynności. W poniższym programie obsługuje ona korutyny. System wykonuje tylko 1 proces - proces bezczynności, nie ma innych zadań. + */ +void vApplicationIdleHook( void ); + + +/*-----------------------------------------------------------*/ + +portSHORT main( void ) +{ + /// Konfiguracja portów, określanie adresu urządzenia, konfiguracja portu szeregowego. + hardwareInit(); + + /// Dodawanie korutyn. Można tutaj uruchomić kolejne korutyny + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vDioda, 0, 0); + xCoRoutineCreate(vDioda, 0, 1); + + /// Uruchomienie planisty. Od tego momentu działa wielozadaniowy system operacyjny. + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; // get rid compiller worning. Theare is only one such coroutine. We don't need info about its index. + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + } + crEND(); +} + +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + crSTART( xHandle ); + for (;;) + { + ledOn(uxIndex); + crDELAY(xHandle, 100); + } + crEND(); +} + +// Tej funkcji nie należy modyfikować. +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} diff --git a/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.h b/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.h new file mode 100644 index 0000000..a543370 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorCoroutines/main.h @@ -0,0 +1,26 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "hardware.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/FreeRTOSConfig.h b/Projects/DidacticSystem/Labs/AcutatorRS485/FreeRTOSConfig.h new file mode 100644 index 0000000..97ad256 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/Makefile b/Projects/DidacticSystem/Labs/AcutatorRS485/Makefile new file mode 100644 index 0000000..2009019 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/Makefile @@ -0,0 +1,410 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTOS_SRC_DIR = ../../../../FreeRtosCore/Source +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega168 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang + +SRC = \ +main.c \ +hardware.c\ +serial.c\ +$(RTOS_SRC_DIR)/tasks.c \ +$(RTOS_SRC_DIR)/queue.c \ +$(RTOS_SRC_DIR)/list.c \ +$(RTOS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#serial.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTOS_SRC_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/Rs485.cbp b/Projects/DidacticSystem/Labs/AcutatorRS485/Rs485.cbp new file mode 100644 index 0000000..14d05d2 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/Rs485.cbp @@ -0,0 +1,79 @@ + + + + + + diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.c b/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.c new file mode 100644 index 0000000..4179bdb --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.c @@ -0,0 +1,160 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - Led3 , 1 - Led2 , 2 - Led1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - Key1, 3 - Key2 + PORTC = 0x3F; //4 - Key3, 5 - Key4 + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - ExtLed1, 6 - ExtLed2, 7 - Led4) +} + +void ledOn(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1on(); + break; + case 1: + led2on(); + break; + case 2: + led3on(); + break; + case 3: + led4on(); + break; + default: + break; + } +} + +void ledOff(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1off(); + break; + case 1: + led2off(); + break; + case 2: + led3off(); + break; + case 3: + led4off(); + break; + default: + break; + } +} +void ledToggle(uint8_t ledNo) +{ + switch (ledNo) + { + case 0: + led1toggle(); + break; + case 1: + led2toggle(); + break; + case 2: + led3toggle(); + break; + case 3: + led4toggle(); + break; + default: + break; + } +} + +char readKey(uint8_t keyNo) +{ + switch (keyNo) + { + case 0: return readKey1(); + case 1: return readKey2(); + case 2: return readKey3(); + case 3: return readKey4(); + default: return 1; + } +} + +inline void led1on(void) +{ + PORTB |= 0x04; +} +inline void led1off(void) +{ + PORTB &= ~0x04; +} +inline void led1toggle(void) +{ + PORTB ^= 0x04; +} + +inline void led2on(void) +{ + PORTB |= 0x02; +} +inline void led2off(void) +{ + PORTB &= ~0x02; +} +inline void led2toggle(void) +{ + PORTB ^= 0x02; +} + +inline void led3on(void) +{ + PORTB |= 0x01; +} +inline void led3off(void) +{ + PORTB &= ~0x01; +} +inline void led3toggle(void) +{ + PORTB ^= 0x01; +} + +inline void led4on(void) +{ + PORTD |= 0x80; +} +inline void led4off(void) +{ + PORTD &= ~0x80; +} +inline void led4toggle(void) +{ + PORTD ^= 0x80; +} + + +inline char readKey1(void) +{ + return PINC & 0x04; +} + +inline char readKey2(void) +{ + return PINC & 0x08; +} + +inline char readKey3(void) +{ + return PINC & 0x10; +} + +inline char readKey4(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.h b/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.h new file mode 100644 index 0000000..7879b90 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/hardware.h @@ -0,0 +1,110 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" + +#define TxStart() (PORTD |= 0x0C) /* Podłączenie nadajnika RS 485 do magistrali */ +#define TxStop() (PORTD &= 0xF3) /* Odłączenie nadajnika RS 485 od magistrali */ + +//extern uint8_t address; + +/** + * Herdware initialization + */ +void hardwareInit(void); + +/** + * Switch on specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOn(uint8_t ledNo); + +/** + * Switch off specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOff(uint8_t ledNo); + +/** + * Toggle specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledToggle(uint8_t ledNo); + +/** + * Reads specyfied key state + * @param keyNo - key number (0-3) + * @return 0 - key pressed, > 0 key is not pressed + */ +char readKey(uint8_t keyNo); + +/** + * Switch on (enable) Led 1 + */ +void led1on(void); +/** + * Switch off (disable) Led 1 + */ +void led1off(void); +/** + * Toggle (change state) Led 1 + */ +void led1toggle(void); +/** + * Read key #1 + */ +char readKey1(void); + +/** + * Switch on (enable) Led 2 + */ +void led2on(void); +/** + * Switch off (disable) Led 2 + */ +void led2off(void); +/** + * Toggle (change state) Led 2 + */ +void led2toggle(void); +/** + * Read key #2 + */ +char readKey2(void); + +/** + * Switch on (enable) Led 3 + */ +void led3on(void); +/** + * Switch off (disable) Led 3 + */ +void led3off(void); +/** + * Toggle (change state) Led 3 + */ +void led3toggle(void); +/** + * Read key #3 + */ +char readKey3(void); + +/** + * Switch on (enable) Led 4 + */ +void led4on(void); +/** + * Switch off (disable) Led 4 + */ +void led4off(void); +/** + * Toggle (change state) Led 4 + */ +void led4toggle(void); +/** + * Read key #4 + */ +char readKey4(void); + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/main.c b/Projects/DidacticSystem/Labs/AcutatorRS485/main.c new file mode 100644 index 0000000..a0df3dc --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/main.c @@ -0,0 +1,101 @@ +#include "main.h" +#include "serial.h" +#include "hardware.h" + +/** + * Tablica buforów, za pomocą których komunikują się korutyny obsługujące diody + */ +xQueueHandle xDiodesOn[4]; + +/** + * Deklaracje funkcji wykonywanych przez korutyny. + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +void vApplicationIdleHook( void ); + + +portSHORT main( void ) +{ + /// Utworzenie kolejek + xDiodesOn[0] = xQueueCreate( 4, 1); + xDiodesOn[1] = xQueueCreate( 4, 1); + xDiodesOn[2] = xQueueCreate( 4, 1); + xDiodesOn[3] = xQueueCreate( 4, 1); + + ///Konfiguracja portów + hardwareInit(); + ///Inicjacja portu szeregowego. Utworzenie kolejek do komunikacji z portem szeregowym + xSerialPortInitMinimal(8); + + /// Utworzenie korutyn + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vDioda, 0, 0); + xCoRoutineCreate(vDioda, 0, 1); + xCoRoutineCreate(vDioda, 0, 2); + xCoRoutineCreate(vDioda, 0, 3); + xCoRoutineCreate(vProtocol, 0, 0); + + /// Uruchomienie planisty. Rozpoczyna się praca systemu FreeRtos + vTaskStartScheduler(); + return 0; +} + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + /** + * Jest tylko jedna korutyna do obsługi klawiszy. + * Zatem nie wykorzystyjemy zmiennej uxIndex. + * By pozbyć się ostrzeżenia po kompilacji należy rzutować tą zmienną na void. + */ + (void) uxIndex; + + static uint8_t klawiszNr = 0; + static int16_t result; + + crSTART( xHandle ); + for( ;; ) + { + if (readKey(klawiszNr) == 0) + { + /// 0 oznacza, że klawisz został wciśnięty + } + klawiszNr++; /// Nie ma potrzeby w pętli for robić kolejnej pętli + klawiszNr &= 0x03; /// Operacja %4 zrealizowana za pomoca iloczynu bitowego (klawiszNr = klawiszNr % 4) + + crDELAY( xHandle, 0); /// Wymuszenie przełączenia korutyny. + } /// Makro crQUEUE_SEND z parametrem ticksToWait równym 0 nie przełącza korutyny + crEND(); +} + +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + crSTART( xHandle ); + for (;;) + { + + crDELAY(xHandle, 0); /// Wymuszenie przełączenia korutyny, makro do odbioru wiadomości z czasem 0 nie przełącza korutyn + } + crEND(); +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY(xHandle, 100); + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/main.h b/Projects/DidacticSystem/Labs/AcutatorRS485/main.h new file mode 100644 index 0000000..663947c --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/main.h @@ -0,0 +1,32 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" + +#include "hardware.h" +#include "serial.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + + +/** + * Bufory, do komunikacji z korutynami. + * Same korutyny mają ograniczony kontakt ze sprzętem. + * Wyjątkiem jest wysyłanie danych. Po umieszczeniu ich w buforze nadawczym, + * należy włączyć obsługę przerwania "miejsce w sprzętowym buforze nadawczym". + */ +xQueueHandle xRxedChars; /// Bufor, który przechowuje odebrane znaki z magistrali RS 485 +xQueueHandle xCharsForTx; /// Bufor, który przechowuje znaki do wysłania przez magistralę RS 485 + + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorRS485/serial.c b/Projects/DidacticSystem/Labs/AcutatorRS485/serial.c new file mode 100644 index 0000000..bf19571 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorRS485/serial.c @@ -0,0 +1,146 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 2 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + + +/** + * Konfiguracja portu szeregowego + */ +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /** + * Utworzenie buforów, które służą do przesyłania wiadomości pomiędzy korutynami a portem szeregowym. + */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + /** + * Konfiguracja pracy portu szeregowego + */ + UBRR0L = 3; /// Szybkość transmisji 115 kb/s + UBRR0H = 0; /// wartość rejestru zależy od taktowania procesora + + UCSR0C = ( serUCSRC_SELECT | serEIGHT_DATA_BITS ); /// Długość przesyłanego słowa: 8 bitów + + /** + * Włączenie obsługi przerwań portu szeregowego: + * - odebrano wiadomość + * - zakończono wysyłanie. + * Włączenie Nadajnika i odbiornika portu szeregowego. + * Uwaga: Włączoy nadajnik nie wystarczy do rozpoczęcia transmisji. + * Musi on dodatkowo zostać podłączony do magistrali RS 485. + */ + UCSR0B = ((1< + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/Makefile b/Projects/DidacticSystem/Labs/AcutatorTLV/Makefile new file mode 100644 index 0000000..3c00044 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/Makefile @@ -0,0 +1,411 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTOS_SRC_DIR = ../../../../FreeRtosCore/Source +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega168 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang + +SRC = \ +main.c \ +hardware.c\ +serial.c\ +automat.c\ +$(RTOS_SRC_DIR)/tasks.c \ +$(RTOS_SRC_DIR)/queue.c \ +$(RTOS_SRC_DIR)/list.c \ +$(RTOS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#serial.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTOS_SRC_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/TLV.cbp b/Projects/DidacticSystem/Labs/AcutatorTLV/TLV.cbp new file mode 100644 index 0000000..c24ab0b --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/TLV.cbp @@ -0,0 +1,88 @@ + + + + + + diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/automat.c b/Projects/DidacticSystem/Labs/AcutatorTLV/automat.c new file mode 100644 index 0000000..49a8622 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/automat.c @@ -0,0 +1,88 @@ +#include "automat.h" + +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + + if (klGoraOff) + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + stan->klGora_off++; + } + else + { + if (stan->klGora_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_gore; + wiadomosc = 0xBF; + } + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + stan->klGora_off = 0; + } + + if (klDolOff) + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klDol_on = 0; + stan->klDol_off++; + } + else + { + if (stan->klDol_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_dol; + wiadomosc = 0x3F; + } + } + if (stan->klDol_on == T_START_CONT) + { + stan->czynnosc = w_dol; + } + stan->klDol_on++; + stan->klDol_off = 0; + } + + if (stan->klDol_on == 255) + stan->klDol_on = 254; + if (stan->klGora_on == 255) + stan->klGora_on = 254; + + if (stan->klDol_off == 255) + stan->klDol_off = 254; + if (stan->klGora_off == 255) + stan->klGora_off = 254; + + return wiadomosc; +} diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/automat.h b/Projects/DidacticSystem/Labs/AcutatorTLV/automat.h new file mode 100644 index 0000000..702de30 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/automat.h @@ -0,0 +1,29 @@ +#ifndef AUTOMAT_H +#define AUTOMAT_H + +#include "main.h" + + +typedef enum +{ + bezczynny, + do_konca_w_gore, + do_konca_w_dol, + w_gore, + w_dol +} t_czynnosc; + +typedef struct +{ + uint8_t klGora_on; + uint8_t klDol_on; + + uint8_t klGora_off; + uint8_t klDol_off; + t_czynnosc czynnosc; +} +t_stan_klawiszy; + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan); + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.c b/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.c new file mode 100644 index 0000000..f7dce43 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.c @@ -0,0 +1,165 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - Led3 , 1 - Led2 , 2 - Led1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - Key1, 3 - Key2 + PORTC = 0x3F; //4 - Key3, 5 - Key4 + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - ExtLed1, 6 - ExtLed2, 7 - Led4) + /*Reading Rs485 address + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = (PINB & 0x38) >> 1; + adres |= (PINC & 0x03); +} + +void ledOn(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1on(); + break; + case 1: + led2on(); + break; + case 2: + led3on(); + break; + case 3: + led4on(); + break; + default: + break; + } +} + +void ledOff(uint8_t ledNo) +{ + switch(ledNo) + { + case 0: + led1off(); + break; + case 1: + led2off(); + break; + case 2: + led3off(); + break; + case 3: + led4off(); + break; + default: + break; + } +} +void ledToggle(uint8_t ledNo) +{ + switch (ledNo) + { + case 0: + led1toggle(); + break; + case 1: + led2toggle(); + break; + case 2: + led3toggle(); + break; + case 3: + led4toggle(); + break; + default: + break; + } +} + +char readKey(uint8_t keyNo) +{ + switch (keyNo) + { + case 0: return readKey1(); + case 1: return readKey2(); + case 2: return readKey3(); + case 3: return readKey4(); + default: return 1; + } +} + +inline void led1on(void) +{ + PORTB |= 0x04; +} +inline void led1off(void) +{ + PORTB &= ~0x04; +} +inline void led1toggle(void) +{ + PORTB ^= 0x04; +} + +inline void led2on(void) +{ + PORTB |= 0x02; +} +inline void led2off(void) +{ + PORTB &= ~0x02; +} +inline void led2toggle(void) +{ + PORTB ^= 0x02; +} + +inline void led3on(void) +{ + PORTB |= 0x01; +} +inline void led3off(void) +{ + PORTB &= ~0x01; +} +inline void led3toggle(void) +{ + PORTB ^= 0x01; +} + +inline void led4on(void) +{ + PORTD |= 0x80; +} +inline void led4off(void) +{ + PORTD &= ~0x80; +} +inline void led4toggle(void) +{ + PORTD ^= 0x80; +} + + +inline char readKey1(void) +{ + return PINC & 0x04; +} + +inline char readKey2(void) +{ + return PINC & 0x08; +} + +inline char readKey3(void) +{ + return PINC & 0x10; +} + +inline char readKey4(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.h b/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.h new file mode 100644 index 0000000..ba15125 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/hardware.h @@ -0,0 +1,110 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" + +#define TxStart() (PORTD |= 0x0C) /* Podłączenie nadajnika RS 485 do magistrali */ +#define TxStop() (PORTD &= 0xF3) /* Odłączenie nadajnika RS 485 od magistrali */ + +extern uint8_t address; + +/** + * Herdware initialization + */ +void hardwareInit(void); + +/** + * Switch on specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOn(uint8_t ledNo); + +/** + * Switch off specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledOff(uint8_t ledNo); + +/** + * Toggle specyfied diode + * @param ledNo - diode number (0-3) + */ +void ledToggle(uint8_t ledNo); + +/** + * Reads specyfied key state + * @param keyNo - key number (0-3) + * @return 0 - key pressed, > 0 key is not pressed + */ +char readKey(uint8_t keyNo); + +/** + * Switch on (enable) Led 1 + */ +void led1on(void); +/** + * Switch off (disable) Led 1 + */ +void led1off(void); +/** + * Toggle (change state) Led 1 + */ +void led1toggle(void); +/** + * Read key #1 + */ +char readKey1(void); + +/** + * Switch on (enable) Led 2 + */ +void led2on(void); +/** + * Switch off (disable) Led 2 + */ +void led2off(void); +/** + * Toggle (change state) Led 2 + */ +void led2toggle(void); +/** + * Read key #2 + */ +char readKey2(void); + +/** + * Switch on (enable) Led 3 + */ +void led3on(void); +/** + * Switch off (disable) Led 3 + */ +void led3off(void); +/** + * Toggle (change state) Led 3 + */ +void led3toggle(void); +/** + * Read key #3 + */ +char readKey3(void); + +/** + * Switch on (enable) Led 4 + */ +void led4on(void); +/** + * Switch off (disable) Led 4 + */ +void led4off(void); +/** + * Toggle (change state) Led 4 + */ +void led4toggle(void); +/** + * Read key #4 + */ +char readKey4(void); + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/main.c b/Projects/DidacticSystem/Labs/AcutatorTLV/main.c new file mode 100644 index 0000000..88c5a15 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/main.c @@ -0,0 +1,102 @@ +#include "main.h" +#include "hardware.h" + +/** + * Tablica buforów, za pomocą których komunikują się korutyny obsługujące diody + */ +xQueueHandle xDiodesOn[4]; + +/** + * Deklaracje funkcji wykonywanych przez korutyny. + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +void vApplicationIdleHook( void ); + +portSHORT main( void ) +{ + /// Utworzenie kolejek + xDiodesOn[0] = xQueueCreate( 4, 1); + xDiodesOn[1] = xQueueCreate( 4, 1); + xDiodesOn[2] = xQueueCreate( 4, 1); + xDiodesOn[3] = xQueueCreate( 4, 1); + + hardwareInit(); + + /// Utworzenie korutyn + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vDioda, 0, 0); + xCoRoutineCreate(vDioda, 0, 1); + xCoRoutineCreate(vDioda, 0, 2); + xCoRoutineCreate(vDioda, 0, 3); + + xCoRoutineCreate(vProtocol, 0, 0); + + + /// Uruchomienie planisty. Rozpoczyna się praca systemu FreeRtos + vTaskStartScheduler(); + return 0; +} + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + /** + * Jest tylko jedna korutyna do obsługi klawiszy. + * Zatem nie wykorzystyjemy zmiennej uxIndex. + * By pozbyć się ostrzeżenia po kompilacji należy rzutować tą zmienną na void. + */ + (void) uxIndex; + + static uint8_t czasSwiecenia = 200; /// Dioda zostanie zapalona na 4 sekundy + static uint8_t klawiszNr = 0; + static int16_t result; + + crSTART( xHandle ); + for( ;; ) + { + if (readKey(klawiszNr) == 0) + { /// 0 oznacza, że klawisz został wciśnięty + crQUEUE_SEND(xHandle, xDiodesOn[klawiszNr], (void *) (&czasSwiecenia), 0, &result); ///Wysyłanie wiadomości do odpowiedniej kolejki + } /// by zapalić diodę. Operacja ta z parametrem ticksToWait = 0 nie przełącza korutyny + + klawiszNr++; /// Nie ma potrzeby w pętli for robić kolejnej pętli + klawiszNr &= 0x03; /// Operacja %4 zrealizowana za pomoca iloczynu bitowego (klawiszNr = klawiszNr % 4) + + crDELAY( xHandle, 0); /// Wymuszenie przełączenia korutyny. + } /// Makro crQUEUE_SEND z parametrem ticksToWait równym 0 nie przełącza korutyny + crEND(); +} + +static void vDioda(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + static uint8_t czasy[4]; + static int16_t czasyCzekania[4] = {0, 0, 0, 0}; // UWAGA: Te zmienne muszą być 16 bitowe + static int16_t odebrano[4]; // UWAGA: Te zmienne muszą być 16 bitowe + + crSTART( xHandle ); + for (;;) + { + if (czasyCzekania[uxIndex] > 0) + ledOn(uxIndex); + else + ledOff(uxIndex); + + crQUEUE_RECEIVE(xHandle, xDiodesOn[uxIndex], (void *) (&czasy[uxIndex]), czasyCzekania[uxIndex], &odebrano[uxIndex]); + if (odebrano[uxIndex] == pdPASS) + czasyCzekania[uxIndex] = czasy[uxIndex]; + else + czasyCzekania[uxIndex] = 0; + + crDELAY(xHandle, 0); // Wymuszenie przełączenia korutyny + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/main.h b/Projects/DidacticSystem/Labs/AcutatorTLV/main.h new file mode 100644 index 0000000..45d7340 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/main.h @@ -0,0 +1,31 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" +#include "automat.h" +#include "../../../../Lib/include/protocol1.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + + +uint8_t adres; + +#endif diff --git a/Projects/DidacticSystem/Labs/AcutatorTLV/serial.c b/Projects/DidacticSystem/Labs/AcutatorTLV/serial.c new file mode 100644 index 0000000..219b554 --- /dev/null +++ b/Projects/DidacticSystem/Labs/AcutatorTLV/serial.c @@ -0,0 +1,332 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 2 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "../../../../Lib/include/protocol1.h" +#include "hardware.h" + +//#define debug 1 + +/*-----------------------------------------------------------*/ + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + + +static volatile uint8_t kodRozkazu; +static volatile uint8_t dlDanych; +static uint8_t bDane[MAX_DATA_LEN]; + +static uint8_t wiadomosc; + + +static xSemaphoreHandle xSemaphore; +static portBASE_TYPE xHigherPriorityTaskWoken; + +static uint8_t crcLo; +static uint8_t crcHi; +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + { + case 0: //TODO określić jaką wartość ma mieć rozkaz zapal diodę + wysylac = bDane[0]; //Odczyt informacji o numerze diody, jaką chcemy zapalić + wiadomosc = bDane[1]; //Odczyt informacji o czasie, przez jaki ma być zapalona. Xsłoźrnir 8 bitowa wartość określa czas świecenia + break; + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + static t_serialState stan; + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + + for( ;; ) + { + if (stan == s_sync) + { + znak=0; + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + if ((xResult == pdPASS) && (znak == SYNC)) + { + stan = s_addr; + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + stan = s_rozkaz; + crc = _crc_xmodem_update(crc, znak); + if (znak == adres) + dobryAdres = 1; + else + dobryAdres = 0; + } + else + { + stan = s_sync; + } + } + if (stan == s_rozkaz) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, kodRozkazu); + stan = s_len; + } + else + { + stan = s_sync; + } + } + if (stan == s_len) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, dlDanych); + lOdebrDanych = 0; + stan = s_dane; + } + else + { + stan = s_sync; + } + } + if (stan == s_dane) + { + if (lOdebrDanych == dlDanych) + { + stan = s_CRC_HI; + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, znak); + if (lOdebrDanych < MAX_DATA_LEN) + bDane[lOdebrDanych] = znak; + lOdebrDanych++; + } + else + { + stan = s_sync; + } + } + } + if (stan == s_CRC_HI) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + if (xResult == pdPASS) + { + stan = s_CRC_LO; + } + else + { + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + if (xResult == pdPASS) + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + { + stan = s_sync; + } + else + { + stan = s_CRC_OK; + } + } + } + if (stan == s_CRC_OK) + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + if (rezultat < 4) + { + crQUEUE_SEND(xHandle, xDiodesOn[rezultat], (void *)(&wiadomosc), 0, &xResult); + } + else //Ten fragment kodu nie jest teraz potrzebny. Przyda się gdy będziemy implementować polecenie PING + { + + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(0, temp); + + //ADRES 0x00 adres mastera + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + stan = s_sync; + } + } + } + crEND(); +} + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + UBRR0L = 3; + UBRR0H = 0; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1< + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 32000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 100 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 3100 ) ) +//2800 +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 700 +#define STACK_SIZE_ENC 500 +#define STACK_SIZE_SENSORS 500 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/Makefile b/Projects/DidacticSystem/Labs/MainModuleCli/Makefile new file mode 100644 index 0000000..d91d150 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/Makefile @@ -0,0 +1,456 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega128 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +RTS_SRC_DIR = ../../../../FreeRtosCore/Source +LIB_DIR = ../../../../Lib +LIB_NET_DIR = ../../../../Lib/net +PORT_DIR = ../../../../FreeRtosCore/portable/GCC/ATMega64 +PORT_MEM = ../../../../FreeRtosCore/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/mcp4150.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(RTS_SRC_DIR)/tasks.c \ +$(RTS_SRC_DIR)/queue.c \ +$(RTS_SRC_DIR)/list.c \ +$(RTS_SRC_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I$(RTS_SRC_DIR)/include -I$(LIB_DIR)/include -I$(LIB_NET_DIR)/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +#$(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_en.h b/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_en.h new file mode 100644 index 0000000..558da24 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_en.h @@ -0,0 +1,10 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT EN + +#include + +const char statusRollerDescStr[] PROGMEM = " %d roller driver: roller 1 position %d, roller 2 position %d"; +const char statusRollerDescStrConf[] PROGMEM = " config %x"; +const char statusRollerDescStr2[] PROGMEM = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_pl.h b/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_pl.h new file mode 100644 index 0000000..37be016 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/Rs485_prot_pl.h @@ -0,0 +1,7 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT PL + +prog_char statusRollerDescStr[] = " %d sterownik rolet: pozycja rolety 1 %d, pozycja rolety 2 %d"; +prog_char statusRollerDescStr2[] = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/cli.cbp b/Projects/DidacticSystem/Labs/MainModuleCli/cli.cbp new file mode 100644 index 0000000..836c78c --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/cli.cbp @@ -0,0 +1,146 @@ + + + + + + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.c b/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.c new file mode 100644 index 0000000..e006e08 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.c @@ -0,0 +1,32 @@ +#include "cli_task.h" + +void vTaskVTYusb(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + +void vTaskVTYsocket(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + + char znak; + for( ;; ) + { + znak = 0; + znak = fgetc(state->myStdInOut); + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } +} diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.h b/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.h new file mode 100644 index 0000000..944283c --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/cli_task.h @@ -0,0 +1,30 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYusb(void *cliStatePtr); + + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod uniwersalny dla dowolnego strumienai FILE + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYsocket(void *cliStatePtr); + + +#endif /* CLI_TASK_H */ \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/configuration.c b/Projects/DidacticSystem/Labs/MainModuleCli/configuration.c new file mode 100644 index 0000000..f2a5468 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/configuration.c @@ -0,0 +1,29 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" +#include "nic.h" + + +static struct lockerSensor lockerSensorsEEP[4] __attribute__((section (".eeprom"))) = {{LOCK_SENS_1_ENA, LOCK_SENS_1_THR, 0, 0}, + {LOCK_SENS_2_ENA, LOCK_SENS_2_THR, 0, 0}, + {LOCK_SENS_3_ENA, LOCK_SENS_3_THR, 0, 0}, + {LOCK_SENS_4_ENA, LOCK_SENS_4_THR, 0, 0}}; + +uint32_t udpIpDst_eep __attribute__((section (".eeprom"))); +uint16_t udpPortDstEep __attribute__((section (".eeprom"))); +uint16_t udpPortSrcEep __attribute__((section (".eeprom"))); + + +void loadConfiguration(void) +{ + eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); +} + +void saveConfiguration(void) +{ + //saveNic(); + ipSaveConfig(); + udpSaveConfig(); +} diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/configuration.h b/Projects/DidacticSystem/Labs/MainModuleCli/configuration.h new file mode 100644 index 0000000..c3f862f --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/configuration.h @@ -0,0 +1,18 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "enc28j60.h" +#include "hardware.h" +#include "ip.h" +#include "nic.h" +#include "sensors_task.h" +#include "udp.h" + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/ffconf.h b/Projects/DidacticSystem/Labs/MainModuleCli/ffconf.h new file mode 100644 index 0000000..36ca220 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/ffconf.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1250 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. */ + + +#define _FS_RPATH 0 /* 0:Disable or 1:Enable */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0:Single parition or 1:Multiple partition */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* Include a header file here to define O/S system calls */ +/* #include , , or ohters. */ + +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONFIG */ diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/hardware.c b/Projects/DidacticSystem/Labs/MainModuleCli/hardware.c new file mode 100644 index 0000000..ef33082 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/hardware.c @@ -0,0 +1,383 @@ +#include "hardware.h" + +#if LANG_EN +#include "hardware_en.h" +#endif + +#if LANG_PL +#include "hardware_pl.h" +#endif + +xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję do czasu zakończenia wysyłania poprzedniego bajtu + +void hardwareInit(void) +{ + //DDRA = 0x00; //External Memory + portENTER_CRITICAL(); + xSpiRx = xQueueCreate(1, 1); + portEXIT_CRITICAL(); + + DDRB = 0xF7; + PORTB = 0xD1; + /* + 0 - Sl_RST + 1 - SCK + 2 - MOSI + 3 - MISO + 4 - External SPI ASR 4 + 5 - External SPI ASR 5 (DS1305) 0 - off; 1 - on + 6 - External SPI ASR 6 (MCP3008) 0 - on; 1 - off + 7 - External SPI ASR 7 (MPC23S17) 0 - on; 1 - off + */ + + //DDRC = 0x00; //External Memory + + DDRD = 0x00; + /* + 0 - SCL + 1 - SDA + 2 - RxD USB + 3 - TxD USB + 4 - External SPI ASR 0 + 5 - External SPI ASR 1 + 6 - External SPI ASR 2 + 7 - External SPI ASR 3 + */ + + DDRE = 0x0E; + PORTE = 0x0C; + /* + 0 - RxD Rs485 + 1 - TxD Rs485 + 2 - ENC RST + 3 - ENC CS + 4 - INT 4 + 5 - INT 5 + 6 - INT 6 + 7 - INT Enc28j60 + */ + DDRF = 0x00; //JTAG and A/C + DDRG = 0x1F; + /* + 0 - WR + 1 - RD + 2 - ALE + 3 - SD CS + 4 - RS485 TxEn + 5 - + 6 - + 7 - + */ +} + +void LockersMemInit(void) +{ + lockSensors = xmalloc(4 * sizeof(struct lockerSensor)); +} + +uint8_t printLockers(FILE *stream) +{ + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + { + if (tmpLock->enabled) + { + fprintf_P(stream, statusLockerSensDescStr, i); + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + else + fprintf_P(stream, statusLockerCloseStr); + fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + result++; + } + tmpLock++; + } + return result; +} + +void checkLockerSensors(void) +{ + if (lockSensors[0].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + vTaskDelay(30); + lockSensors[0].acVal = MCP3008_getSampleSingle(LOCK_SENS_1_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + lockSensors[0].locked = (lockSensors[0].acVal > lockSensors[0].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[1].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + vTaskDelay(30); + lockSensors[1].acVal = MCP3008_getSampleSingle(LOCK_SENS_2_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + lockSensors[1].locked = (lockSensors[1].acVal > lockSensors[1].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[2].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + vTaskDelay(30); + lockSensors[2].acVal = MCP3008_getSampleSingle(LOCK_SENS_3_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + lockSensors[2].locked = (lockSensors[2].acVal > lockSensors[2].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[3].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + vTaskDelay(30); + lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + vTaskDelay(10); + } +} + + +uint8_t spiSend(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendENC(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendSpinBlock(uint8_t data) +{ + SPDR = data; + SPCR &= ~(1< +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "mpc23s17.h" +#include "mcp3008.h" +#include "spi.h" + +#define Rs485TxStart() (PORTG |= 0x10) +#define Rs485TxStop() (PORTG &= 0xEF) + +#define ENC_RST_ON PORTE &= ~0x04; +#define ENC_RST_OFF PORTE |= 0x04; + +struct lockerSensor +{ + uint8_t enabled; + uint16_t threshold; + uint16_t acVal; + uint8_t locked; +}; + + +struct lockerSensor *lockSensors; + + +/** + * Hardware initialize + */ +void hardwareInit(void); + +/** + * Initialization of memory for lockers state structs + */ +void LockersMemInit(void); + +// ************************ Printing hardware info ********************* +/** + * Prints lockers + * @param stream - output stream + * @return number of printed lockers + */ +uint8_t printLockers(FILE *stream); + +// ************************ I/O module ********************************* +/** + * Checks locker sensors + */ +void checkLockerSensors(void); + + +// ************************ Obsługa Rs485 ****************************** +void takeRs485(void); +void releaseRs485(void); +void rs485Send(uint8_t c); +uint8_t rs485Receive(uint8_t *c, uint8_t timeout); + +// ************************ Obsługa SPI ******************************** +uint8_t spiSend(uint8_t data); +uint8_t spiSendENC(uint8_t data); +uint8_t spiSendSpinBlock(uint8_t data); +uint8_t spiSendENCSpinBlock(uint8_t data); + +void disableAllSpiDevices(void); + +void spiEnableEnc28j60(void); +void spiDisableEnc28j60(void); + +void enableSpiSd(void); +void disableSpiSd(void); + +void enableSpiMPC23S17(void); +void disableSpiMPC23S17(void); + +void enableSpiMCP3008(void); +void disableSpiMCP3008(void); + +void spiEnableDS1305(void); +void spiDisableDS1305(void); + +void enableSpiMCP4150(void); +void disableSpiMCP4150(void); + +#endif + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/hardwareConfig.h b/Projects/DidacticSystem/Labs/MainModuleCli/hardwareConfig.h new file mode 100644 index 0000000..83e255a --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/hardwareConfig.h @@ -0,0 +1,169 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +// --------------------- Configuration I/O module -------------------------------- + +//Locker 1 (723 / 687) broken +#define LOCK_SENS_1_LIGHT 0x40 +#define LOCK_SENS_1_AC_IN 4 +#define LOCK_SENS_1_THR 700 +#define LOCK_SENS_1_ENA 0 + +//Locker 2 (603 / 993) OK +#define LOCK_SENS_2_LIGHT 0x20 +#define LOCK_SENS_2_AC_IN 5 +#define LOCK_SENS_2_THR 750 +#define LOCK_SENS_2_ENA 1 + +//Locker 3 (934/937) broken +#define LOCK_SENS_3_LIGHT 0x10 +#define LOCK_SENS_3_AC_IN 6 +#define LOCK_SENS_3_THR 700 +#define LOCK_SENS_3_ENA 0 + +//Locker 4 (831 / 980) OK +#define LOCK_SENS_4_LIGHT 0x08 +#define LOCK_SENS_4_AC_IN 7 +#define LOCK_SENS_4_THR 900 +#define LOCK_SENS_4_ENA 1 + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + +#define HEAP_BEGIN 0x1100 +#define HEAP_END CLI_1_BUF_ADDR - 1 +#define HEAP_SIZE HEAP_END - HEAP_BEGIN + 1 + +#define CLI_BUF_TOT_LEN 0x0100 +#define CLI_1_BUF_ADDR 0x2800 +#define CLI_2_BUF_ADDR 0x2900 +#define CLI_3_BUF_ADDR 0x2A00 +#define CLI_4_BUF_ADDR 0x2B00 + +#define RTOS_TCP_BUF_BASE_ADDR 0x2C00 + +#define FAT32_BUF_ADDR 0x7000 +#define FAT32_BUF_LENGTH 0x0800 + + +#define RTOS_UDP_TX_BUF_ADDR 0x7800 +#define RTOS_UDP_RX_BUF_ADDR 0x7900 + +#define NETWORK_STACK_BUF_SIZE 0x0600 // 1532 bytes +#define NETWORK_STACK_BUF_ADDR 0x7A00 // 30 1/4 - 32 kB +#define ENC28J60BUF_ADDR_END ENC28J60BUF_ADDR + ENC28J60BUF_SIZE - 1 + +/* Memory Map + 0x0000 +-----------------------------+ + 256 | Controll registers | + 0x0100 +-----------------------------+ + 4k | Internal memory | + 0x1FFF +-----------------------------+ 4k + + + + + 0x1100 +-----------------------------+ + 5k768 | Heap | + 0x2800 +-----------------------------+ 11 k 768 + 256 * CLI 1 buffer + + 0x2900 +-----------------------------+ + 256 * CLI 2 buffer + + 0x2A00 +-----------------------------+ + TCP buffers + + + 0x7000 +-----------------------------+ 28 k + | Fat32 Buffer | + 0x7800 +-----------------------------+ 30 k + 256 | RTOS UDP Tx buffer | + 0x7900 +-----------------------------+ + 256 | RTOS UDP Rx buffer | + 0x7A00 +-----------------------------+ + 1k512 | Enc28j60Buffer | + 0x8000 +-----------------------------+ 32 K + 32k | Filesystem Fat8 | + 0xFFFF +-----------------------------+ +*/ + + +//Konfiguracja biblioteki ds1305.h +#define USE_DECODED_TIME_STRUCT 1 + +//Konfiguracja Sterownika ethenretowego Enc28j60 +//CS jest na PORT E.3 +#define ENC_SPI_CS_PORT PORTE +#define ENC_SPI_CS_EN_MASK_OR 0x00 +#define ENC_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja Karty SD +//CS jest na PORT G.3 +#define SD_SPI_CS_PORT PORTG +#define SD_SPI_CS_EN_MASK_OR 0x00 +#define SD_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja portu równoległego MPC23S17 +//CS jest na PORT B.7 +#define MPC23S17_SPI_CS_PORT PORTB +#define MPC23S17_SPI_CS_EN_MASK_OR 0x00 +#define MPC23S17_SPI_CS_EN_MASK_AND 0x7F + +//Konfiguracja Układu analogowo cyfrowego MPC3008 +//CS jest na PORT B.6 +#define MCP3008_SPI_CS_PORT PORTB +#define MCP3008_SPI_CS_EN_MASK_OR 0x00 +#define MCP3008_SPI_CS_EN_MASK_AND 0xBF + +//Konfiguracja rezystora cyfrowego MCP4150 +//CS jest na PORT B.6 +#define MCP4150_SPI_CS_PORT PORTB +#define MCP4150_SPI_CS_EN_MASK_OR 0x00 +#define MCP4150_SPI_CS_EN_MASK_AND 0xBF + + +//Konfiguracja Zegara czasu rzeczywistego DS1305 +//CE jest na PORT B.5 +#define DS1305_SPI_CS_PORT PORTB +#define DS1305_SPI_CS_EN_MASK_OR 0x20 +#define DS1305_SPI_CS_EN_MASK_AND 0xFF + + + +//konfiguracja wyłączania wszystkich urządzeń SPI + +//PORT A: Zewnętrzna pamięć +#define disableSpiPORTA_OR 0x00 +#define disableSpiPORTA_AND 0xFF + +//PORT B: SPICS na PB4-PB7 +// PB4 - brak +// PB5 - DS1305 0 - off, 1 - on +// PB6 - MCP3008 0 - on. 1 - off +// PB7 - MCP23S17 0 - on, 1 - off +#define disableSpiPORTB_OR 0xC0 +#define disableSpiPORTB_AND 0xDF + +//PORT C: Zewnętrzna pamięć +#define disableSpiPORTC_OR 0x00 +#define disableSpiPORTC_AND 0xFF + +//PORD D: brak SPI SS +#define disableSpiPORTD_OR 0x00 +#define disableSpiPORTD_AND 0xFF + +//PORT E +// PE3 - ENC28j60 0 - on, 1 - off +#define disableSpiPORTE_OR 0x08 +#define disableSpiPORTE_AND 0xFF + +//PORT F - brak SPI SS +#define disableSpiPORTF_OR 0x00 +#define disableSpiPORTF_AND 0xFF + +//PORT G +// PG3 - SD +#define disableSpiPORTG_OR 0x08 +#define disableSpiPORTG_AND 0xFF + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/hardware_en.h b/Projects/DidacticSystem/Labs/MainModuleCli/hardware_en.h new file mode 100644 index 0000000..e92e921 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/hardware_en.h @@ -0,0 +1,10 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE EN + +#include +const char statusLockerSensDescStr[] PROGMEM = " locker %d"; +const char statusLockerOpenStr[] PROGMEM = " open "; +const char statusLockerCloseStr[] PROGMEM = " locked "; +const char statusLockerSensAdditionalDescStr[] PROGMEM = " (threshold %d, AC value %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/hardware_pl.h b/Projects/DidacticSystem/Labs/MainModuleCli/hardware_pl.h new file mode 100644 index 0000000..9bf0733 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/hardware_pl.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE PL + +prog_char statusLockerSensDescStr[] = " rygiel %d"; +prog_char statusLockerOpenStr[] = " otwarty "; +prog_char statusLockerCloseStr[] = " zamkniety"; +prog_char statusLockerSensAdditionalDescStr[] = " (granica %d, wartosc AC %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/main.c b/Projects/DidacticSystem/Labs/MainModuleCli/main.c new file mode 100644 index 0000000..09fdcd3 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/main.c @@ -0,0 +1,177 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + +uint8_t timer100Hz = 0; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; + +xQueueHandle xRs485Tx; +xQueueHandle xRs485Rec; + + +volatile uint8_t temperature; +volatile uint8_t voltage; + + +void vApplicationIdleHook( void ); + +/** + * RTC clock support + */ +void vApplicationTickHook( void ); + +xTaskHandle xHandleVTY_USB; +xTaskHandle xHandleVTY_UDP; +xTaskHandle xHandleEnc; +xTaskHandle xHandleSensors; + +void initExternalMem(void) +{ + MCUCR |= _BV(SRE); //Włączenie pamięci zewnętrznej + MCUCR |= 0x0E; + +#define testZewPamiec 1 +#if testZewPamiec == 1 +#define SND(DTA) UDR1=DTA; \ + while( ! (UCSR1A & (1<>4 & 0x0F); + uint8_t znLo = (hiAddr & 0x0F); + + znHi = (znHi < 10) ? znHi + '0' : znHi + 'A' - 10; + znLo = (znLo < 10) ? znLo + '0' : znLo + 'A' - 10; + + SND('\r') SND('0') SND('x') SND(znHi) SND(znLo) SND('*') SND('*') SND(' ') + + uint16_t addr; + uint16_t startAddr = hiAddr<<8; + uint16_t stopAddr = startAddr + 0xFF; + + for (addr = startAddr; addr <= stopAddr; addr++) + *((uint8_t *) addr) = (uint8_t)((addr>>1) & 0xFF); + + uint8_t isOK=1; + for (addr = startAddr; addr <= stopAddr; addr++) + if (*((uint8_t *) addr) != (uint8_t)((addr>>1) & 0xFF)) + isOK = 0; + + if (isOK == 1) { SND ('O') SND ('K') SND('\n') } + else { SND ('F') SND ('A') SND ('I') SND('L') SND('\n') } + } + SND ('\r') SND ('\n') +#undef SND +#endif +} + +cmdState_t *CLIStateSerialUsb; +cmdState_t *CLIStateSerialUdp; +FILE usbStream; +FILE udpStream; + +streamBuffers_t udpBuffers; + +portSHORT main( void ) +{ + ramDyskInit(); //Inicjalizacja Ram dysku + hardwareInit(); + spiInit(disableAllSpiDevices); + +// VTY on serial + xSerialPortInitMinimal(); + CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + + +// cmdStateClear(newCmdState); + + sensorsTaskInit(); + loadConfiguration(); + + initQueueStreamUSB(&usbStream); + VtyInit(CLIStateSerialUsb, &usbStream); + + udpInit_0(); + socketInit(); + initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + VtyInit(CLIStateSerialUdp, &udpStream); + +//xTaskCreate(encTask, NULL /*"ENC" */, STACK_SIZE_ENC, (void *)CLIStateSerialUsb->myStdInOut, 0, &xHandleEnc); + xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb), 1, &xHandleVTY_USB); +//xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp), 1, &xHandleVTY_UDP); + xTaskCreate(sensorsTask, NULL /*"Sensors"*/, STACK_SIZE_SENSORS, NULL, 1, &xHandleSensors); + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + arpTimer(); + } +} diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/main.h b/Projects/DidacticSystem/Labs/MainModuleCli/main.h new file mode 100644 index 0000000..f10d133 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/main.h @@ -0,0 +1,66 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + +#include "memory_x.h" +#include "Rs485_prot.h" + +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "queueStream.h" +#include "cli_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" +#include "spi.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "enc28j60.h" + +#include "ramdysk.h" +#include "ff.h" +#include "sd_diskio.h" +#include "rtc.h" + +#include "sensors_task.h" +#include "netstack_task.h" + + +#include "cmdline.h" +#include "vty.h" + +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" + + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.31" + + + + +volatile timeDecoded_t czasRtc; + +void initExternalMem(void) __attribute__ ((naked)) __attribute__ ((section (".init4"))); + +extern UdpSocket_t *udpSocket; + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.c b/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.c new file mode 100644 index 0000000..d648e7a --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.c @@ -0,0 +1,157 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include "netstack_task.h" + + +/*uint16_t printHTMLstatus(char *buf, uint16_t pos, uint16_t maxPos) +{*/ +/* char *tmpPtr; + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "

Status

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

"SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), temperature); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp, L_KLASTROW); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Temperatura%d C
Napięcie na magistrali%d V
Liczba wolnych klastrów%d / %d

")); + + tmpPtr = getBufPosToWrite(buf, pos); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Czujniki rygli

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + for (tmp = 0; tmp < 4; tmp++) + { + if (lockSensors[tmp].enabled) + { + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp+1); + if (lockSensors[tmp].locked) + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + else + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), lockSensors[tmp].acVal, lockSensors[tmp].threshold); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + } + } + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Czujnik nrPołożenie ryglaOdczyt z przetwornika ACWart graniczna
%dzamkniętyotwarty%d%d

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Moduły wykonawcze

")); + return pos;*/ +// return 0; +// } + + +void encTask ( void *pvParameters ) +{ + FILE *netstackDebug = (FILE *) pvParameters; + uint16_t plen; + + nicInit(); + ipInit(); + arpInit(); + icmpInit(); + + + //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + + + for ( ; ; ) + { + vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebrzeniu przerwania od ENC + + // get the next new packet: + plen = nicPoll(); + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + { + flushUdpQueues(); + flushTcpQueues(); + //flush HTTP long file queue + continue; + } + + if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + { + arpIpIn(); + netstackIPv4Process(); + } + else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + { + arpArpIn(); + } + else + { + if (netstackDebug != NULL) + { + fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + } + } + + continue; + } +} + +#if 0 +// uint16_t dat_p; +// uint8_t cmd_pos=0; +// int8_t cmd; +// uint8_t payloadlen=0; +// char str[30]; +// char cmdval; + + + // arp is broadcast if unknown but a host may also + // verify the mac address by sending it to + // a unicast address. + if ( eth_type_is_arp_and_my_ip(Enc28j60_global.buf, plen)) + { + make_arp_answer_from_request(Enc28j60_global.buf); + continue; + } + + // IP - check if ip packets are for us: + if ( eth_type_is_ip_and_my_ip ( Enc28j60_global.buf,plen ) ==0 ) + continue; + + // PING + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_ICMP && Enc28j60_global.buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V ) + { + // a ping packet, let's send pong + make_echo_reply_from_request (Enc28j60_global.buf, plen); + continue; + } + + } + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_H_P]==MYTELNETPOERT_H + && (Enc28j60_global.buf[TCP_DST_PORT_L_P]>=MYTELNETPOERT_L || Enc28j60_global.buf[TCP_DST_PORT_L_P]<=MYTELNETPOERT_L + 20)) + { + processIpPacket(Enc28j60_global.buf); + continue; + } +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.h b/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.h new file mode 100644 index 0000000..a79a3a6 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/netstack_task.h @@ -0,0 +1,51 @@ +#ifndef ENC_TASK_H +#define ENC_TASK_H 1 + +#include +#include +#include +#include +#include + +#include "enc28j60.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" +#include "icmp.h" +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +//TODO add new task: http server +typedef enum +{ + URLramDysk, + URLsdDysk, + URLstatus, + URLerror +} urlSource_t; + + +extern struct lockerSensor *lockSensors; + +uint8_t verify_password(char *str); + +/** + * takes a string of url address and process it + * @param str - part of URL string + * @param [out] - filename or command + * @return http source (SD, RamDysk, status) + */ +urlSource_t analyse_get_url (const char *str, char *fname); + +/** + * Enc28j60 task + */ +void encTask(void *pvParameters); + +extern nicState_t nicState; +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/rtc.c b/Projects/DidacticSystem/Labs/MainModuleCli/rtc.c new file mode 100644 index 0000000..bf54760 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/rtc.c @@ -0,0 +1,259 @@ +/*--------------------------------------------------------------------------*/ +/* RTC controls */ + +#include +#include +#include "rtc.h" + + + +#define SCL_LOW() DDRE |= 0x04 /* SCL = LOW */ +#define SCL_HIGH() DDRE &= 0xFB /* SCL = High-Z */ +#define SCL_VAL ((PINE & 0x04) ? 1 : 0) /* SCL input level */ +#define SDA_LOW() DDRE |= 0x08 /* SDA = LOW */ +#define SDA_HIGH() DDRE &= 0xF7 /* SDA = High-Z */ +#define SDA_VAL ((PINE & 0x08) ? 1 : 0) /* SDA input level */ + + + +/*-------------------------------------------------*/ +/* I2C bus protocol */ + + +static +void iic_delay (void) +{ + int n; + + for (n = 4; n; n--) PINB; +} + + +/* Generate start condition on the IIC bus */ +static +void iic_start (void) +{ + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_LOW(); + iic_delay(); + SCL_LOW(); + iic_delay(); +} + + +/* Generate stop condition on the IIC bus */ +static +void iic_stop (void) +{ + SDA_LOW(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_HIGH(); + iic_delay(); +} + + +/* Send a byte to the IIC bus */ +static +int iic_send (BYTE dat) +{ + BYTE b = 0x80; + int ack; + + + do { + if (dat & b) { /* SDA = Z/L */ + SDA_HIGH(); + } else { + SDA_LOW(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (b >>= 1); + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + ack = SDA_VAL ? 0 : 1; /* Sample ACK */ + iic_delay(); + SCL_LOW(); + iic_delay(); + return ack; +} + + +/* Receive a byte from the IIC bus */ +static +BYTE iic_rcvr (int ack) +{ + UINT d = 1; + + + do { + d <<= 1; + SCL_HIGH(); + if (SDA_VAL) d++; + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (d < 0x100); + if (ack) { /* SDA = ACK */ + SDA_LOW(); + } else { + SDA_HIGH(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + SDA_HIGH(); + iic_delay(); + + return (BYTE)d; +} + + + +/*-------------------------------------------------*/ +/* I2C block read/write controls */ + + +int iic_read ( + BYTE dev, /* Device address */ + UINT adr, /* Read start address */ + UINT cnt, /* Read byte count */ + void* buff /* Read data buffer */ +) +{ + BYTE *rbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + iic_start(); /* Reselect device in read mode */ + if (iic_send(dev | 1)) { + do { /* Receive data */ + cnt--; + *rbuff++ = iic_rcvr(cnt ? 1 : 0); + } while (cnt); + } + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +int iic_write ( + BYTE dev, /* Device address */ + UINT adr, /* Write start address */ + UINT cnt, /* Write byte count */ + const void* buff /* Data to be written */ +) +{ + const BYTE *wbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + do { /* Send data */ + if (!iic_send(*wbuff++)) break; + } while (--cnt); + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +/*-------------------------------------------------*/ +/* RTC functions */ + + +int rtc_gettime (RTC *rtc) +{ + BYTE buf[8]; + + + if (!iic_read(0xD0, 0, 7, buf)) return 0; + + rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10; + rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10; + rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10; + rtc->wday = (buf[2] & 0x07); + rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10; + rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10; + rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10; + + return 1; +} + + + + +int rtc_settime (const RTC *rtc) +{ + + BYTE buf[8]; + + + buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10; + buf[1] = rtc->min / 10 * 16 + rtc->min % 10; + buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10; + buf[3] = rtc->wday & 7; + buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10; + buf[5] = rtc->month / 10 * 16 + rtc->month % 10; + buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10; + return iic_write(0xD0, 0, 7, buf); +} + + + + +int rtc_init (void) +{ + BYTE buf[8]; /* RTC R/W buffer */ + UINT adr; + + + /* Read RTC registers */ + if (!iic_read(0xD0, 0, 8, buf)) return 0; /* IIC error */ + + if (buf[7] & 0x20) { /* When data has been volatiled, set default time */ + /* Clear nv-ram. Reg[8..63] */ + memset(buf, 0, 8); + for (adr = 8; adr < 64; adr += 8) + iic_write(0x0D, adr, 8, buf); + /* Reset time to Jan 1, '08. Reg[0..7] */ + buf[4] = 1; buf[5] = 1; buf[6] = 8; + iic_write(0x0D, 0, 8, buf); + } + return 1; +} + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/rtc.h b/Projects/DidacticSystem/Labs/MainModuleCli/rtc.h new file mode 100644 index 0000000..4642685 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/rtc.h @@ -0,0 +1,19 @@ +#include "integer.h" + +typedef struct { + WORD year; /* 2000..2099 */ + BYTE month; /* 1..12 */ + BYTE mday; /* 1.. 31 */ + BYTE wday; /* 1..7 */ + BYTE hour; /* 0..23 */ + BYTE min; /* 0..59 */ + BYTE sec; /* 0..59 */ +} RTC; + +int iic_write (BYTE, UINT, UINT, const void*); /* Write to IIC device */ +int iic_read (BYTE, UINT, UINT, void*); /* Read from IIC device */ + +int rtc_init (void); /* Initialize RTC */ +int rtc_gettime (RTC*); /* Get time */ +int rtc_settime (const RTC*); /* Set time */ + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.c b/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.c new file mode 100644 index 0000000..602b879 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.c @@ -0,0 +1,81 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include +#include +#include "sensors_task.h" +#include "memory_x.h" +#include "main.h" +#include "Rs485_prot.h" +#include "protocol1.h" +#include "mpc23s17.h" + + + +void sensorsTaskInit(void) +{ + LockersMemInit(); + rollersMemInit(); +} + +void sensorsTask(void* pvParameters) +{ + (void) pvParameters; + uint8_t addr = 255; +// uint8_t i; + + MPC23s17SetDirA(0x00, 0); + + MPC23s17SetDirB(0x00, 0); + + for( ; ; ) + { + uint16_t tmp; + //Read power suply voltage + tmp = MCP3008_getSampleSingle(0); + voltage = (uint8_t)(tmp>>5); + vTaskDelay(10); + + //Read temperature inside chasis + tmp = MCP3008_getSampleSingle(1); + tmp *=10; + temperature = (uint8_t)(tmp / 24); + vTaskDelay(10); + + //read lock + checkLockerSensors(); + + for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + { + rs485rollerHello(addr); + vTaskDelay(10); + } + + for (addr = FIRST_LIGHT_DRIVER_ADDR; addr <= LAST_LIGHT_DRIVER_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + + for (addr = FIRST_SENSOR_ADDR; addr <= LAST_SENSOR_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + } +} diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.h b/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.h new file mode 100644 index 0000000..05b0780 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/sensors_task.h @@ -0,0 +1,51 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include + +#include "main.h" +#include "memory_x.h" +#include "Rs485_prot.h" + +#ifndef SENSORS_TASK_H +#define SENSORS_TASK_H + + + + +#define NOT_DETECTED 0x01 +#define BOOTLOADER_MODE 0x02 +#define NEW_STATE 0x04 +#define RESERVED 0x08 +#define ROLLER1_UP 0x10 +#define ROLLER1_DOWN 0x20 +#define ROLLER2_UP 0x40 +#define ROLLER2_DOWN 0x80 + + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + + + + +void sensorsTaskInit(void); + +void sensorsTask(void *pvParameters); + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/serial.c b/Projects/DidacticSystem/Labs/MainModuleCli/serial.c new file mode 100644 index 0000000..700dac7 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/serial.c @@ -0,0 +1,186 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + (void) stream; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + (void) stream; + uartVtySendByte(c); + return 0; +} + +void xSerialPortInitMinimal(void) +{ + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xRs485Rec = xQueueCreate( 16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xRs485Tx = xQueueCreate( 4, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + vSemaphoreCreateBinary(xSemaphoreRs485); + } + portEXIT_CRITICAL(); + + UBRR0L = 7; + UBRR0H = 0; + + UBRR1L = 7; + UBRR1H = 0; + + UCSR0B = ((1< + +/* ************ Debug options ***************************************** */ +#define UDP_DEBUG 1 +#define IP_DEBUG 1 +#define ARP_DEBUG 1 +#define ICMP_DEBUG 1 +#define TCP_DEBUG 1 + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +#define MAX_NUMBER_OF_ROLLERS 10 + + +/* maximum number of TCP connections */ +#define NUMBER_OF_SOCKETS 20 + +/* CLI */ +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + +/* Telnet */ +#define MYTELNETPOERT 25000 + + +uint8_t wwwport; // 80 is just a default value. Gets overwritten during init +//int16_t info_hdr_len=0; +//int16_t info_data_len=0; + + +#define SEQNUM 0xFA000000; // my initial tcp sequence number + +#define ARP_TABLE_SIZE 10 +#define ARP_CACHE_TIME_TO_LIVE 128 + + +#define MYWWWPORT 80 +#define MYTELNETPORT 23 +#define MYUDPPORT 1200 + +#define MY_IP1 192 +#define MY_IP2 168 +#define MY_IP3 0 +#define MY_IP4 2 + +#define MY_GW1 192 +#define MY_GW2 168 +#define MY_GW3 0 +#define MY_GW4 1 + +#define MY_MASK1 255 +#define MY_MASK2 255 +#define MY_MASK3 255 +#define MY_MASK4 0 + +#define UDP_SRC_PORT 3000 +#define UDP_DST_PORT 0 + +#define UDP_DST_IP1 192 +#define UDP_DST_IP2 168 +#define UDP_DST_IP3 0 +#define UDP_DST_IP4 1 + +#define MAC_ADR1 0x12 +#define MAC_ADR2 0x34 +#define MAC_ADR3 0x56 +#define MAC_ADR4 0x78 +#define MAC_ADR5 0x9A +#define MAC_ADR6 0xBC + + + +//#define NUMBER_OF_UDP_SOCK + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/vty.c b/Projects/DidacticSystem/Labs/MainModuleCli/vty.c new file mode 100644 index 0000000..2856573 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/vty.c @@ -0,0 +1,985 @@ +#include "main.h" +#include "vty.h" +#include "ramdysk.h" +#include "protocol1.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "softwareConfig.h" +#include "mcp4150.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t statusEncFunction (cmdState_t *state); +static cliExRes_t curtainDownFunction (cmdState_t *state); +static cliExRes_t curtainUpFunction (cmdState_t *state); +static cliExRes_t rpingFunction (cmdState_t *state); +static cliExRes_t pingFunction (cmdState_t *state); +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state); +static cliExRes_t goXmodemWyslijFunction (cmdState_t *state); +static cliExRes_t dodajRamPlikFunction (cmdState_t *state); +static cliExRes_t eraseRamFileFunction (cmdState_t *state); +static cliExRes_t flashExModuleFunction (cmdState_t *state); +static cliExRes_t writeRamFileFunction (cmdState_t *state); +static cliExRes_t editRamFileFunction (cmdState_t *state); +static cliExRes_t readRamFIleFunction (cmdState_t *state); + +static cliExRes_t ustawPortExtAFunction (cmdState_t *state); +static cliExRes_t ustawPortExtBFunction (cmdState_t *state); +static cliExRes_t ustawPortRezystor (cmdState_t *state); + +static cliExRes_t ustawModWykFunction (cmdState_t *state); +static cliExRes_t zapiszModWykFunction (cmdState_t *state); + +static cliExRes_t pokazCzasFunction (cmdState_t *state); +static cliExRes_t debugFunction (cmdState_t *state); +static cliExRes_t czytajAC_Function (cmdState_t *state); + +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +static cliExRes_t setIpFunction(cmdState_t *state); +static cliExRes_t setIpMaskFunction(cmdState_t *state); +static cliExRes_t setIpGwFunction(cmdState_t *state); +static cliExRes_t setUdpFunction(cmdState_t *state); + +static cliExRes_t setMacAddrFunction (cmdState_t *state); +static cliExRes_t setTimeFunction (cmdState_t *state); + +static cliExRes_t saveConfigFunction (cmdState_t *state); + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction (cmdState_t *state); +#endif + +struct ramPlikFd fdVty; //TODO move it to CLI struct + +const char okStr[] PROGMEM = "OK\r\n"; +const char nlStr[] PROGMEM = "\r\n"; +const char BladBuforaPozostaloBajtowStr[] PROGMEM = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + + +const char * const errorStrings[] PROGMEM = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +const command_t cmdListNormal[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListEnable[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enc_stat, cmd_help_enc_stat, statusEncFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_net_dbg, cmd_help_net_dbg, debugFunction}, + + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_xRec, cmd_help_xRec, goXmodemOdbierzFunction}, + {cmd_xSend, cmd_help_xSend, goXmodemWyslijFunction}, + {cmd_xflash, cmd_help_xflash, flashExModuleFunction}, +#ifdef testZewPamiec + {cmd_rtest, cmd_help_rtest, testPamZewFunction}, +#endif + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_create_rf, cmd_help_create_rf, dodajRamPlikFunction}, + {cmd_erase_rf, cmd_help_erase_rf, eraseRamFileFunction}, + {cmd_edit_rf, cmd_help_edit_rf, editRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + + {cmd_up, cmd_help_up, curtainUpFunction}, + {cmd_down, cmd_help_down, curtainDownFunction}, + + {cmd_spa, cmd_help_spa, ustawPortExtAFunction}, + {cmd_spb, cmd_help_spb, ustawPortExtBFunction}, + {cmd_ustawR, cmd_help_ustawR, ustawPortRezystor}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_ac, cmd_help_ac, czytajAC_Function}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {cmd_ustawMW, cmd_help_ustawMW, ustawModWykFunction}, + {cmd_zapiszMW, cmd_help_zapiszMW, zapiszModWykFunction}, + {NULL, NULL, NULL} +}; + +const command_t cmdListConfigure[] PROGMEM = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_conf_ip, cmd_help_conf_ip, setIpFunction}, + {cmd_conf_ip_mask, cmd_conf_ip_mask_help, setIpMaskFunction}, + {cmd_conf_ip_gw, cmd_conf_ip_gw_help, setIpGwFunction}, + {cmd_conf_udp, cmd_help_conf_udp, setUdpFunction}, + {cmd_conf_mac, cmd_help_conf_mac, setMacAddrFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + fprintf_P(stream, statusTemperatureStr, temperature); + fprintf_P(stream, statusVoltageStr, voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); +// printErrorInfo(state); //TODO fix and uncomment + + //Print system configuration + fprintf_P(stream, systemRamConfigStr); + + fprintf_P(stream, statusMacStr); + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpStr); + netPrintIPAddr(stream, ipGetConfig()->ip); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpMaskStr); + netPrintIPAddr(stream, ipGetConfig()->netmask); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpGwStr); + netPrintIPAddr(stream, ipGetConfig()->gateway); + fprintf_P(stream, PSTR("\r\n")); + + //Print Rs485 Execitive modules + fprintf_P(stream, statusRs485listStr); +// tmp = printRs485devices(stream); +// if (tmp == 0) +// fprintf_P(stream, statusNoRs485Dev); + + //Print locker sensors + fprintf_P(stream, statusLockerSensorsStr); + tmp = printLockers(stream); + if (tmp == 0) + fprintf_P(stream, statusLockerSensorsDisStr); + + //Print time FIXME deadlock problem +/* readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + + udpPrintStatus(stream); +// arpPrintTable(stream); +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + if (state->argc < 1) + { + printStatus(state->myStdInOut); + return OK_SILENT; + } + + FILE stream; + if (ramDyskOtworzPlikStdIo(cmdlineGetArgStr(1, state), &fdVty, &stream, __SWR | __SRD) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + printStatus(&stream); + ramDyskZamknijPlikStdIo(&stream); + return OK_SILENT; +} + +static cliExRes_t statusEncFunction(cmdState_t *state) +{ + nicRegDump(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + return OK_SILENT; +} + +static cliExRes_t debugFunction (cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t level = cmdlineGetArgInt(2, state); + const char *str = (const char*)cmdlineGetArgStr(1, state); + if (level == 0) + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + + } + else //level > 0 + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + } + + return SYNTAX_ERROR; +} + + +static cliExRes_t setTimeFunction(cmdState_t *state) +{ + uint8_t godzina = cmdlineGetArgInt(1, state); + uint8_t minuta = cmdlineGetArgInt(2, state); + uint8_t sekunda = cmdlineGetArgInt(3, state); + + ds1305start(); + + uint8_t cDzies = godzina/10; + uint8_t cJedn = godzina - cDzies*10; + czasRtc.hours.syst24.cDzies = cDzies; + czasRtc.hours.syst24.cJedn = cJedn; + + cDzies = minuta/10; + cJedn = minuta - cDzies * 10; + czasRtc.minutes.cDzies = cDzies; + czasRtc.minutes.cJedn = cJedn; + + cDzies = sekunda/10; + cJedn = sekunda - cDzies * 10; + czasRtc.seconds.cDzies = cDzies; + czasRtc.seconds.cJedn = cJedn; + + setTimeDecoded((timeDecoded_t *)(&czasRtc)); + return OK_SILENT; +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + return OK_SILENT; +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + udpSocket->dstIp = ip; + + uint16_t port = cmdlineGetArgInt(5, state); + udpSocket->srcPort = htons(port); + + if (state->argc > 5) + { + port = cmdlineGetArgInt(6, state); + udpSocket->dstPort = htons(port); + } + return OK_SILENT; +} + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + + ipSetConfigMask(mask); + return OK_SILENT; +} + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + return OK_SILENT; +} + +static cliExRes_t ustawModWykFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + uint8_t wartosc = cmdlineGetArgHex(2, state); + + sendSettings(adres, wartosc); + + return OK_SILENT; +} +static cliExRes_t zapiszModWykFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t adres = cmdlineGetArgInt(1, state); + saveSettings(adres); + return OK_SILENT; +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + if (state->argc < 6) + return SYNTAX_ERROR; + + nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + +static cliExRes_t czytajAC_Function(cmdState_t *state) +{ + uint8_t nrWejscia = cmdlineGetArgInt(1, state); + uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t curtainDownFunction(cmdState_t *state) +{ + uint8_t nrRolety; + uint8_t nrSterownika; + uint8_t wartosc; + + nrSterownika = cmdlineGetArgInt(1, state); + nrRolety = cmdlineGetArgInt(2, state); + nrRolety &= 0x01; + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut,movingCurtainDownStr, nrSterownika, nrRolety+1); + + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t curtainUpFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + uint8_t wartosc = 255; + if (state->argc > 2) + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut, movingCurtainUpStr, nrSterownika, nrRolety+1); + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t ustawPortExtAFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirA(0x00, 0); + MPC23s17SetPortA(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortExtBFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirB(0x00, 0); + MPC23s17SetPortB(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortRezystor(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t wartosc = cmdlineGetArgInt(1, state); + + MCP4150_setValue(wartosc); + + return OK_SILENT; +} + +static cliExRes_t rpingFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + if ((state->err2 = rs485ping(nrSterownika)) == 0) + return OK_INFORM; + + state->errno = noRemoteDevice; + state->err1 = nrSterownika; + printErrorInfo(state); + return OK_SILENT; +} + +static cliExRes_t pingFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + //uint8_t ip[4]; + //ip[0] = (uint8_t)(cmdlineGetArgInt(1, state)); + //ip[1] = (uint8_t)(cmdlineGetArgInt(2, state)); + //ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + //ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + //Ipv4Ping(*((uint32_t *)(ip))); + + return OK_SILENT; +} + + +static cliExRes_t flashExModuleFunction(cmdState_t *state) +{ + if (state->argc != 2) + return SYNTAX_ERROR; + + uint8_t nrUrzadzenia = cmdlineGetArgInt(1, state); + char *nazwaPliku = cmdlineGetArgStr(2, state); + uint8_t blad; + + // Sprawdzanie, czy moduł wykonawczy odpowiada + if (rs485ping(nrUrzadzenia) != 0) + { + state->errno = noRemoteDevice; + printErrorInfo(state); + return ERROR_INFORM; + } + + //Sprawdzanie, czy istnieje odpowiedni plik z firmware + if (ramDyskOtworzPlik(nazwaPliku, &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, nazwaPliku); + return ERROR_INFORM; + } + + blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + + ramDyskZamknijPlik(&fdVty); + + if (blad != 0) + return ERROR_INFORM; + + return OK_SILENT; +} + +static cliExRes_t goXmodemWyslijFunction(cmdState_t *state) // TODO add code in xModem +{ + fprintf_P(state->myStdInOut, xwyslijStartStr); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + return OK_SILENT; +} + +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state) //TODO move to xmodem +{ + fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + uint8_t i = 25; + + uint8_t temp1; +// uint8_t temp2; + + uint8_t c; + uint8_t liczbaProb; + uint8_t *zapPtr; + uint8_t *zapPtrKopia; + + uint16_t crcLokalne; + uint8_t nrBloku; + + uint8_t nrBlokuZdalny; + uint8_t nrBlokuZdalnyNeg; + + uint8_t crcHi; + uint8_t crcLo; + + state->err1=0; + state->err2=0; + liczbaProb = 20; + for ( ; ; ) + { + fputc('C' , state->myStdInOut); + while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + + if(xQueueReceive(xVtyRec, &c, 100)) + if (c == SOH) + break; //Rozpoczynamy transmisje + + liczbaProb--; + if (liczbaProb == 0) + { + ramDyskZamknijPlik(&fdVty); + state->errno = (uint8_t)(AllOK); + return ERROR_INFORM; + } + } + + nrBloku = 1; + liczbaProb = 10; + + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + for ( ; ; ) + { + if (!xQueueReceive(xVtyRec, &nrBlokuZdalny, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (!xQueueReceive(xVtyRec, &nrBlokuZdalnyNeg, 1)) + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + + //1 Sprawdzanie, czy pasuje numer bloku z numerem bloku w usupełnieniu bitowym do 1 + c = 255-nrBlokuZdalnyNeg; + if (nrBlokuZdalny != c) + { + state->errno = (uint8_t)(xModemFrameFrameNoCorrectionNotMatch); + state->err1 = nrBlokuZdalny; + state->err2 = nrBlokuZdalnyNeg; + break; + } + + //Sprawdzenie, czy nie jest wznowiona transmisja poprzedniego bloku lub nie zaczęła się od bloku 0 + c = nrBloku-1; + if (nrBlokuZdalny == c) + { + nrBloku = c; //Cofnięcie nr aktualnego bloku o 1 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + } + + //2 Sprawdzanie, czy pasuje numer bloku + if (nrBlokuZdalny != nrBloku) + { + state->errno = (uint8_t)(xModemWrongFrameNo); + state->err1 = nrBlokuZdalnyNeg; + state->err2 = nrBloku; + break; + } + + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + { + if(xQueueReceive(xVtyRec, &c, 10)) + *(zapPtr++) = c; + else + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + } + if (!xQueueReceive(xVtyRec, &crcHi, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 2; + break; + } + if (!xQueueReceive(xVtyRec, &crcLo, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 1; + break; + } + + //3 Zerowanie CRC + crcLokalne=0; + + //4 Obliczanie CRC + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + + //5 Srawdzanie CRC + if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + { + liczbaProb = 10; + uartVtySendByte(ACK); + } + else + { + liczbaProb--; + nrBloku--; + uartVtySendByte(NAK); + } + + if (liczbaProb == 0) + { + state->err1 = nrBlokuZdalny; + state->err2 = nrBloku; + state->errno = (uint8_t)(xModemWrongFrameNo); + break; + } + + if (!xQueueReceive(xVtyRec, &temp1, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (temp1 == SOH) + { + nrBloku++; + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + state->errno = (uint8_t)(AllOK); + continue; + } + + if (temp1 == CAN) + { + state->err1 = nrBloku; + state->errno = (uint8_t)(xModemRemoteSideCan); + break; + } + if (temp1 == EOT) + { + uartVtySendByte(NAK); + if (xQueueReceive(xVtyRec, &temp1, 10)) + { + if (temp1 == EOT) + uartVtySendByte(ACK); + } + state->errno = (uint8_t)(AllOK); + break; + } + state->errno = (uint8_t)(xModemUnknownResponse); + state->err1 = temp1; + break; + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t eraseRamFileFunction(cmdState_t *state) +{ + if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + return OK_INFORM; + + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t dodajRamPlikFunction(cmdState_t *state) +{ + if (state->argc != 1) + return SYNTAX_ERROR; + + if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + { + return OK_INFORM; + } + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t writeRamFileFunction(cmdState_t *state) +{ + ramDyskDir(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t editRamFileFunction(cmdState_t *state) +{ + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + ramDyskUstawWskaznikNaKoniec(&fdVty); + uint8_t znak = 0; + fprintf_P(state->myStdInOut, editRamFileIntroStr); + while(1) + { + if(!xQueueReceive( xVtyRec, &znak, portMAX_DELAY)) + continue; + + if (znak == 0x03) // ^C + break; + + uartVtySendByte(znak); //Echo + ramDyskZapiszBajtDoPliku(&fdVty, znak); + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t readRamFIleFunction(cmdState_t *state) //TODO move this code to fat8 +{ + uint8_t rezultat; + uint8_t znak = ' '; + if ((rezultat = ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty)) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + while (rezultat == 0) + { + rezultat = ramDyskCzytajBajtZPliku(&fdVty, &znak); + + uartVtySendByte(znak); + if (znak == '\r') + uartVtySendByte('\n'); + } + fprintf_P(state->myStdInOut, nlStr); + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + (void) state; + saveConfiguration(); + return OK_SILENT; +} + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction(cmdState_t *state) +{ + state = NULL; + uint8_t *ptr; + ptr= 0x4000; + uint8_t tmp; + for (tmp=0; tmp <255; tmp++) + { + *(ptr) = tmp; + ptr++; + } + ptr= 0x4000; + uint8_t tmp2; + for (tmp=0; tmp <4; tmp++) + { + uartVtySendByte('\r'); + uartVtySendByte('\n'); + for (tmp2=0; tmp2<64; tmp2++) + { + uartVtySendByte(*(ptr)); + ptr++; + } + } + return OK_SILENT; +} +#endif + + diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/vty.h b/Projects/DidacticSystem/Labs/MainModuleCli/vty.h new file mode 100644 index 0000000..e4251f4 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/vty.h @@ -0,0 +1,81 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include +#include + +#include "ds1305.h" +#include "enc28j60.h" +#include "memory_x.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "sensors_task.h" +#include "nic.h" +#include "ip.h" +#include "net.h" +#include "arp.h" +#include "cmdline.h" +#include "udp.h" + + +// Znaki kontrolne w protokole Xmodem +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +// xmodem timeout/retry parameters +#define XMODEM_RETRY_LIMIT 16 + +// error return codes +#define XMODEM_ERROR_REMOTECANCEL 1 +#define XMODEM_ERROR_OUTOFSYNC 2 +#define XMODEM_ERROR_RETRYEXCEED 3 + +#define XMODEM_BUFFER_SIZE 128 + + +extern nicState_t nicState; +extern UdpSocket_t *udpSocket; + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + +extern xQueueHandle xRs485Rec; +extern xQueueHandle xRs485Tx; + +extern volatile timeDecoded_t czasRtc; +extern struct Enc28j60_config Enc28j60_global; + +extern struct sterRolet *rollers; + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/vty_en.h b/Projects/DidacticSystem/Labs/MainModuleCli/vty_en.h new file mode 100644 index 0000000..a535e93 --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/vty_en.h @@ -0,0 +1,96 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +#include +// *************************** Error Strings ******************************************************* + +const char errorOK[] PROGMEM = "All OK\r\n"; +const char errorNoFile[] PROGMEM = "No File\r\n"; +const char errorxModemFrameStartTimeout[] PROGMEM = "\r\n"; +const char errorxModemByteSendTimeout[] PROGMEM = "\r\n"; +const char errorxModemWrongFrameNo[] PROGMEM = "\r\n"; +const char errorxModemFrameFrameNoCorrectionNotMatch[] PROGMEM = "\r\n"; +const char errorxModemFrameCrc[] PROGMEM = "xModem CRC error\r\n"; +const char errorxModemRemoteSideCan[] PROGMEM = "Remote side cancelled at frame no %d\r\n"; +const char errorxModemUnknownResponse[] PROGMEM = "xModem unknown response 0x%x\r\n"; +const char errorNoRemoteDevice[] PROGMEM = "Device %d is not responding (%d)\r\n"; +const char errorBootloaderNotResponding[] PROGMEM = "Bootloader is not responding\r\n"; +const char errorOpenFile[] PROGMEM = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +const char systemStateStr[] PROGMEM = "System state:\r\n"; +const char statusNumberOfTasksStr[] PROGMEM = " Number of tasks : %d\r\n"; +const char statusStaticHeapStateStr[] PROGMEM = " FreeRtos heap : %d free of %d bytes\r\n"; +const char statusDynamicHeapStateStr[] PROGMEM = " Malloc heap : %d free of %d bytes\r\n"; +const char statusRamDiskStateStr[] PROGMEM = " Ram disc space : %d free of %d clusters\r\n"; +const char statusTemperatureStr[] PROGMEM = " Temperature : %d C\r\n"; +const char statusVoltageStr[] PROGMEM = " Voltage : %d V\r\n"; +const char systemRamConfigStr[] PROGMEM = "System settings:\r\n"; +const char statusMacStr[] PROGMEM = " Mac address : "; +const char statusIpStr[] PROGMEM = " IP address : "; +const char statusIpMaskStr[] PROGMEM = " mask : "; +const char statusIpGwStr[] PROGMEM = " gateway : "; + +const char statusRs485listStr[] PROGMEM = "Detected RS 485 devices:\r\n"; +const char statusNoRs485Dev[] PROGMEM = " Can't find any device\r\n"; + +const char statusLockerSensorsStr[] PROGMEM = "Locker sensors states:\r\n"; +const char statusLockerSensorsDisStr[] PROGMEM = " Locker sensors disabled\r\n"; + +const char editRamFileIntroStr[] PROGMEM = "Writing to file. Press CTRL+C to quit\r\n"; +const char readRamFIleLenStr[] PROGMEM = "File length: %d\r\n"; + +const char xwyslijStartStr[] PROGMEM = "Xmodem: Transmission start\r\n"; + +const char movingCurtainUpStr[] PROGMEM = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +const char movingCurtainDownStr[] PROGMEM = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +const char movingCurtainPosStr[] PROGMEM = "\tpozycja %d\r\n"; + +const char debugEnabledInfoStr[] PROGMEM = "Enabled %s debug\r\n"; +const char debugDisabledInfoStr[] PROGMEM = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +const char cmd_help[] PROGMEM = "help"; const char cmd_help_help[] PROGMEM = "Print help string"; +const char cmd_status[] PROGMEM = "status"; const char cmd_help_status[] PROGMEM = "{filename} Print device status on VTY or write to file"; +const char cmd_enc_stat[] PROGMEM = "encstat"; const char cmd_help_enc_stat[] PROGMEM = "Print Enc 28j60 registers"; +const char cmd_time[] PROGMEM = "time"; const char cmd_help_time[] PROGMEM = "Print time"; +const char cmd_net_dbg[] PROGMEM = "debug"; const char cmd_help_net_dbg[] PROGMEM = "[arp|icmp|ip|tcp|udp] [level] write debug info. Level 0 disable debuging"; + +const char cmd_rping[] PROGMEM = "rping"; const char cmd_help_rping[] PROGMEM = "[Device no] Send ping to Rs485 device"; +const char cmd_ping[] PROGMEM = "ping"; const char cmd_help_ping[] PROGMEM = "[A1] [A2] [A3] [A4] Sends ping throught ethernet"; +const char cmd_xRec[] PROGMEM = "xrec"; const char cmd_help_xRec[] PROGMEM = "[file name] receive file using xModem"; +const char cmd_xSend[] PROGMEM = "xsend"; const char cmd_help_xSend[] PROGMEM = "[file name] send file using xModem"; +const char cmd_xflash[] PROGMEM = "xflash"; const char cmd_help_xflash[] PROGMEM = "[device no] [file name] flash device connected to Rs485"; +#ifdef testZewPamiec +const char cmd_rtest[] PROGMEM = "rtest"; const char cmd_help_rtest[] PROGMEM = "External ram test"; +#endif +const char cmd_dir_rf[] PROGMEM = "dirrf"; const char cmd_help_dir_rf[] PROGMEM = "Print ramdisk files"; +const char cmd_create_rf[] PROGMEM = "crf"; const char cmd_help_create_rf[] PROGMEM = "[file name] create ram file"; +const char cmd_erase_rf[] PROGMEM = "eraserf"; const char cmd_help_erase_rf[] PROGMEM = "[file name] erase file from ram disk"; +const char cmd_edit_rf[] PROGMEM = "editrf"; const char cmd_help_edit_rf[] PROGMEM = "[file name] edit file located on ram disk"; +const char cmd_read_rf[] PROGMEM = "readrf"; const char cmd_help_read_rf[] PROGMEM = "[file name] read file located on ram disk"; + +const char cmd_up[] PROGMEM = "up"; const char cmd_help_up[] PROGMEM = "[driver no] [channel] {value} move up"; +const char cmd_down[] PROGMEM = "down"; const char cmd_help_down[] PROGMEM = "[driver no] [channel] {value} move down"; +const char cmd_spa[] PROGMEM = "spa"; const char cmd_help_spa[] PROGMEM = "[value] set port A"; +const char cmd_spb[] PROGMEM = "spb"; const char cmd_help_spb[] PROGMEM = "[value] set port B"; + +const char cmd_settime[] PROGMEM = "settime"; const char cmd_help_settime[] PROGMEM = "[h] [m] [s] set time (24h format)"; +const char cmd_ac[] PROGMEM = "ac"; const char cmd_help_ac[] PROGMEM = "[channel 0-7] read analog value"; +const char cmd_enable[] PROGMEM = "enable"; const char cmd_help_enable[] PROGMEM = "Enable mode"; +const char cmd_disable[] PROGMEM = "disable"; const char cmd_help_disable[] PROGMEM = "View mode"; +const char cmd_configure[] PROGMEM = "config"; const char cmd_help_configure[] PROGMEM = "Configure mode"; +const char cmd_conf_ip[] PROGMEM = "ip"; const char cmd_help_conf_ip[] PROGMEM = "[A1] [A2] [A3] [A4] set IP address"; +const char cmd_conf_udp[] PROGMEM = "udp"; const char cmd_help_conf_udp[] PROGMEM = "[A1] [A2] [A3] [A4] [src port] {dst port} set udp client IP address and ports"; +const char cmd_conf_ip_mask[] PROGMEM = "mask"; const char cmd_conf_ip_mask_help[] PROGMEM = "[mask] set mask"; +const char cmd_conf_ip_gw[] PROGMEM = "gw"; const char cmd_conf_ip_gw_help[] PROGMEM = "[A1] [A2] [A3] [A4] set default gateway"; +const char cmd_conf_mac[] PROGMEM = "mac"; const char cmd_help_conf_mac[] PROGMEM = "[A1] [A2] [A3] [A4] [A5] [A6] set MAC address"; +const char cmd_conf_save[] PROGMEM = "save"; const char cmd_help_conf_save[] PROGMEM = "Save configuration"; +const char cmd_ustawR[] PROGMEM = "setr"; const char cmd_help_ustawR[] PROGMEM = "[value] set resistance value"; + +const char cmd_ustawMW[] PROGMEM = "rset"; const char cmd_help_ustawMW[] PROGMEM = "[A] [C] set execution module"; +const char cmd_zapiszMW[] PROGMEM = "rsave"; const char cmd_help_zapiszMW[] PROGMEM = "[A] save execution module settings"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/Labs/MainModuleCli/vty_pl.h b/Projects/DidacticSystem/Labs/MainModuleCli/vty_pl.h new file mode 100644 index 0000000..7550a2a --- /dev/null +++ b/Projects/DidacticSystem/Labs/MainModuleCli/vty_pl.h @@ -0,0 +1,92 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char statusRamDiskStateStr[] = " Ram dysk : %d wolnych z %d klastrow\r\n"; +prog_char statusTemperatureStr[] = " Temperatura : %d C\r\n"; +prog_char statusVoltageStr[] = " Napiecie : %d V\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; +prog_char statusMacStr[] = " Adres MAC : "; +prog_char statusIpStr[] = " IP adres : "; +prog_char statusIpMaskStr[] = " maska : "; +prog_char statusIpGwStr[] = " brama : "; + +prog_char statusRs485listStr[] = "Wykryte urzadzenia na magistrali RS 485:\r\n"; +prog_char statusNoRs485Dev[] = " Nie moge znale ani jednego urzadzenia\r\n"; + +prog_char statusLockerSensorsStr[] = "Stan czujników rygli:\r\n"; +prog_char statusLockerSensorsDisStr[] = " Czujniki rygli wyłączone\r\n"; + +prog_char editRamFileIntroStr[] = "Zapis do pliku. CTRL+C koniec\r\n"; +prog_char readRamFIleLenStr[] = "Dlugosc pliku: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: rozpoczynanie wysylania\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Wlaczono debugowanie %s\r\n"; +prog_char debugDisabledInfoStr[] = "Wylaczono debugowanie %s\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Wypisz rejestry Enc 28j60"; +prog_char cmd_time[] = "czas"; prog_char cmd_help_time[] = "Wypisuje czas"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[arp|icmp|ip|tcp|udp] [poziom] wypisywanie komunikatow. Poziom 0 wylacza komunikaty"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[numer sterownika] Wysyla ping do sterownika podpietego do magistrali Rs485"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Wysyla ping przez ethernet"; +prog_char cmd_xRec[] = "xodb"; prog_char cmd_help_xRec[] = "[nazwa pliku] odbiera plik za pomoca protokolu xModem"; +prog_char cmd_xSend[] = "xwyslij"; prog_char cmd_help_xSend[] = "[nazwa pliku] wysyla plik za pomoca protokolu xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[numer urzadzenia] [nazwa pliku] wgrywa firmware do urzadzenia podpietego do Rs485"; +#ifdef testZewPamiec +prog_char cmd_rtest[] = "rtest"; prog_char cmd_help_rtest[] = "Test pamieci zewnetrznej"; +#endif +prog_char cmd_dir_rf[] = "dirrp" ; prog_char cmd_help_dir_rf[] = "Wypisuje nazwy plikow zapisanych w pamieci RAM"; +prog_char cmd_create_rf[] = "utwrp"; prog_char cmd_help_create_rf[] = "[nazwa pliku] Tworzy plik w pamieci RAM"; +prog_char cmd_erase_rf[] = "kasrp"; prog_char cmd_help_erase_rf[] = "[nazwa pliku] Usuwa plik z pamieci RAM"; +prog_char cmd_edit_rf[] = "dopiszrp"; prog_char cmd_help_edit_rf[] = "[nazwa pliku] Dopisuje do pliku zapisanego w pamieci ram"; +prog_char cmd_read_rf[] = "czytrp"; prog_char cmd_help_read_rf[] = "[nazwa pliku] Wypisuje zawartosc pliku"; + +prog_char cmd_up[] = "podnies"; prog_char cmd_help_up[] = "[numer sterownika] [nr rolety] {wartosc} podnoszenie rolety"; +prog_char cmd_down[] = "opusc"; prog_char cmd_help_down[] = "[numer sterownika] [nr rolety] {wartosc} opuszczanie rolety"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[wartosc] ustaw zewnetrzny port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[wartosc] ustaw zewnetrzny port B"; + +prog_char cmd_settime[] = "ustawcz"; prog_char cmd_help_settime[] = "[h] [m] [s] ustawia czas w formacie 24h format"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[wejscie 0-7] czyta analogowa wartosc na wejsciu przetwornika"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A2] [A3] ustaw adres IP"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} ustaw adres klienta udp oraz porty"; +prog_char cmd_conf_ip_mask[]= "maska"; prog_char cmd_conf_ip_mask_help[]= "[maska] ustaw maske adresu IP"; +prog_char cmd_conf_ip_gw[] = "brama"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] ustaw domyslna brame"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] set MAC address"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] ustaw adres MAC"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/Projects/DidacticSystem/_templAcModRelayers/Bootloader/Makefile b/Projects/DidacticSystem/_templAcModRelayers/Bootloader/Makefile new file mode 100644 index 0000000..dc2b897 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/Bootloader/Makefile @@ -0,0 +1,89 @@ +############################################################################### +# Makefile for the project Bootldr +############################################################################### + +## General Flags +PROJECT = Bootloader +MCU = atmega168 +TARGET = bootloader +CC = avr-gcc +CPP = avr-g++ + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -DF_CPU=7372800UL -Os -fsigned-char +#CFLAGS += -gdwarf-2 +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-section-start=.text=0x3800 + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + +## Objects that must be built in order to link +OBJECTS = bootldr.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET).elf Bootldr.hex Bootldr.eep size + +## Compile +bootldr.o: bootldr.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET).elf: $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf + +%.hex: $(TARGET).elf + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET).elf + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET).elf + avr-objdump -h -S $< > $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) Bootldr.elf dep/* Bootldr.hex Bootldr.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/_templAcModRelayers/Bootloader/bootldr.c b/Projects/DidacticSystem/_templAcModRelayers/Bootloader/bootldr.c new file mode 100644 index 0000000..39f0ef8 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/Bootloader/bootldr.c @@ -0,0 +1,382 @@ +/* + Project: AVR Rs485 bootloader + Base on + Project: AVR Universal BootLoader + Author: Shaoziyang + Shaoziyang@gmail.com + http://avrubd.googlepages.com + + Author: Adam Kaliszan + adam.kaliszan@gmail.com + + File: bootldr.c + main program code + + Version: 0.9 + + Date: 2010.4 +*/ + +#include "bootldr.h" + +uint8_t helloBuf[] = {SYNC, 0, rHELLO, 7, 0xFF , 0xFF, 'b', '0', '.', '6', '2'}; //rHELLO response +uint8_t pingBuf[HDR_LEN+PROT_BUF_LEN] = {SYNC, 0, rPING, 8}; //rPING response +uint8_t noCommandBuf[] = {SYNC, 0, rUNKNOWN, 0}; //unknown command response + +uint8_t buf[BUFSIZE]; // xModem receive buffer +uint8_t bufptr; +uint8_t pagptr; +uint8_t ch; +uint8_t cl; +uint16_t FlashAddr; +uint8_t cnt; + +uint8_t tmp; +uint8_t adres; // Adres urządzenia zczytany na starcie +stanAutomatu_t stan; // Stan automatu +uint16_t crc; // Crc +uint16_t crcObl; // Crc +uint8_t protAddr; // Odebrany adres w magistrali Rs485 +uint8_t protRozkaz; // Odebrany kod rozkazu +uint8_t protDlDanych; // Odebrana inf. o długości pola danych +uint8_t protBuf[PROT_BUF_LEN]; // Odebrane dane do rozkazu +uint8_t protCrcHi; // Odebrany bardziej znaczący bajt CRC +uint8_t protCrcLo; // Odebrany mniej znaczący bajt CRC +uint8_t protDaneWsk; // Licznik odebranych danych + + +inline void write_one_page(unsigned char *buf) //Uaktualnianie strony z pamięcią flash +{ + boot_page_erase(FlashAddr); //Kasowanie strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji + + uint16_t *tmpPtr = (uint16_t *)(buf); //kompilator musi być little bit endian + for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2) + { + boot_page_fill(pagptr, *tmpPtr); //brzydkie rzutowanie 2X uint8_t na uint16_t + tmpPtr++; //wskaźnik zwiększa się o 2 + } + boot_page_write(FlashAddr); //Zapis strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji +} + +//send data to comport +void WriteCom(unsigned char dat) +{ + RS485Enable(); + UDRREG(COMPORTNo) = dat; + while(!(UCSR0A & (1<>8)); + WriteCom((uint8_t)(crc & 0xFF)); + crc=0; +} + + +void wykonajRozkaz(void) +{ + uint8_t tmpCrcLo = (uint8_t)(crcObl & 0xFF); + uint8_t tmpCrcHi = (uint8_t)(crcObl >>8); + + resetStateMachine(); + if ((tmpCrcHi != protCrcHi) ||(tmpCrcLo != protCrcLo)) + { + return; + } + stan = sync; + cnt = TimeOutCnt; + if (adres != protAddr) + { + if (protRozkaz == rFLASH) + { + waitAndQuit(); + } + return; + } + if (protRozkaz == rFLASH) + { + stan = xModem; + return; + } + if (protRozkaz == rHELLO) + { + sendBuf(helloBuf, HDR_LEN+7); + return; + } + if (protRozkaz == rPING) + { + if (protDlDanych > PROT_BUF_LEN) + protDlDanych = PROT_BUF_LEN; + pingBuf[3] = protDlDanych; + for (tmp=0; tmp>1); //Read address + adres |= (PINC & 0x03); + + //initialize serial port UART0 + UCSR0A = 0; + UCSR0B = (1 << RXENBIT(COMPORTNo))|(1 << TXENBIT(COMPORTNo)); + UCSR0C = (1 << USEURSEL)|(1 << UCSZ01)|(1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 3; + + cnt = TimeOutCnt; // Timeout (wg. częstotliwości zegara 1Hz) + cl = 0; // Liczba poprawnych liter od hasła + + +//Wykonywanie poleceń. Tryb bootloadera. + while(stan != xModem) // Czekanie aż zostanie odebrany rozkaz rozpoczęcia transmisji xModemowej + { + if(TIFRREG & (1< + break; + } + + //begin xModem transmission - receive data + packNO = 1; + bufptr = 0; + cnt = 0; + FlashAddr = 0; + while(1) + { + ch = ReadCom_withLimitedWaiting(); // get package number + cl = ~ReadCom_withLimitedWaiting(); + if ((packNO == ch) && (packNO == cl)) + { + uint16_t crc = 0; // start calculate CRC + for(li = 0; li < BUFFERSIZE; li++) // receive a full data frame + { + tmp = ReadCom_withLimitedWaiting(); // read from uart + buf[bufptr++] = tmp; // write to temporary buffer + crc = _crc_xmodem_update(crc, tmp); // calculate CRC + } + + crch = ReadCom_withLimitedWaiting(); // get checksum Hi + crcl = ReadCom_withLimitedWaiting(); // get checksum Lo + ch = crc / 256; + cl = crc % 256; + if ((crch == ch) && (crcl == cl)) + { + PORTD |= (uint8_t)(0x40); + packNO++; + while(bufptr > 0) // receive one frame, write multi pages + { + write_one_page(&buf[BUFSIZE - bufptr]); + FlashAddr += SPM_PAGESIZE; // modify Flash page address + bufptr -= SPM_PAGESIZE; + if (FlashAddr >= 2*BootStart) // BootStart is word number (not byte number) + quit(); + } + WriteCom(XMODEM_ACK); // All OK send ACK + cnt = 0; + } + else //CRC + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + } + else //PackNo + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + //too much error, update abort + if(cnt > 3) + { + PORTD |= (uint8_t)(0x20); + break; + } + tmp = ReadCom_withLimitedWaiting(); + + if (tmp == XMODEM_EOT) + break; + } + WriteCom(XMODEM_NAK); + + quit(); + return 0; +} + +//! quit boot mode and jump to user's application +void quit(void) +{ + boot_rww_enable(); //enable application section + (*((void(*)(void))PROG_START))(); //jump +} + +//! wait 1 minute and jump to user's application +void waitAndQuit(void) +{ +// PORTD = 0x20; //LED 1 and 2 on + cnt=120; + while(1) + { + if(TIFRREG & (1< +#include +#include +#include +#include + +#include "../../../freeRtos/Lib/include/protocol1.h" +#include "../../../freeRtos/Lib/include/xModemCommands.h" + +#define PROT_BUF_LEN 32 /// Rs485 rec buffer length + + +#ifndef F_CPU ///system clock(Hz) +#define F_CPU 7372800UL +#endif + +#define PROG_START 0x0000 /// User's application start address +#define BootStart 0x1C00 /// Boot section address start + +#define BUFFERSIZE 128 /// Xmodem buffer length +#define BAUDRATE 115200 /// Rs485 baudrate + + +#define timeclk 500 /// basic timer interval(ms) +#define TimeOutCnt 10 /// max wait for password time = TimeOutCnt * timeclk +#define TimeOutCntC 40 /// numbers of sending C char for start xModem + + +#define COMPORTNo 0 /// comport number: 0/1/2.. + +#define RS485RXDis 2 /// Pin that disables Rs485 receiver +#define RS485TXEn 3 /// Pin that enables Rs485 transmitter +#define LEDPORTNo 5 /// Pin that is connected to the diode 1 +#define LED2PORTNo 6 /// Pin that is connected to the diode 2 + + +//receive buffer' size will not smaller than SPM_PAGESIZE +#if BUFFERSIZE < SPM_PAGESIZE +#define BUFSIZE SPM_PAGESIZE +#else +#define BUFSIZE BUFFERSIZE +#endif + + + + +//Don't modify code below, unless your really konw what to do + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE +#if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#else +#if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + +//check baudrate register error +//mocro below maybe not same in different C compiler +#define FreqTemp (16UL * BAUDRATE * (((F_CPU * 10) / (16 * BAUDRATE) + 5)/ 10)) +#if ((FreqTemp * 50) > (51 * F_CPU) || (FreqTemp * 50) < (49 * F_CPU)) +#error "BaudRate error > 2% ! Please check BaudRate and F_CPU value." +#endif + +#define True 1 +#define False 0 +#define TRUE 1 +#define FALSE 0 + +//internal use macro +#define CONCAT(a, b) a ## b +#define CONCAT3(a, b, c) a ## b ## c + +//register of PORT and bit define +#define PORTREG(No) CONCAT(PORT, No) +#define PINREG(No) CONCAT(PIN, No) +#define UDRREG(No) CONCAT(UDR, No) +#define DDRREG(No) CONCAT(DDR, No) +#define TXCBIT(No) CONCAT(TXC, No) +#define RXCBIT(No) CONCAT(RXC, No) +#define RXENBIT(No) CONCAT(RXEN, No) +#define TXENBIT(No) CONCAT(TXEN, No) +#define URSELBIT(No) CONCAT(URSEL, No) + +//some kind of AVR need URSEL define when comport initialize +#define USEURSEL 0 + + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#define RS485Enable() PORTD = 0x0C +#define RS485Disable() PORTD = 0x00 + +//#define DataInCom() (UCSRAREG(COMPORTNo) & (1 << RXCBIT(COMPORTNo))) +#define DataInCom() (UCSR0A & (1 << RXC0)) +#define ReadCom() UDR0 + +//@{ +/** + * Stan automatu: + * sync, addr, rozkaz, dlDanych, dane, crcHi, crcLo, xModem + */ +enum stanAutomatu +{ + sync, + addr, + rozkaz, + dlDanych, + dane, + crcHi, + crcLo, + xModem +}; +typedef enum stanAutomatu stanAutomatu_t; + +/** + * Leave bootloader mode + */ +void quit(void) __attribute__((noreturn)); + +/** + * Wait for a tame of different device flashing and leave next bootloader mode + */ +void waitAndQuit(void) __attribute__((noreturn)); + +//@} +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/_templAcModRelayers/CMakeLists.txt b/Projects/DidacticSystem/_templAcModRelayers/CMakeLists.txt new file mode 100644 index 0000000..1f34388 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/CMakeLists.txt @@ -0,0 +1,4 @@ +PROJECT(ModWykonawczy) + +ADD_EXECUTABLE(modWykonawczy main.c automat.c hardware.c serial.c) +add_library(headers main.h automat.h FreeRTOSConfig.h hardware.h ../protocol1.h serial.h) diff --git a/Projects/DidacticSystem/_templAcModRelayers/FreeRTOSConfig.h b/Projects/DidacticSystem/_templAcModRelayers/FreeRTOSConfig.h new file mode 100644 index 0000000..ec621a7 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/_templAcModRelayers/Makefile b/Projects/DidacticSystem/_templAcModRelayers/Makefile new file mode 100644 index 0000000..ba7c4ea --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/Makefile @@ -0,0 +1,405 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +PORT_DIR = ../../freeRtos/portable/GCC/ATMega168 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +serial.c \ +hardware.c\ +automat.c\ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/_templAcModRelayers/automat.c b/Projects/DidacticSystem/_templAcModRelayers/automat.c new file mode 100644 index 0000000..49a8622 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/automat.c @@ -0,0 +1,88 @@ +#include "automat.h" + +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + + if (klGoraOff) + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + stan->klGora_off++; + } + else + { + if (stan->klGora_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_gore; + wiadomosc = 0xBF; + } + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + stan->klGora_off = 0; + } + + if (klDolOff) + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klDol_on = 0; + stan->klDol_off++; + } + else + { + if (stan->klDol_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_dol; + wiadomosc = 0x3F; + } + } + if (stan->klDol_on == T_START_CONT) + { + stan->czynnosc = w_dol; + } + stan->klDol_on++; + stan->klDol_off = 0; + } + + if (stan->klDol_on == 255) + stan->klDol_on = 254; + if (stan->klGora_on == 255) + stan->klGora_on = 254; + + if (stan->klDol_off == 255) + stan->klDol_off = 254; + if (stan->klGora_off == 255) + stan->klGora_off = 254; + + return wiadomosc; +} diff --git a/Projects/DidacticSystem/_templAcModRelayers/automat.h b/Projects/DidacticSystem/_templAcModRelayers/automat.h new file mode 100644 index 0000000..702de30 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/automat.h @@ -0,0 +1,29 @@ +#ifndef AUTOMAT_H +#define AUTOMAT_H + +#include "main.h" + + +typedef enum +{ + bezczynny, + do_konca_w_gore, + do_konca_w_dol, + w_gore, + w_dol +} t_czynnosc; + +typedef struct +{ + uint8_t klGora_on; + uint8_t klDol_on; + + uint8_t klGora_off; + uint8_t klDol_off; + t_czynnosc czynnosc; +} +t_stan_klawiszy; + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan); + +#endif diff --git a/Projects/DidacticSystem/_templAcModRelayers/executingModule.cbp b/Projects/DidacticSystem/_templAcModRelayers/executingModule.cbp new file mode 100644 index 0000000..97e8294 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/executingModule.cbp @@ -0,0 +1,80 @@ + + + + + + diff --git a/Projects/DidacticSystem/_templAcModRelayers/flash.sh b/Projects/DidacticSystem/_templAcModRelayers/flash.sh new file mode 100755 index 0000000..f40b1d2 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/flash.sh @@ -0,0 +1,16 @@ +#!/usr/bin/expect -f + +set dev "/dev/rs485tty" +set file "./rtosdemo.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" +send "bootaa" +expect "C" +send_user "Starting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" + diff --git a/Projects/DidacticSystem/_templAcModRelayers/hardware.c b/Projects/DidacticSystem/_templAcModRelayers/hardware.c new file mode 100644 index 0000000..a948d54 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/hardware.c @@ -0,0 +1,127 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - P3 , 1 - P2 , 2 - P1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - KlRolety1Up, 3 - klRolety1Down + PORTC = 0x3F; //4 - KlRolety2Up, 5 - KlRolety2Down + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - Led1, 6 - Led2, 7 - P4) + /*Ustalanie adresu + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = (PINB & 0x38) >> 1; + adres |= (PINC & 0x03); +} + +void roletawGore(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wGore(); + else + roleta2wGore(); +} + +void roletawDol(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wDol(); + else + roleta2wDol(); +} + +void roletaStop(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1Stop(); + else + roleta2Stop(); +} + +inline void roleta1wGore(void) +{ + PORTB &= ~0x02; + PORTB |= 0x04; +} + +inline void roleta1wDol(void) +{ + PORTB &= ~0x04; + PORTB |= 0x02; +} + +inline void roleta1Stop(void) +{ + PORTB &= ~0x06; +} + +inline void roleta2wGore(void) +{ + PORTD &= ~0x80; + PORTB |= 0x01; +} + +inline void roleta2wDol(void) +{ + PORTB &= ~0x01; + PORTD |= 0x80; +} + +inline void roleta2Stop(void) +{ + PORTB &= ~0x01; + PORTD &= ~0x80; +} + +inline void Led1On(void) +{ + PORTD |= 0x20; +} + +inline void Led1Toggle(void) +{ + PORTD ^= 0x20; +} + +inline void Led1Off(void) +{ + PORTD &= ~0x20; +} + +inline void Led2On(void) +{ + PORTD |= 0x40; +} + +inline void Led2Toggle(void) +{ + PORTD ^= 0x40; +} + +inline void Led2Off(void) +{ + PORTD &= ~0x40; +} + +inline char czytKlawiszRol1wGore(void) +{ + return PINC & 0x04; +} + +inline char czytKlawiszRol1wDol(void) +{ + return PINC & 0x08; +} + +inline char czytKlawiszRol2wGore(void) +{ + return PINC & 0x10; +} + +inline char czytKlawiszRol2wDol(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/_templAcModRelayers/hardware.h b/Projects/DidacticSystem/_templAcModRelayers/hardware.h new file mode 100644 index 0000000..46ebdeb --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/hardware.h @@ -0,0 +1,102 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +#define TxStart() (PORTD |= 0x0C) +#define TxStop() (PORTD &= 0xF3) + +extern uint8_t adres; +extern char bHelloResp[]; + +/** + * Inicjalizacja sprzętu + */ +void hardwareInit(void); + +void roletawGore(uint8_t nrRolety); +void roletaStop(uint8_t nrRolety); +void roletawDol(uint8_t nrRolety); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 1 + */ +void roleta1wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 1 + */ +void roleta1wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 1 + */ +void roleta1Stop(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 2 + */ +void roleta2wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 2 + */ +void roleta2wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 2 + */ +void roleta2Stop(void); + +/** + * Zapalenie diody kontrolej 1 + */ +void Led1On(void); + +/** + * Zmiana stanu diody kontrolej 1 + */ +void Led1Toggle(void); + +/** + * Gaszenie diody kontrolej 1 + */ +void Led1Off(void); + +/** + * Zapalenie diody kontrolej 2 + */ +void Led2On(void); + +/** + * Zmiana stanu diody kontrolej 2 + */ +void Led2Toggle(void); + +/** + * Gaszenie diody kontrolej 2 + */ +void Led2Off(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 1 + */ +char czytKlawiszRol1wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 1 + */ +char czytKlawiszRol1wDol(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 2 + */ +char czytKlawiszRol2wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 2 + */ +char czytKlawiszRol2wDol(void); +#endif diff --git a/Projects/DidacticSystem/_templAcModRelayers/main.c b/Projects/DidacticSystem/_templAcModRelayers/main.c new file mode 100644 index 0000000..b0f4773 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/main.c @@ -0,0 +1,185 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +/** + * Proces odpowiedzialny za obsługę klawiszy + * @param pvParameters ignorowane parametry + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Proces odpowiedzialny za obsługę rolety + * @param pvParameters ignorowane parametry + */ +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +static void prvIncrementResetCount( void ); + +void vApplicationIdleHook( void ); + + +/*-----------------------------------------------------------*/ + +/* Device address on RS 485 bus */ +uint8_t adres; +char bHelloResp[HELLO_RESP_LEN+HDR_LEN] = {SYNC, 0, rHELLO, HELLO_RESP_LEN, 'r', 0, 'v', '0', '.', '5', '1'}; + +t_stan_klawiszy roleta1 = {0, 0, 0, 0, bezczynny}; +t_stan_klawiszy roleta2 = {0, 0, 0, 0, bezczynny}; + +extern xQueueHandle xRxedChars; +extern xQueueHandle xCharsForTx; + +xQueueHandle xRoleta[2]; + +portSHORT main( void ) +{ +//prvIncrementResetCount(); + + hardwareInit(); + xSerialPortInitMinimal(16); + + xRoleta[0] = xQueueCreate(4, 1); + xRoleta[1] = xQueueCreate(4, 1); + + xCoRoutineCreate(vProtocol, 0, 0); + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vRoleta, 0, 0); + xCoRoutineCreate(vRoleta, 0, 1); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + static portBASE_TYPE xResult; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + } + wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta2)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + } + } + crEND(); +} + +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + static uint8_t rozkaz[2]; + static uint16_t czasAkcji[2]; + czasAkcji[uxIndex] = portMAX_DELAY; + static portBASE_TYPE xResult[2]; + crSTART( xHandle ); + for (;;) + { + crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz[uxIndex], czasAkcji[uxIndex], &xResult[uxIndex]); + + if (xResult[uxIndex] == pdTRUE) + { + uint8_t tmp = rozkaz[uxIndex] & 0x3F; + if (tmp == 0) + czasAkcji[uxIndex] = portMAX_DELAY; + else + czasAkcji[uxIndex] = tmp*20; + if (rozkaz[uxIndex] & 0x40) + { + roletaStop(uxIndex); + } + else + { + if (rozkaz[uxIndex] & 0x80) + roletawGore(uxIndex); + else + roletawDol(uxIndex); + } + } + else + { + czasAkcji[uxIndex] = portMAX_DELAY; + roletaStop(uxIndex); + } + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +#if 0 +static void prvIncrementResetCount( void ) +{ + unsigned portCHAR ucCount; + eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); + ucCount++; + eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); +} +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templAcModRelayers/main.h b/Projects/DidacticSystem/_templAcModRelayers/main.h new file mode 100644 index 0000000..db7f8be --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/main.h @@ -0,0 +1,28 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" +#include "automat.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + +#endif diff --git a/Projects/DidacticSystem/_templAcModRelayers/serial.c b/Projects/DidacticSystem/_templAcModRelayers/serial.c new file mode 100644 index 0000000..8026459 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModRelayers/serial.c @@ -0,0 +1,446 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 2 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "../../freeRtos/Lib/include/protocol1.h" +#include "hardware.h" + +//#define debug 1 + +/*-----------------------------------------------------------*/ + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + + +static volatile uint8_t kodRozkazu; +static volatile uint8_t dlDanych; +static uint8_t bDane[MAX_DATA_LEN]; + +static uint8_t wiadomosc; + + +static xSemaphoreHandle xSemaphore; +static portBASE_TYPE xHigherPriorityTaskWoken; + +static uint8_t crcLo; +static uint8_t crcHi; +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + { + case rOpuscRolete1: + wiadomosc = 0x3F; + wysylac = 2; + break; + + case rOpuscRolete2: + wiadomosc = 0x3F; + wysylac = 3; + break; + + case rPodniesRolete1: + wiadomosc = 0xBF; + wysylac = 2; + break; + + case rPodniesRolete2: + wiadomosc = 0xBF; + wysylac = 3; + break; + + case rZatrzymajRolete1: + wiadomosc = 0x40; + wysylac = 2; + break; + + case rZatrzymajRolete2: + wiadomosc = 0x40; + wysylac = 3; + break; + + case rPING: + wysylac = 1; + break; + case rHELLO: + wysylac = 4; + break; + case rFLASH: + wysylac = 1; + break; + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + static t_serialState stan; + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + +/* + for ( ;; ) + { + static uint8_t tmp = 'C'; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1On(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1Off(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + } +*/ + for( ;; ) + { + if (stan == s_sync) + { + znak=0; + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + if ((xResult == pdPASS) && (znak == SYNC)) + { + stan = s_addr; + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + stan = s_rozkaz; + crc = _crc_xmodem_update(crc, znak); + if (znak == adres) + dobryAdres = 1; + else + dobryAdres = 0; + } + else + { + stan = s_sync; + } + } + if (stan == s_rozkaz) + { + Led1On(); + Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, kodRozkazu); + stan = s_len; + } + else + { + stan = s_sync; + } + } + if (stan == s_len) + { + Led1Off(); + Led2On(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, dlDanych); + lOdebrDanych = 0; + stan = s_dane; + Led1On(); + Led2On(); + } + else + { + stan = s_sync; + } + } + if (stan == s_dane) + { + if (lOdebrDanych == dlDanych) + { + stan = s_CRC_HI; + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, znak); + if (lOdebrDanych < MAX_DATA_LEN) + bDane[lOdebrDanych] = znak; + lOdebrDanych++; + } + else + { + Led1Off(); + stan = s_sync; + } + } + } + if (stan == s_CRC_HI) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + if (xResult == pdPASS) + { + stan = s_CRC_LO; + } + else + { + Led1Off(); + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + if (xResult == pdPASS) + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + { + Led1Off(); + stan = s_sync; + } + else + { + stan = s_CRC_OK; + } + } + } + if (stan == s_CRC_OK) + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + if (rezultat == 1) + { + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(0, temp); + + //ADRES 0x00 adres mastera + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + + if (kodRozkazu == rFLASH) + { + Led1On(); + Led2On(); + crDELAY(xHandle, 10); + Led1Off(); + Led2Off(); + (*((void(*)(void))BOOT_START))(); //reboot + } + } + else if (rezultat == 2) + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 3) + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 4) + { + //SYNC + crc = 0; + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + Led1Off(); + Led2Off(); + stan = s_sync; + } + else //Zły adres + { + if (kodRozkazu == rFLASH) + { + DISABLE_RX(); + Led1On(); + Led2On(); + //TODO disable RX buffer + crDELAY(xHandle, 1000); + ENABLE_RX(); + } + Led1Off(); + stan = s_sync; + } + } + } + crEND(); +} + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + UBRR0L = 3; + UBRR0H = 0; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1< $@ + +size: $(TARGET).hex + @echo + @avr-size -A $(TARGET).elf + +# Program the device. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) Bootldr.elf dep/* Bootldr.hex Bootldr.eep + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/Projects/DidacticSystem/_templAcModTriacs/Bootloader/bootldr.c b/Projects/DidacticSystem/_templAcModTriacs/Bootloader/bootldr.c new file mode 100644 index 0000000..39f0ef8 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/Bootloader/bootldr.c @@ -0,0 +1,382 @@ +/* + Project: AVR Rs485 bootloader + Base on + Project: AVR Universal BootLoader + Author: Shaoziyang + Shaoziyang@gmail.com + http://avrubd.googlepages.com + + Author: Adam Kaliszan + adam.kaliszan@gmail.com + + File: bootldr.c + main program code + + Version: 0.9 + + Date: 2010.4 +*/ + +#include "bootldr.h" + +uint8_t helloBuf[] = {SYNC, 0, rHELLO, 7, 0xFF , 0xFF, 'b', '0', '.', '6', '2'}; //rHELLO response +uint8_t pingBuf[HDR_LEN+PROT_BUF_LEN] = {SYNC, 0, rPING, 8}; //rPING response +uint8_t noCommandBuf[] = {SYNC, 0, rUNKNOWN, 0}; //unknown command response + +uint8_t buf[BUFSIZE]; // xModem receive buffer +uint8_t bufptr; +uint8_t pagptr; +uint8_t ch; +uint8_t cl; +uint16_t FlashAddr; +uint8_t cnt; + +uint8_t tmp; +uint8_t adres; // Adres urządzenia zczytany na starcie +stanAutomatu_t stan; // Stan automatu +uint16_t crc; // Crc +uint16_t crcObl; // Crc +uint8_t protAddr; // Odebrany adres w magistrali Rs485 +uint8_t protRozkaz; // Odebrany kod rozkazu +uint8_t protDlDanych; // Odebrana inf. o długości pola danych +uint8_t protBuf[PROT_BUF_LEN]; // Odebrane dane do rozkazu +uint8_t protCrcHi; // Odebrany bardziej znaczący bajt CRC +uint8_t protCrcLo; // Odebrany mniej znaczący bajt CRC +uint8_t protDaneWsk; // Licznik odebranych danych + + +inline void write_one_page(unsigned char *buf) //Uaktualnianie strony z pamięcią flash +{ + boot_page_erase(FlashAddr); //Kasowanie strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji + + uint16_t *tmpPtr = (uint16_t *)(buf); //kompilator musi być little bit endian + for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2) + { + boot_page_fill(pagptr, *tmpPtr); //brzydkie rzutowanie 2X uint8_t na uint16_t + tmpPtr++; //wskaźnik zwiększa się o 2 + } + boot_page_write(FlashAddr); //Zapis strony + boot_spm_busy_wait(); //Czekanie na wykonanie operacji +} + +//send data to comport +void WriteCom(unsigned char dat) +{ + RS485Enable(); + UDRREG(COMPORTNo) = dat; + while(!(UCSR0A & (1<>8)); + WriteCom((uint8_t)(crc & 0xFF)); + crc=0; +} + + +void wykonajRozkaz(void) +{ + uint8_t tmpCrcLo = (uint8_t)(crcObl & 0xFF); + uint8_t tmpCrcHi = (uint8_t)(crcObl >>8); + + resetStateMachine(); + if ((tmpCrcHi != protCrcHi) ||(tmpCrcLo != protCrcLo)) + { + return; + } + stan = sync; + cnt = TimeOutCnt; + if (adres != protAddr) + { + if (protRozkaz == rFLASH) + { + waitAndQuit(); + } + return; + } + if (protRozkaz == rFLASH) + { + stan = xModem; + return; + } + if (protRozkaz == rHELLO) + { + sendBuf(helloBuf, HDR_LEN+7); + return; + } + if (protRozkaz == rPING) + { + if (protDlDanych > PROT_BUF_LEN) + protDlDanych = PROT_BUF_LEN; + pingBuf[3] = protDlDanych; + for (tmp=0; tmp>1); //Read address + adres |= (PINC & 0x03); + + //initialize serial port UART0 + UCSR0A = 0; + UCSR0B = (1 << RXENBIT(COMPORTNo))|(1 << TXENBIT(COMPORTNo)); + UCSR0C = (1 << USEURSEL)|(1 << UCSZ01)|(1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 3; + + cnt = TimeOutCnt; // Timeout (wg. częstotliwości zegara 1Hz) + cl = 0; // Liczba poprawnych liter od hasła + + +//Wykonywanie poleceń. Tryb bootloadera. + while(stan != xModem) // Czekanie aż zostanie odebrany rozkaz rozpoczęcia transmisji xModemowej + { + if(TIFRREG & (1< + break; + } + + //begin xModem transmission - receive data + packNO = 1; + bufptr = 0; + cnt = 0; + FlashAddr = 0; + while(1) + { + ch = ReadCom_withLimitedWaiting(); // get package number + cl = ~ReadCom_withLimitedWaiting(); + if ((packNO == ch) && (packNO == cl)) + { + uint16_t crc = 0; // start calculate CRC + for(li = 0; li < BUFFERSIZE; li++) // receive a full data frame + { + tmp = ReadCom_withLimitedWaiting(); // read from uart + buf[bufptr++] = tmp; // write to temporary buffer + crc = _crc_xmodem_update(crc, tmp); // calculate CRC + } + + crch = ReadCom_withLimitedWaiting(); // get checksum Hi + crcl = ReadCom_withLimitedWaiting(); // get checksum Lo + ch = crc / 256; + cl = crc % 256; + if ((crch == ch) && (crcl == cl)) + { + PORTD |= (uint8_t)(0x40); + packNO++; + while(bufptr > 0) // receive one frame, write multi pages + { + write_one_page(&buf[BUFSIZE - bufptr]); + FlashAddr += SPM_PAGESIZE; // modify Flash page address + bufptr -= SPM_PAGESIZE; + if (FlashAddr >= 2*BootStart) // BootStart is word number (not byte number) + quit(); + } + WriteCom(XMODEM_ACK); // All OK send ACK + cnt = 0; + } + else //CRC + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + } + else //PackNo + { + //ask resend + WriteCom(XMODEM_NAK); + PORTD |= (uint8_t)(0x20); + cnt++; + } + //too much error, update abort + if(cnt > 3) + { + PORTD |= (uint8_t)(0x20); + break; + } + tmp = ReadCom_withLimitedWaiting(); + + if (tmp == XMODEM_EOT) + break; + } + WriteCom(XMODEM_NAK); + + quit(); + return 0; +} + +//! quit boot mode and jump to user's application +void quit(void) +{ + boot_rww_enable(); //enable application section + (*((void(*)(void))PROG_START))(); //jump +} + +//! wait 1 minute and jump to user's application +void waitAndQuit(void) +{ +// PORTD = 0x20; //LED 1 and 2 on + cnt=120; + while(1) + { + if(TIFRREG & (1< +#include +#include +#include +#include + +#include "../../../freeRtos/Lib/include/protocol1.h" +#include "../../../freeRtos/Lib/include/xModemCommands.h" + +#define PROT_BUF_LEN 32 /// Rs485 rec buffer length + + +#ifndef F_CPU ///system clock(Hz) +#define F_CPU 7372800UL +#endif + +#define PROG_START 0x0000 /// User's application start address +#define BootStart 0x1C00 /// Boot section address start + +#define BUFFERSIZE 128 /// Xmodem buffer length +#define BAUDRATE 115200 /// Rs485 baudrate + + +#define timeclk 500 /// basic timer interval(ms) +#define TimeOutCnt 10 /// max wait for password time = TimeOutCnt * timeclk +#define TimeOutCntC 40 /// numbers of sending C char for start xModem + + +#define COMPORTNo 0 /// comport number: 0/1/2.. + +#define RS485RXDis 2 /// Pin that disables Rs485 receiver +#define RS485TXEn 3 /// Pin that enables Rs485 transmitter +#define LEDPORTNo 5 /// Pin that is connected to the diode 1 +#define LED2PORTNo 6 /// Pin that is connected to the diode 2 + + +//receive buffer' size will not smaller than SPM_PAGESIZE +#if BUFFERSIZE < SPM_PAGESIZE +#define BUFSIZE SPM_PAGESIZE +#else +#define BUFSIZE BUFFERSIZE +#endif + + + + +//Don't modify code below, unless your really konw what to do + + +//certain version compiler missing this in head files +#ifndef SPM_PAGESIZE +#error "Not define SPM_PAGESIZE, please define below or update your WinAVR" +//#define SPM_PAGESIZE XXX +#endif + +//certain version compiler missing this in head files +#ifndef FLASHEND +#error "Not define FLASHEND, please define below or update your WinAVR" +//#define FLASHEND XXX +#endif + +//two buffer size must be multiple or submultiple relation +#if BUFFERSIZE >= SPM_PAGESIZE +#if (BUFFERSIZE / SPM_PAGESIZE * SPM_PAGESIZE) != BUFFERSIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#else +#if (SPM_PAGESIZE /BUFFERSIZE * BUFFERSIZE) != SPM_PAGESIZE +#error "Result of (BUFFERSIZE / SPM_PAGESIZE) is not a Integer!" +#error "Please check and set 'BUFFERSIZE/SPM_PAGESIZE' Macro again!" +#endif +#endif + +//calculate baudrate register +#define BAUDREG ((unsigned int)((F_CPU * 10) / (16UL * BAUDRATE) - 5) / 10) + +//check baudrate register error +//mocro below maybe not same in different C compiler +#define FreqTemp (16UL * BAUDRATE * (((F_CPU * 10) / (16 * BAUDRATE) + 5)/ 10)) +#if ((FreqTemp * 50) > (51 * F_CPU) || (FreqTemp * 50) < (49 * F_CPU)) +#error "BaudRate error > 2% ! Please check BaudRate and F_CPU value." +#endif + +#define True 1 +#define False 0 +#define TRUE 1 +#define FALSE 0 + +//internal use macro +#define CONCAT(a, b) a ## b +#define CONCAT3(a, b, c) a ## b ## c + +//register of PORT and bit define +#define PORTREG(No) CONCAT(PORT, No) +#define PINREG(No) CONCAT(PIN, No) +#define UDRREG(No) CONCAT(UDR, No) +#define DDRREG(No) CONCAT(DDR, No) +#define TXCBIT(No) CONCAT(TXC, No) +#define RXCBIT(No) CONCAT(RXC, No) +#define RXENBIT(No) CONCAT(RXEN, No) +#define TXENBIT(No) CONCAT(TXEN, No) +#define URSELBIT(No) CONCAT(URSEL, No) + +//some kind of AVR need URSEL define when comport initialize +#define USEURSEL 0 + + +//timer1 overflow register +#ifdef TIFR +#define TIFRREG TIFR +#else +#define TIFRREG TIFR1 +#endif + +//Xmoden control command +#define XMODEM_NUL 0x00 +#define XMODEM_SOH 0x01 +#define XMODEM_STX 0x02 +#define XMODEM_EOT 0x04 +#define XMODEM_ACK 0x06 +#define XMODEM_NAK 0x15 +#define XMODEM_CAN 0x18 +#define XMODEM_EOF 0x1A +#define XMODEM_RWC 'C' + +#define RS485Enable() PORTD = 0x0C +#define RS485Disable() PORTD = 0x00 + +//#define DataInCom() (UCSRAREG(COMPORTNo) & (1 << RXCBIT(COMPORTNo))) +#define DataInCom() (UCSR0A & (1 << RXC0)) +#define ReadCom() UDR0 + +//@{ +/** + * Stan automatu: + * sync, addr, rozkaz, dlDanych, dane, crcHi, crcLo, xModem + */ +enum stanAutomatu +{ + sync, + addr, + rozkaz, + dlDanych, + dane, + crcHi, + crcLo, + xModem +}; +typedef enum stanAutomatu stanAutomatu_t; + +/** + * Leave bootloader mode + */ +void quit(void) __attribute__((noreturn)); + +/** + * Wait for a tame of different device flashing and leave next bootloader mode + */ +void waitAndQuit(void) __attribute__((noreturn)); + +//@} +#endif + +//End of file: bootldr.h diff --git a/Projects/DidacticSystem/_templAcModTriacs/CMakeLists.txt b/Projects/DidacticSystem/_templAcModTriacs/CMakeLists.txt new file mode 100644 index 0000000..1f34388 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/CMakeLists.txt @@ -0,0 +1,4 @@ +PROJECT(ModWykonawczy) + +ADD_EXECUTABLE(modWykonawczy main.c automat.c hardware.c serial.c) +add_library(headers main.h automat.h FreeRTOSConfig.h hardware.h ../protocol1.h serial.h) diff --git a/Projects/DidacticSystem/_templAcModTriacs/FreeRTOSConfig.h b/Projects/DidacticSystem/_templAcModTriacs/FreeRTOSConfig.h new file mode 100644 index 0000000..ec621a7 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/FreeRTOSConfig.h @@ -0,0 +1,93 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 7372800 ) +#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 85 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 750 ) ) +#define configMAX_TASK_NAME_LEN ( 1 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE 0 + +/** Co-routine definitions. */ +#define configUSE_CO_ROUTINES 1 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/** Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/_templAcModTriacs/Makefile b/Projects/DidacticSystem/_templAcModTriacs/Makefile new file mode 100644 index 0000000..ba7c4ea --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/Makefile @@ -0,0 +1,405 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega168 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +PORT_DIR = ../../freeRtos/portable/GCC/ATMega168 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +serial.c \ +hardware.c\ +automat.c\ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +#AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_PORT = /dev/avrMultiTool # Stk500v2 on multi PCB + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +AVR_DUDE_WRITE_FUSES = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m +#-U efuse:w:0xf8:m something is not working with fuse extended. Please enable bootloader manualy. + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVR_DUDE_WRITE_FUSES) + +bin: $(TARGET).hex + hex2bin $(TARGET).hex + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/_templAcModTriacs/automat.c b/Projects/DidacticSystem/_templAcModTriacs/automat.c new file mode 100644 index 0000000..49a8622 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/automat.c @@ -0,0 +1,88 @@ +#include "automat.h" + +#define T_START 5 +#define T_START_CONT 40 +#define T_STOP 5 + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan) +{ + uint8_t wiadomosc = 0; + + if (klGoraOff) + { + if ((stan->czynnosc == w_gore) && (stan->klGora_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klGora_on = 0; + stan->klGora_off++; + } + else + { + if (stan->klGora_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_gore; + wiadomosc = 0xBF; + } + } + if (stan->klGora_on == T_START_CONT) + { + stan->czynnosc = w_gore; + } + stan->klGora_on++; + stan->klGora_off = 0; + } + + if (klDolOff) + { + if ((stan->czynnosc == w_dol) && (stan->klDol_off == T_STOP)) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + stan->klDol_on = 0; + stan->klDol_off++; + } + else + { + if (stan->klDol_on == T_START) + { + if (stan->czynnosc != bezczynny) + { + stan->czynnosc = bezczynny; + wiadomosc = 0x40; + } + else + { + stan->czynnosc = do_konca_w_dol; + wiadomosc = 0x3F; + } + } + if (stan->klDol_on == T_START_CONT) + { + stan->czynnosc = w_dol; + } + stan->klDol_on++; + stan->klDol_off = 0; + } + + if (stan->klDol_on == 255) + stan->klDol_on = 254; + if (stan->klGora_on == 255) + stan->klGora_on = 254; + + if (stan->klDol_off == 255) + stan->klDol_off = 254; + if (stan->klGora_off == 255) + stan->klGora_off = 254; + + return wiadomosc; +} diff --git a/Projects/DidacticSystem/_templAcModTriacs/automat.h b/Projects/DidacticSystem/_templAcModTriacs/automat.h new file mode 100644 index 0000000..702de30 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/automat.h @@ -0,0 +1,29 @@ +#ifndef AUTOMAT_H +#define AUTOMAT_H + +#include "main.h" + + +typedef enum +{ + bezczynny, + do_konca_w_gore, + do_konca_w_dol, + w_gore, + w_dol +} t_czynnosc; + +typedef struct +{ + uint8_t klGora_on; + uint8_t klDol_on; + + uint8_t klGora_off; + uint8_t klDol_off; + t_czynnosc czynnosc; +} +t_stan_klawiszy; + +uint8_t automatStanowKlawiszy(uint8_t klGoraOff, uint8_t klDolOff, t_stan_klawiszy *stan); + +#endif diff --git a/Projects/DidacticSystem/_templAcModTriacs/executingModule.cbp b/Projects/DidacticSystem/_templAcModTriacs/executingModule.cbp new file mode 100644 index 0000000..97e8294 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/executingModule.cbp @@ -0,0 +1,80 @@ + + + + + + diff --git a/Projects/DidacticSystem/_templAcModTriacs/flash.sh b/Projects/DidacticSystem/_templAcModTriacs/flash.sh new file mode 100755 index 0000000..f40b1d2 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/flash.sh @@ -0,0 +1,16 @@ +#!/usr/bin/expect -f + +set dev "/dev/rs485tty" +set file "./rtosdemo.bin" + +system "stty 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke < $dev" + +spawn -open [ open $dev r+ ] +send_user "Calling bootloader\n" +send "bootaa" +expect "C" +send_user "Starting xmodem $dev\n" +close +system "sx -vv -o -b -X $file > $dev < $dev" +send_user "\nOK ready\n" + diff --git a/Projects/DidacticSystem/_templAcModTriacs/hardware.c b/Projects/DidacticSystem/_templAcModTriacs/hardware.c new file mode 100644 index 0000000..a948d54 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/hardware.c @@ -0,0 +1,127 @@ +#include "hardware.h" + + +void hardwareInit(void) +{ + DDRB = 0x07; //0 - P3 , 1 - P2 , 2 - P1 + PORTB = 0x38; //3 - Adr3, 4 - Adr4, 5 - Adr5 + DDRC = 0x00; //0 - Adr0, 1 - Adr1, 2 - KlRolety1Up, 3 - klRolety1Down + PORTC = 0x3F; //4 - KlRolety2Up, 5 - KlRolety2Down + DDRD = 0xEE; //0 - RXD, 1 - TXD, 2 - !RxEn, 3 - TxEn, + PORTD = 0x00; //5 - Led1, 6 - Led2, 7 - P4) + /*Ustalanie adresu + bit 7, 6 = 0 dla sterowników rolet i światła + */ + adres = (PINB & 0x38) >> 1; + adres |= (PINC & 0x03); +} + +void roletawGore(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wGore(); + else + roleta2wGore(); +} + +void roletawDol(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1wDol(); + else + roleta2wDol(); +} + +void roletaStop(uint8_t nrRolety) +{ + if (nrRolety == 0) + roleta1Stop(); + else + roleta2Stop(); +} + +inline void roleta1wGore(void) +{ + PORTB &= ~0x02; + PORTB |= 0x04; +} + +inline void roleta1wDol(void) +{ + PORTB &= ~0x04; + PORTB |= 0x02; +} + +inline void roleta1Stop(void) +{ + PORTB &= ~0x06; +} + +inline void roleta2wGore(void) +{ + PORTD &= ~0x80; + PORTB |= 0x01; +} + +inline void roleta2wDol(void) +{ + PORTB &= ~0x01; + PORTD |= 0x80; +} + +inline void roleta2Stop(void) +{ + PORTB &= ~0x01; + PORTD &= ~0x80; +} + +inline void Led1On(void) +{ + PORTD |= 0x20; +} + +inline void Led1Toggle(void) +{ + PORTD ^= 0x20; +} + +inline void Led1Off(void) +{ + PORTD &= ~0x20; +} + +inline void Led2On(void) +{ + PORTD |= 0x40; +} + +inline void Led2Toggle(void) +{ + PORTD ^= 0x40; +} + +inline void Led2Off(void) +{ + PORTD &= ~0x40; +} + +inline char czytKlawiszRol1wGore(void) +{ + return PINC & 0x04; +} + +inline char czytKlawiszRol1wDol(void) +{ + return PINC & 0x08; +} + +inline char czytKlawiszRol2wGore(void) +{ + return PINC & 0x10; +} + +inline char czytKlawiszRol2wDol(void) +{ + return PINC & 0x20; +} + diff --git a/Projects/DidacticSystem/_templAcModTriacs/hardware.h b/Projects/DidacticSystem/_templAcModTriacs/hardware.h new file mode 100644 index 0000000..46ebdeb --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/hardware.h @@ -0,0 +1,102 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +#include +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +#define TxStart() (PORTD |= 0x0C) +#define TxStop() (PORTD &= 0xF3) + +extern uint8_t adres; +extern char bHelloResp[]; + +/** + * Inicjalizacja sprzętu + */ +void hardwareInit(void); + +void roletawGore(uint8_t nrRolety); +void roletaStop(uint8_t nrRolety); +void roletawDol(uint8_t nrRolety); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 1 + */ +void roleta1wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 1 + */ +void roleta1wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 1 + */ +void roleta1Stop(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie podnoszenia rolety 2 + */ +void roleta2wGore(void); + +/** + * Włącznenie przekaźnika - rozpoczęcie opuszczania rolety 2 + */ +void roleta2wDol(void); + +/** + * Wyłącznenie przekaźników - zatrzymanie rolety 2 + */ +void roleta2Stop(void); + +/** + * Zapalenie diody kontrolej 1 + */ +void Led1On(void); + +/** + * Zmiana stanu diody kontrolej 1 + */ +void Led1Toggle(void); + +/** + * Gaszenie diody kontrolej 1 + */ +void Led1Off(void); + +/** + * Zapalenie diody kontrolej 2 + */ +void Led2On(void); + +/** + * Zmiana stanu diody kontrolej 2 + */ +void Led2Toggle(void); + +/** + * Gaszenie diody kontrolej 2 + */ +void Led2Off(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 1 + */ +char czytKlawiszRol1wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 1 + */ +char czytKlawiszRol1wDol(void); + +/** + * Odczyt stanu klawisza do podnoszenie rolety 2 + */ +char czytKlawiszRol2wGore(void); + +/** + * Odczyt stanu klawisza do opuszczania rolety 2 + */ +char czytKlawiszRol2wDol(void); +#endif diff --git a/Projects/DidacticSystem/_templAcModTriacs/main.c b/Projects/DidacticSystem/_templAcModTriacs/main.c new file mode 100644 index 0000000..b0f4773 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/main.c @@ -0,0 +1,185 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +/** + * Proces odpowiedzialny za obsługę klawiszy + * @param pvParameters ignorowane parametry + */ +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +/** + * Proces odpowiedzialny za obsługę rolety + * @param pvParameters ignorowane parametry + */ +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex); + +static void prvIncrementResetCount( void ); + +void vApplicationIdleHook( void ); + + +/*-----------------------------------------------------------*/ + +/* Device address on RS 485 bus */ +uint8_t adres; +char bHelloResp[HELLO_RESP_LEN+HDR_LEN] = {SYNC, 0, rHELLO, HELLO_RESP_LEN, 'r', 0, 'v', '0', '.', '5', '1'}; + +t_stan_klawiszy roleta1 = {0, 0, 0, 0, bezczynny}; +t_stan_klawiszy roleta2 = {0, 0, 0, 0, bezczynny}; + +extern xQueueHandle xRxedChars; +extern xQueueHandle xCharsForTx; + +xQueueHandle xRoleta[2]; + +portSHORT main( void ) +{ +//prvIncrementResetCount(); + + hardwareInit(); + xSerialPortInitMinimal(16); + + xRoleta[0] = xQueueCreate(4, 1); + xRoleta[1] = xQueueCreate(4, 1); + + xCoRoutineCreate(vProtocol, 0, 0); + xCoRoutineCreate(vKlawisze, 0, 0); + xCoRoutineCreate(vRoleta, 0, 0); + xCoRoutineCreate(vRoleta, 0, 1); + + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +static void vKlawisze(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + static portBASE_TYPE xResult; + + crSTART( xHandle ); + for( ;; ) + { + crDELAY( xHandle, 1); + uint8_t wiadomosc; + wiadomosc = (uint8_t) (automatStanowKlawiszy(czytKlawiszRol1wGore(), czytKlawiszRol1wDol(), &roleta1)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[0], &wiadomosc, 10, &xResult); + } + wiadomosc = (uint8_t)(automatStanowKlawiszy(czytKlawiszRol2wGore(), czytKlawiszRol2wDol(), &roleta2)); + if (wiadomosc) + { + crQUEUE_SEND(xHandle, xRoleta[1], &wiadomosc, 10, &xResult); + } + } + crEND(); +} + +static void vRoleta(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + static uint8_t rozkaz[2]; + static uint16_t czasAkcji[2]; + czasAkcji[uxIndex] = portMAX_DELAY; + static portBASE_TYPE xResult[2]; + crSTART( xHandle ); + for (;;) + { + crQUEUE_RECEIVE(xHandle, xRoleta[uxIndex], &rozkaz[uxIndex], czasAkcji[uxIndex], &xResult[uxIndex]); + + if (xResult[uxIndex] == pdTRUE) + { + uint8_t tmp = rozkaz[uxIndex] & 0x3F; + if (tmp == 0) + czasAkcji[uxIndex] = portMAX_DELAY; + else + czasAkcji[uxIndex] = tmp*20; + if (rozkaz[uxIndex] & 0x40) + { + roletaStop(uxIndex); + } + else + { + if (rozkaz[uxIndex] & 0x80) + roletawGore(uxIndex); + else + roletawDol(uxIndex); + } + } + else + { + czasAkcji[uxIndex] = portMAX_DELAY; + roletaStop(uxIndex); + } + } + crEND(); +} + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +#if 0 +static void prvIncrementResetCount( void ) +{ + unsigned portCHAR ucCount; + eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); + ucCount++; + eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); +} +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templAcModTriacs/main.h b/Projects/DidacticSystem/_templAcModTriacs/main.h new file mode 100644 index 0000000..db7f8be --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/main.h @@ -0,0 +1,28 @@ +#ifndef MAIN_H +#define MAIN_H + + +#include +#include +#include +#include +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" +#include "automat.h" +#include "../../freeRtos/Lib/include/protocol1.h" + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 100 +#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) + +#define STR_V1 '0' +#define STR_V2 '.' +#define STR_V3 '0' +#define STR_V4 '0' +#define STR_V5 '0' + +#endif diff --git a/Projects/DidacticSystem/_templAcModTriacs/serial.c b/Projects/DidacticSystem/_templAcModTriacs/serial.c new file mode 100644 index 0000000..8026459 --- /dev/null +++ b/Projects/DidacticSystem/_templAcModTriacs/serial.c @@ -0,0 +1,446 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 2 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "../../freeRtos/Lib/include/protocol1.h" +#include "hardware.h" + +//#define debug 1 + +/*-----------------------------------------------------------*/ + +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + + +static volatile uint8_t kodRozkazu; +static volatile uint8_t dlDanych; +static uint8_t bDane[MAX_DATA_LEN]; + +static uint8_t wiadomosc; + + +static xSemaphoreHandle xSemaphore; +static portBASE_TYPE xHigherPriorityTaskWoken; + +static uint8_t crcLo; +static uint8_t crcHi; +static uint16_t crc; + +static uint8_t wykonajRozkaz(void) +{ +// static portBASE_TYPE xResult; + uint8_t wysylac = 0; + + switch (kodRozkazu) + { + case rOpuscRolete1: + wiadomosc = 0x3F; + wysylac = 2; + break; + + case rOpuscRolete2: + wiadomosc = 0x3F; + wysylac = 3; + break; + + case rPodniesRolete1: + wiadomosc = 0xBF; + wysylac = 2; + break; + + case rPodniesRolete2: + wiadomosc = 0xBF; + wysylac = 3; + break; + + case rZatrzymajRolete1: + wiadomosc = 0x40; + wysylac = 2; + break; + + case rZatrzymajRolete2: + wiadomosc = 0x40; + wysylac = 3; + break; + + case rPING: + wysylac = 1; + break; + case rHELLO: + wysylac = 4; + break; + case rFLASH: + wysylac = 1; + break; + } + return wysylac; +} + +void vProtocol(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex) +{ + (void) uxIndex; + + crSTART( xHandle ); + static t_serialState stan; + static uint8_t znak; + static portBASE_TYPE xResult; + static uint8_t dobryAdres; + static uint8_t lOdebrDanych; + static uint8_t rezultat; + stan = s_sync; + +/* + for ( ;; ) + { + static uint8_t tmp = 'C'; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1On(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&tmp), 0, &xResult); + Led1Off(); + TxStart(); + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + crDELAY(xHandle, 100); + } +*/ + for( ;; ) + { + if (stan == s_sync) + { + znak=0; + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, portMAX_DELAY, &xResult); + if ((xResult == pdPASS) && (znak == SYNC)) + { + stan = s_addr; + //TODO tutaj jest zawsze wartość stała. Lepiej ją przypisać + crc = _crc_xmodem_update(0, znak); + } + } + if (stan == s_addr) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + stan = s_rozkaz; + crc = _crc_xmodem_update(crc, znak); + if (znak == adres) + dobryAdres = 1; + else + dobryAdres = 0; + } + else + { + stan = s_sync; + } + } + if (stan == s_rozkaz) + { + Led1On(); + Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&kodRozkazu), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, kodRozkazu); + stan = s_len; + } + else + { + stan = s_sync; + } + } + if (stan == s_len) + { + Led1Off(); + Led2On(); + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&dlDanych), 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, dlDanych); + lOdebrDanych = 0; + stan = s_dane; + Led1On(); + Led2On(); + } + else + { + stan = s_sync; + } + } + if (stan == s_dane) + { + if (lOdebrDanych == dlDanych) + { + stan = s_CRC_HI; + } + else + { + //Led2Off(); + crQUEUE_RECEIVE(xHandle, xRxedChars, &znak, 1, &xResult); + if (xResult == pdPASS) + { + crc = _crc_xmodem_update(crc, znak); + if (lOdebrDanych < MAX_DATA_LEN) + bDane[lOdebrDanych] = znak; + lOdebrDanych++; + } + else + { + Led1Off(); + stan = s_sync; + } + } + } + if (stan == s_CRC_HI) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcHi), 1, &xResult); + if (xResult == pdPASS) + { + stan = s_CRC_LO; + } + else + { + Led1Off(); + stan = s_sync; + } + } + if (stan == s_CRC_LO) + { + crQUEUE_RECEIVE(xHandle, xRxedChars, (void *)(&crcLo), 1, &xResult); + if (xResult == pdPASS) + { + if ((crcHi != (uint8_t)(crc >> 8)) || (crcLo != (uint8_t)(crc & 0xFF))) + { + Led1Off(); + stan = s_sync; + } + else + { + stan = s_CRC_OK; + } + } + } + if (stan == s_CRC_OK) + { + if (dobryAdres == 1) + { + if (lOdebrDanych > MAX_DATA_LEN) + lOdebrDanych = MAX_DATA_LEN; + rezultat = wykonajRozkaz(); + if (rezultat == 1) + { + //SYNC + uint8_t temp; + temp = SYNC; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(0, temp); + + //ADRES 0x00 adres mastera + temp = 0x00; + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 0, &xResult); + crc = _crc_xmodem_update(crc, temp); + + //Rozkaz + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&kodRozkazu), 0, &xResult); + crc = _crc_xmodem_update(crc, kodRozkazu); + + //Długość danych + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&lOdebrDanych), 0, &xResult); + crc = _crc_xmodem_update(crc, lOdebrDanych); + + //Dane + for (temp = 0; temp < lOdebrDanych; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bDane[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bDane[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + + if (kodRozkazu == rFLASH) + { + Led1On(); + Led2On(); + crDELAY(xHandle, 10); + Led1Off(); + Led2Off(); + (*((void(*)(void))BOOT_START))(); //reboot + } + } + else if (rezultat == 2) + { + crQUEUE_SEND(xHandle, xRoleta[0], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 3) + { + crQUEUE_SEND(xHandle, xRoleta[1], (void *)(&wiadomosc), 0, &xResult); + } + else if (rezultat == 4) + { + //SYNC + crc = 0; + uint8_t temp; + + //Dane + for (temp = 0; temp < 11; temp++) + { + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&bHelloResp[temp]), 1, &xResult); + crc = _crc_xmodem_update(crc, bHelloResp[temp]); + } + + temp = (uint8_t)(crc>>8); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + temp = (uint8_t)(crc & 0xFF); + crQUEUE_SEND(xHandle, xCharsForTx, (void *)(&temp), 1, &xResult); + + if (xResult == pdPASS) + { + TxStart(); + } + vInterruptOn(); //W przypadku błędu wysyłamy wszystko z bufora przy wyłączonym nadajniku + } + Led1Off(); + Led2Off(); + stan = s_sync; + } + else //Zły adres + { + if (kodRozkazu == rFLASH) + { + DISABLE_RX(); + Led1On(); + Led2On(); + //TODO disable RX buffer + crDELAY(xHandle, 1000); + ENABLE_RX(); + } + Led1Off(); + stan = s_sync; + } + } + } + crEND(); +} + +void xSerialPortInitMinimal(unsigned portBASE_TYPE uxQueueLength ) +{ + portENTER_CRITICAL(); + { + /* Create the queues used by the com test task. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + UBRR0L = 3; + UBRR0H = 0; + + /* Enable the Rx interrupt. The Tx interrupt will get enabled later. Also enable the Rx and Tx. */ + UCSR0B = ((1<0 then + accum:=(accum shl 1) xor genpoly + else + accum:=accum shl 1; + data:=data shl1; + end; + calctable:=accum; + end; + + begin + for i:=0 to 255 do + crctable[i]:=calctable(i,4129,0); + end; + +The CRC starts with a value of zero at the beginning of each block. Now to + update the CRC, with each byte in the 128 byte packet simply do this (the + oldcrc is the crc value to be updated, data is the current byte): + CRC:=(oldcrc shl 8) xor (crctable[(oldcrc shr 8) xor data]); +The final value of the CRC (after all 128 bytes) is what is being sent in the + X-Modem CRC protocol. + +If you have somewhat understood what has just been described then you catch + on a lot faster than I did :) If you just use + + +--- The Actual Transfer --- + +As in X-Modem, the uploader waits for the downloader to send the NCGbyte. + The NCGbyte for X-Modem CRC is chr(67) or the capital letter C (unlike + X-Modem where the NCGbyte is chr(21), the NAK). If the downloader takes too + long or an error occurs then the uploader will stop waiting or "Time Out". + If this happens, then the file transfer must restart. + +With each packet sent... + + The uploader sends: + + 1. an SOH byte {1 byte} + 2. the packet number {1 byte} + 3. the 1's complement of the packet number {1 byte} + 4. the packet {128 bytes} + 5. the high byte of the CRC-16 {1 byte} + 6. the low byte of the CRC-16 {1 byte} + + These six things make up the block. + + The downloader: + + 1. ensures that the packet number sent matches the actual packet number + that it is (If the third block sent has a '4' as the second byte, + something is wrong --> CANCEL TRANSFER (send CAN byte)) + 2. adds the packet number and the 1's complement of the packet number + together to make sure that they add up to 255. if they don't --> + CANCEL TRANSFER + 3. sets the CRC to zero + 4. updates the CRC as each byte in the packet is sent + 5. compares the calculated CRC to the CRC that is sent + 6. if everything looks ok (calculated CRC=sent CRC), then the downloader + appends the bytes in the packet to the file being created (sent). + The downloader then sends an ACK byte which tells the uploader to + send the next block. + if the CRCs do not match, then the downloader sends a NAK byte which + tells the uploader to send the same block it just sent over again. + +When the uploader sends an EOT byte instead of an SOH byte, the downloader + sends a NAK byte. If the uploader sends another EOT immediately after that, + the downloader sends an ACK byte and the transfer is complete. + +Another thing, the downloader can cancel the transfer at any time by sending + a CAN byte. The uploadered can cancel only between blocks by sending a CAN + byte. It is recommended that you send between 2 and 8 consecutive CAN bytes + as some communication programs will not allow you to cancel with only 1 CAN + byte. + + +--- Wrap Up --- + +Hopefully, you were able to follow along. :) If not, you can e-mail me at + em_decay@norlink.net and I will try to clarify it for you. Have fun :) + +Perception: Em Decay -- Mark Korhonen + Cmf ------- Chris Fillion + +Written on Jan.3/95 + diff --git a/Projects/DidacticSystem/_templMainController/Doc/protRs485 b/Projects/DidacticSystem/_templMainController/Doc/protRs485 new file mode 100644 index 0000000..dd8d88d --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/Doc/protRs485 @@ -0,0 +1,17 @@ +#ifndef PROT485_H +#define PROT485_H + +#include +#include "main.h" + +#define Rs485TxStart() (PORTG |= 0x10) +#define Rs485TxStop() (PORTG &= 0xEF) + + +/** + * Inicjalizacja sprzętu + */ +void hardwareInit(void); + + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/FreeRTOSConfig.h b/Projects/DidacticSystem/_templMainController/FreeRTOSConfig.h new file mode 100644 index 0000000..a4fab4a --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + + + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 14745600 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 3 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 100 ) +#define configTOTAL_HEAP_SIZE ( (size_t ) ( 3100 ) ) +//2800 +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 +#define configQUEUE_REGISTRY_SIZE 0 + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define STACK_SIZE_VTY 700 +#define STACK_SIZE_ENC 500 +#define STACK_SIZE_SENSORS 500 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Projects/DidacticSystem/_templMainController/Makefile b/Projects/DidacticSystem/_templMainController/Makefile new file mode 100644 index 0000000..c3af190 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/Makefile @@ -0,0 +1,454 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega128 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../Lib +LIB_NET_DIR = ../../Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../Lib/include -I../../Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +#AVRDUDE_PORT = /dev/jtag +AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/_templMainController/Makefile64 b/Projects/DidacticSystem/_templMainController/Makefile64 new file mode 100644 index 0000000..f9bd78a --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/Makefile64 @@ -0,0 +1,454 @@ +# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega64 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = firmware + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List C source files here. (C dependencies are automatically generated.) +SOURCE_DIR = ../../freeRtos/Source +LIB_DIR = ../../freeRtos/Lib +LIB_NET_DIR = ../../freeRtos/Lib/net +PORT_DIR = ../../freeRtos/portable/GCC/ATMega64 +PORT_MEM = ../../freeRtos/portable/MemMang + +SRC = \ +main.c \ +configuration.c \ +serial.c \ +hardware.c \ +sensors_task.c \ +vty.c \ +netstack_task.c \ +cli_task.c \ +$(LIB_DIR)/spi.c \ +$(LIB_DIR)/memory_x.c \ +$(LIB_DIR)/ramdysk.c \ +$(LIB_DIR)/cmdline.c \ +$(LIB_DIR)/xmodem.c \ +$(LIB_DIR)/vt100.c \ +$(LIB_DIR)/ds1305.c \ +$(LIB_DIR)/mpc23s17.c \ +$(LIB_DIR)/mcp3008.c \ +$(LIB_DIR)/enc28j60.c \ +$(LIB_DIR)/queueStream.c \ +$(LIB_NET_DIR)/nic.c \ +$(LIB_NET_DIR)/net.c \ +$(LIB_NET_DIR)/ip.c \ +$(LIB_NET_DIR)/icmp.c \ +$(LIB_NET_DIR)/arp.c \ +$(LIB_NET_DIR)/tcp.c \ +$(LIB_NET_DIR)/udp.c \ +$(LIB_DIR)/Rs485_prot.c \ +$(SOURCE_DIR)/tasks.c \ +$(SOURCE_DIR)/queue.c \ +$(SOURCE_DIR)/list.c \ +$(SOURCE_DIR)/croutine.c \ +$(PORT_MEM)/heap_avr.c \ +$(PORT_DIR)/port.c + + +#regtest.c \ + +# If there is more than one source file, append them above, or modify and +# uncomment the following: +#SRC += foo.c bar.c + +# You can also wrap lines by appending a backslash to the end of the line: +#SRC += baz.c \ +#xyzzy.c + + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing + +DEBUG_LEVEL=-g +WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ + -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused + +CFLAGS = -D GCC_MEGA_AVR -I. -I../../freeRtos/Source/include -I../../freeRtos/Lib/include -I../../freeRtos/Lib/net/include \ +$(DEBUG_LEVEL) -O$(OPT) \ +-fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +$(WARNINGS) \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + +CFLAGS += -DF_CPU=14745600UL + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8027ff + +#EXTMEMOPTS = -Wl + +# Optional linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = $(EXTMEMOPTS),-Map=$(TARGET).map,--cref + + + +# Additional libraries + +# Minimalistic printf version +LDFLAGS += -Wl,-u,vfprintf + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = jtag1 +AVRDUDE_PORT = /dev/jtag +#AVRDUDE_PORT = /dev/avrMultiTool +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET)_readed.eep +AVRDUDE_WRITE_FUSES_H = -U hfuse:w:0x90:m +AVRDUDE_READ_FUSES_H = -U hfuse:r:$(TARGET).hfuse:i +AVRDUDE_WRITE_FUSES_L = -U lfuse:w:0xff:m +AVRDUDE_READ_FUSES_L = -U lfuse:r:$(TARGET).lfuse:i +AVRDUDE_WRITE_FUSES_E = -U efuse:w:0xff:m +AVRDUDE_READ_FUSES_E = -U efuse:r:$(TARGET).efuse:i + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + + +# Program the device. +flash: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +readfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) $(AVRDUDE_READ_FUSES_H) $(AVRDUDE_READ_FUSES_E) + +programfuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES_L) $(AVRDUDE_WRITE_FUSES_H) $(AVRDUDE_WRITE_FUSES_E) + +reset: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES_L) + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +# Create final output files (.hex, .eep) from ELF output file. +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Projects/DidacticSystem/_templMainController/Rs485_prot_en.h b/Projects/DidacticSystem/_templMainController/Rs485_prot_en.h new file mode 100644 index 0000000..6d5282e --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/Rs485_prot_en.h @@ -0,0 +1,7 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT EN + +prog_char statusRollerDescStr[] = " %d roller driver: roller 1 position %d, roller 2 position %d"; +prog_char statusRollerDescStr2[] = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/Rs485_prot_pl.h b/Projects/DidacticSystem/_templMainController/Rs485_prot_pl.h new file mode 100644 index 0000000..37be016 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/Rs485_prot_pl.h @@ -0,0 +1,7 @@ +#ifndef LANG_RS485_PROT +#define LANG_RS485_PROT PL + +prog_char statusRollerDescStr[] = " %d sterownik rolet: pozycja rolety 1 %d, pozycja rolety 2 %d"; +prog_char statusRollerDescStr2[] = ", firmware %s\r\n"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/cli_task.c b/Projects/DidacticSystem/_templMainController/cli_task.c new file mode 100644 index 0000000..e006e08 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/cli_task.c @@ -0,0 +1,32 @@ +#include "cli_task.h" + +void vTaskVTYusb(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + fprintf_P(state->myStdInOut, PSTR("Restart\r\n")); + cmdlineInputFunc('\r', state); + + char znak; + for( ;; ) + { + if( xQueueReceive(xVtyRec, &znak, portMAX_DELAY)) + { + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } + } +} + +void vTaskVTYsocket(void *cliStatePtr) +{ + cmdState_t *state = (cmdState_t *)(cliStatePtr); + + char znak; + for( ;; ) + { + znak = 0; + znak = fgetc(state->myStdInOut); + cmdlineInputFunc((char)znak, state); + cmdlineMainLoop(state); + } +} diff --git a/Projects/DidacticSystem/_templMainController/cli_task.h b/Projects/DidacticSystem/_templMainController/cli_task.h new file mode 100644 index 0000000..944283c --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/cli_task.h @@ -0,0 +1,30 @@ +#ifndef CLI_TASK_H +#define CLI_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "queue.h" +#include "cmdline.h" + +extern xQueueHandle xVtyRec; +extern xQueueHandle xVtyTx; + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod zoptymalizowany do szczególnego przypadku + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYusb(void *cliStatePtr); + + +/** + * Proces odpowiedzialny za obsługę VTY + * Kod uniwersalny dla dowolnego strumienai FILE + * @param *cliStatePtr wskaźnik do struktury przechowującej stan interpretera poleceń + */ +void vTaskVTYsocket(void *cliStatePtr); + + +#endif /* CLI_TASK_H */ \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/configuration.c b/Projects/DidacticSystem/_templMainController/configuration.c new file mode 100644 index 0000000..ad21758 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/configuration.c @@ -0,0 +1,24 @@ +#include "configuration.h" +#include +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" +#include "nic.h" + + +static struct lockerSensor lockerSensorsEEP[4] __attribute__((section (".eeprom"))) = {{LOCK_SENS_1_ENA, LOCK_SENS_1_THR, 0, 0}, + {LOCK_SENS_2_ENA, LOCK_SENS_2_THR, 0, 0}, + {LOCK_SENS_3_ENA, LOCK_SENS_3_THR, 0, 0}, + {LOCK_SENS_4_ENA, LOCK_SENS_4_THR, 0, 0}}; + +void loadConfiguration(void) +{ + eeprom_read_block(lockSensors, lockerSensorsEEP, 4*sizeof(struct lockerSensor)); +} + +void saveConfiguration(void) +{ + saveNic(); + ipSaveConfig(); + udpSaveConfig(); +} diff --git a/Projects/DidacticSystem/_templMainController/configuration.h b/Projects/DidacticSystem/_templMainController/configuration.h new file mode 100644 index 0000000..c3f862f --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/configuration.h @@ -0,0 +1,18 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include "enc28j60.h" +#include "hardware.h" +#include "ip.h" +#include "nic.h" +#include "sensors_task.h" +#include "udp.h" + +extern struct lockerSensor *lockSensors; + +void loadConfiguration(void); +void saveConfiguration(void); + + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/ffconf.h b/Projects/DidacticSystem/_templMainController/ffconf.h new file mode 100644 index 0000000..36ca220 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/ffconf.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1250 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. */ + + +#define _FS_RPATH 0 /* 0:Disable or 1:Enable */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0:Single parition or 1:Multiple partition */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* Include a header file here to define O/S system calls */ +/* #include , , or ohters. */ + +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONFIG */ diff --git a/Projects/DidacticSystem/_templMainController/hardware.c b/Projects/DidacticSystem/_templMainController/hardware.c new file mode 100644 index 0000000..36590d7 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/hardware.c @@ -0,0 +1,341 @@ +#include "hardware.h" + +#if LANG_EN +#include "hardware_en.h" +#endif + +#if LANG_PL +#include "hardware_pl.h" +#endif + +xQueueHandle xSpiRx; /// Kolejka z odebranymi bajtami z SPI. Blokuje transmisję do czasu zakończenia wysyłania poprzedniego bajtu + +void hardwareInit(void) +{ + //DDRA = 0x00; //External Memory + portENTER_CRITICAL(); + xSpiRx = xQueueCreate(1, 1); + portEXIT_CRITICAL(); + + DDRB = 0xF7; + PORTB = 0xD1; + /* + 0 - Sl_RST + 1 - SCK + 2 - MOSI + 3 - MISO + 4 - External SPI ASR 4 + 5 - External SPI ASR 5 (DS1305) 0 - off; 1 - on + 6 - External SPI ASR 6 (MCP3008) 0 - on; 1 - off + 7 - External SPI ASR 7 (MPC23S17) 0 - on; 1 - off + */ + + //DDRC = 0x00; //External Memory + + DDRD = 0x00; + /* + 0 - SCL + 1 - SDA + 2 - RxD USB + 3 - TxD USB + 4 - External SPI ASR 0 + 5 - External SPI ASR 1 + 6 - External SPI ASR 2 + 7 - External SPI ASR 3 + */ + + DDRE = 0x0E; + PORTE = 0x0C; + /* + 0 - RxD Rs485 + 1 - TxD Rs485 + 2 - ENC RST + 3 - ENC CS + 4 - INT 4 + 5 - INT 5 + 6 - INT 6 + 7 - INT Enc28j60 + */ + DDRF = 0x00; //JTAG and A/C + DDRG = 0x1F; + /* + 0 - WR + 1 - RD + 2 - ALE + 3 - SD CS + 4 - RS485 TxEn + 5 - + 6 - + 7 - + */ +} + +void LockersMemInit(void) +{ + lockSensors = xmalloc(4 * sizeof(struct lockerSensor)); +} + +uint8_t printLockers(FILE *stream) +{ + uint8_t i; + uint8_t result = 0; + struct lockerSensor *tmpLock = lockSensors; + for (i=1; i<=4; i++) + { + if (tmpLock->enabled) + { + fprintf_P(stream, statusLockerSensDescStr, i); + if (tmpLock->threshold > tmpLock->acVal) + fprintf_P(stream, statusLockerOpenStr); + else + fprintf_P(stream, statusLockerCloseStr); + fprintf_P(stream, statusLockerSensAdditionalDescStr, tmpLock->threshold, tmpLock->acVal); + result++; + } + tmpLock++; + } + return result; +} + +void checkLockerSensors(void) +{ + if (lockSensors[0].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + vTaskDelay(30); + lockSensors[0].acVal = MCP3008_getSampleSingle(LOCK_SENS_1_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_1_LIGHT, 0); + lockSensors[0].locked = (lockSensors[0].acVal > lockSensors[0].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[1].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + vTaskDelay(30); + lockSensors[1].acVal = MCP3008_getSampleSingle(LOCK_SENS_2_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_2_LIGHT, 0); + lockSensors[1].locked = (lockSensors[1].acVal > lockSensors[1].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[2].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + vTaskDelay(30); + lockSensors[2].acVal = MCP3008_getSampleSingle(LOCK_SENS_3_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_3_LIGHT, 0); + lockSensors[2].locked = (lockSensors[2].acVal > lockSensors[2].threshold) ? 1 : 0; + vTaskDelay(10); + } + + if (lockSensors[3].enabled) + { + MPC23s17SetBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + vTaskDelay(30); + lockSensors[3].acVal = MCP3008_getSampleSingle(LOCK_SENS_4_AC_IN); + MPC23s17ClearBitsOnPortA(LOCK_SENS_4_LIGHT, 0); + lockSensors[3].locked = (lockSensors[3].acVal > lockSensors[3].threshold) ? 1 : 0; + vTaskDelay(10); + } +} + + +uint8_t spiSend(uint8_t data) +{ + uint8_t result; + SPDR = data; + xQueueReceive(xSpiRx, &result, 10); + return result; +} + +uint8_t spiSendSpinBlock(uint8_t data) +{ + SPDR = data; + SPCR &= ~(1< +#include +#include +#include +#include + +#include "memory_x.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "mpc23s17.h" +#include "mcp3008.h" +#include "spi.h" + +#define Rs485TxStart() (PORTG |= 0x10) +#define Rs485TxStop() (PORTG &= 0xEF) + +struct lockerSensor +{ + uint8_t enabled; + uint16_t threshold; + uint16_t acVal; + uint8_t locked; +}; + + +struct lockerSensor *lockSensors; + + +/** + * Hardware initialize + */ +void hardwareInit(void); + +/** + * Initialization of memory for lockers state structs + */ +void LockersMemInit(void); + +// ************************ Printing hardware info ********************* +/** + * Prints lockers + * @param stream - output stream + * @return number of printed lockers + */ +uint8_t printLockers(FILE *stream); + +// ************************ I/O module ********************************* +/** + * Checks locker sensors + */ +void checkLockerSensors(void); + + +// ************************ Obsługa Rs485 ****************************** +void takeRs485(void); +void releaseRs485(void); +void rs485Send(uint8_t c); +uint8_t rs485Receive(uint8_t *c, uint8_t timeout); + +// ************************ Obsługa SPI ******************************** +uint8_t spiSend(uint8_t data); +uint8_t spiSendSpinBlock(uint8_t data); + + +void disableAllSpiDevices(void); + +void spiEnableEnc28j60(void); +void spiDisableEnc28j60(void); + +void enableSpiSd(void); +void disableSpiSd(void); + +void enableSpiMPC23S17(void); +void disableSpiMPC23S17(void); + +void enableSpiMCP3008(void); +void disableSpiMCP3008(void); + +void spiEnableDS1305(void); +void spiDisableDS1305(void); + +#endif + diff --git a/Projects/DidacticSystem/_templMainController/hardwareConfig.h b/Projects/DidacticSystem/_templMainController/hardwareConfig.h new file mode 100644 index 0000000..18853ad --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/hardwareConfig.h @@ -0,0 +1,156 @@ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +// --------------------- Configuration I/O module -------------------------------- + +//Locker 1 (723 / 687) broken +#define LOCK_SENS_1_LIGHT 0x40 +#define LOCK_SENS_1_AC_IN 4 +#define LOCK_SENS_1_THR 700 +#define LOCK_SENS_1_ENA 0 + +//Locker 2 (603 / 993) OK +#define LOCK_SENS_2_LIGHT 0x20 +#define LOCK_SENS_2_AC_IN 5 +#define LOCK_SENS_2_THR 750 +#define LOCK_SENS_2_ENA 1 + +//Locker 3 (934/937) broken +#define LOCK_SENS_3_LIGHT 0x10 +#define LOCK_SENS_3_AC_IN 6 +#define LOCK_SENS_3_THR 700 +#define LOCK_SENS_3_ENA 0 + +//Locker 4 (831 / 980) OK +#define LOCK_SENS_4_LIGHT 0x08 +#define LOCK_SENS_4_AC_IN 7 +#define LOCK_SENS_4_THR 900 +#define LOCK_SENS_4_ENA 1 + + +// --------------------- Konfiguracja pamięci ------------------------------------ +// + +#define HEAP_BEGIN 0x1100 +#define HEAP_END CLI_1_BUF_ADDR - 1 +#define HEAP_SIZE HEAP_END - HEAP_BEGIN + 1 + +#define CLI_BUF_TOT_LEN 0x0100 +#define CLI_1_BUF_ADDR 0x2800 +#define CLI_2_BUF_ADDR 0x2900 +#define CLI_3_BUF_ADDR 0x2A00 +#define CLI_4_BUF_ADDR 0x2B00 + +#define RTOS_TCP_BUF_BASE_ADDR 0x2C00 + +#define RTOS_UDP_TX_BUF_ADDR 0x7800 +#define RTOS_UDP_RX_BUF_ADDR 0x7900 + +#define NETWORK_STACK_BUF_SIZE 0x0600 // 1532 bytes +#define NETWORK_STACK_BUF_ADDR 0x7A00 // 30 1/4 - 32 kB +#define ENC28J60BUF_ADDR_END ENC28J60BUF_ADDR + ENC28J60BUF_SIZE - 1 + +/* Memory Map + 0x0000 +-----------------------------+ + 256 | Controll registers | + 0x0100 +-----------------------------+ + 4k | Internal memory | + 0x1FFF +-----------------------------+ 4k + 0x1100 +-----------------------------+ + 5k768 | Heap | + 0x2800 +-----------------------------+ 11 k 768 + 256 * CLI 1 buffer + + 0x2900 +-----------------------------+ + 256 * CLI 2 buffer + + 0x2A00 +-----------------------------+ + 256 + CLI 3 buffer + + 0x2B00 +-----------------------------+ + 256 * CLI 4 buffer + + 0x2C00 +-----------------------------+ + TCP buffers + + + 0x7800 +-----------------------------+ 30 k + 256 | RTOS UDP Tx buffer | + 0x7900 +-----------------------------+ + 256 | RTOS UDP Rx buffer | + 0x7A00 +-----------------------------+ + 1k512 | Enc28j60Buffer | + 0x8000 +-----------------------------+ 32 K + 32k | Filesystem Fat8 | + 0xFFFF +-----------------------------+ +*/ + + +//Konfiguracja biblioteki ds1305.h +#define USE_DECODED_TIME_STRUCT 1 + +//Konfiguracja Sterownika ethenretowego Enc28j60 +//CS jest na PORT E.3 +#define ENC_SPI_CS_PORT PORTE +#define ENC_SPI_CS_EN_MASK_OR 0x00 +#define ENC_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja Karty SD +//CS jest na PORT G.3 +#define SD_SPI_CS_PORT PORTG +#define SD_SPI_CS_EN_MASK_OR 0x00 +#define SD_SPI_CS_EN_MASK_AND 0xF7 + +//Konfiguracja portu równoległego MPC23S17 +//CS jest na PORT B.7 +#define MPC23S17_SPI_CS_PORT PORTB +#define MPC23S17_SPI_CS_EN_MASK_OR 0x00 +#define MPC23S17_SPI_CS_EN_MASK_AND 0x7F + +//Konfiguracja Układu analogowo cyfrowego MPC3008 +//CS jest na PORT B.6 +#define MCP3008_SPI_CS_PORT PORTB +#define MCP3008_SPI_CS_EN_MASK_OR 0x00 +#define MCP3008_SPI_CS_EN_MASK_AND 0xBF + +//Konfiguracja Zegara czasu rzeczywistego DS1305 +//CE jest na PORT B.5 +#define DS1305_SPI_CS_PORT PORTB +#define DS1305_SPI_CS_EN_MASK_OR 0x20 +#define DS1305_SPI_CS_EN_MASK_AND 0xFF + + + +//konfiguracja wyłączania wszystkich urządzeń SPI + +//PORT A: Zewnętrzna pamięć +#define disableSpiPORTA_OR 0x00 +#define disableSpiPORTA_AND 0xFF + +//PORT B: SPICS na PB4-PB7 +// PB4 - brak +// PB5 - DS1305 0 - off, 1 - on +// PB6 - MCP3008 0 - on. 1 - off +// PB7 - MCP23S17 0 - on, 1 - off +#define disableSpiPORTB_OR 0xC0 +#define disableSpiPORTB_AND 0xDF + +//PORT C: Zewnętrzna pamięć +#define disableSpiPORTC_OR 0x00 +#define disableSpiPORTC_AND 0xFF + +//PORD D: brak SPI SS +#define disableSpiPORTD_OR 0x00 +#define disableSpiPORTD_AND 0xFF + +//PORT E +// PE3 - ENC28j60 0 - on, 1 - off +#define disableSpiPORTE_OR 0x08 +#define disableSpiPORTE_AND 0xFF + +//PORT F - brak SPI SS +#define disableSpiPORTF_OR 0x00 +#define disableSpiPORTF_AND 0xFF + +//PORT G +// PG3 - SD +#define disableSpiPORTG_OR 0x08 +#define disableSpiPORTG_AND 0xFF + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/hardware_en.h b/Projects/DidacticSystem/_templMainController/hardware_en.h new file mode 100644 index 0000000..51e7e46 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/hardware_en.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE EN + +prog_char statusLockerSensDescStr[] = " locker %d"; +prog_char statusLockerOpenStr[] = " open "; +prog_char statusLockerCloseStr[] = " locked "; +prog_char statusLockerSensAdditionalDescStr[] = " (threshold %d, AC value %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/_templMainController/hardware_pl.h b/Projects/DidacticSystem/_templMainController/hardware_pl.h new file mode 100644 index 0000000..9bf0733 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/hardware_pl.h @@ -0,0 +1,9 @@ +#ifndef LANG_HARDWARE +#define LANG_HARDWARE PL + +prog_char statusLockerSensDescStr[] = " rygiel %d"; +prog_char statusLockerOpenStr[] = " otwarty "; +prog_char statusLockerCloseStr[] = " zamkniety"; +prog_char statusLockerSensAdditionalDescStr[] = " (granica %d, wartosc AC %d)\r\n"; + +#endif diff --git a/Projects/DidacticSystem/_templMainController/main.c b/Projects/DidacticSystem/_templMainController/main.c new file mode 100644 index 0000000..bc4ec47 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/main.c @@ -0,0 +1,158 @@ +/* + + FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry. + This file is part of the FreeRTOS.org distribution. + FreeRTOS.org is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License (version 2) as published + by the Free Software Foundation and modified by the FreeRTOS exception. + FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + A special exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS.org without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details. + *************************************************************************** + * * + * Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation * + * * + * This is a concise, step by step, 'hands on' guide that describes both * + * general multitasking concepts and FreeRTOS specifics. It presents and * + * explains numerous examples that are written using the FreeRTOS API. * + * Full source code for all the examples is provided in an accompanying * + * .zip file. * + * * + *************************************************************************** + 1 tab == 4 spaces! + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "main.h" + +uint8_t timer100Hz = 0; + +xQueueHandle xVtyTx; +xQueueHandle xVtyRec; + +xQueueHandle xRs485Tx; +xQueueHandle xRs485Rec; + + +volatile uint8_t temperature; +volatile uint8_t voltage; + + +void vApplicationIdleHook( void ); + +void vBlinkLed(void *pvParameters); + +/** + * RTC clock support + */ +void vApplicationTickHook( void ); + +xTaskHandle xHandleVTY_USB; +xTaskHandle xHandleVTY_UDP; +xTaskHandle xHandleEnc; +xTaskHandle xHandleSensors; +xTaskHandle xHandleBlinkLed; + +void initExternalMem(void) +{ + MCUCR |= _BV(SRE); //Włączenie pamięci zewnętrznej + MCUCR |= 0x0E; +} + +cmdState_t *CLIStateSerialUsb; +cmdState_t *CLIStateSerialUdp; +FILE usbStream; +FILE udpStream; + +streamBuffers_t udpBuffers; + +portSHORT main( void ) +{ + ramDyskInit(); //Inicjalizacja Ram dysku + hardwareInit(); + spiInit(disableAllSpiDevices); + +// VTY on serial + xSerialPortInitMinimal(); + CLIStateSerialUsb = xmalloc(sizeof(cmdState_t)); + CLIStateSerialUdp = xmalloc(sizeof(cmdState_t)); + + +// cmdStateClear(newCmdState); + DDRF = 0x0F; //JTAG and A/C + PORTF |= 0x06; + + sensorsTaskInit(); + loadConfiguration(); + + initQueueStreamUSB(&usbStream); + VtyInit(CLIStateSerialUsb, &usbStream); + + udpInit(); + socketInit(); + initQueueStream(&udpStream, &udpBuffers, udpSocket->Rx, udpSocket->Tx); + VtyInit(CLIStateSerialUdp, &udpStream); + + xTaskCreate(encTask, NULL /*"ENC" */, STACK_SIZE_ENC, (void *)CLIStateSerialUsb->myStdInOut, 0, &xHandleEnc); + xTaskCreate(vTaskVTYusb, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUsb), 1, &xHandleVTY_USB); + xTaskCreate(vTaskVTYsocket, NULL /*"VTY" */, STACK_SIZE_VTY, (void *)(CLIStateSerialUdp), 1, &xHandleVTY_UDP); + xTaskCreate(sensorsTask, NULL /*"Sensors"*/, STACK_SIZE_SENSORS, NULL, 1, &xHandleSensors); + xTaskCreate(vBlinkLed, NULL /*"ENC" */, 0, NULL, 2, &xHandleBlinkLed); + vTaskStartScheduler(); + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + for( ;; ) + { + vCoRoutineSchedule(); + } +} + +void vApplicationTickHook( void ) +{ + static uint8_t tickCntr = configTICK_RATE_HZ; + if (--tickCntr == 0) + { + tickCntr = configTICK_RATE_HZ; + arpTimer(); + } +} + +void vBlinkLed(void *pvParameters) +{ + //cmdState_t *state = (cmdState_t *)(pvParameters); + + //uint8_t f = 0; + for(;;) + { + portTickType xDelay2 = 1000 / portTICK_RATE_MS; + vTaskDelay(xDelay2); + PORTF ^= 0x04; +// f = xTaskGetTickCount(); + //fprintf( (FILE *)&state->myStdInOut, "B"); + //fprintf(&state->myStdInOut, "TickTime: %d\r\n", f); + } +} diff --git a/Projects/DidacticSystem/_templMainController/main.h b/Projects/DidacticSystem/_templMainController/main.h new file mode 100644 index 0000000..f10d133 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/main.h @@ -0,0 +1,66 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + +#include "memory_x.h" +#include "Rs485_prot.h" + +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" +#include "task.h" +#include "queueStream.h" +#include "cli_task.h" +#include "serial.h" + +#include "hardwareConfig.h" +#include "softwareConfig.h" + +#include "hardware.h" +#include "spi.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "enc28j60.h" + +#include "ramdysk.h" +#include "ff.h" +#include "sd_diskio.h" +#include "rtc.h" + +#include "sensors_task.h" +#include "netstack_task.h" + + +#include "cmdline.h" +#include "vty.h" + +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" + + + +#define mainCHECK_TASK_PRIORITY 1 +#define mainCHECK_PERIOD 1 + +#define SYSTEM_NAME "FreeRtos+" +#define S_VERSION "0.31" + + + + +volatile timeDecoded_t czasRtc; + +void initExternalMem(void) __attribute__ ((naked)) __attribute__ ((section (".init4"))); + +extern UdpSocket_t *udpSocket; + +#endif diff --git a/Projects/DidacticSystem/_templMainController/mainController.cbp b/Projects/DidacticSystem/_templMainController/mainController.cbp new file mode 100644 index 0000000..6692dfc --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/mainController.cbp @@ -0,0 +1,129 @@ + + + + + + diff --git a/Projects/DidacticSystem/_templMainController/netstack_task.c b/Projects/DidacticSystem/_templMainController/netstack_task.c new file mode 100644 index 0000000..8e0cce3 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/netstack_task.c @@ -0,0 +1,157 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include "netstack_task.h" + + +/*uint16_t printHTMLstatus(char *buf, uint16_t pos, uint16_t maxPos) +{*/ +/* char *tmpPtr; + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ( "

Status

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

"SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), temperature); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp, L_KLASTROW); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Temperatura%d C
Napięcie na magistrali%d V
Liczba wolnych klastrów%d / %d

")); + + tmpPtr = getBufPosToWrite(buf, pos); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Czujniki rygli

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("

")); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + for (tmp = 0; tmp < 4; tmp++) + { + if (lockSensors[tmp].enabled) + { + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), tmp+1); + if (lockSensors[tmp].locked) + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + else + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + + tmpPtr = getBufPosToWrite(buf, pos); + pos +=sprintf_P(tmpPtr, PSTR(""), lockSensors[tmp].acVal, lockSensors[tmp].threshold); + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("")); + } + } + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR ("
Czujnik nrPołożenie ryglaOdczyt z przetwornika ACWart graniczna
%dzamkniętyotwarty%d%d

")); + + pos=fill_tcp_data_p(Enc28j60_global.buf, pos, PSTR("

Moduły wykonawcze

")); + return pos;*/ +// return 0; +// } + + +void encTask ( void *pvParameters ) +{ + FILE *netstackDebug = (FILE *) pvParameters; + uint16_t plen; + + nicInit(); + ipInit(); + arpInit(); + icmpInit(); + + + //TODO init_ip_arp_udp_tcp (mymac, ipGetConfig()->ip, MYWWWPORT); + + + for ( ; ; ) + { + vTaskDelay ( 0 ); //Zastąpić oczekiwaniem na zwolnienie semafora. Semafor zostaje zwolniony po odebrzeniu przerwania od ENC + + // get the next new packet: + plen = nicPoll(); + /*plen will ne unequal to zero if there is a valid + * packet (without crc error) */ + if ( plen==0 ) + { + flushUdpQueues(); + flushTcpQueues(); + //flush HTTP long file queue + continue; + } + + if(nicState.layer2.ethHeader->type == htons(ETHTYPE_IP)) // process an IP packet + { + arpIpIn(); + netstackIPv4Process(); + } + else if(nicState.layer2.ethHeader->type == htons(ETHTYPE_ARP)) // process an ARP packet + { + arpArpIn(); + } + else + { + if (netstackDebug != NULL) + { + fprintf_P(netstackDebug, PSTR("Unknown packet\r\n")); + } + } + + continue; + } +} + +#if 0 +// uint16_t dat_p; +// uint8_t cmd_pos=0; +// int8_t cmd; +// uint8_t payloadlen=0; +// char str[30]; +// char cmdval; + + + // arp is broadcast if unknown but a host may also + // verify the mac address by sending it to + // a unicast address. + if ( eth_type_is_arp_and_my_ip(Enc28j60_global.buf, plen)) + { + make_arp_answer_from_request(Enc28j60_global.buf); + continue; + } + + // IP - check if ip packets are for us: + if ( eth_type_is_ip_and_my_ip ( Enc28j60_global.buf,plen ) ==0 ) + continue; + + // PING + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_ICMP && Enc28j60_global.buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V ) + { + // a ping packet, let's send pong + make_echo_reply_from_request (Enc28j60_global.buf, plen); + continue; + } + + } + if ( Enc28j60_global.buf[IP_PROTO_P]==IP_PROTO_TCP && Enc28j60_global.buf[TCP_DST_PORT_H_P]==0 && Enc28j60_global.buf[TCP_DST_PORT_H_P]==MYTELNETPOERT_H + && (Enc28j60_global.buf[TCP_DST_PORT_L_P]>=MYTELNETPOERT_L || Enc28j60_global.buf[TCP_DST_PORT_L_P]<=MYTELNETPOERT_L + 20)) + { + processIpPacket(Enc28j60_global.buf); + continue; + } +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/netstack_task.h b/Projects/DidacticSystem/_templMainController/netstack_task.h new file mode 100644 index 0000000..a79a3a6 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/netstack_task.h @@ -0,0 +1,51 @@ +#ifndef ENC_TASK_H +#define ENC_TASK_H 1 + +#include +#include +#include +#include +#include + +#include "enc28j60.h" +#include "net.h" +#include "nic.h" +#include "ip.h" +#include "arp.h" +#include "udp.h" +#include "tcp.h" +#include "icmp.h" +#include "hardware.h" +#include "hardwareConfig.h" +#include "softwareConfig.h" + + +//TODO add new task: http server +typedef enum +{ + URLramDysk, + URLsdDysk, + URLstatus, + URLerror +} urlSource_t; + + +extern struct lockerSensor *lockSensors; + +uint8_t verify_password(char *str); + +/** + * takes a string of url address and process it + * @param str - part of URL string + * @param [out] - filename or command + * @return http source (SD, RamDysk, status) + */ +urlSource_t analyse_get_url (const char *str, char *fname); + +/** + * Enc28j60 task + */ +void encTask(void *pvParameters); + +extern nicState_t nicState; +#endif diff --git a/Projects/DidacticSystem/_templMainController/rtc.c b/Projects/DidacticSystem/_templMainController/rtc.c new file mode 100644 index 0000000..bf54760 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/rtc.c @@ -0,0 +1,259 @@ +/*--------------------------------------------------------------------------*/ +/* RTC controls */ + +#include +#include +#include "rtc.h" + + + +#define SCL_LOW() DDRE |= 0x04 /* SCL = LOW */ +#define SCL_HIGH() DDRE &= 0xFB /* SCL = High-Z */ +#define SCL_VAL ((PINE & 0x04) ? 1 : 0) /* SCL input level */ +#define SDA_LOW() DDRE |= 0x08 /* SDA = LOW */ +#define SDA_HIGH() DDRE &= 0xF7 /* SDA = High-Z */ +#define SDA_VAL ((PINE & 0x08) ? 1 : 0) /* SDA input level */ + + + +/*-------------------------------------------------*/ +/* I2C bus protocol */ + + +static +void iic_delay (void) +{ + int n; + + for (n = 4; n; n--) PINB; +} + + +/* Generate start condition on the IIC bus */ +static +void iic_start (void) +{ + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_LOW(); + iic_delay(); + SCL_LOW(); + iic_delay(); +} + + +/* Generate stop condition on the IIC bus */ +static +void iic_stop (void) +{ + SDA_LOW(); + iic_delay(); + SCL_HIGH(); + iic_delay(); + SDA_HIGH(); + iic_delay(); +} + + +/* Send a byte to the IIC bus */ +static +int iic_send (BYTE dat) +{ + BYTE b = 0x80; + int ack; + + + do { + if (dat & b) { /* SDA = Z/L */ + SDA_HIGH(); + } else { + SDA_LOW(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (b >>= 1); + SDA_HIGH(); + iic_delay(); + SCL_HIGH(); + ack = SDA_VAL ? 0 : 1; /* Sample ACK */ + iic_delay(); + SCL_LOW(); + iic_delay(); + return ack; +} + + +/* Receive a byte from the IIC bus */ +static +BYTE iic_rcvr (int ack) +{ + UINT d = 1; + + + do { + d <<= 1; + SCL_HIGH(); + if (SDA_VAL) d++; + iic_delay(); + SCL_LOW(); + iic_delay(); + } while (d < 0x100); + if (ack) { /* SDA = ACK */ + SDA_LOW(); + } else { + SDA_HIGH(); + } + iic_delay(); + SCL_HIGH(); + iic_delay(); + SCL_LOW(); + SDA_HIGH(); + iic_delay(); + + return (BYTE)d; +} + + + +/*-------------------------------------------------*/ +/* I2C block read/write controls */ + + +int iic_read ( + BYTE dev, /* Device address */ + UINT adr, /* Read start address */ + UINT cnt, /* Read byte count */ + void* buff /* Read data buffer */ +) +{ + BYTE *rbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + iic_start(); /* Reselect device in read mode */ + if (iic_send(dev | 1)) { + do { /* Receive data */ + cnt--; + *rbuff++ = iic_rcvr(cnt ? 1 : 0); + } while (cnt); + } + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +int iic_write ( + BYTE dev, /* Device address */ + UINT adr, /* Write start address */ + UINT cnt, /* Write byte count */ + const void* buff /* Data to be written */ +) +{ + const BYTE *wbuff = buff; + int n; + + + if (!cnt) return 0; + + n = 10; + do { /* Select device */ + iic_start(); + } while (!iic_send(dev) && --n); + if (n) { + if (iic_send((BYTE)adr)) { /* Set start address */ + do { /* Send data */ + if (!iic_send(*wbuff++)) break; + } while (--cnt); + } + } + + iic_stop(); /* Deselect device */ + + return cnt ? 0 : 1; +} + + + +/*-------------------------------------------------*/ +/* RTC functions */ + + +int rtc_gettime (RTC *rtc) +{ + BYTE buf[8]; + + + if (!iic_read(0xD0, 0, 7, buf)) return 0; + + rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10; + rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10; + rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10; + rtc->wday = (buf[2] & 0x07); + rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10; + rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10; + rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10; + + return 1; +} + + + + +int rtc_settime (const RTC *rtc) +{ + + BYTE buf[8]; + + + buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10; + buf[1] = rtc->min / 10 * 16 + rtc->min % 10; + buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10; + buf[3] = rtc->wday & 7; + buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10; + buf[5] = rtc->month / 10 * 16 + rtc->month % 10; + buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10; + return iic_write(0xD0, 0, 7, buf); +} + + + + +int rtc_init (void) +{ + BYTE buf[8]; /* RTC R/W buffer */ + UINT adr; + + + /* Read RTC registers */ + if (!iic_read(0xD0, 0, 8, buf)) return 0; /* IIC error */ + + if (buf[7] & 0x20) { /* When data has been volatiled, set default time */ + /* Clear nv-ram. Reg[8..63] */ + memset(buf, 0, 8); + for (adr = 8; adr < 64; adr += 8) + iic_write(0x0D, adr, 8, buf); + /* Reset time to Jan 1, '08. Reg[0..7] */ + buf[4] = 1; buf[5] = 1; buf[6] = 8; + iic_write(0x0D, 0, 8, buf); + } + return 1; +} + diff --git a/Projects/DidacticSystem/_templMainController/rtc.h b/Projects/DidacticSystem/_templMainController/rtc.h new file mode 100644 index 0000000..4642685 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/rtc.h @@ -0,0 +1,19 @@ +#include "integer.h" + +typedef struct { + WORD year; /* 2000..2099 */ + BYTE month; /* 1..12 */ + BYTE mday; /* 1.. 31 */ + BYTE wday; /* 1..7 */ + BYTE hour; /* 0..23 */ + BYTE min; /* 0..59 */ + BYTE sec; /* 0..59 */ +} RTC; + +int iic_write (BYTE, UINT, UINT, const void*); /* Write to IIC device */ +int iic_read (BYTE, UINT, UINT, void*); /* Read from IIC device */ + +int rtc_init (void); /* Initialize RTC */ +int rtc_gettime (RTC*); /* Get time */ +int rtc_settime (const RTC*); /* Set time */ + diff --git a/Projects/DidacticSystem/_templMainController/sensors_task.c b/Projects/DidacticSystem/_templMainController/sensors_task.c new file mode 100644 index 0000000..fced070 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/sensors_task.c @@ -0,0 +1,81 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include +#include +#include "sensors_task.h" +#include "memory_x.h" +#include "main.h" +#include "Rs485_prot.h" +#include "protocol1.h" +#include "mpc23s17.h" + + + +void sensorsTaskInit(void) +{ + LockersMemInit(); + rollersMemInit(); +} + +void sensorsTask(void* pvParameters) +{ + pvParameters = NULL; + uint8_t addr = 255; +// uint8_t i; + + MPC23s17SetDirA(0x00, 0); + + MPC23s17SetDirB(0x00, 0); + + for( ; ; ) + { + uint16_t tmp; + //Read power suply voltage + tmp = MCP3008_getSampleSingle(0); + voltage = (uint8_t)(tmp>>5); + vTaskDelay(10); + + //Read temperature inside chasis + tmp = MCP3008_getSampleSingle(1); + tmp *=10; + temperature = (uint8_t)(tmp / 24); + vTaskDelay(10); + + //read lock + checkLockerSensors(); + + for (addr = FIRST_ROLLER_DRIVER_ADDR; addr <= LAST_ROLLER_DRIVER_ADDR; addr++) + { + rs485rollerHello(addr); + vTaskDelay(10); + } + + for (addr = FIRST_LIGHT_DRIVER_ADDR; addr <= LAST_LIGHT_DRIVER_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + + for (addr = FIRST_SENSOR_ADDR; addr <= LAST_SENSOR_ADDR; addr++) + { + ; + //vTaskDelay(10); + } + } +} diff --git a/Projects/DidacticSystem/_templMainController/sensors_task.h b/Projects/DidacticSystem/_templMainController/sensors_task.h new file mode 100644 index 0000000..05b0780 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/sensors_task.h @@ -0,0 +1,51 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * Ethernet remote device and sensor + * UDP and HTTP interface + url looks like this http://baseurl/password/command + or http://baseurl/password/ + * + * Chip type : Atmega88 or Atmega168 or Atmega328 with ENC28J60 + * Note: there is a version number in the text. Search for tuxgraphics + *********************************************/ +#include +#include +#include +#include + +#include "main.h" +#include "memory_x.h" +#include "Rs485_prot.h" + +#ifndef SENSORS_TASK_H +#define SENSORS_TASK_H + + + + +#define NOT_DETECTED 0x01 +#define BOOTLOADER_MODE 0x02 +#define NEW_STATE 0x04 +#define RESERVED 0x08 +#define ROLLER1_UP 0x10 +#define ROLLER1_DOWN 0x20 +#define ROLLER2_UP 0x40 +#define ROLLER2_DOWN 0x80 + + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + + + + +void sensorsTaskInit(void); + +void sensorsTask(void *pvParameters); + +#endif diff --git a/Projects/DidacticSystem/_templMainController/serial.c b/Projects/DidacticSystem/_templMainController/serial.c new file mode 100644 index 0000000..3066726 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/serial.c @@ -0,0 +1,186 @@ +#include +#include +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" +#include "serial.h" +#include "hardware.h" + +#define debug 1 + +/*-----------------------------------------------------------*/ + +void initQueueStreamUSB(FILE *stream) +{ + fdev_setup_stream(stream, VtyPutChar, VtyGetChar, _FDEV_SETUP_RW); + fdev_set_udata(stream, NULL); + return; +} + +int VtyGetChar(FILE *stream) +{ + stream = NULL; + uint8_t c; + if (xQueueReceive(xVtyRec, &c, portMAX_DELAY) == 0) + return EOF; + return c; +} + +int VtyPutChar(char c, FILE *stream) +{ + stream = NULL; + uartVtySendByte(c); + return 0; +} + +void xSerialPortInitMinimal(void) +{ + portENTER_CRITICAL(); + { + xVtyRec = xQueueCreate(64, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xVtyTx = xQueueCreate(32, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR )); + xRs485Rec = xQueueCreate( 16, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + xRs485Tx = xQueueCreate( 4, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); + + vSemaphoreCreateBinary(xSemaphoreRs485); + } + portEXIT_CRITICAL(); + + UBRR0L = 7; + UBRR0H = 0; + + UBRR1L = 7; + UBRR1H = 0; + + UCSR0B = ((1< + +/* ************ Debug options ***************************************** */ +#define UDP_DEBUG 1 +#define IP_DEBUG 1 +#define ARP_DEBUG 1 +#define ICMP_DEBUG 1 +#define TCP_DEBUG 1 + +/* Only one language can be available */ +#define LANG_EN 1 +#define LANG_PL 0 + + +#define MAX_NUMBER_OF_ROLLERS 10 + + +/* maximum number of TCP connections */ +#define NUMBER_OF_SOCKETS 20 + +/* CLI */ +#define CMD_STATE_HISTORY 4 +#define CMD_STATE_HISTORY_MASK 0x03 + + +/* Telnet */ +#define MYTELNETPOERT 25000 + + +uint8_t wwwport; // 80 is just a default value. Gets overwritten during init +//int16_t info_hdr_len=0; +//int16_t info_data_len=0; + + +#define SEQNUM 0xFA000000; // my initial tcp sequence number + +#define ARP_TABLE_SIZE 10 +#define ARP_CACHE_TIME_TO_LIVE 128 + + +#define MYWWWPORT 80 +#define MYTELNETPORT 23 +#define MYUDPPORT 1200 + +#define MY_IP1 192 +#define MY_IP2 168 +#define MY_IP3 0 +#define MY_IP4 2 + +#define MY_GW1 192 +#define MY_GW2 168 +#define MY_GW3 0 +#define MY_GW4 1 + +#define MY_MASK1 255 +#define MY_MASK2 255 +#define MY_MASK3 255 +#define MY_MASK4 0 + +#define UDP_SRC_PORT 3000 +#define UDP_DST_PORT 0 + +#define UDP_DST_IP1 192 +#define UDP_DST_IP2 168 +#define UDP_DST_IP3 0 +#define UDP_DST_IP4 1 + +//#define NUMBER_OF_UDP_SOCK + +#endif diff --git a/Projects/DidacticSystem/_templMainController/vty.c b/Projects/DidacticSystem/_templMainController/vty.c new file mode 100644 index 0000000..1e30748 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/vty.c @@ -0,0 +1,944 @@ +#include "main.h" +#include "vty.h" +#include "ramdysk.h" +#include "protocol1.h" +#include "mpc23s17.h" +#include "mcp3008.h" +#include "ds1305.h" +#include "hardwareConfig.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "net.h" +#include "ip.h" +#include "arp.h" +#include "softwareConfig.h" + +#if LANG_EN +#include "vty_en.h" +#endif + +#if LANG_PL +#include "vty_pl.h" +#endif + +#ifndef LANG_VTY +#error "Vty Language not defined" +#endif + + +static cliExRes_t helpFunction (cmdState_t *state); +static cliExRes_t statusFunction (cmdState_t *state); +static cliExRes_t statusEncFunction (cmdState_t *state); +static cliExRes_t curtainDownFunction (cmdState_t *state); +static cliExRes_t curtainUpFunction (cmdState_t *state); +static cliExRes_t rpingFunction (cmdState_t *state); +static cliExRes_t pingFunction (cmdState_t *state); +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state); +static cliExRes_t goXmodemWyslijFunction (cmdState_t *state); +static cliExRes_t dodajRamPlikFunction (cmdState_t *state); +static cliExRes_t eraseRamFileFunction (cmdState_t *state); +static cliExRes_t flashExModuleFunction (cmdState_t *state); +static cliExRes_t writeRamFileFunction (cmdState_t *state); +static cliExRes_t editRamFileFunction (cmdState_t *state); +static cliExRes_t readRamFIleFunction (cmdState_t *state); + +static cliExRes_t ustawPortExtAFunction (cmdState_t *state); +static cliExRes_t ustawPortExtBFunction (cmdState_t *state); + +static cliExRes_t pokazCzasFunction (cmdState_t *state); +static cliExRes_t debugFunction (cmdState_t *state); +static cliExRes_t czytajAC_Function (cmdState_t *state); + +static cliExRes_t enableFunction (cmdState_t *state); +static cliExRes_t disableFunction (cmdState_t *state); +static cliExRes_t configureModeFunction (cmdState_t *state); + +static cliExRes_t setIpFunction(cmdState_t *state); +static cliExRes_t setIpMaskFunction(cmdState_t *state); +static cliExRes_t setIpGwFunction(cmdState_t *state); +static cliExRes_t setUdpFunction(cmdState_t *state); + +static cliExRes_t setMacAddrFunction (cmdState_t *state); +static cliExRes_t setTimeFunction (cmdState_t *state); + +static cliExRes_t saveConfigFunction (cmdState_t *state); + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction (cmdState_t *state); +#endif + +struct ramPlikFd fdVty; //TODO move it to CLI struct + +prog_char okStr[] = "OK\r\n"; +prog_char nlStr[] = "\r\n"; +prog_char BladBuforaPozostaloBajtowStr[] = "!!! W budorze Rs485 pozostalo %d bajtow\r\n"; + + +prog_char __ATTR_PROGMEM__ *errorStrings[] = { + errorOK, + errorNoFile, + errorxModemFrameStartTimeout, + errorxModemByteSendTimeout, + errorxModemWrongFrameNo, + errorxModemFrameFrameNoCorrectionNotMatch, + errorxModemFrameCrc, + errorxModemRemoteSideCan, + errorxModemUnknownResponse, + errorNoRemoteDevice, + errorBootloaderNotResponding, + errorOpenFile +}; + +command_t __ATTR_PROGMEM__ cmdListNormal[] = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {NULL, NULL, NULL} +}; + +command_t __ATTR_PROGMEM__ cmdListEnable[] = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_enc_stat, cmd_help_enc_stat, statusEncFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_net_dbg, cmd_help_net_dbg, debugFunction}, + + {cmd_rping, cmd_help_rping, rpingFunction}, + {cmd_ping, cmd_help_ping, pingFunction}, + {cmd_xRec, cmd_help_xRec, goXmodemOdbierzFunction}, + {cmd_xSend, cmd_help_xSend, goXmodemWyslijFunction}, + {cmd_xflash, cmd_help_xflash, flashExModuleFunction}, +#ifdef testZewPamiec + {cmd_rtest, cmd_help_rtest, testPamZewFunction}, +#endif + {cmd_dir_rf, cmd_help_dir_rf, writeRamFileFunction}, + {cmd_create_rf, cmd_help_create_rf, dodajRamPlikFunction}, + {cmd_erase_rf, cmd_help_erase_rf, eraseRamFileFunction}, + {cmd_edit_rf, cmd_help_edit_rf, editRamFileFunction}, + {cmd_read_rf, cmd_help_read_rf, readRamFIleFunction}, + + {cmd_up, cmd_help_up, curtainUpFunction}, + {cmd_down, cmd_help_down, curtainDownFunction}, + + {cmd_spa, cmd_help_spa, ustawPortExtAFunction}, + {cmd_spb, cmd_help_spb, ustawPortExtBFunction}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_ac, cmd_help_ac, czytajAC_Function}, + {cmd_disable, cmd_help_disable, disableFunction}, + {cmd_configure, cmd_help_configure, configureModeFunction}, + {NULL, NULL, NULL} +}; + +command_t __ATTR_PROGMEM__ cmdListConfigure[] = +{ + {cmd_help, cmd_help_help, helpFunction}, + {cmd_status, cmd_help_status, statusFunction}, + {cmd_time, cmd_help_time, pokazCzasFunction}, + {cmd_settime, cmd_help_settime, setTimeFunction}, + {cmd_conf_ip, cmd_help_conf_ip, setIpFunction}, + {cmd_conf_ip_mask, cmd_conf_ip_mask_help, setIpMaskFunction}, + {cmd_conf_ip_gw, cmd_conf_ip_gw_help, setIpGwFunction}, + {cmd_conf_udp, cmd_help_conf_udp, setUdpFunction}, + {cmd_conf_mac, cmd_help_conf_mac, setMacAddrFunction}, + {cmd_conf_save, cmd_help_conf_save, saveConfigFunction}, + {cmd_enable, cmd_help_enable, enableFunction}, + {cmd_disable, cmd_help_disable, disableFunction}, + {NULL, NULL, NULL} +}; + +void VtyInit(cmdState_t* state, FILE *stream) +{ + cmdStateConfigure(state, (char *)(CLI_1_BUF_ADDR), CLI_BUF_TOT_LEN, stream, &cmdListNormal[0], NR_NORMAL); +} + +void printErrorInfo(cmdState_t *state) +{ + if (state->errno != 0) + { + fprintf_P(state->myStdInOut, (const char*)(pgm_read_word(errorStrings + state->errno)), state->err1, state->err2); + } + state->errno = 0; + state->err1 = 0; + state->err2 = 0; +} + +static cliExRes_t enableFunction(cmdState_t *state) +{ + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cmdList = cmdListEnable; + state->cliMode = NR_ENABLE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} +static cliExRes_t disableFunction(cmdState_t *state) +{ + state->cmdList = cmdListNormal; + if (state->cliMode != RESTRICTED_NORMAL) + { + state->cliMode = NR_NORMAL; + } + return OK_SILENT; +} +static cliExRes_t configureModeFunction(cmdState_t *state) +{ + if (state->cliMode == NR_ENABLE) + { + state->cmdList = cmdListConfigure; + state->cliMode = NR_CONFIGURE; + return OK_SILENT; + } + return ERROR_OPERATION_NOT_ALLOWED; +} + +// ************************** VTY API *************************************************************************************** +void printStatus(FILE *stream) +{ + fprintf_P(stream, PSTR(SYSTEM_NAME" ver "S_VERSION" build: "__DATE__", "__TIME__"\r\n")); + //Print system state + fprintf_P(stream, systemStateStr); + fprintf_P(stream, statusNumberOfTasksStr, uxTaskGetNumberOfTasks()); + fprintf_P(stream, statusStaticHeapStateStr, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE); + fprintf_P(stream, statusDynamicHeapStateStr, xmallocAvailable(), HEAP_SIZE); + fprintf_P(stream, statusTemperatureStr, temperature); + fprintf_P(stream, statusVoltageStr, voltage); + + uint8_t tmp = ramDyskLiczbaWolnychKlastrow(); + fprintf_P(stream, statusRamDiskStateStr, tmp, L_KLASTROW); +// printErrorInfo(state); //TODO fix and uncomment + + //Print system configuration + fprintf_P(stream, systemRamConfigStr); + + fprintf_P(stream, statusMacStr); + netPrintEthAddr(stream, &nicState.mac); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpStr); + netPrintIPAddr(stream, ipGetConfig()->ip); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpMaskStr); + netPrintIPAddr(stream, ipGetConfig()->netmask); + fprintf_P(stream, PSTR("\r\n")); + + fprintf_P(stream, statusIpGwStr); + netPrintIPAddr(stream, ipGetConfig()->gateway); + fprintf_P(stream, PSTR("\r\n")); + + //Print Rs485 Execitive modules + fprintf_P(stream, statusRs485listStr); + tmp = printRs485devices(stream); + if (tmp == 0) + fprintf_P(stream, statusNoRs485Dev); + + //Print locker sensors + fprintf_P(stream, statusLockerSensorsStr); + tmp = printLockers(stream); + if (tmp == 0) + fprintf_P(stream, statusLockerSensorsDisStr); + + //Print time FIXME deadlock problem +/* readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("%d:%d:%d\r\n"), godzina, minuta, sekunda);*/ + + udpPrintStatus(stream); +// arpPrintTable(stream); +} + + +// ************************** CLI Functions ********************************************************************************* + +static cliExRes_t statusFunction(cmdState_t *state) +{ + if (state->argc < 1) + { + printStatus(state->myStdInOut); + return OK_SILENT; + } + + FILE stream; + if (ramDyskOtworzPlikStdIo(cmdlineGetArgStr(1, state), &fdVty, &stream, __SWR | __SRD) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + printStatus(&stream); + ramDyskZamknijPlikStdIo(&stream); + return OK_SILENT; +} + +static cliExRes_t statusEncFunction(cmdState_t *state) +{ + nicRegDump(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t pokazCzasFunction(cmdState_t *state) +{ + readTimeDecoded((timeDecoded_t *)(&czasRtc)); + uint8_t godzina = 10*czasRtc.hours.syst24.cDzies + czasRtc.hours.syst24.cJedn; + uint8_t minuta = 10*czasRtc.minutes.cDzies + czasRtc.minutes.cJedn; + uint8_t sekunda = 10*czasRtc.seconds.cDzies + czasRtc.seconds.cJedn; + fprintf_P(state->myStdInOut, PSTR("Aktualny czas %d:%d:%d\r\n"), godzina, minuta, sekunda); + return OK_SILENT; +} + +static cliExRes_t debugFunction (cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t level = cmdlineGetArgInt(2, state); + const char *str = (const char*)cmdlineGetArgStr(1, state); + if (level == 0) + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(NULL, 0); + fprintf_P(state->myStdInOut, debugDisabledInfoStr, str); + return OK_SILENT; + } + + + } + else //level > 0 + { + if (strncmp_P(str, PSTR("arp"), 3) == 0) + { + setArpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("ip"), 2) == 0) + { + setIpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("icmp"), 2) == 0) + { + setIcmpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("tcp"), 2) == 0) + { + setTcpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + + if (strncmp_P(str, PSTR("udp"), 2) == 0) + { + setUdpDebug(state->myStdInOut, level); + fprintf_P(state->myStdInOut, debugEnabledInfoStr, str); + return OK_SILENT; + } + } + + return SYNTAX_ERROR; +} + + +static cliExRes_t setTimeFunction(cmdState_t *state) +{ + uint8_t godzina = cmdlineGetArgInt(1, state); + uint8_t minuta = cmdlineGetArgInt(2, state); + uint8_t sekunda = cmdlineGetArgInt(3, state); + + ds1305start(); + + uint8_t cDzies = godzina/10; + uint8_t cJedn = godzina - cDzies*10; + czasRtc.hours.syst24.cDzies = cDzies; + czasRtc.hours.syst24.cJedn = cJedn; + + cDzies = minuta/10; + cJedn = minuta - cDzies * 10; + czasRtc.minutes.cDzies = cDzies; + czasRtc.minutes.cJedn = cJedn; + + cDzies = sekunda/10; + cJedn = sekunda - cDzies * 10; + czasRtc.seconds.cDzies = cDzies; + czasRtc.seconds.cJedn = cJedn; + + setTimeDecoded((timeDecoded_t *)(&czasRtc)); + return OK_SILENT; +} + +static cliExRes_t setIpFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + + ipSetConfigIp(ip); + return OK_SILENT; +} + +static cliExRes_t setUdpFunction(cmdState_t *state) +{ + if (state->argc < 5) + return SYNTAX_ERROR; + + uint32_t ip = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + udpSocket->dstIp = ip; + + uint16_t port = cmdlineGetArgInt(5, state); + udpSocket->srcPort = htons(port); + + if (state->argc > 5) + { + port = cmdlineGetArgInt(6, state); + udpSocket->dstPort = htons(port); + } + return OK_SILENT; +} + + +static cliExRes_t setIpMaskFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint32_t mask = ((uint32_t)(0xFFFFFFFF))>>(32-cmdlineGetArgInt(1, state)); + + ipSetConfigMask(mask); + return OK_SILENT; +} + + +static cliExRes_t setIpGwFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint32_t gw = cmdlineGetArgInt(1, state) + + (((uint32_t)(cmdlineGetArgInt(2, state)))<< 8) + + (((uint32_t)(cmdlineGetArgInt(3, state)))<<16) + + (((uint32_t)(cmdlineGetArgInt(4, state)))<<24); + ipSetConfigGw(gw); + return OK_SILENT; +} + +static cliExRes_t setMacAddrFunction(cmdState_t *state) +{ + if (state->argc < 6) + return SYNTAX_ERROR; + + nicState.mac.addr[0] = cmdlineGetArgHex(1, state); + nicState.mac.addr[1] = cmdlineGetArgHex(2, state); + nicState.mac.addr[2] = cmdlineGetArgHex(3, state); + nicState.mac.addr[3] = cmdlineGetArgHex(4, state); + nicState.mac.addr[4] = cmdlineGetArgHex(5, state); + nicState.mac.addr[5] = cmdlineGetArgHex(6, state); + nicSetMacAddress(nicState.mac.addr); + return OK_SILENT; +} + +static cliExRes_t czytajAC_Function(cmdState_t *state) +{ + uint8_t nrWejscia = cmdlineGetArgInt(1, state); + uint16_t wynik = MCP3008_getSampleSingle(nrWejscia); + fprintf_P(state->myStdInOut, PSTR("Wartosc probki na wejsciu %d: %d\r\n"), nrWejscia, wynik); + return OK_SILENT; +} + +static cliExRes_t helpFunction(cmdState_t *state) +{ + cmdPrintHelp(state); + return OK_SILENT; +} + +static cliExRes_t curtainDownFunction(cmdState_t *state) +{ + uint8_t nrRolety; + uint8_t nrSterownika; + uint8_t wartosc; + + nrSterownika = cmdlineGetArgInt(1, state); + nrRolety = cmdlineGetArgInt(2, state); + nrRolety &= 0x01; + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut,movingCurtainDownStr, nrSterownika, nrRolety+1); + + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainDown(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t curtainUpFunction(cmdState_t *state) +{ + if (state->argc < 2) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (cmdlineGetArgInt(1, state) & 0x3F); + uint8_t nrRolety = (cmdlineGetArgInt(2, state) & 0x01); + uint8_t wartosc = 255; + if (state->argc > 2) + wartosc = cmdlineGetArgInt(3, state); + + fprintf_P(state->myStdInOut, movingCurtainUpStr, nrSterownika, nrRolety+1); + if ((wartosc > 0) && (wartosc <=100)) + fprintf_P(state->myStdInOut, movingCurtainPosStr, wartosc); + + uint8_t result = rs485curtainUp(nrSterownika, nrRolety, wartosc); + + if (result == 0) + return OK_INFORM; + + return ERROR_SILENT; +} + +static cliExRes_t ustawPortExtAFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirA(0x00, 0); + MPC23s17SetPortA(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t ustawPortExtBFunction(cmdState_t *state) +{ + uint8_t wyjscie = cmdlineGetArgInt(1, state); + MPC23s17SetDirB(0x00, 0); + MPC23s17SetPortB(wyjscie, 0); + return OK_SILENT; +} + +static cliExRes_t rpingFunction(cmdState_t *state) +{ + if (state->argc < 1) + return SYNTAX_ERROR; + + uint8_t nrSterownika = (uint8_t)(cmdlineGetArgInt(1, state)); + if ((state->err2 = rs485ping(nrSterownika)) == 0) + return OK_INFORM; + + state->errno = noRemoteDevice; + state->err1 = nrSterownika; + printErrorInfo(state); + return OK_SILENT; +} + +static cliExRes_t pingFunction(cmdState_t *state) +{ + if (state->argc < 4) + return SYNTAX_ERROR; + + uint8_t ip[4]; + ip[0] = (uint8_t)(cmdlineGetArgInt(1, state)); + ip[1] = (uint8_t)(cmdlineGetArgInt(2, state)); + ip[2] = (uint8_t)(cmdlineGetArgInt(3, state)); + ip[3] = (uint8_t)(cmdlineGetArgInt(4, state)); + +// Ipv4Ping(*((uint32_t *)(ip))); + + return OK_SILENT; +} + + +static cliExRes_t flashExModuleFunction(cmdState_t *state) +{ + if (state->argc != 2) + return SYNTAX_ERROR; + + uint8_t nrUrzadzenia = cmdlineGetArgInt(1, state); + char *nazwaPliku = cmdlineGetArgStr(2, state); + uint8_t blad; + + // Sprawdzanie, czy moduł wykonawczy odpowiada + if (rs485ping(nrUrzadzenia) != 0) + { + state->errno = noRemoteDevice; + printErrorInfo(state); + return ERROR_INFORM; + } + + //Sprawdzanie, czy istnieje odpowiedni plik z firmware + if (ramDyskOtworzPlik(nazwaPliku, &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, nazwaPliku); + return ERROR_INFORM; + } + + blad = rs485xModemFlash(&fdVty, nrUrzadzenia, state->myStdInOut); + + ramDyskZamknijPlik(&fdVty); + + if (blad != 0) + return ERROR_INFORM; + + return OK_SILENT; +} + +static cliExRes_t goXmodemWyslijFunction(cmdState_t *state) // TODO add code in xModem +{ + fprintf_P(state->myStdInOut, xwyslijStartStr); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + return OK_SILENT; +} + +static cliExRes_t goXmodemOdbierzFunction(cmdState_t *state) //TODO move to xmodem +{ + fprintf_P(state->myStdInOut, PSTR("Xmodem: rozpoczynanie odbioru\r\n")); + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + + uint8_t i = 25; + + uint8_t temp1; +// uint8_t temp2; + + uint8_t c; + uint8_t liczbaProb; + uint8_t *zapPtr; + uint8_t *zapPtrKopia; + + uint16_t crcLokalne; + uint8_t nrBloku; + + uint8_t nrBlokuZdalny; + uint8_t nrBlokuZdalnyNeg; + + uint8_t crcHi; + uint8_t crcLo; + + state->err1=0; + state->err2=0; + liczbaProb = 20; + for ( ; ; ) + { + fputc('C' , state->myStdInOut); + while(!(UCSR1A & (1 << TXC1))); //Czekanie na opróżnienie bufora + + if(xQueueReceive(xVtyRec, &c, 100)) + if (c == SOH) + break; //Rozpoczynamy transmisje + + liczbaProb--; + if (liczbaProb == 0) + { + ramDyskZamknijPlik(&fdVty); + state->errno = (uint8_t)(AllOK); + return ERROR_INFORM; + } + } + + nrBloku = 1; + liczbaProb = 10; + + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + for ( ; ; ) + { + if (!xQueueReceive(xVtyRec, &nrBlokuZdalny, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (!xQueueReceive(xVtyRec, &nrBlokuZdalnyNeg, 1)) + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + + //1 Sprawdzanie, czy pasuje numer bloku z numerem bloku w usupełnieniu bitowym do 1 + c = 255-nrBlokuZdalnyNeg; + if (nrBlokuZdalny != c) + { + state->errno = (uint8_t)(xModemFrameFrameNoCorrectionNotMatch); + state->err1 = nrBlokuZdalny; + state->err2 = nrBlokuZdalnyNeg; + break; + } + + //Sprawdzenie, czy nie jest wznowiona transmisja poprzedniego bloku lub nie zaczęła się od bloku 0 + c = nrBloku-1; + if (nrBlokuZdalny == c) + { + nrBloku = c; //Cofnięcie nr aktualnego bloku o 1 + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + } + + //2 Sprawdzanie, czy pasuje numer bloku + if (nrBlokuZdalny != nrBloku) + { + state->errno = (uint8_t)(xModemWrongFrameNo); + state->err1 = nrBlokuZdalnyNeg; + state->err2 = nrBloku; + break; + } + + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + { + if(xQueueReceive(xVtyRec, &c, 10)) + *(zapPtr++) = c; + else + { + state->errno = (uint8_t)(xModemByteSendTimeout); + break; + } + } + if (!xQueueReceive(xVtyRec, &crcHi, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 2; + break; + } + if (!xQueueReceive(xVtyRec, &crcLo, 10)) + { + state->errno = (uint8_t)(xModemFrameCrc); + state->err1 = 1; + break; + } + + //3 Zerowanie CRC + crcLokalne=0; + + //4 Obliczanie CRC + for (i=0; i < XMODEM_BUFFER_SIZE; i++) + crcLokalne = _crc_xmodem_update(crcLokalne, *(zapPtrKopia++)); + + //5 Srawdzanie CRC + if ((crcHi == crcLokalne / 256) && (crcLo == crcLokalne % 256)) + { + liczbaProb = 10; + uartVtySendByte(ACK); + } + else + { + liczbaProb--; + nrBloku--; + uartVtySendByte(NAK); + } + + if (liczbaProb == 0) + { + state->err1 = nrBlokuZdalny; + state->err2 = nrBloku; + state->errno = (uint8_t)(xModemWrongFrameNo); + break; + } + + if (!xQueueReceive(xVtyRec, &temp1, 100)) + { + state->errno = (uint8_t)(xModemFrameStartTimeout); + break; + } + + if (temp1 == SOH) + { + nrBloku++; + zapPtr = ramDyskDodajBlokXmodem(&fdVty, nrBloku); + zapPtrKopia = zapPtr; + state->errno = (uint8_t)(AllOK); + continue; + } + + if (temp1 == CAN) + { + state->err1 = nrBloku; + state->errno = (uint8_t)(xModemRemoteSideCan); + break; + } + if (temp1 == EOT) + { + uartVtySendByte(NAK); + if (xQueueReceive(xVtyRec, &temp1, 10)) + { + if (temp1 == EOT) + uartVtySendByte(ACK); + } + state->errno = (uint8_t)(AllOK); + break; + } + state->errno = (uint8_t)(xModemUnknownResponse); + state->err1 = temp1; + break; + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t eraseRamFileFunction(cmdState_t *state) +{ + if (ramDyskUsunPlik(cmdlineGetArgStr(1, state)) == 0) + return OK_INFORM; + + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t dodajRamPlikFunction(cmdState_t *state) +{ + if (state->argc != 1) + return SYNTAX_ERROR; + + if (ramDyskUtworzPlik(cmdlineGetArgStr(1, state)) == 0) + { + return OK_INFORM; + } + printErrorInfo(state); + return ERROR_INFORM; +} + +static cliExRes_t writeRamFileFunction(cmdState_t *state) +{ + ramDyskDir(state->myStdInOut); + return OK_SILENT; +} + +static cliExRes_t editRamFileFunction(cmdState_t *state) +{ + if (ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + ramDyskUstawWskaznikNaKoniec(&fdVty); + uint8_t znak = 0; + fprintf_P(state->myStdInOut, editRamFileIntroStr); + while(1) + { + if(!xQueueReceive( xVtyRec, &znak, portMAX_DELAY)) + continue; + + if (znak == 0x03) // ^C + break; + + uartVtySendByte(znak); //Echo + ramDyskZapiszBajtDoPliku(&fdVty, znak); + } + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t readRamFIleFunction(cmdState_t *state) //TODO move this code to fat8 +{ + uint8_t rezultat; + uint8_t znak = ' '; + if ((rezultat = ramDyskOtworzPlik(cmdlineGetArgStr(1, state), &fdVty)) != 0) + { + fprintf_P(state->myStdInOut, errorOpenFile, cmdlineGetArgStr(1, state)); + return ERROR_INFORM; + } + uint16_t rozmiar = fdVty.wpis->rozmiarHi * 256 + fdVty.wpis->rozmiarLo; + fprintf_P(state->myStdInOut, readRamFIleLenStr , rozmiar); + while (rezultat == 0) + { + rezultat = ramDyskCzytajBajtZPliku(&fdVty, &znak); + + uartVtySendByte(znak); + if (znak == '\r') + uartVtySendByte('\n'); + } + fprintf_P(state->myStdInOut, nlStr); + ramDyskZamknijPlik(&fdVty); + return OK_SILENT; +} + +static cliExRes_t saveConfigFunction(cmdState_t *state) +{ + state = NULL; + saveConfiguration(); + return OK_SILENT; +} + +#ifdef testZewPamiec +static cliExRes_t testPamZewFunction(cmdState_t *state) +{ + state = NULL; + uint8_t *ptr; + ptr= 0x4000; + uint8_t tmp; + for (tmp=0; tmp <255; tmp++) + { + *(ptr) = tmp; + ptr++; + } + ptr= 0x4000; + uint8_t tmp2; + for (tmp=0; tmp <4; tmp++) + { + uartVtySendByte('\r'); + uartVtySendByte('\n'); + for (tmp2=0; tmp2<64; tmp2++) + { + uartVtySendByte(*(ptr)); + ptr++; + } + } + return OK_SILENT; +} +#endif + + diff --git a/Projects/DidacticSystem/_templMainController/vty.h b/Projects/DidacticSystem/_templMainController/vty.h new file mode 100644 index 0000000..e4251f4 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/vty.h @@ -0,0 +1,81 @@ +#ifndef VTY_H +#define VTY_H + +#include "main.h" +#include +#include +#include + +#include "ds1305.h" +#include "enc28j60.h" +#include "memory_x.h" +#include "configuration.h" +#include "Rs485_prot.h" +#include "sensors_task.h" +#include "nic.h" +#include "ip.h" +#include "net.h" +#include "arp.h" +#include "cmdline.h" +#include "udp.h" + + +// Znaki kontrolne w protokole Xmodem +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +// xmodem timeout/retry parameters +#define XMODEM_RETRY_LIMIT 16 + +// error return codes +#define XMODEM_ERROR_REMOTECANCEL 1 +#define XMODEM_ERROR_OUTOFSYNC 2 +#define XMODEM_ERROR_RETRYEXCEED 3 + +#define XMODEM_BUFFER_SIZE 128 + + +extern nicState_t nicState; +extern UdpSocket_t *udpSocket; + +void VtyInit(cmdState_t *state, FILE *stream); + +void printErrorInfo(cmdState_t *state); + +void printStatus(FILE *stream); + +extern volatile uint8_t temperature; +extern volatile uint8_t voltage; + +extern xQueueHandle xRs485Rec; +extern xQueueHandle xRs485Tx; + +extern volatile timeDecoded_t czasRtc; +extern struct Enc28j60_config Enc28j60_global; + +extern struct sterRolet *rollers; + +enum errorType +{ + AllOK = 0, + noFile = 1, + xModemFrameStartTimeout = 2, + xModemByteSendTimeout = 3, + xModemWrongFrameNo = 4, + xModemFrameFrameNoCorrectionNotMatch = 5, + xModemFrameCrc = 6, + xModemRemoteSideCan = 7, + xModemUnknownResponse = 8, + noRemoteDevice = 9, + bootloaderNotResponding = 10, + cantOpenFile = 11 +}; + +typedef enum errorType errorType_t; + +#endif diff --git a/Projects/DidacticSystem/_templMainController/vty_en.h b/Projects/DidacticSystem/_templMainController/vty_en.h new file mode 100644 index 0000000..9233259 --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/vty_en.h @@ -0,0 +1,91 @@ +#ifndef LANG_VTY +#define LANG_VTY EN + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "All OK\r\n"; +prog_char errorNoFile[] = "No File\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Remote side cancelled at frame no %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem unknown response 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Device %d is not responding (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader is not responding\r\n"; +prog_char errorOpenFile[] = "Can't open file %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "System state:\r\n"; +prog_char statusNumberOfTasksStr[] = " Number of tasks : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " FreeRtos heap : %d free of %d bytes\r\n"; +prog_char statusDynamicHeapStateStr[] = " Malloc heap : %d free of %d bytes\r\n"; +prog_char statusRamDiskStateStr[] = " Ram disc space : %d free of %d clusters\r\n"; +prog_char statusTemperatureStr[] = " Temperature : %d C\r\n"; +prog_char statusVoltageStr[] = " Voltage : %d V\r\n"; +prog_char systemRamConfigStr[] = "System settings:\r\n"; +prog_char statusMacStr[] = " Mac address : "; +prog_char statusIpStr[] = " IP address : "; +prog_char statusIpMaskStr[] = " mask : "; +prog_char statusIpGwStr[] = " gateway : "; + +prog_char statusRs485listStr[] = "Detected RS 485 devices:\r\n"; +prog_char statusNoRs485Dev[] = " Can't find any device\r\n"; + +prog_char statusLockerSensorsStr[] = "Locker sensors states:\r\n"; +prog_char statusLockerSensorsDisStr[] = " Locker sensors disabled\r\n"; + +prog_char editRamFileIntroStr[] = "Writing to file. Press CTRL+C to quit\r\n"; +prog_char readRamFIleLenStr[] = "File length: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: Transmission start\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Enabled %s debug\r\n"; +prog_char debugDisabledInfoStr[] = "Disabled %s debug\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "help"; prog_char cmd_help_help[] = "Print help string"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{filename} Print device status on VTY or write to file"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Print Enc 28j60 registers"; +prog_char cmd_time[] = "time"; prog_char cmd_help_time[] = "Print time"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[arp|icmp|ip|tcp|udp] [level] write debug info. Level 0 disable debuging"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[Device no] Send ping to Rs485 device"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Sends ping throught ethernet"; +prog_char cmd_xRec[] = "xrec"; prog_char cmd_help_xRec[] = "[file name] receive file using xModem"; +prog_char cmd_xSend[] = "xsend"; prog_char cmd_help_xSend[] = "[file name] send file using xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[device no] [file name] flash device connected to Rs485"; +#ifdef testZewPamiec +prog_char cmd_rtest[] = "rtest"; prog_char cmd_help_rtest[] = "External ram test"; +#endif +prog_char cmd_dir_rf[] = "dirrf"; prog_char cmd_help_dir_rf[] = "Print ramdisk files"; +prog_char cmd_create_rf[] = "crf"; prog_char cmd_help_create_rf[] = "[file name] create ram file"; +prog_char cmd_erase_rf[] = "eraserf"; prog_char cmd_help_erase_rf[] = "[file name] erase file from ram disk"; +prog_char cmd_edit_rf[] = "editrf"; prog_char cmd_help_edit_rf[] = "[file name] edit file located on ram disk"; +prog_char cmd_read_rf[] = "readrf"; prog_char cmd_help_read_rf[] = "[file name] read file located on ram disk"; + +prog_char cmd_up[] = "up"; prog_char cmd_help_up[] = "[driver no] [channel] {value} move up"; +prog_char cmd_down[] = "down"; prog_char cmd_help_down[] = "[driver no] [channel] {value} move down"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[value] set port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[value] set port B"; + +prog_char cmd_settime[] = "settime"; prog_char cmd_help_settime[] = "[h] [m] [s] set time (24h format)"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[channel 0-7] read analog value"; +prog_char cmd_enable[] = "enable"; prog_char cmd_help_enable[] = "Enable mode"; +prog_char cmd_disable[] = "disable"; prog_char cmd_help_disable[] = "View mode"; +prog_char cmd_configure[] = "config"; prog_char cmd_help_configure[] = "Configure mode"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A3] [A4] set IP address"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} set udp client IP address and ports"; +prog_char cmd_conf_ip_mask[]= "mask"; prog_char cmd_conf_ip_mask_help[]= "[mask] set mask"; +prog_char cmd_conf_ip_gw[] = "gw"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] set default gateway"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] set MAC address"; +prog_char cmd_conf_save[] = "save"; prog_char cmd_help_conf_save[] = "Save configuration"; + +#endif \ No newline at end of file diff --git a/Projects/DidacticSystem/_templMainController/vty_pl.h b/Projects/DidacticSystem/_templMainController/vty_pl.h new file mode 100644 index 0000000..7550a2a --- /dev/null +++ b/Projects/DidacticSystem/_templMainController/vty_pl.h @@ -0,0 +1,92 @@ +#ifndef LANG_VTY +#define LANG_VTY PL + +// *************************** Error Strings ******************************************************* + +prog_char errorOK[] = "Wszystko poprawnie\r\n"; +prog_char errorNoFile[] = "Brak pliku\r\n"; +prog_char errorxModemFrameStartTimeout[] = "\r\n"; +prog_char errorxModemByteSendTimeout[] = "\r\n"; +prog_char errorxModemWrongFrameNo[] = "\r\n"; +prog_char errorxModemFrameFrameNoCorrectionNotMatch[] = "\r\n"; +prog_char errorxModemFrameCrc[] = "xModem CRC error\r\n"; +prog_char errorxModemRemoteSideCan[] = "Strona zdalna przerwala transmisje na ramce nr %d\r\n"; +prog_char errorxModemUnknownResponse[] = "xModem nieznana odpowiedx 0x%x\r\n"; +prog_char errorNoRemoteDevice[] = "Urządzenie %d nie odpowiada (%d)\r\n"; +prog_char errorBootloaderNotResponding[] = "Bootloader nie odpowiada\r\n"; +prog_char errorOpenFile[] = "Nie mozna otworzyc pliku %s\r\n"; + +// *************************** Message Strings ***************************************************** + +prog_char systemStateStr[] = "Stan systemu:\r\n"; +prog_char statusNumberOfTasksStr[] = " Liczba zadan : %d\r\n"; +prog_char statusStaticHeapStateStr[] = " Sterta dla FreeRtos : %d wolnych z %d bajtow\r\n"; +prog_char statusDynamicHeapStateStr[] = " Sterta dla malloc : %d wolnych z %d bajtow\r\n"; +prog_char statusRamDiskStateStr[] = " Ram dysk : %d wolnych z %d klastrow\r\n"; +prog_char statusTemperatureStr[] = " Temperatura : %d C\r\n"; +prog_char statusVoltageStr[] = " Napiecie : %d V\r\n"; +prog_char systemRamConfigStr[] = "Ustawienia systemu:\r\n"; +prog_char statusMacStr[] = " Adres MAC : "; +prog_char statusIpStr[] = " IP adres : "; +prog_char statusIpMaskStr[] = " maska : "; +prog_char statusIpGwStr[] = " brama : "; + +prog_char statusRs485listStr[] = "Wykryte urzadzenia na magistrali RS 485:\r\n"; +prog_char statusNoRs485Dev[] = " Nie moge znale ani jednego urzadzenia\r\n"; + +prog_char statusLockerSensorsStr[] = "Stan czujników rygli:\r\n"; +prog_char statusLockerSensorsDisStr[] = " Czujniki rygli wyłączone\r\n"; + +prog_char editRamFileIntroStr[] = "Zapis do pliku. CTRL+C koniec\r\n"; +prog_char readRamFIleLenStr[] = "Dlugosc pliku: %d\r\n"; + +prog_char xwyslijStartStr[] = "Xmodem: rozpoczynanie wysylania\r\n"; + +prog_char movingCurtainUpStr[] = "Podnoszenie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainDownStr[] = "Opuszczanie rolety\r\n\tsterownik %d\r\n\troleta %d\r\n"; +prog_char movingCurtainPosStr[] = "\tpozycja %d\r\n"; + +prog_char debugEnabledInfoStr[] = "Wlaczono debugowanie %s\r\n"; +prog_char debugDisabledInfoStr[] = "Wylaczono debugowanie %s\r\n"; + +// *************************** Command Strings ***************************************************** + +prog_char cmd_help[] = "pomoc"; prog_char cmd_help_help[] = "Wypisuje wszystkie komendy"; +prog_char cmd_status[] = "status"; prog_char cmd_help_status[] = "{nazwa pliku} Wypisuje status urzadzenia na ekranie lub zapisuje do pliku"; +prog_char cmd_enc_stat[] = "encstat"; prog_char cmd_help_enc_stat[] = "Wypisz rejestry Enc 28j60"; +prog_char cmd_time[] = "czas"; prog_char cmd_help_time[] = "Wypisuje czas"; +prog_char cmd_net_dbg[] = "debug"; prog_char cmd_help_net_dbg[] = "[arp|icmp|ip|tcp|udp] [poziom] wypisywanie komunikatow. Poziom 0 wylacza komunikaty"; + +prog_char cmd_rping[] = "rping"; prog_char cmd_help_rping[] = "[numer sterownika] Wysyla ping do sterownika podpietego do magistrali Rs485"; +prog_char cmd_ping[] = "ping"; prog_char cmd_help_ping[] = "[A1] [A2] [A3] [A4] Wysyla ping przez ethernet"; +prog_char cmd_xRec[] = "xodb"; prog_char cmd_help_xRec[] = "[nazwa pliku] odbiera plik za pomoca protokolu xModem"; +prog_char cmd_xSend[] = "xwyslij"; prog_char cmd_help_xSend[] = "[nazwa pliku] wysyla plik za pomoca protokolu xModem"; +prog_char cmd_xflash[] = "xflash"; prog_char cmd_help_xflash[] = "[numer urzadzenia] [nazwa pliku] wgrywa firmware do urzadzenia podpietego do Rs485"; +#ifdef testZewPamiec +prog_char cmd_rtest[] = "rtest"; prog_char cmd_help_rtest[] = "Test pamieci zewnetrznej"; +#endif +prog_char cmd_dir_rf[] = "dirrp" ; prog_char cmd_help_dir_rf[] = "Wypisuje nazwy plikow zapisanych w pamieci RAM"; +prog_char cmd_create_rf[] = "utwrp"; prog_char cmd_help_create_rf[] = "[nazwa pliku] Tworzy plik w pamieci RAM"; +prog_char cmd_erase_rf[] = "kasrp"; prog_char cmd_help_erase_rf[] = "[nazwa pliku] Usuwa plik z pamieci RAM"; +prog_char cmd_edit_rf[] = "dopiszrp"; prog_char cmd_help_edit_rf[] = "[nazwa pliku] Dopisuje do pliku zapisanego w pamieci ram"; +prog_char cmd_read_rf[] = "czytrp"; prog_char cmd_help_read_rf[] = "[nazwa pliku] Wypisuje zawartosc pliku"; + +prog_char cmd_up[] = "podnies"; prog_char cmd_help_up[] = "[numer sterownika] [nr rolety] {wartosc} podnoszenie rolety"; +prog_char cmd_down[] = "opusc"; prog_char cmd_help_down[] = "[numer sterownika] [nr rolety] {wartosc} opuszczanie rolety"; +prog_char cmd_spa[] = "spa"; prog_char cmd_help_spa[] = "[wartosc] ustaw zewnetrzny port A"; +prog_char cmd_spb[] = "spb"; prog_char cmd_help_spb[] = "[wartosc] ustaw zewnetrzny port B"; + +prog_char cmd_settime[] = "ustawcz"; prog_char cmd_help_settime[] = "[h] [m] [s] ustawia czas w formacie 24h format"; +prog_char cmd_ac[] = "ac"; prog_char cmd_help_ac[] = "[wejscie 0-7] czyta analogowa wartosc na wejsciu przetwornika"; +prog_char cmd_enable[] = "admin"; prog_char cmd_help_enable[] = "Wejscie w tryb uprzywilejowany"; +prog_char cmd_disable[] = "normalny"; prog_char cmd_help_disable[] = "Wyjscie z trybu uprzywilejowanego"; +prog_char cmd_configure[] = "konfig"; prog_char cmd_help_configure[] = "Wejscie w tryb konfiguracji"; +prog_char cmd_conf_ip[] = "ip"; prog_char cmd_help_conf_ip[] = "[A1] [A2] [A2] [A3] ustaw adres IP"; +prog_char cmd_conf_udp[] = "udp"; prog_char cmd_help_conf_udp[] = "[A1] [A2] [A3] [A4] [src port] {dst port} ustaw adres klienta udp oraz porty"; +prog_char cmd_conf_ip_mask[]= "maska"; prog_char cmd_conf_ip_mask_help[]= "[maska] ustaw maske adresu IP"; +prog_char cmd_conf_ip_gw[] = "brama"; prog_char cmd_conf_ip_gw_help[] = "[A1] [A2] [A3] [A4] ustaw domyslna brame"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] set MAC address"; +prog_char cmd_conf_mac[] = "mac"; prog_char cmd_help_conf_mac[] = "[A1] [A2] [A3] [A4] [A5] [A6] ustaw adres MAC"; +prog_char cmd_conf_save[] = "zapisz"; prog_char cmd_help_conf_save[] = "Zapisz konfiguracje"; + +#endif diff --git a/README.md b/README.md index f584798..0ebe8f8 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# FreeRtosOnAvr \ No newline at end of file +# FreeRtosOnAvr + +An alternative for arduino. Multitasking firmware provides great flexibility. diff --git a/Tools/avrMultiTool/Stk500/Makefile b/Tools/avrMultiTool/Stk500/Makefile new file mode 100644 index 0000000..69da96b --- /dev/null +++ b/Tools/avrMultiTool/Stk500/Makefile @@ -0,0 +1,78 @@ +# makefile, written by guido socher +MCU=atmega8 +CC=avr-gcc +OBJCOPY=avr-objcopy +# optimize for size: +CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues + +TARGET = avrusb500 + +# Programming support using avrdude. +AVRDUDE = avrdude +AVRDUDE_PROGRAMMER = stk500v2 +AVRDUDE_PORT = /dev/avrStk500v2prog # Stk500v2 on dedicated PCB +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_FLASH_PRE = -U flash:w:avrusb500_pre.hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + +#------------------- +all: avrusb500.hex test_1.hex test_2.hex ttydevinit1152 +#------------------- +help: + @echo "Usage: make help" + @echo " Print this help" + @echo " " + @echo "Usage: make all|program|program_pre" + @echo " " + @echo "Usage: make clean" + @echo " delete all generated files except the pre-compiled ones" +#------------------- +avrusb500.hex : avrusb500.out + $(OBJCOPY) -R .eeprom -O ihex avrusb500.out avrusb500.hex + avr-size avrusb500.out + @echo " " + @echo "Expl.: data=initialized data, bss=uninitialized data, text=code" + @echo " " +avrusb500.out : main.o uart.o spi.o timeout.o + $(CC) $(CFLAGS) -o avrusb500.out -Wl,-Map,avrusb500.map main.o uart.o spi.o timeout.o +main.o : main.c led.h avr_compat.h command.h spi.h uart.h timeout.h + $(CC) $(CFLAGS) -Os -c main.c +#------------------- +timeout.o : timeout.c timeout.h avr_compat.h + $(CC) $(CFLAGS) -Os -c timeout.c +#------------------- +spi.o : spi.c spi.h avr_compat.h timeout.h + $(CC) $(CFLAGS) -Os -c spi.c +#------------------- +uart.o : uart.c uart.h avr_compat.h timeout.h + $(CC) $(CFLAGS) -Os -c uart.c +#------------------- +# avrdude is better than uisp because it can verify the eeprom: +program_pre: avrusb500.hex + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH_PRE) -U lfuse:w:0xff:m -U hfuse:w:0xd9:m + + +# Program the device. +program: $(TARGET).hex + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) -U lfuse:w:0xff:m -U hfuse:w:0xd9:m + +#------------------- +clean: + rm -f *.o *.map *.out test_2.hex avrusb500.hex +#------------------- diff --git a/Tools/avrMultiTool/Stk500/avr_compat.h b/Tools/avrMultiTool/Stk500/avr_compat.h new file mode 100644 index 0000000..c667ccb --- /dev/null +++ b/Tools/avrMultiTool/Stk500/avr_compat.h @@ -0,0 +1,57 @@ +/* vim: set sw=8 ts=8 si et: */ +/**************************************************************************** +* Title : compatibility module for forward compatibility with + newer ARV C compiler which does not have older + macros +* Authors: Guido Socher +* Copyright: GPL +* +* +*****************************************************************************/ +#ifndef AVR_COMPAT_H +#define AVR_COMPAT_H + + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#ifndef inb +#define inb(sfr) _SFR_BYTE(sfr) +#endif + +#ifndef outb +#define outb(sfr, val) (_SFR_BYTE(sfr) = (val)) +#endif + +#ifndef inw +#define inw(sfr) _SFR_WORD(sfr) +#endif + +#ifndef outw +#define outw(sfr, val) ( _SFR_WORD(sfr) = (val)) +#endif + +#ifndef outp +#define outp(val, sfr) outb(sfr, val) +#endif + +#ifndef inp +#define inp(sfr) inb(sfr) +#endif + +#ifndef BV +#define BV(bit) _BV(bit) +#endif + +/* compatibility macro for libc 1.0 to 1.2 */ +#ifndef PRG_RDB +#define PRG_RDB(addr) pgm_read_byte(addr) +#endif + +#endif //AVR_COMPAT_H + diff --git a/Tools/avrMultiTool/Stk500/command.h b/Tools/avrMultiTool/Stk500/command.h new file mode 100644 index 0000000..2802185 --- /dev/null +++ b/Tools/avrMultiTool/Stk500/command.h @@ -0,0 +1,117 @@ +// This is the original command.h file available from the atmel +// website (file: AVR068.zip) +// +//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************ +//* +//* Title: AVR068 - STK500 Communication Protocol +//* Filename: command.h +//* Version: 1.0 +//* Last updated: 31.01.2005 +//* +//* Support E-mail: avr@atmel.com +//* +//************************************************************************** + +// *****************[ STK message constants ]*************************** + +#define MESSAGE_START 0x1B //= ESC = 27 decimal +#define TOKEN 0x0E + +// *****************[ STK general command constants ]************************** + +#define CMD_SIGN_ON 0x01 +#define CMD_SET_PARAMETER 0x02 +#define CMD_GET_PARAMETER 0x03 +#define CMD_SET_DEVICE_PARAMETERS 0x04 +#define CMD_OSCCAL 0x05 +#define CMD_LOAD_ADDRESS 0x06 +#define CMD_FIRMWARE_UPGRADE 0x07 + + +// *****************[ STK ISP command constants ]****************************** + +#define CMD_ENTER_PROGMODE_ISP 0x10 +#define CMD_LEAVE_PROGMODE_ISP 0x11 +#define CMD_CHIP_ERASE_ISP 0x12 +#define CMD_PROGRAM_FLASH_ISP 0x13 +#define CMD_READ_FLASH_ISP 0x14 +#define CMD_PROGRAM_EEPROM_ISP 0x15 +#define CMD_READ_EEPROM_ISP 0x16 +#define CMD_PROGRAM_FUSE_ISP 0x17 +#define CMD_READ_FUSE_ISP 0x18 +#define CMD_PROGRAM_LOCK_ISP 0x19 +#define CMD_READ_LOCK_ISP 0x1A +#define CMD_READ_SIGNATURE_ISP 0x1B +#define CMD_READ_OSCCAL_ISP 0x1C +#define CMD_SPI_MULTI 0x1D + +// *****************[ STK PP command constants ]******************************* + +#define CMD_ENTER_PROGMODE_PP 0x20 +#define CMD_LEAVE_PROGMODE_PP 0x21 +#define CMD_CHIP_ERASE_PP 0x22 +#define CMD_PROGRAM_FLASH_PP 0x23 +#define CMD_READ_FLASH_PP 0x24 +#define CMD_PROGRAM_EEPROM_PP 0x25 +#define CMD_READ_EEPROM_PP 0x26 +#define CMD_PROGRAM_FUSE_PP 0x27 +#define CMD_READ_FUSE_PP 0x28 +#define CMD_PROGRAM_LOCK_PP 0x29 +#define CMD_READ_LOCK_PP 0x2A +#define CMD_READ_SIGNATURE_PP 0x2B +#define CMD_READ_OSCCAL_PP 0x2C + +#define CMD_SET_CONTROL_STACK 0x2D + +// *****************[ STK HVSP command constants ]***************************** + +#define CMD_ENTER_PROGMODE_HVSP 0x30 +#define CMD_LEAVE_PROGMODE_HVSP 0x31 +#define CMD_CHIP_ERASE_HVSP 0x32 +#define CMD_PROGRAM_FLASH_HVSP 0x33 +#define CMD_READ_FLASH_HVSP 0x34 +#define CMD_PROGRAM_EEPROM_HVSP 0x35 +#define CMD_READ_EEPROM_HVSP 0x36 +#define CMD_PROGRAM_FUSE_HVSP 0x37 +#define CMD_READ_FUSE_HVSP 0x38 +#define CMD_PROGRAM_LOCK_HVSP 0x39 +#define CMD_READ_LOCK_HVSP 0x3A +#define CMD_READ_SIGNATURE_HVSP 0x3B +#define CMD_READ_OSCCAL_HVSP 0x3C + +// *****************[ STK status constants ]*************************** + +// Success +#define STATUS_CMD_OK 0x00 + +// Warnings +#define STATUS_CMD_TOUT 0x80 +#define STATUS_RDY_BSY_TOUT 0x81 +#define STATUS_SET_PARAM_MISSING 0x82 + +// Errors +#define STATUS_CMD_FAILED 0xC0 +#define STATUS_CKSUM_ERROR 0xC1 +#define STATUS_CMD_UNKNOWN 0xC9 + +// *****************[ STK parameter constants ]*************************** +#define PARAM_BUILD_NUMBER_LOW 0x80 +#define PARAM_BUILD_NUMBER_HIGH 0x81 +#define PARAM_HW_VER 0x90 +#define PARAM_SW_MAJOR 0x91 +#define PARAM_SW_MINOR 0x92 +#define PARAM_VTARGET 0x94 +#define PARAM_VADJUST 0x95 +#define PARAM_OSC_PSCALE 0x96 +#define PARAM_OSC_CMATCH 0x97 +#define PARAM_SCK_DURATION 0x98 +#define PARAM_TOPCARD_DETECT 0x9A +#define PARAM_STATUS 0x9C +#define PARAM_DATA 0x9D +#define PARAM_RESET_POLARITY 0x9E +#define PARAM_CONTROLLER_INIT 0x9F + +// *****************[ STK answer constants ]*************************** + +#define ANSWER_CKSUM_ERROR 0xB0 + diff --git a/Tools/avrMultiTool/Stk500/flash.sh b/Tools/avrMultiTool/Stk500/flash.sh new file mode 100755 index 0000000..2123d41 --- /dev/null +++ b/Tools/avrMultiTool/Stk500/flash.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ "$#" -ne 1 ]; +then + echo "usage: flash.sh SERIAL_PORT, e.g. flash.sh /dev/ttyUSB0" +else + echo "avrude -p atmega8 -P $1 -c stk500v2 -U lfuse:w:0xde:m -U hfuse:w:0xc9:m -U flash:w:avrusb500_pre.hex" + avrdude -p atmega8 -P $1 -c stk500v2 -U lfuse:w:0xde:m -U hfuse:w:0xc9:m -U flash:w:avrusb500_pre.hex +fi + diff --git a/Tools/avrMultiTool/Stk500/led.h b/Tools/avrMultiTool/Stk500/led.h new file mode 100644 index 0000000..1751b23 --- /dev/null +++ b/Tools/avrMultiTool/Stk500/led.h @@ -0,0 +1,13 @@ +/* vim: set sw=8 ts=8 si et: */ +#ifndef LED_H +#define LED_H +#include + +/* enable PC0 as output */ +#define LED_INIT DDRC|=_BV(PC0) +/* led on, pin=0 */ +#define LED_ON PORTC&=~_BV(PC0) +/* led off, pin=1 */ +#define LED_OFF PORTC|=_BV(PC0) + +#endif //LED_H diff --git a/Tools/avrMultiTool/Stk500/main.c b/Tools/avrMultiTool/Stk500/main.c new file mode 100644 index 0000000..8ee571d --- /dev/null +++ b/Tools/avrMultiTool/Stk500/main.c @@ -0,0 +1,839 @@ +/* vim: set sw=8 ts=8 si et: */ +/********************************************* +* An implemenation of the STK500 specification (appl. note AVR068) for atmega8 +* * Author: Guido Socher, Copyright: GPL +* +* Terminal capabilities for updating SW/HW version: +* Idea from Florin-Viorel Petrov, www.fonitzu.com/electronics, Date: 28Feb2006 +* Florin-Viorel's version was a bit more fancy than the version implemented +* here. This implemenation is just small and simple. +* +* Copyright: GPL +**********************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "uart.h" +#include "led.h" +#include "spi.h" +#include "avr_compat.h" +#include "command.h" +#include "timeout.h" + +// remember to change the "AvrUsb500-X.X terminal mode" version string towards the end +// of the program at version change. + +#define CONFIG_PARAM_BUILD_NUMBER_LOW 0 +#define CONFIG_PARAM_BUILD_NUMBER_HIGH 1 +// be careful with changing HW versions. avrstudio does not like all numbers: +#define CONFIG_PARAM_HW_VER 2 +// update here our own default sw version: +#define D_CONFIG_PARAM_SW_MAJOR 2 +#define D_CONFIG_PARAM_SW_MINOR 4 +#define CONFIG_PARAM_VTARGET 50 +#define CONFIG_PARAM_VADJUST 25 +#define CONFIG_PARAM_OSC_PSCALE 2 +#define CONFIG_PARAM_OSC_CMATCH 1 + +// you can change the CONFIG_PARAM_SW in terminal mode +#define EEPROM_MAJOR ((uint8_t*)2) +#define EEPROM_MINOR ((uint8_t*)1) +#define EEPROM_MAGIC ((uint8_t*)0) +uint8_t CONFIG_PARAM_SW_MAJOR; +uint8_t CONFIG_PARAM_SW_MINOR; +const char terminal_init[] PROGMEM = {"\x1B[0m\x1B[2J\x1B[0;0f"}; + +#define MSG_IDLE 0 +#define MSG_WAIT_SEQNUM 1 +#define MSG_WAIT_SIZE1 2 +#define MSG_WAIT_SIZE2 3 +#define MSG_WAIT_TOKEN 4 +#define MSG_WAIT_MSG 5 +#define MSG_WAIT_CKSUM 6 + +static unsigned char msg_buf[295]; +static unsigned char param_reset_polarity=1; // 1=avr (reset active=low), 0=at89 (not supported by this avrusb500) +static unsigned char param_controller_init=0; +unsigned long address=0; +unsigned long saddress=0; + +/* transmit an answer back to the programmer software, message is + * in msg_buf, seqnum is the seqnum of the last message from the programmer software, + * len=1..275 according to avr068 */ +void transmit_answer(unsigned char seqnum,unsigned int len) +{ + unsigned char cksum; + unsigned char ch; + int i; + if (len>285 || len <1){ + // software error + len = 2; + // msg_buf[0]: not changed + msg_buf[1] = STATUS_CMD_FAILED; + } + uart_sendchar(MESSAGE_START); // 0x1B + cksum = MESSAGE_START^0; + uart_sendchar(seqnum); + cksum^=seqnum; + ch=(len>>8)&0xFF; + uart_sendchar(ch); + cksum^=ch; + ch=len&0xFF; + uart_sendchar(ch); + cksum^=ch; + uart_sendchar(TOKEN); // 0x0E + cksum^=TOKEN; + wd_kick(); + for(i=0;i 48){ + msg_buf[4]=48; + } + if (msg_buf[5] < 1){ + // minimum byteDelay + msg_buf[5]=1; + } + while(i 32){ + msg_buf[4]=32; + } + saddress=address; // previous address, start address + nbytes = ((unsigned int)msg_buf[1])<<8; + nbytes |= msg_buf[2]; + if (nbytes> 280){ + // corrupted message + answerlen = 2; + msg_buf[1] = STATUS_CMD_FAILED; + break; + } + wd_kick(); + // store the original mode: + tmp2=msg_buf[3]; + // result code + cstatus=STATUS_CMD_OK; + // msg_buf[3] test Word/Page Mode bit: + if ((msg_buf[3]&1)==0){ + // word mode + for(i=0;i 280){ + nbytes=280; + } + // + for(i=0;i= tmp2 && ci = '0') && (ch <= '9'))||((ch >= 'A') && (ch <= 'F'))||((ch >= 'a') && (ch <= 'f'))){ + if (rval==0xff){ + rval=0; + } + uart_sendchar(ch); // echo number back to terminal + if((ch >= '0') && (ch <= '9')) { + rval=rval*16 + (ch - (unsigned char)'0'); + } else if ((ch >= 'A') && (ch <= 'F')){ + rval=rval*16 + (ch - (unsigned char)'A' + 10); + } else { + rval=rval*16 + (ch - (unsigned char)'a' + 10); + } + digits--; + } + ch=uart_getchar(1); + } + // user just pressed return or enter just 1 digit + if (ch == '\r' || ch == '\n'){ + lineendcnt--; + } + // get \n or \r\n after a number was entered: + while(lineendcnt){ + ch=uart_getchar(1); + lineendcnt--; + } + return(rval); +} + +void terminalmode_next_line(void) +{ + uart_sendchar('\x1B'); + uart_sendchar('E'); +} + +void terminalmode(unsigned char chr_nl) +{ + unsigned char i; + // Init terminal + uart_sendstr_p(terminal_init); + // + uart_sendstr_P("AvrUsb500-1.5 terminal mode\r\n"); + uart_sendstr_P("Enter SW Version Major in hex ["); + utoa(CONFIG_PARAM_SW_MAJOR,(char *)msg_buf, 16); + uart_sendstr((char *)msg_buf); + uart_sendstr_P("]: "); + i=terminalmode_readnum(chr_nl); + if (i!=0xff){ + CONFIG_PARAM_SW_MAJOR=(unsigned char)i; + } + terminalmode_next_line(); + uart_sendstr_P("Enter SW Version Minor in hex ["); + utoa(CONFIG_PARAM_SW_MINOR,(char *)msg_buf, 16); + uart_sendstr((char *)msg_buf); + uart_sendstr_P("]: "); + i=terminalmode_readnum(chr_nl); + if (i!=0xff){ + CONFIG_PARAM_SW_MINOR=i; + } + terminalmode_next_line(); + eeprom_write_byte(EEPROM_MINOR, CONFIG_PARAM_SW_MINOR); + eeprom_write_byte(EEPROM_MAJOR, CONFIG_PARAM_SW_MAJOR); + eeprom_write_byte(EEPROM_MAGIC, 20);// magic number=data is valid + uart_sendstr_P("\r\nOK, my SW version is now: "); + utoa(CONFIG_PARAM_SW_MAJOR,(char *)msg_buf, 16); + uart_sendstr((char *)msg_buf); + uart_sendchar('.'); + if (CONFIG_PARAM_SW_MINOR < 16){ + uart_sendchar('0'); + } + utoa(CONFIG_PARAM_SW_MINOR,(char *)msg_buf, 16); + uart_sendstr((char *)msg_buf); + uart_sendstr_P(" (hex)\r\n"); + uart_sendstr_P("Ready. Just close the terminal. No reset needed.\r\n"); +} + +int main(void) +{ + unsigned char ch; + unsigned char prev_ch=0; + unsigned char chr_nl=0; + unsigned char msgparsestate; + unsigned char cksum=0; + unsigned char seqnum=0; + int msglen=0; + int i=0; + uart_init(); + wd_init(); + LED_INIT; + LED_OFF; + sei(); + msgparsestate=MSG_IDLE; + // default values: + CONFIG_PARAM_SW_MINOR=D_CONFIG_PARAM_SW_MINOR; + CONFIG_PARAM_SW_MAJOR=D_CONFIG_PARAM_SW_MAJOR; + if (eeprom_read_byte((uint8_t *)EEPROM_MAGIC) == 20){ + // ok magic number matches accept values + CONFIG_PARAM_SW_MINOR=eeprom_read_byte(EEPROM_MINOR); + CONFIG_PARAM_SW_MAJOR=eeprom_read_byte(EEPROM_MAJOR); + } + while(1){ + if (msgparsestate==MSG_IDLE){ + ch=uart_getchar(1); + }else{ + ch=uart_getchar(0); + } + // parse message according to appl. note AVR068 table 3-1: + if (msgparsestate==MSG_IDLE && ch == MESSAGE_START){ + msgparsestate=MSG_WAIT_SEQNUM; + cksum = ch^0; + continue; + } + // The special avrusb500 terminal mode. + // Just connect a serial terminal and press enter twice. + // Both Windows and Linux send normally \r (=0xd) as the + // only line end character. It is however possible to configure + // \r\n as line end in some serial terminals. Therefore we + // must handle it. + if (msgparsestate==MSG_IDLE && (ch == '\r'||ch == '\n')){ + i++; + if(chr_nl ==0 && ch=='\n' && prev_ch== '\r'){ + // terminal sends \r\n for new line + chr_nl=1; + } + prev_ch=ch; + if (chr_nl){ + // wait for \r\n \r\n + if (i==4){ + terminalmode(1); + i=0; + } + }else{ + // Linux wait for \n\n + if (i==2){ + terminalmode(0); + i=0; + } + } + continue; + } + if (msgparsestate==MSG_WAIT_SEQNUM){ + seqnum=ch; + cksum^=ch; + msgparsestate=MSG_WAIT_SIZE1; + continue; + } + if (msgparsestate==MSG_WAIT_SIZE1){ + cksum^=ch; + msglen=ch<<8; + msgparsestate=MSG_WAIT_SIZE2; + continue; + } + if (msgparsestate==MSG_WAIT_SIZE2){ + cksum^=ch; + msglen|=ch; + msgparsestate=MSG_WAIT_TOKEN; + continue; + } + if (msgparsestate==MSG_WAIT_TOKEN){ + cksum^=ch; + if (ch==TOKEN){ + msgparsestate=MSG_WAIT_MSG; + i=0; + }else{ + msgparsestate=MSG_IDLE; + } + continue; + } + if (msgparsestate==MSG_WAIT_MSG && i 0){ + // message correct, process it + wdt_reset(); //wd_kick(); + programcmd(seqnum); + }else{ + msg_buf[0] = ANSWER_CKSUM_ERROR; + msg_buf[1] = STATUS_CKSUM_ERROR; + transmit_answer(seqnum,2); + } + // no continue here, set state=MSG_IDLE + } + msgparsestate=MSG_IDLE; + msglen=0; + seqnum=0; + prev_ch=0; + i=0; + } + return(0); +} + diff --git a/Tools/avrMultiTool/Stk500/spi.c b/Tools/avrMultiTool/Stk500/spi.c new file mode 100644 index 0000000..1b93e71 --- /dev/null +++ b/Tools/avrMultiTool/Stk500/spi.c @@ -0,0 +1,191 @@ +/* vim: set sw=8 ts=8 si et: */ +/********************************************* +* Serial Peripheral Interface +* Author: Guido Socher, Copyright: GPL +* Copyright: GPL +**********************************************/ +#include +#include "avr_compat.h" +#include "timeout.h" +// timing for software spi: +#define F_CPU 3686400UL // 3.6864 MHz +#include +static unsigned char sck_dur=1; +static unsigned char spi_in_sw=0; +//static unsigned char sck_dur=12; +//static unsigned char spi_in_sw=1; + +// set the speed (used by PARAM_SCK_DURATION, page 31 in AVR068) +// For a clock of 3.6864MHz this is: +// SPI2X SPR1 SPR0 divider result_spi_Freq avrisp dur +// 0 0 0 f/4 921KHz : sckdur =0 +// 0 0 1 f/16 230KHz : sckdur =1 +// 0 1 0 f/64 57KHz : sckdur =2 +// 0 1 1 f/128 28KHz : sckdur =3 +// +//SPI2X=SPSR bit 0 +//SPR0 and SPR1 =SPCR bit 0 and 1 +unsigned char spi_set_sck_duration(unsigned char dur) +{ + spi_in_sw=0; + if (dur >= 4){ + // sofware spi very slow + spi_in_sw=1; + sck_dur=12; + return(sck_dur); + } + if (dur >= 3){ + // 28KHz + cbi(SPSR,SPI2X); + sbi(SPCR,SPR1); + sbi(SPCR,SPR0); + sck_dur=3; + return(sck_dur); + } + if (dur >= 2){ + // 57KHz + cbi(SPSR,SPI2X); + sbi(SPCR,SPR1); + cbi(SPCR,SPR0); + sck_dur=2; + return(sck_dur); + } + if (dur == 1){ + // 230KHz + cbi(SPSR,SPI2X); + cbi(SPCR,SPR1); + sbi(SPCR,SPR0); + sck_dur=1; + return(sck_dur); + } + if (dur == 0){ + // 921KHz + cbi(SPSR,SPI2X); + cbi(SPCR,SPR0); + cbi(SPCR,SPR1); + sck_dur=0; + return(sck_dur); + } + return(1); // we should never come here +} + +unsigned char spi_get_sck_duration(void) +{ + return(sck_dur); +} + +void spi_sck_pulse(void) +{ + uint8_t spcrval; + spcrval=SPCR; // store old value + SPCR=0x00; // SPI off + cbi(PORTB,PB5); // SCK low + _delay_ms(0.10); + sbi(PORTB,PB5); // SCK high + _delay_ms(0.10); + cbi(PORTB,PB5); // SCK low + SPCR=spcrval; +} + +void spi_reset_pulse(void) +{ + /* give a positive RESET pulse, we can't guarantee + * that SCK was low during power up (see Atmel's + * data sheets, search for "Serial Downloading in e.g atmega8 + * data sheet): + * the programmer can not guarantee that SCK is held low during + * Power-up. In this case, RESET must be given a positive pulse of at least two + * CPU clock cycles duration after SCK has been set to 0."*/ + PORTB|= (1<>1; + } + return(rval); +} + +// send 16 bit, return last rec byte +unsigned char spi_mastertransmit_16(unsigned int data) +{ + spi_mastertransmit((data>>8)&0xFF); + return(spi_mastertransmit(data&0xFF)); +} + +// send 32 bit, return last rec byte +unsigned char spi_mastertransmit_32(unsigned long data) +{ + spi_mastertransmit((data>>24)&0xFF); + spi_mastertransmit((data>>16)&0xFF); + spi_mastertransmit((data>>8)&0xFF); + return(spi_mastertransmit(data&0xFF)); +} + + +void spi_disable(void) +{ + SPCR=0x00; // SPI off + sbi(PORTB,PB2);// reset = high, off + cbi(DDRB,PB3); // MOSI high impedance, input + cbi(PORTB,PINB3);// pullup off + cbi(DDRB,PB5); // SCK high impedance, input + cbi(PORTB,PINB5);// pullup off + // + cbi(DDRB,PINB2); // reset pin as input, high impedance + cbi(PORTB,PINB2);// pullup off +} + diff --git a/Tools/avrMultiTool/Stk500/spi.h b/Tools/avrMultiTool/Stk500/spi.h new file mode 100644 index 0000000..f77711e --- /dev/null +++ b/Tools/avrMultiTool/Stk500/spi.h @@ -0,0 +1,20 @@ +/* vim: set sw=8 ts=8 si et: */ +/************************************************************************* + Title: C include file for spi + Target: atmega8 + Copyright: GPL +***************************************************************************/ +#ifndef SPI_H +#define SPI_H + +extern void spi_init(void); +extern unsigned char spi_set_sck_duration(unsigned char dur); +extern unsigned char spi_get_sck_duration(void); +extern unsigned char spi_mastertransmit(unsigned char data); +extern unsigned char spi_mastertransmit_16(unsigned int data); +extern unsigned char spi_mastertransmit_32(unsigned long data); +extern void spi_disable(void); +extern void spi_reset_pulse(void); +extern void spi_sck_pulse(void); + +#endif /* SPI_H */ diff --git a/Tools/avrMultiTool/Stk500/timeout.c b/Tools/avrMultiTool/Stk500/timeout.c new file mode 100644 index 0000000..ac26abb --- /dev/null +++ b/Tools/avrMultiTool/Stk500/timeout.c @@ -0,0 +1,40 @@ +/* vim: set sw=8 ts=8 si et: */ +/********************************************* +* Timer for timeout supervision of the stk 500 protocol +* Author: Guido Socher, Copyright: GPL +* Copyright: GPL +**********************************************/ + +//#include +#include +#include +#include +#include +#define F_CPU 3686400UL // 3.6864 MHz +#include +#include "avr_compat.h" + +void delay_ms(unsigned int ms) +/* delay for a minimum of */ +{ + // we use a calibrated macro. This is more + // accurate and not so much compiler dependent + // as self made code. + while(ms){ + _delay_ms(0.96); + ms--; + } +} + +void wd_init(void) +{ + // timeout the watchdog after 2 sec: + wdt_enable(WDTO_2S); +} + +void wd_kick(void) +{ + wdt_reset(); +} + + diff --git a/Tools/avrMultiTool/Stk500/timeout.h b/Tools/avrMultiTool/Stk500/timeout.h new file mode 100644 index 0000000..145a331 --- /dev/null +++ b/Tools/avrMultiTool/Stk500/timeout.h @@ -0,0 +1,14 @@ +/* vim: set sw=8 ts=8 si et: */ +/************************************************************************* + Title: C include file + Copyright: GPL +***************************************************************************/ +#ifndef TOUT_H +#define TOUT_H + +extern void delay_ms(unsigned int ms); +extern void wd_init(void); +extern void wd_kick(void); + + +#endif /* TOUT_H */ diff --git a/Tools/avrMultiTool/Stk500/ttydevinit1152.c b/Tools/avrMultiTool/Stk500/ttydevinit1152.c new file mode 100644 index 0000000..c165eeb --- /dev/null +++ b/Tools/avrMultiTool/Stk500/ttydevinit1152.c @@ -0,0 +1,41 @@ +/* vim: set sw=8 ts=8 si et: */ +/* Linux software to set the speed on the serial line +* Written by Guido Socher +* run this program like this: +* ttydevinit /dev/usb/tts/0 (for usb com1) and then use +* cat > /dev/usb/tts/0 to write or cat /dev/usb/tts/0 to read the answrers +*/ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + struct termios portset; + char *device; + int fd; + + if (argc != 2){ + printf("USAGE: ttydevinit1152 /dev/ttyUSB0\n"); + exit(0); + } + device=argv[1]; + + /* Set up io port correctly, and open it... */ + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) { + fprintf(stderr, "ERROR: open for %s failed.\n",device); + exit(1); + } + tcgetattr(fd, &portset); + cfmakeraw(&portset); + //cfsetospeed(&portset, B9600); /* speed */ + cfsetospeed(&portset, B115200); /* speed */ + //cfsetospeed(&portset, B19200); /* speed */ + tcsetattr(fd, TCSANOW, &portset); + close(fd); + return(0); +} diff --git a/Tools/avrMultiTool/Stk500/uart.c b/Tools/avrMultiTool/Stk500/uart.c new file mode 100644 index 0000000..425829e --- /dev/null +++ b/Tools/avrMultiTool/Stk500/uart.c @@ -0,0 +1,75 @@ +/* vim: set sw=8 ts=8 si et: */ +/********************************************* +* UART interface without interrupt +* Author: Guido Socher, Copyright: GPL +* Copyright: GPL +**********************************************/ +//#include +#include +#include +#include +#include "uart.h" +#include "avr_compat.h" +#include "timeout.h" + +void uart_init(void) +{ + // baud=1=115.2K only with an external 3.6864MHz crystal: + unsigned int baud=1; + UBRRH=(unsigned char) (baud >>8); + UBRRL=(unsigned char) (baud & 0xFF); + /* enable tx/rx and no interrupt on tx/rx */ + UCSRB = (1< + +extern void uart_init(void); +extern void uart_sendchar(char c); +extern void uart_sendstr(char *s); +extern void uart_sendstr_p(const prog_char *progmem_s); +extern unsigned char uart_getchar(unsigned char kickwd); +extern void uart_flushRXbuf(void); + +/* +** macros for automatically storing string constant in program memory +*/ +#ifndef P +#define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;}) +#endif +#define uart_sendstr_P(__s) uart_sendstr_p(P(__s)) + +#endif /* UART_H */ diff --git a/Tools/avrMultiTool/avrMultiTool.backup b/Tools/avrMultiTool/avrMultiTool.backup new file mode 100644 index 0000000..e086965 Binary files /dev/null and b/Tools/avrMultiTool/avrMultiTool.backup differ diff --git a/Tools/avrMultiTool/avrMultiTool.conf b/Tools/avrMultiTool/avrMultiTool.conf new file mode 100644 index 0000000..7767328 --- /dev/null +++ b/Tools/avrMultiTool/avrMultiTool.conf @@ -0,0 +1,10 @@ +vendor_id=0x0403 +product_id=0x6001 +max_power=100 +manufacturer="Adam Kaliszan" +product="AVR multi tool" +serial="1" +self_powered=false +remote_wakeup=false +filename=avrMultiTool.backup + diff --git a/Tools/avrMultiTool/flashFt232.sh b/Tools/avrMultiTool/flashFt232.sh new file mode 100755 index 0000000..a743196 --- /dev/null +++ b/Tools/avrMultiTool/flashFt232.sh @@ -0,0 +1,3 @@ +#!/bin/bash +sudo ftdi_eeprom --flash-eeprom avrMultiTool.conf + diff --git a/Tools/avrMultiTool/jtagICE/README.txt b/Tools/avrMultiTool/jtagICE/README.txt new file mode 100644 index 0000000..4f9cfb9 --- /dev/null +++ b/Tools/avrMultiTool/jtagICE/README.txt @@ -0,0 +1,17 @@ +Wgranie oprogramowania do mikrokontrolera AtMega16 + +Płytka ma 2 błędy :(. Należy je przed uruchomieniem progamatora JTAG skorygować. Na górnej stronie płytki do masy (najlepiej w prawym górnym rogu, gdzie jest przycisk reset) nalezy dolutować opornik 10 kilo omów. Drugi koniec opornika należy podłączyć (za pośrednictwem kynaru) do nóżki nr 12 (PD3). + +

+Drugi błąd należy skorygować rozcinając jedną ścieżkę na dolnej stronie płytki. NAstępnie nalezy kynarem podlutowac tą ścieżkę do innego wyjścia na złączu IDC10. +

+

Po skorygowniu błędów można przejść do uruchamiania programatora. Do wgrywania oprogramowania na procesor AtMega16 (ten co obsługuje programator JTAG ICE) złuży złącze J3. Jako programator można wykorzystać programator Stk500, który znajduje się na uruchamianej płytce. W tym celu należy połączyć ze sobą na wprowst złącza J2 i j3. Następnie należy przestawić zworki FT_RX i FT_TX na pozycję skrajnie lewe. Najpierw należy skonfigurować bezpieczniki, najlepiej za pomocą AVR Studio: +

    +
  • zewnÄ™trzny kwarc,
  • +
  • wÅ‚Ä…czony bootloader,
  • +
  • rozmiar kodu bootloadera: 1 kB.
  • +
+Następnie należy wgrać kod bootloadera. Jest on dostępny tutaj. +

+

Po wgraniu kodu bootloadera, przestawiamy zworki na pozycje skrajnie prawe. W AVR studio uruchamiany AVRProg i wybieramy obraz programatora JTAG do wgrania. Po wgraniu obrazu (za pomocą bootloadera) pojawi się informacja o błędzie. Należy ją zignorować, a następnie wyłączyć bootloader (wykorzystując programator STK500, należy pamiętać o przestawieniu zworek). Od tej pory mamy działający programator JTAG ICE. Dokłądniejszy opis jest zawarty na stronie: http://www.scienceprog.com/build-your-own-avr-jtagice-clone. +

diff --git a/Tools/avrMultiTool/jtagICE/flash.sh b/Tools/avrMultiTool/jtagICE/flash.sh new file mode 100755 index 0000000..2c6c586 --- /dev/null +++ b/Tools/avrMultiTool/jtagICE/flash.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ "$#" -ne 1 ]; +then + echo "usage: flash.sh SERIAL_PORT, e.g. flash.sh /dev/ttyUSB0" +else + echo "avrude -p atmega16 -P $1 -c stk500v2 -U lfuse:w:lfuse:w:0xCE:m -U hfuse:w:0xc98:m -U flash:w:boot.hex" + avrdude -p atmega16 -P $1 -c stk500v2 -U lfuse:w:0xCE:m -U hfuse:w:0xc98:m -U flash:w:boot.hex +fi + diff --git a/Tools/avrMultiToolv2/opis.txt b/Tools/avrMultiToolv2/opis.txt new file mode 100644 index 0000000..f319bf5 --- /dev/null +++ b/Tools/avrMultiToolv2/opis.txt @@ -0,0 +1,11 @@ +PORT A - JTAG +0 - TCK +1 - TDI +2 - TDO +3 - TMS + +PORT B - ISP +0 - SCK +1 - MOSI +2 - MISO +3 - RST diff --git a/Tools/netClient/.kdev4/udpClient.kdev4 b/Tools/netClient/.kdev4/udpClient.kdev4 new file mode 100644 index 0000000..1be135b --- /dev/null +++ b/Tools/netClient/.kdev4/udpClient.kdev4 @@ -0,0 +1,42 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x12\x00u\x00d\x00p\x00C\x00l\x00i\x00e\x00n\x00t) + +[CMake] +BuildDirs[$e]=$HOME/akme/Tools/netConsole +CMakeDir=/usr/share/cmake-2.8/Modules +Current CMake Binary=file:///usr/bin/cmake +CurrentBuildDir=file:///$HOME/akme/Tools/netConsole +CurrentInstallDir=. +ProjectRootRelative=./ + +[Launch] +Launch Configurations=Launch Configuration 0 + +[Launch][Launch Configuration 0] +Configured Launch Modes=execute +Configured Launchers=nativeAppLauncher +Name=New Native Application Configuration +Type=Native Application + +[Launch][Launch Configuration 0][Data] +Arguments= +Debugger Shell= +Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00) +Dependency Action=SudoInstall +Display Demangle Names=true +Display Static Members=true +EnvironmentGroup=default +GDB Path=gdb +Project Target=netConsole,netConsole +Remote GDB Config Script= +Remote GDB Run Script= +Remote GDB Shell Script= +Try Setting Breakpoints On Loading Libraries=true +Working Directory= +isExecutable=false + +[MakeBuilder] +Number Of Jobs=1 + +[Project] +VersionControlSupport=kdevsubversion diff --git a/Tools/netClient/CMakeCache.txt b/Tools/netClient/CMakeCache.txt new file mode 100644 index 0000000..f10eeb5 --- /dev/null +++ b/Tools/netClient/CMakeCache.txt @@ -0,0 +1,279 @@ +# This is the CMakeCache file. +# For build in directory: /media/truecrypt1/mgr/withCLI/svn/Tools/netClient +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + +//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or +// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. +CMAKE_BUILD_TYPE:STRING= + +//Enable/Disable color output during build. +CMAKE_COLOR_MAKEFILE:BOOL=ON + +//CXX compiler. +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//Flags used by the compiler during all build types. +CMAKE_CXX_FLAGS:STRING= + +//Flags used by the compiler during debug builds. +CMAKE_CXX_FLAGS_DEBUG:STRING=-g + +//Flags used by the compiler during release minsize builds. +CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the compiler during release builds (/MD /Ob1 /Oi +// /Ot /Oy /Gs will produce slightly less optimized but smaller +// files). +CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the compiler during Release with Debug Info builds. +CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g + +//C compiler. +CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc + +//Flags used by the compiler during all build types. +CMAKE_C_FLAGS:STRING= + +//Flags used by the compiler during debug builds. +CMAKE_C_FLAGS_DEBUG:STRING=-g + +//Flags used by the compiler during release minsize builds. +CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the compiler during release builds (/MD /Ob1 /Oi +// /Ot /Oy /Gs will produce slightly less optimized but smaller +// files). +CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the compiler during Release with Debug Info builds. +CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g + +//Flags used by the linker. +CMAKE_EXE_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/usr/local + +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make + +//Flags used by the linker during the creation of modules. +CMAKE_MODULE_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=netConsole + +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + +//Flags used by the linker during the creation of dll's. +CMAKE_SHARED_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//If set, runtime paths are not added when using shared libraries. +CMAKE_SKIP_RPATH:BOOL=NO + +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + +//If true, cmake will use relative paths in makefiles and projects. +CMAKE_USE_RELATIVE_PATHS:BOOL=OFF + +//If this value is on, makefiles will be generated without the +// .SILENT directive, and all commands will be echoed to the console +// during the make. This is useful for debugging only. With Visual +// Studio IDE projects all commands are done without /nologo. +CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE + +//Value Computed by CMake +netConsole_BINARY_DIR:STATIC=/media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +//Value Computed by CMake +netConsole_SOURCE_DIR:STATIC=/media/truecrypt1/mgr/withCLI/svn/Tools/netClient + + +######################## +# INTERNAL cache entries +######################## + +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_BUILD_TOOL +CMAKE_BUILD_TOOL-ADVANCED:INTERNAL=1 +//What is the target build tool cmake is generating for. +CMAKE_BUILD_TOOL:INTERNAL=/usr/bin/make +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/media/truecrypt1/mgr/withCLI/svn/Tools/netClient +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=8 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=3 +//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE +CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +CMAKE_CXX_COMPILER_WORKS:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS +CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG +CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL +CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE +CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO +CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +CMAKE_C_COMPILER_WORKS:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS +CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG +CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL +CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE +CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO +CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Result of TRY_COMPILE +CMAKE_DETERMINE_CXX_ABI_COMPILED:INTERNAL=TRUE +//Result of TRY_COMPILE +CMAKE_DETERMINE_C_ABI_COMPILED:INTERNAL=TRUE +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS +CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG +CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE +CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Start directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=. +//Install .so files without execute permission. +CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS +CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG +CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE +CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.8 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS +CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG +CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE +CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_RPATH +CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname +//ADVANCED property for variable: CMAKE_USE_RELATIVE_PATHS +CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE +CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 + diff --git a/Tools/netClient/CMakeFiles/CMakeCCompiler.cmake b/Tools/netClient/CMakeFiles/CMakeCCompiler.cmake new file mode 100644 index 0000000..2b06f62 --- /dev/null +++ b/Tools/netClient/CMakeFiles/CMakeCCompiler.cmake @@ -0,0 +1,44 @@ +SET(CMAKE_C_COMPILER "/usr/bin/gcc") +SET(CMAKE_C_COMPILER_ARG1 "") +SET(CMAKE_C_COMPILER_ID "GNU") +SET(CMAKE_C_PLATFORM_ID "Linux") + +SET(CMAKE_AR "/usr/bin/ar") +SET(CMAKE_RANLIB "/usr/bin/ranlib") +SET(CMAKE_LINKER "/usr/bin/ld") +SET(CMAKE_COMPILER_IS_GNUCC 1) +SET(CMAKE_C_COMPILER_LOADED 1) +SET(CMAKE_COMPILER_IS_MINGW ) +SET(CMAKE_COMPILER_IS_CYGWIN ) +IF(CMAKE_COMPILER_IS_CYGWIN) + SET(CYGWIN 1) + SET(UNIX 1) +ENDIF(CMAKE_COMPILER_IS_CYGWIN) + +SET(CMAKE_C_COMPILER_ENV_VAR "CC") + +IF(CMAKE_COMPILER_IS_MINGW) + SET(MINGW 1) +ENDIF(CMAKE_COMPILER_IS_MINGW) +SET(CMAKE_C_COMPILER_ID_RUN 1) +SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c) +SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) +SET(CMAKE_C_LINKER_PREFERENCE 10) + +# Save compiler ABI information. +SET(CMAKE_C_SIZEOF_DATA_PTR "4") +SET(CMAKE_C_COMPILER_ABI "ELF") + +IF(CMAKE_C_SIZEOF_DATA_PTR) + SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") +ENDIF(CMAKE_C_SIZEOF_DATA_PTR) + +IF(CMAKE_C_COMPILER_ABI) + SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") +ENDIF(CMAKE_C_COMPILER_ABI) + +SET(CMAKE_C_HAS_ISYSROOT "") + + +SET(CMAKE_C_IMPLICIT_LINK_LIBRARIES "c") +SET(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2;/usr/lib/i386-linux-gnu") diff --git a/Tools/netClient/CMakeFiles/CMakeCXXCompiler.cmake b/Tools/netClient/CMakeFiles/CMakeCXXCompiler.cmake new file mode 100644 index 0000000..7613c41 --- /dev/null +++ b/Tools/netClient/CMakeFiles/CMakeCXXCompiler.cmake @@ -0,0 +1,45 @@ +SET(CMAKE_CXX_COMPILER "/usr/bin/c++") +SET(CMAKE_CXX_COMPILER_ARG1 "") +SET(CMAKE_CXX_COMPILER_ID "GNU") +SET(CMAKE_CXX_PLATFORM_ID "Linux") + +SET(CMAKE_AR "/usr/bin/ar") +SET(CMAKE_RANLIB "/usr/bin/ranlib") +SET(CMAKE_LINKER "/usr/bin/ld") +SET(CMAKE_COMPILER_IS_GNUCXX 1) +SET(CMAKE_CXX_COMPILER_LOADED 1) +SET(CMAKE_COMPILER_IS_MINGW ) +SET(CMAKE_COMPILER_IS_CYGWIN ) +IF(CMAKE_COMPILER_IS_CYGWIN) + SET(CYGWIN 1) + SET(UNIX 1) +ENDIF(CMAKE_COMPILER_IS_CYGWIN) + +SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX") + +IF(CMAKE_COMPILER_IS_MINGW) + SET(MINGW 1) +ENDIF(CMAKE_COMPILER_IS_MINGW) +SET(CMAKE_CXX_COMPILER_ID_RUN 1) +SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) +SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) +SET(CMAKE_CXX_LINKER_PREFERENCE 30) +SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) + +# Save compiler ABI information. +SET(CMAKE_CXX_SIZEOF_DATA_PTR "4") +SET(CMAKE_CXX_COMPILER_ABI "ELF") + +IF(CMAKE_CXX_SIZEOF_DATA_PTR) + SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") +ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR) + +IF(CMAKE_CXX_COMPILER_ABI) + SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") +ENDIF(CMAKE_CXX_COMPILER_ABI) + +SET(CMAKE_CXX_HAS_ISYSROOT "") + + +SET(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c") +SET(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2;/usr/lib/i386-linux-gnu") diff --git a/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_C.bin b/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_C.bin new file mode 100755 index 0000000..b7710c0 Binary files /dev/null and b/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_C.bin differ diff --git a/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin b/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin new file mode 100755 index 0000000..0e039b8 Binary files /dev/null and b/Tools/netClient/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin differ diff --git a/Tools/netClient/CMakeFiles/CMakeDirectoryInformation.cmake b/Tools/netClient/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..ee39022 --- /dev/null +++ b/Tools/netClient/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,21 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Tools/netClient/CMakeFiles/CMakeOutput.log b/Tools/netClient/CMakeFiles/CMakeOutput.log new file mode 100644 index 0000000..69f6f4e --- /dev/null +++ b/Tools/netClient/CMakeFiles/CMakeOutput.log @@ -0,0 +1,250 @@ +The system is: Linux - 2.6.38-10-generic-pae - i686 +Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. +Compiler: /usr/bin/gcc +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" + +The C compiler identification is GNU, found in "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CompilerIdC/a.out" + +Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. +Compiler: /usr/bin/c++ +Build flags: +Id flags: + +The output was: +0 +CMakeCXXCompilerId.cpp:79:58: warning: deprecated conversion from string constant to ‘char*’ +CMakeCXXCompilerId.cpp:192:58: warning: deprecated conversion from string constant to ‘char*’ +CMakeCXXCompilerId.cpp:193:54: warning: deprecated conversion from string constant to ‘char*’ + + +Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" + +The CXX compiler identification is GNU, found in "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CompilerIdCXX/a.out" + +Determining if the C compiler works passed with the following output: +Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o +/usr/bin/gcc -o CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/testCCompiler.c +Linking C executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/gcc CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o -o cmTryCompileExec -rdynamic +make[2]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +make[1]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' + + +Detecting C compiler ABI info compiled with the following output: +Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o +/usr/bin/gcc -o CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c +Linking C executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/gcc -v CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/gcc +COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/lto-wrapper +Target: i686-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/i386-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu +Thread model: posix +gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) +COMPILER_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/ +LIBRARY_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../:/lib/:/usr/lib/:/usr/lib/i386-linux-gnu/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-mtune=generic' '-march=i686' + /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2 --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu -export-dynamic -dynamic-linker /lib/ld-linux.so.2 -z relro -o cmTryCompileExec /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2 -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../.. -L/usr/lib/i386-linux-gnu CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o +make[2]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +make[1]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' + + +Parsed C implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:/usr/bin/make "cmTryCompileExec/fast"] + ignore line: [make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build] + ignore line: [make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1] + ignore line: [Building C object CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o] + ignore line: [/usr/bin/gcc -o CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c] + ignore line: [Linking C executable cmTryCompileExec] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1] + ignore line: [/usr/bin/gcc -v CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/gcc] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/lto-wrapper] + ignore line: [Target: i686-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/i386-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ] + ignore line: [COMPILER_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../:/lib/:/usr/lib/:/usr/lib/i386-linux-gnu/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-mtune=generic' '-march=i686'] + link line: [ /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2 --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu -export-dynamic -dynamic-linker /lib/ld-linux.so.2 -z relro -o cmTryCompileExec /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2 -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../.. -L/usr/lib/i386-linux-gnu CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o] + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_i386] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib/ld-linux.so.2] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o] ==> ignore + arg [-L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] ==> dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] + arg [-L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] ==> dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] + arg [-L/usr/lib/i386-linux-gnu] ==> dir [/usr/lib/i386-linux-gnu] + arg [CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o] ==> ignore + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [-lc] ==> lib [c] + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o] ==> ignore + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + collapse dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] ==> [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] + collapse dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] ==> [/usr/lib/i386-linux-gnu] + collapse dir [/usr/lib/i386-linux-gnu] ==> [/usr/lib/i386-linux-gnu] + implicit libs: [c] + implicit dirs: [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2;/usr/lib/i386-linux-gnu] + + +Determining if the CXX compiler works passed with the following output: +Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/testCXXCompiler.cxx +Linking CXX executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o -o cmTryCompileExec -rdynamic +make[2]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +make[1]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' + + +Detecting CXX compiler ABI info compiled with the following output: +Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp +Linking CXX executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/c++ -v CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/lto-wrapper +Target: i686-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/i386-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu +Thread model: posix +gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) +COMPILER_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/ +LIBRARY_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../:/lib/:/usr/lib/:/usr/lib/i386-linux-gnu/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=i686' + /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2 --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu -export-dynamic -dynamic-linker /lib/ld-linux.so.2 -z relro -o cmTryCompileExec /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2 -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../.. -L/usr/lib/i386-linux-gnu CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o +make[2]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' +make[1]: Leaving directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp' + + +Parsed CXX implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:/usr/bin/make "cmTryCompileExec/fast"] + ignore line: [make[1]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build] + ignore line: [make[2]: Entering directory `/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/cmake -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/CMakeTmp/CMakeFiles 1] + ignore line: [Building CXX object CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Linking CXX executable cmTryCompileExec] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1] + ignore line: [/usr/bin/c++ -v CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/lto-wrapper] + ignore line: [Target: i686-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/i386-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ] + ignore line: [COMPILER_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../:/lib/:/usr/lib/:/usr/lib/i386-linux-gnu/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=i686'] + link line: [ /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2 --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu -export-dynamic -dynamic-linker /lib/ld-linux.so.2 -z relro -o cmTryCompileExec /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2 -L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../.. -L/usr/lib/i386-linux-gnu CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o] + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/collect2] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_i386] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib/ld-linux.so.2] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crti.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtbegin.o] ==> ignore + arg [-L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] ==> dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] + arg [-L/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] ==> dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] + arg [-L/usr/lib/i386-linux-gnu] ==> dir [/usr/lib/i386-linux-gnu] + arg [CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/crtend.o] ==> ignore + arg [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crtn.o] ==> ignore + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + collapse dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] ==> [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2] + collapse dir [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../..] ==> [/usr/lib/i386-linux-gnu] + collapse dir [/usr/lib/i386-linux-gnu] ==> [/usr/lib/i386-linux-gnu] + implicit libs: [stdc++;m;c] + implicit dirs: [/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2;/usr/lib/i386-linux-gnu] + + diff --git a/Tools/netClient/CMakeFiles/CMakeSystem.cmake b/Tools/netClient/CMakeFiles/CMakeSystem.cmake new file mode 100644 index 0000000..278db3c --- /dev/null +++ b/Tools/netClient/CMakeFiles/CMakeSystem.cmake @@ -0,0 +1,15 @@ + + +SET(CMAKE_SYSTEM "Linux-2.6.38-10-generic-pae") +SET(CMAKE_SYSTEM_NAME "Linux") +SET(CMAKE_SYSTEM_VERSION "2.6.38-10-generic-pae") +SET(CMAKE_SYSTEM_PROCESSOR "i686") + +SET(CMAKE_HOST_SYSTEM "Linux-2.6.38-10-generic-pae") +SET(CMAKE_HOST_SYSTEM_NAME "Linux") +SET(CMAKE_HOST_SYSTEM_VERSION "2.6.38-10-generic-pae") +SET(CMAKE_HOST_SYSTEM_PROCESSOR "i686") + +SET(CMAKE_CROSSCOMPILING "FALSE") + +SET(CMAKE_SYSTEM_LOADED 1) diff --git a/Tools/netClient/CMakeFiles/CompilerIdC/CMakeCCompilerId.c b/Tools/netClient/CMakeFiles/CompilerIdC/CMakeCCompilerId.c new file mode 100644 index 0000000..efa5677 --- /dev/null +++ b/Tools/netClient/CMakeFiles/CompilerIdC/CMakeCCompilerId.c @@ -0,0 +1,220 @@ +#ifdef __cplusplus +# error "A C++ compiler has been selected for C." +#endif + +#if defined(__18CXX) +# define ID_VOID_MAIN +#endif + +#if defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" + +#elif defined(__clang__) +# define COMPILER_ID "Clang" + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + +#elif defined(__SUNPRO_C) +# define COMPILER_ID "SunPro" + +#elif defined(__HP_cc) +# define COMPILER_ID "HP" + +#elif defined(__DECC) +# define COMPILER_ID "Compaq" + +#elif defined(__IBMC__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# elif __IBMC__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" + +#elif defined(__PATHSCALE__) +# define COMPILER_ID "PathScale" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +/* Analog Devices C++ compiler for Blackfin, TigerSHARC and + SHARC (21000) DSPs */ +# define COMPILER_ID "ADSP" + +/* IAR Systems compiler for embedded systems. + http://www.iar.com + Not supported yet by CMake +#elif defined(__IAR_SYSTEMS_ICC__) +# define COMPILER_ID "IAR" */ + +/* sdcc, the small devices C compiler for embedded systems, + http://sdcc.sourceforge.net */ +#elif defined(SDCC) +# define COMPILER_ID "SDCC" + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +# define PLATFORM_ID "Haiku" +/* Haiku also defines __BEOS__ so we must + put it prior to the check for __BEOS__ +*/ + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is becase + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; + (void)argv; + return require; +} +#endif diff --git a/Tools/netClient/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp b/Tools/netClient/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..4c2289b --- /dev/null +++ b/Tools/netClient/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,206 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + +#if defined(__COMO__) +# define COMPILER_ID "Comeau" + +#elif defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" + +#elif defined(__clang__) +# define COMPILER_ID "Clang" + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + +#elif defined(__IBMCPP__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# elif __IBMCPP__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" + +#elif defined(__PATHSCALE__) +# define COMPILER_ID "PathScale" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +/* Analog Devices C++ compiler for Blackfin, TigerSHARC and + SHARC (21000) DSPs */ +# define COMPILER_ID "ADSP" + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +# define PLATFORM_ID "Haiku" +/* Haiku also defines __BEOS__ so we must + put it prior to the check for __BEOS__ +*/ + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is becase + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + (void)argv; + return require; +} diff --git a/Tools/netClient/CMakeFiles/Makefile.cmake b/Tools/netClient/CMakeFiles/Makefile.cmake new file mode 100644 index 0000000..b8c290b --- /dev/null +++ b/Tools/netClient/CMakeFiles/Makefile.cmake @@ -0,0 +1,43 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# The generator used is: +SET(CMAKE_DEPENDS_GENERATOR "Unix Makefiles") + +# The top level Makefile was generated from the following files: +SET(CMAKE_MAKEFILE_DEPENDS + "CMakeCache.txt" + "CMakeFiles/CMakeCCompiler.cmake" + "CMakeFiles/CMakeCXXCompiler.cmake" + "CMakeFiles/CMakeSystem.cmake" + "CMakeLists.txt" + "/usr/share/cmake-2.8/Modules/CMakeCInformation.cmake" + "/usr/share/cmake-2.8/Modules/CMakeCXXInformation.cmake" + "/usr/share/cmake-2.8/Modules/CMakeCommonLanguageInclude.cmake" + "/usr/share/cmake-2.8/Modules/CMakeGenericSystem.cmake" + "/usr/share/cmake-2.8/Modules/CMakeSystemSpecificInformation.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU-C.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU-CXX.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU-C.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU-CXX.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux.cmake" + "/usr/share/cmake-2.8/Modules/Platform/UnixPaths.cmake" + ) + +# The corresponding makefile is: +SET(CMAKE_MAKEFILE_OUTPUTS + "Makefile" + "CMakeFiles/cmake.check_cache" + ) + +# Byproducts of CMake generate step: +SET(CMAKE_MAKEFILE_PRODUCTS + "CMakeFiles/CMakeDirectoryInformation.cmake" + ) + +# Dependency information for all targets: +SET(CMAKE_DEPEND_INFO_FILES + "CMakeFiles/netConsole.dir/DependInfo.cmake" + ) diff --git a/Tools/netClient/CMakeFiles/Makefile2 b/Tools/netClient/CMakeFiles/Makefile2 new file mode 100644 index 0000000..b8ccd86 --- /dev/null +++ b/Tools/netClient/CMakeFiles/Makefile2 @@ -0,0 +1,96 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# The main recursive all target +all: +.PHONY : all + +# The main recursive preinstall target +preinstall: +.PHONY : preinstall + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canoncical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +#============================================================================= +# Target rules for target CMakeFiles/netConsole.dir + +# All Build rule for target. +CMakeFiles/netConsole.dir/all: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/depend + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles 1 2 + @echo "Built target netConsole" +.PHONY : CMakeFiles/netConsole.dir/all + +# Include target in all. +all: CMakeFiles/netConsole.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +CMakeFiles/netConsole.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles 2 + $(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/netConsole.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles 0 +.PHONY : CMakeFiles/netConsole.dir/rule + +# Convenience name for target. +netConsole: CMakeFiles/netConsole.dir/rule +.PHONY : netConsole + +# clean rule for target. +CMakeFiles/netConsole.dir/clean: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/clean +.PHONY : CMakeFiles/netConsole.dir/clean + +# clean rule for target. +clean: CMakeFiles/netConsole.dir/clean +.PHONY : clean + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Tools/netClient/CMakeFiles/TargetDirectories.txt b/Tools/netClient/CMakeFiles/TargetDirectories.txt new file mode 100644 index 0000000..1a4baa9 --- /dev/null +++ b/Tools/netClient/CMakeFiles/TargetDirectories.txt @@ -0,0 +1 @@ +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles/netConsole.dir diff --git a/Tools/netClient/CMakeFiles/cmake.check_cache b/Tools/netClient/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/Tools/netClient/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/C.includecache b/Tools/netClient/CMakeFiles/netConsole.dir/C.includecache new file mode 100644 index 0000000..c2ffb89 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/C.includecache @@ -0,0 +1,60 @@ +#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) + +#IncludeRegexScan: ^.*$ + +#IncludeRegexComplain: ^$ + +#IncludeRegexTransform: + +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c +netconsole.h +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.h +vt100.h +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.h +stdio.h +- +string.h +- +sys/types.h +- +sys/socket.h +- +netinet/in.h +- +arpa/inet.h +- +netdb.h +- + +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.h +stdio.h +- +stdlib.h +- +termios.h +- +errno.h +- +unistd.h +- +string.h +- +sys/time.h +- +sys/types.h +- +sys/socket.h +- +arpa/inet.h +- +netinet/in.h +- +netdb.h +- +vt100.h +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.h + +/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.h +string.h +- + diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/DependInfo.cmake b/Tools/netClient/CMakeFiles/netConsole.dir/DependInfo.cmake new file mode 100644 index 0000000..a95a198 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/DependInfo.cmake @@ -0,0 +1,14 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "C" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_C + "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c" "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles/netConsole.dir/netconsole.c.o" + "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.c" "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles/netConsole.dir/vt100.c.o" + ) +SET(CMAKE_C_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/build.make b/Tools/netClient/CMakeFiles/netConsole.dir/build.make new file mode 100644 index 0000000..6d2fd16 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/build.make @@ -0,0 +1,127 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canoncical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +# Include any dependencies generated for this target. +include CMakeFiles/netConsole.dir/depend.make + +# Include the progress variables for this target. +include CMakeFiles/netConsole.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/netConsole.dir/flags.make + +CMakeFiles/netConsole.dir/netconsole.c.o: CMakeFiles/netConsole.dir/flags.make +CMakeFiles/netConsole.dir/netconsole.c.o: netconsole.c + $(CMAKE_COMMAND) -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/netConsole.dir/netconsole.c.o" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -o CMakeFiles/netConsole.dir/netconsole.c.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c + +CMakeFiles/netConsole.dir/netconsole.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/netConsole.dir/netconsole.c.i" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -E /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c > CMakeFiles/netConsole.dir/netconsole.c.i + +CMakeFiles/netConsole.dir/netconsole.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/netConsole.dir/netconsole.c.s" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -S /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c -o CMakeFiles/netConsole.dir/netconsole.c.s + +CMakeFiles/netConsole.dir/netconsole.c.o.requires: +.PHONY : CMakeFiles/netConsole.dir/netconsole.c.o.requires + +CMakeFiles/netConsole.dir/netconsole.c.o.provides: CMakeFiles/netConsole.dir/netconsole.c.o.requires + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/netconsole.c.o.provides.build +.PHONY : CMakeFiles/netConsole.dir/netconsole.c.o.provides + +CMakeFiles/netConsole.dir/netconsole.c.o.provides.build: CMakeFiles/netConsole.dir/netconsole.c.o +.PHONY : CMakeFiles/netConsole.dir/netconsole.c.o.provides.build + +CMakeFiles/netConsole.dir/vt100.c.o: CMakeFiles/netConsole.dir/flags.make +CMakeFiles/netConsole.dir/vt100.c.o: vt100.c + $(CMAKE_COMMAND) -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/netConsole.dir/vt100.c.o" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -o CMakeFiles/netConsole.dir/vt100.c.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.c + +CMakeFiles/netConsole.dir/vt100.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/netConsole.dir/vt100.c.i" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -E /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.c > CMakeFiles/netConsole.dir/vt100.c.i + +CMakeFiles/netConsole.dir/vt100.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/netConsole.dir/vt100.c.s" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -S /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.c -o CMakeFiles/netConsole.dir/vt100.c.s + +CMakeFiles/netConsole.dir/vt100.c.o.requires: +.PHONY : CMakeFiles/netConsole.dir/vt100.c.o.requires + +CMakeFiles/netConsole.dir/vt100.c.o.provides: CMakeFiles/netConsole.dir/vt100.c.o.requires + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/vt100.c.o.provides.build +.PHONY : CMakeFiles/netConsole.dir/vt100.c.o.provides + +CMakeFiles/netConsole.dir/vt100.c.o.provides.build: CMakeFiles/netConsole.dir/vt100.c.o +.PHONY : CMakeFiles/netConsole.dir/vt100.c.o.provides.build + +# Object files for target netConsole +netConsole_OBJECTS = \ +"CMakeFiles/netConsole.dir/netconsole.c.o" \ +"CMakeFiles/netConsole.dir/vt100.c.o" + +# External object files for target netConsole +netConsole_EXTERNAL_OBJECTS = + +netConsole: CMakeFiles/netConsole.dir/netconsole.c.o +netConsole: CMakeFiles/netConsole.dir/vt100.c.o +netConsole: CMakeFiles/netConsole.dir/build.make +netConsole: CMakeFiles/netConsole.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C executable netConsole" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/netConsole.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/netConsole.dir/build: netConsole +.PHONY : CMakeFiles/netConsole.dir/build + +CMakeFiles/netConsole.dir/requires: CMakeFiles/netConsole.dir/netconsole.c.o.requires +CMakeFiles/netConsole.dir/requires: CMakeFiles/netConsole.dir/vt100.c.o.requires +.PHONY : CMakeFiles/netConsole.dir/requires + +CMakeFiles/netConsole.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/netConsole.dir/cmake_clean.cmake +.PHONY : CMakeFiles/netConsole.dir/clean + +CMakeFiles/netConsole.dir/depend: + cd /media/truecrypt1/mgr/withCLI/svn/Tools/netClient && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /media/truecrypt1/mgr/withCLI/svn/Tools/netClient /media/truecrypt1/mgr/withCLI/svn/Tools/netClient /media/truecrypt1/mgr/withCLI/svn/Tools/netClient /media/truecrypt1/mgr/withCLI/svn/Tools/netClient /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles/netConsole.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : CMakeFiles/netConsole.dir/depend + diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/cmake_clean.cmake b/Tools/netClient/CMakeFiles/netConsole.dir/cmake_clean.cmake new file mode 100644 index 0000000..1d72dc5 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/netConsole.dir/netconsole.c.o" + "CMakeFiles/netConsole.dir/vt100.c.o" + "netConsole.pdb" + "netConsole" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang C) + INCLUDE(CMakeFiles/netConsole.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/depend.internal b/Tools/netClient/CMakeFiles/netConsole.dir/depend.internal new file mode 100644 index 0000000..be16ee1 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/depend.internal @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +CMakeFiles/netConsole.dir/netconsole.c.o + /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.c + /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netconsole.h + /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.h +CMakeFiles/netConsole.dir/vt100.c.o + /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.c + /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/vt100.h diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/depend.make b/Tools/netClient/CMakeFiles/netConsole.dir/depend.make new file mode 100644 index 0000000..ede6231 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/depend.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +CMakeFiles/netConsole.dir/netconsole.c.o: netconsole.c +CMakeFiles/netConsole.dir/netconsole.c.o: netconsole.h +CMakeFiles/netConsole.dir/netconsole.c.o: vt100.h + +CMakeFiles/netConsole.dir/vt100.c.o: vt100.c +CMakeFiles/netConsole.dir/vt100.c.o: vt100.h + diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/flags.make b/Tools/netClient/CMakeFiles/netConsole.dir/flags.make new file mode 100644 index 0000000..ae9cfa2 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile C with /usr/bin/gcc +C_FLAGS = + +C_DEFINES = + diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/link.txt b/Tools/netClient/CMakeFiles/netConsole.dir/link.txt new file mode 100644 index 0000000..eef030b --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/gcc CMakeFiles/netConsole.dir/netconsole.c.o CMakeFiles/netConsole.dir/vt100.c.o -o netConsole -rdynamic diff --git a/Tools/netClient/CMakeFiles/netConsole.dir/progress.make b/Tools/netClient/CMakeFiles/netConsole.dir/progress.make new file mode 100644 index 0000000..abadeb0 --- /dev/null +++ b/Tools/netClient/CMakeFiles/netConsole.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 1 +CMAKE_PROGRESS_2 = 2 + diff --git a/Tools/netClient/CMakeFiles/progress.marks b/Tools/netClient/CMakeFiles/progress.marks new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/Tools/netClient/CMakeFiles/progress.marks @@ -0,0 +1 @@ +2 diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/C.includecache b/Tools/netClient/CMakeFiles/udpConsole.dir/C.includecache new file mode 100644 index 0000000..1614e97 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/C.includecache @@ -0,0 +1,60 @@ +#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) + +#IncludeRegexScan: ^.*$ + +#IncludeRegexComplain: ^$ + +#IncludeRegexTransform: + +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c +udpconsole.h +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.h +vt100.h +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.h +stdio.h +- +string.h +- +sys/types.h +- +sys/socket.h +- +netinet/in.h +- +arpa/inet.h +- +netdb.h +- + +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.h +stdio.h +- +stdlib.h +- +termios.h +- +errno.h +- +unistd.h +- +string.h +- +sys/time.h +- +sys/types.h +- +sys/socket.h +- +arpa/inet.h +- +netinet/in.h +- +netdb.h +- +vt100.h +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.h + +/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.h +string.h +- + diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/DependInfo.cmake b/Tools/netClient/CMakeFiles/udpConsole.dir/DependInfo.cmake new file mode 100644 index 0000000..bafece4 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/DependInfo.cmake @@ -0,0 +1,14 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "C" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_C + "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c" "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/udpConsole.dir/udpconsole.c.o" + "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.c" "/media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/udpConsole.dir/vt100.c.o" + ) +SET(CMAKE_C_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/build.make b/Tools/netClient/CMakeFiles/udpConsole.dir/build.make new file mode 100644 index 0000000..7125fe3 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/build.make @@ -0,0 +1,127 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canoncical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient + +# Include any dependencies generated for this target. +include CMakeFiles/udpConsole.dir/depend.make + +# Include the progress variables for this target. +include CMakeFiles/udpConsole.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/udpConsole.dir/flags.make + +CMakeFiles/udpConsole.dir/udpconsole.c.o: CMakeFiles/udpConsole.dir/flags.make +CMakeFiles/udpConsole.dir/udpconsole.c.o: udpconsole.c + $(CMAKE_COMMAND) -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/udpConsole.dir/udpconsole.c.o" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -o CMakeFiles/udpConsole.dir/udpconsole.c.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c + +CMakeFiles/udpConsole.dir/udpconsole.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/udpConsole.dir/udpconsole.c.i" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -E /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c > CMakeFiles/udpConsole.dir/udpconsole.c.i + +CMakeFiles/udpConsole.dir/udpconsole.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/udpConsole.dir/udpconsole.c.s" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -S /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c -o CMakeFiles/udpConsole.dir/udpconsole.c.s + +CMakeFiles/udpConsole.dir/udpconsole.c.o.requires: +.PHONY : CMakeFiles/udpConsole.dir/udpconsole.c.o.requires + +CMakeFiles/udpConsole.dir/udpconsole.c.o.provides: CMakeFiles/udpConsole.dir/udpconsole.c.o.requires + $(MAKE) -f CMakeFiles/udpConsole.dir/build.make CMakeFiles/udpConsole.dir/udpconsole.c.o.provides.build +.PHONY : CMakeFiles/udpConsole.dir/udpconsole.c.o.provides + +CMakeFiles/udpConsole.dir/udpconsole.c.o.provides.build: CMakeFiles/udpConsole.dir/udpconsole.c.o +.PHONY : CMakeFiles/udpConsole.dir/udpconsole.c.o.provides.build + +CMakeFiles/udpConsole.dir/vt100.c.o: CMakeFiles/udpConsole.dir/flags.make +CMakeFiles/udpConsole.dir/vt100.c.o: vt100.c + $(CMAKE_COMMAND) -E cmake_progress_report /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/udpConsole.dir/vt100.c.o" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -o CMakeFiles/udpConsole.dir/vt100.c.o -c /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.c + +CMakeFiles/udpConsole.dir/vt100.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/udpConsole.dir/vt100.c.i" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -E /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.c > CMakeFiles/udpConsole.dir/vt100.c.i + +CMakeFiles/udpConsole.dir/vt100.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/udpConsole.dir/vt100.c.s" + /usr/bin/gcc $(C_DEFINES) $(C_FLAGS) -S /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.c -o CMakeFiles/udpConsole.dir/vt100.c.s + +CMakeFiles/udpConsole.dir/vt100.c.o.requires: +.PHONY : CMakeFiles/udpConsole.dir/vt100.c.o.requires + +CMakeFiles/udpConsole.dir/vt100.c.o.provides: CMakeFiles/udpConsole.dir/vt100.c.o.requires + $(MAKE) -f CMakeFiles/udpConsole.dir/build.make CMakeFiles/udpConsole.dir/vt100.c.o.provides.build +.PHONY : CMakeFiles/udpConsole.dir/vt100.c.o.provides + +CMakeFiles/udpConsole.dir/vt100.c.o.provides.build: CMakeFiles/udpConsole.dir/vt100.c.o +.PHONY : CMakeFiles/udpConsole.dir/vt100.c.o.provides.build + +# Object files for target udpConsole +udpConsole_OBJECTS = \ +"CMakeFiles/udpConsole.dir/udpconsole.c.o" \ +"CMakeFiles/udpConsole.dir/vt100.c.o" + +# External object files for target udpConsole +udpConsole_EXTERNAL_OBJECTS = + +udpConsole: CMakeFiles/udpConsole.dir/udpconsole.c.o +udpConsole: CMakeFiles/udpConsole.dir/vt100.c.o +udpConsole: CMakeFiles/udpConsole.dir/build.make +udpConsole: CMakeFiles/udpConsole.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C executable udpConsole" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/udpConsole.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/udpConsole.dir/build: udpConsole +.PHONY : CMakeFiles/udpConsole.dir/build + +CMakeFiles/udpConsole.dir/requires: CMakeFiles/udpConsole.dir/udpconsole.c.o.requires +CMakeFiles/udpConsole.dir/requires: CMakeFiles/udpConsole.dir/vt100.c.o.requires +.PHONY : CMakeFiles/udpConsole.dir/requires + +CMakeFiles/udpConsole.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/udpConsole.dir/cmake_clean.cmake +.PHONY : CMakeFiles/udpConsole.dir/clean + +CMakeFiles/udpConsole.dir/depend: + cd /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/CMakeFiles/udpConsole.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : CMakeFiles/udpConsole.dir/depend + diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/cmake_clean.cmake b/Tools/netClient/CMakeFiles/udpConsole.dir/cmake_clean.cmake new file mode 100644 index 0000000..81392e4 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/udpConsole.dir/udpconsole.c.o" + "CMakeFiles/udpConsole.dir/vt100.c.o" + "udpConsole.pdb" + "udpConsole" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang C) + INCLUDE(CMakeFiles/udpConsole.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/depend.internal b/Tools/netClient/CMakeFiles/udpConsole.dir/depend.internal new file mode 100644 index 0000000..60609d0 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/depend.internal @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +CMakeFiles/udpConsole.dir/udpconsole.c.o + /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.c + /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/udpconsole.h + /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.h +CMakeFiles/udpConsole.dir/vt100.c.o + /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.c + /media/truecrypt1/mgr/withCLI/svn/Tools/udpClient/vt100.h diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/depend.make b/Tools/netClient/CMakeFiles/udpConsole.dir/depend.make new file mode 100644 index 0000000..dcebafd --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/depend.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +CMakeFiles/udpConsole.dir/udpconsole.c.o: udpconsole.c +CMakeFiles/udpConsole.dir/udpconsole.c.o: udpconsole.h +CMakeFiles/udpConsole.dir/udpconsole.c.o: vt100.h + +CMakeFiles/udpConsole.dir/vt100.c.o: vt100.c +CMakeFiles/udpConsole.dir/vt100.c.o: vt100.h + diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/flags.make b/Tools/netClient/CMakeFiles/udpConsole.dir/flags.make new file mode 100644 index 0000000..ae9cfa2 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile C with /usr/bin/gcc +C_FLAGS = + +C_DEFINES = + diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/link.txt b/Tools/netClient/CMakeFiles/udpConsole.dir/link.txt new file mode 100644 index 0000000..8d33fd7 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/gcc CMakeFiles/udpConsole.dir/udpconsole.c.o CMakeFiles/udpConsole.dir/vt100.c.o -o udpConsole -rdynamic diff --git a/Tools/netClient/CMakeFiles/udpConsole.dir/progress.make b/Tools/netClient/CMakeFiles/udpConsole.dir/progress.make new file mode 100644 index 0000000..abadeb0 --- /dev/null +++ b/Tools/netClient/CMakeFiles/udpConsole.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 1 +CMAKE_PROGRESS_2 = 2 + diff --git a/Tools/netClient/CMakeLists.txt b/Tools/netClient/CMakeLists.txt new file mode 100644 index 0000000..59f5b03 --- /dev/null +++ b/Tools/netClient/CMakeLists.txt @@ -0,0 +1,6 @@ +PROJECT(netConsole) + +cmake_minimum_required(VERSION 2.8) + +ADD_EXECUTABLE(netConsole netconsole.c vt100.c) +INSTALL(TARGETS netConsole DESTINATION /usr/local/bin/) diff --git a/Tools/netClient/Makefile b/Tools/netClient/Makefile new file mode 100644 index 0000000..317f689 --- /dev/null +++ b/Tools/netClient/Makefile @@ -0,0 +1,232 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canoncical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /media/truecrypt1/mgr/withCLI/svn/Tools/netClient/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named netConsole + +# Build rule for target. +netConsole: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 netConsole +.PHONY : netConsole + +# fast build rule for target. +netConsole/fast: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/build +.PHONY : netConsole/fast + +netconsole.o: netconsole.c.o +.PHONY : netconsole.o + +# target to build an object file +netconsole.c.o: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/netconsole.c.o +.PHONY : netconsole.c.o + +netconsole.i: netconsole.c.i +.PHONY : netconsole.i + +# target to preprocess a source file +netconsole.c.i: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/netconsole.c.i +.PHONY : netconsole.c.i + +netconsole.s: netconsole.c.s +.PHONY : netconsole.s + +# target to generate assembly for a file +netconsole.c.s: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/netconsole.c.s +.PHONY : netconsole.c.s + +vt100.o: vt100.c.o +.PHONY : vt100.o + +# target to build an object file +vt100.c.o: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/vt100.c.o +.PHONY : vt100.c.o + +vt100.i: vt100.c.i +.PHONY : vt100.i + +# target to preprocess a source file +vt100.c.i: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/vt100.c.i +.PHONY : vt100.c.i + +vt100.s: vt100.c.s +.PHONY : vt100.s + +# target to generate assembly for a file +vt100.c.s: + $(MAKE) -f CMakeFiles/netConsole.dir/build.make CMakeFiles/netConsole.dir/vt100.c.s +.PHONY : vt100.c.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... netConsole" + @echo "... rebuild_cache" + @echo "... netconsole.o" + @echo "... netconsole.i" + @echo "... netconsole.s" + @echo "... vt100.o" + @echo "... vt100.i" + @echo "... vt100.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Tools/netClient/cmake_install.cmake b/Tools/netClient/cmake_install.cmake new file mode 100644 index 0000000..ed0c804 --- /dev/null +++ b/Tools/netClient/cmake_install.cmake @@ -0,0 +1,62 @@ +# Install script for directory: /media/truecrypt1/mgr/withCLI/svn/Tools/netClient + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/usr/local") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}/usr/local/bin/netConsole" AND + NOT IS_SYMLINK "$ENV{DESTDIR}/usr/local/bin/netConsole") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}/usr/local/bin/netConsole" + RPATH "") + ENDIF() + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/usr/local/bin/netConsole") +FILE(INSTALL DESTINATION "/usr/local/bin" TYPE EXECUTABLE FILES "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/netConsole") + IF(EXISTS "$ENV{DESTDIR}/usr/local/bin/netConsole" AND + NOT IS_SYMLINK "$ENV{DESTDIR}/usr/local/bin/netConsole") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}/usr/local/bin/netConsole") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") +ELSE(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +ENDIF(CMAKE_INSTALL_COMPONENT) + +FILE(WRITE "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/${CMAKE_INSTALL_MANIFEST}" "") +FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES}) + FILE(APPEND "/media/truecrypt1/mgr/withCLI/svn/Tools/netClient/${CMAKE_INSTALL_MANIFEST}" "${file}\n") +ENDFOREACH(file) diff --git a/Tools/netClient/install_manifest.txt b/Tools/netClient/install_manifest.txt new file mode 100644 index 0000000..d972e89 --- /dev/null +++ b/Tools/netClient/install_manifest.txt @@ -0,0 +1 @@ +/usr/local/bin/netConsole diff --git a/Tools/netClient/netClient.kdev4 b/Tools/netClient/netClient.kdev4 new file mode 100644 index 0000000..b8258d2 --- /dev/null +++ b/Tools/netClient/netClient.kdev4 @@ -0,0 +1,4 @@ +[Project] +Manager=KDevCMakeManager +Name=netClient +VersionControl= diff --git a/Tools/netClient/netConsole b/Tools/netClient/netConsole new file mode 100755 index 0000000..57b7e45 Binary files /dev/null and b/Tools/netClient/netConsole differ diff --git a/Tools/netClient/netconsole.c b/Tools/netClient/netconsole.c new file mode 100644 index 0000000..ae27bfe --- /dev/null +++ b/Tools/netClient/netconsole.c @@ -0,0 +1,434 @@ +/** + * Author Adam Kaliszan, Jakub Muszynski + * + * Creation: xx.2010 + * Modified: 30,08,2011 + * + * Version: 0.5 + * + * Simple TCP/UDP client for sending/receiving data on socket layer3: IPv4 or IPv6 + * + * Notice that it is very simple + * Reading stdin (0) and send it to remote ip + * + * Todo: Add some argv input validation; change strcmp(argv[1], "6t") to enum variable + */ + +#include "netconsole.h" +#include "vt100.h" + +int main(int argc, char **argv) +{ + local_port=2222; //to tylko po to, aby (jesli argc <5) if sprawdzajacy czy porty <1024 nie wysypal sie + if(argc<4 || argc>5) + { + fprintf(stderr, "Usage: %s [type] [options] \n", argv[0]); + fprintf(stderr, "4t - TCP_IPv4; 6t - TCP_IPv6; 4u - UDP_IPv4\n"); + fprintf(stderr, "Options UDP_IPv4: [ - optional]\n", argv[0]); + fprintf(stderr, "Options TCP_IPv4: \n", argv[0]); + fprintf(stderr, "Options TCP_IPv6: \n", argv[0]); + fprintf(stderr, "Example: ./netConsole 4u 192.168.4.4 2345 1234\n"); + fprintf(stderr, "Example: ./udpConsole 6t 2000::1111 2345\n"); + exit(EXIT_FAILURE); + } + //I found out, that local port is not required + if(argc > 4) + local_port=atoi(argv[4]); + remote_port=atoi(argv[3]); + if (argc > 1 && strcmp(argv[1], "6t")==0) + strcpy(server, argv[2]); + + memset(srv_addr, 0, 128); + memcpy(srv_addr, argv[2], strlen(argv[2])); + + if((local_port < 1024) || (remote_port < 1024)) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "\twhere shall be > 1023\n"); + exit(EXIT_FAILURE); + } + + struct termios attr; + struct termios *p=&attr; + int fd_term_in=fileno(stdin); + int fd_term_out=fileno(stdout); + + if(!flush_term(fd_term_in, p) ) + term_error(); + + char str[128]; + unsigned char buf3[sizeof(struct in6_addr)]; + + /** + * Here, depending on protocol type, create and open socket + */ + if(strcmp(argv[1], "4t")==0) + { + if ((fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + perror("socket"); + exit(EXIT_FAILURE); + } + memset((char *) &si_remote, 0, sizeof(si_remote)); + si_remote.sin_family = AF_INET; + si_remote.sin_port = htons(remote_port); + if (inet_aton(srv_addr, &si_remote.sin_addr)==0) + { + fprintf(stderr, "inet_pton() failed\n"); + } + if (connect(fd, (const struct sockaddr *)&si_remote, sizeof(si_remote))==-1) + { + printf("Failed to connect ip %s\r\n", inet_ntoa(si_remote.sin_addr)); + perror("connect"); + exit(EXIT_FAILURE); + } + } + else if(strcmp(argv[1], "6t")==0) + { + if ((fd=socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + perror("socket"); + exit(EXIT_FAILURE); + } + memset((char *) &si_remote6, 0, sizeof(si_remote6)); + si_remote6.sin6_family = AF_INET6; + si_remote6.sin6_port = htons(remote_port); + rc = inet_pton(AF_INET6, server, buf3); + if (rc != 1) /* valid IPv6 text address? */ + { + fprintf(stderr, "inet_pton() failed\n"); + } + if (inet_ntop(AF_INET6, buf3, str, INET6_ADDRSTRLEN) == NULL) { + perror("inet_ntop"); + exit(EXIT_FAILURE); + } + memcpy(&si_remote6.sin6_addr, buf3, sizeof(struct in6_addr)); + if (inet_ntop(AF_INET6, &si_remote6.sin6_addr, str, INET6_ADDRSTRLEN) == NULL) + { + perror("inet_ntop"); + exit(EXIT_FAILURE); + } + if (connect(fd, (const struct sockaddr *)&si_remote6, sizeof(si_remote6))==-1) + { + printf("Failed to connect ip \r\n"); + perror("connect"); + exit(EXIT_FAILURE); + } + } + else if(strcmp(argv[1], "4u")==0) + { + if ((fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) + { + perror("socket"); + exit(EXIT_FAILURE); + } + memset((char *) &si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_INET; + si_local.sin_port = htons(local_port); + si_local.sin_addr.s_addr = htonl(INADDR_ANY); + + memset((char *) &si_remote, 0, sizeof(si_local)); + si_remote.sin_family = AF_INET; + si_remote.sin_port = htons(remote_port); + if (inet_aton(srv_addr, &si_remote.sin_addr)==0) + { + fprintf(stderr, "inet_aton() failed\n"); + exit(EXIT_FAILURE); + } + if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local))==-1) + { + printf("Failed to bind ip %s\r\n", inet_ntoa(si_local.sin_addr)); + perror("bind"); + exit(EXIT_FAILURE); + } + } + else if(strcmp(argv[1], "4u")==0) + { + printf("Failed to prepare socket, check argv[1] - type\r\n"); + exit(EXIT_FAILURE); + } + + fd_set rfds; + struct timeval tv; + int retval; + +/* Obserwacja stdin (fd 0) i sprawdzanie kiedy ma wejście. */ + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(fd, &rfds); + + + while(1) + { + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(fd, &rfds); + /* Czekanie nie dłużej niż sekund. */ + tv.tv_sec = 5; + tv.tv_usec = 0; + retval = select(fd+1, &rfds, NULL, NULL, &tv); + /* Nie należy już polegać na wartości tv! */ + + if (retval) + { + if (FD_ISSET(0, &rfds)) + { + int odczytano = read(0, buf, BUFLEN); + if (odczytano == -1) + { + perror("read"); + exit(EXIT_FAILURE); + } + odczytano = strToVt100(buf, odczytano, buf2, BUFLEN); + if(strcmp(argv[1], "4u")==0) + { + if (sendto(fd, buf2, odczytano, 0, (struct sockaddr *)&si_remote, sizeof(si_remote))==-1) + { + perror("send"); + exit(EXIT_FAILURE); + } + } + else + { + if (send(fd, buf2, odczytano, 0)==-1) + { + perror("send"); + exit(EXIT_FAILURE); + } + } + } + if (FD_ISSET(fd, &rfds)) + { + memset(buf, 0, sizeof(char)*BUFLEN); + int odczytano = recv(fd, buf, BUFLEN, 0); + if (odczytano == -1) + { + perror("recvfrom()"); + exit(EXIT_FAILURE); + } + if (write(1, buf, odczytano) == -1) + { + perror("write to console"); + } + } + } + } + shutdown(fd, SHUT_RDWR); + close(fd); + return 0; +} + +int checktty(struct termios *p, int term_fd) +{ + struct termios ck; +return (tcgetattr(term_fd, &ck) == 0 && (p->c_lflag == ck.c_lflag) && (p->c_cc[VMIN] == ck.c_cc[VMIN]) && (p->c_cc[VTIME] == ck.c_cc[VMIN]) ); +} + +int flush_term(int term_fd, struct termios *p) +{ + struct termios newterm; + errno=0; + tcgetattr(term_fd, p); /* get current stty settings*/ + + newterm = *p; +// newterm.c_lflag &= ~(ECHO); + newterm.c_lflag &= ~(ECHO | ICANON); + newterm.c_cc[VMIN] = 0; + newterm.c_cc[VTIME] = 0; + + return(tcgetattr(term_fd, p) == 0 && tcsetattr(term_fd, TCSAFLUSH, &newterm) == 0 && checktty(&newterm, term_fd) != 0); +} + +void term_error(void) +{ + fprintf(stderr, "unable to set terminal characteristics\n"); + perror(""); + exit(1); +} + +#if 0 +http://publib.boulder.ibm.com/iseries/v5r2/ic2928/index.htm?info/rzab6/rzab6xip6client.htm + +/**************************************************************************/ +/* This is an IPv4 or IPv6 client. */ +/**************************************************************************/ + +/**************************************************************************/ +/* Header files needed for this sample program */ +/**************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************/ +/* Constants used by this program */ +/**************************************************************************/ +#define BUFFER_LENGTH 250 +#define FALSE 0 +#define SERVER_NAME "ServerHostName" + +/* Pass in 1 parameter which is either the */ +/* address or host name of the server, or */ +/* set the server name in the #define */ +/* SERVER_NAME. */ +void main(int argc, char *argv[]) +{ + /***********************************************************************/ + /* Variable and structure definitions. */ + /***********************************************************************/ + int sd=-1, rc, bytesReceived=0; + char buffer[BUFFER_LENGTH]; + char server[NETDB_MAX_HOST_NAME_LENGTH]; + char servport[] = "3005"; + struct in6_addr serveraddr; + struct addrinfo hints, *res=NULL; + + /***********************************************************************/ + /* A do/while(FALSE) loop is used to make error cleanup easier. The */ + /* close() of the socket descriptor is only done once at the very end */ + /* of the program along with the free of the list of addresses. */ + /***********************************************************************/ + do + { + /********************************************************************/ + /* If an argument was passed in, use this as the server, otherwise */ + /* use the #define that is located at the top of this program. */ + /********************************************************************/ + if (argc > 1) + strcpy(server, argv[1]); + else + strcpy(server, SERVER_NAME); + + memset(&hints, 0x00, sizeof(hints)); + hints.ai_flags = AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + /********************************************************************/ + /* Check if we were provided the address of the server using */ + /* inet_pton() to convert the text form of the address to binary */ + /* form. If it is numeric then we want to prevent getaddrinfo() */ + /* from doing any name resolution. */ + /********************************************************************/ + rc = inet_pton(AF_INET, server, &serveraddr); + if (rc == 1) /* valid IPv4 text address? */ + { + hints.ai_family = AF_INET; + hints.ai_flags |= AI_NUMERICHOST; + } + else + { + rc = inet_pton(AF_INET6, server, &serveraddr); + if (rc == 1) /* valid IPv6 text address? */ + { + + hints.ai_family = AF_INET6; + hints.ai_flags |= AI_NUMERICHOST; + } + } + /********************************************************************/ + /* Get the address information for the server using getaddrinfo(). */ + /********************************************************************/ + rc = getaddrinfo(server, servport, &hints, &res); + if (rc != 0) + { + printf("Host not found --> %s\n", gai_strerror(rc)); + if (rc == EAI_SYSTEM) + perror("getaddrinfo() failed"); + break; + } + + /********************************************************************/ + /* The socket() function returns a socket descriptor representing */ + /* an endpoint. The statement also identifies the address family, */ + /* socket type, and protocol using the information returned from */ + /* getaddrinfo(). */ + /********************************************************************/ + sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sd < 0) + { + perror("socket() failed"); + break; + } + /********************************************************************/ + /* Use the connect() function to establish a connection to the */ + /* server. */ + /********************************************************************/ + rc = connect(sd, res->ai_addr, res->ai_addrlen); + if (rc < 0) + { + /*****************************************************************/ + /* Note: the res is a linked list of addresses found for server. */ + /* If the connect() fails to the first one, subsequent addresses */ + /* (if any) in the list could be tried if desired. */ + /*****************************************************************/ + perror("connect() failed"); + break; + } + + /********************************************************************/ + /* Send 250 bytes of a's to the server */ + /********************************************************************/ + memset(buffer, 'a', sizeof(buffer)); + rc = send(sd, buffer, sizeof(buffer), 0); + if (rc < 0) + { + perror("send() failed"); + break; + } + + /********************************************************************/ + /* In this example we know that the server is going to respond with */ + /* the same 250 bytes that we just sent. Since we know that 250 */ + /* bytes are going to be sent back to us, we could use the */ + /* SO_RCVLOWAT socket option and then issue a single recv() and */ + /* retrieve all of the data. */ + /* */ + /* The use of SO_RCVLOWAT is already illustrated in the server */ + /* side of this example, so we will do something different here. */ + /* The 250 bytes of the data may arrive in separate packets, */ + /* therefore we will issue recv() over and over again until all */ + /* 250 bytes have arrived. */ + /********************************************************************/ + while (bytesReceived < BUFFER_LENGTH) + { + rc = recv(sd, & buffer[bytesReceived], + BUFFER_LENGTH - bytesReceived, 0); + if (rc < 0) + { + perror("recv() failed"); + break; + } + else if (rc == 0) + { + printf("The server closed the connection\n"); + break; + } + + /*****************************************************************/ + /* Increment the number of bytes that have been received so far */ + /*****************************************************************/ + bytesReceived += rc; + } + + } while (FALSE); + + /***********************************************************************/ + /* Close down any open socket descriptors */ + /***********************************************************************/ + if (sd != -1) + close(sd); + /***********************************************************************/ + /* Free any results returned from getaddrinfo */ + /***********************************************************************/ + if (res != NULL) + freeaddrinfo(res); +} + + + + +#endif diff --git a/Tools/netClient/netconsole.h b/Tools/netClient/netconsole.h new file mode 100644 index 0000000..50adaba --- /dev/null +++ b/Tools/netClient/netconsole.h @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vt100.h" + +#define BUFLEN 1024 + +struct sockaddr_in si_local;//I found out, that local port is not required - you can remove it if you like +struct sockaddr_in si_remote; +struct sockaddr_in6 si_remote6; +int fd; +int local_port; +int remote_port; +char buf[BUFLEN]; +char buf2[BUFLEN]; +char srv_addr[16]; + +char server[40]; +int rc; +struct in6_addr serveraddr; +struct addrinfo hints, *res=NULL; + + +/*void wait_and_exit(void);*/ +void term_error(void); +int flush_term(int term_fd, struct termios *p); +/*int keypress(int term_fd);*/ +int checktty(struct termios *p, int term_fd); diff --git a/Tools/netClient/vt100.c b/Tools/netClient/vt100.c new file mode 100644 index 0000000..2d2b348 --- /dev/null +++ b/Tools/netClient/vt100.c @@ -0,0 +1,64 @@ +#include "vt100.h" + +// defines +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_CR 0x0D +#define ASCII_LF 0x0A +#define ASCII_ESC 0x1B +#define ASCII_DEL 0x7F + +#define VT100_ARROWUP 'A' +#define VT100_ARROWDOWN 'B' +#define VT100_ARROWRIGHT 'C' +#define VT100_ARROWLEFT 'D' +#define VT100_ATTR_OFF 0 +#define VT100_BOLD 1 +#define VT100_USCORE 4 +#define VT100_BLINK 5 +#define VT100_REVERSE 7 +#define VT100_BOLD_OFF 21 +#define VT100_USCORE_OFF 24 +#define VT100_BLINK_OFF 25 +#define VT100_REVERSE_OFF 27 + + +int strToVt100(const char *srcBuf, int srcBufLen, char *dstBuf, int maxDstBufLen) +{ + int result = 0; + int i; + for (i=0; i < srcBufLen; i++) + { + switch (*srcBuf) + { + case ASCII_LF: + case ASCII_CR: +// *dstBuf++ = ASCII_ESC; +// *dstBuf++ = '['; + *dstBuf++ = ASCII_CR; +// result +=3; + result ++; + break; + case ASCII_DEL: +// *dstBuf++ = ASCII_ESC; +// *dstBuf++ = '['; + *dstBuf++ = ASCII_BS; +// result +=3; + result ++; + break; + default: + *dstBuf++ = *srcBuf; + result++; + break; + } + srcBuf++; + } + return result; +} + +int vt100Tostr(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen) +{ + strncpy(dstBuf, scrBuf, srcBufLen); + return srcBufLen; +} + diff --git a/Tools/netClient/vt100.h b/Tools/netClient/vt100.h new file mode 100644 index 0000000..658f2e8 --- /dev/null +++ b/Tools/netClient/vt100.h @@ -0,0 +1,5 @@ +#include + +int strToVt100(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen); + +int vt100Tostr(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen); diff --git a/Tools/serialCapture/serialCapture.c b/Tools/serialCapture/serialCapture.c new file mode 100644 index 0000000..9e6d80d --- /dev/null +++ b/Tools/serialCapture/serialCapture.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +/* Change to the baud rate of the port B2400, B9600, B19200, etc */ +#define SPEED B115200 +//#define SPEED B9600 + +/* Change to the serial port you want to use /dev/ttyUSB0, /dev/ttyS0, etc. */ +#define PORT "/dev/avrMultiTool" + +int main( ) +{ + int fd = open( PORT, O_RDONLY | O_NOCTTY ); + if (fd <0) + { + perror(PORT); exit(-1); + } + + struct termios options; + + bzero(&options, sizeof(options)); + options.c_cflag = SPEED | CS8 | CLOCAL | CREAD | CRTSCTS; + options.c_iflag = IGNPAR; +// options.c_lflag &= ~(ECHO | ICANON); + options.c_cc[VMIN] = 1; + options.c_cc[VTIME] = 0; + + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &options); + + + + int r; + unsigned char buf[255]; + int i; + while( 1 ) + { + r = read( fd, buf, 255 ); + if (r == 0) + continue; + printf("długość = %d (0x%02x)", r, r); + for(i=0; i \n", argv[0]); + exit(EXIT_FAILURE); + } + + memset(srv_addr, 0, 16); + memcpy(srv_addr, argv[1], strlen(argv[1])); + + local_port=atoi(argv[2]); + remote_port=atoi(argv[3]); + + if((local_port < 1024) || (remote_port < 1024)) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "\twhere shall be > 1023\n"); + exit(EXIT_FAILURE); + } + + struct termios attr; + struct termios *p=&attr; + int fd_term_in=fileno(stdin); + int fd_term_out=fileno(stdout); + + if(!flush_term(fd_term_in, p) ) + term_error(); + + if ((fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) + { + perror("socket"); + exit(EXIT_FAILURE); + } + + memset((char *) &si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_INET; + si_local.sin_port = htons(local_port); + si_local.sin_addr.s_addr = htonl(INADDR_ANY); + + memset((char *) &si_remote, 0, sizeof(si_local)); + si_remote.sin_family = AF_INET; + si_remote.sin_port = htons(remote_port); + if (inet_aton(srv_addr, &si_remote.sin_addr)==0) + { + fprintf(stderr, "inet_aton() failed\n"); + exit(EXIT_FAILURE); + } + + + if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local))==-1) + { + printf("Failed to bind ip %s\r\n", inet_ntoa(si_local.sin_addr)); + perror("bind"); + exit(EXIT_FAILURE); + } + + fd_set rfds; + struct timeval tv; + int retval; + +/* Obserwacja stdin (fd 0) i sprawdzanie kiedy ma wejście. */ + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(fd, &rfds); + + + while(1) + { + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(fd, &rfds); + /* Czekanie nie dłużej niż sekund. */ + tv.tv_sec = 5; + tv.tv_usec = 0; + retval = select(fd+1, &rfds, NULL, NULL, &tv); + /* Nie należy już polegać na wartości tv! */ + + if (retval) + { + if (FD_ISSET(0, &rfds)) + { + int odczytano = read(0, buf, BUFLEN); + if (odczytano == -1) + { + perror("read"); + exit(EXIT_FAILURE); + } + odczytano = strToVt100(buf, odczytano, buf2, BUFLEN); + if (sendto(fd, buf2, odczytano, 0, (struct sockaddr *)&si_remote, sizeof(si_remote))==-1) + { + perror("send"); + exit(EXIT_FAILURE); + } + } + if (FD_ISSET(fd, &rfds)) + { + memset(buf, 0, sizeof(char)*BUFLEN); + int odczytano = recv(fd, buf, BUFLEN, 0); + if (odczytano == -1) + { + perror("recvfrom()"); + exit(EXIT_FAILURE); + } + if (write(1, buf, odczytano) == -1) + { + perror("write to console"); + } + } + } + } + close(fd); + return 0; +} + +int checktty(struct termios *p, int term_fd) +{ + struct termios ck; +return (tcgetattr(term_fd, &ck) == 0 && (p->c_lflag == ck.c_lflag) && (p->c_cc[VMIN] == ck.c_cc[VMIN]) && (p->c_cc[VTIME] == ck.c_cc[VMIN]) ); +} + +int flush_term(int term_fd, struct termios *p) +{ + struct termios newterm; + errno=0; + tcgetattr(term_fd, p); /* get current stty settings*/ + + newterm = *p; +// newterm.c_lflag &= ~(ECHO); + newterm.c_lflag &= ~(ECHO | ICANON); + newterm.c_cc[VMIN] = 0; + newterm.c_cc[VTIME] = 0; + + return(tcgetattr(term_fd, p) == 0 && tcsetattr(term_fd, TCSAFLUSH, &newterm) == 0 && checktty(&newterm, term_fd) != 0); +} + +void term_error(void) +{ + fprintf(stderr, "unable to set terminal characteristics\n"); + perror(""); + exit(1); +} + diff --git a/Tools/udpClient/udpconsole.h b/Tools/udpClient/udpconsole.h new file mode 100644 index 0000000..a610cf4 --- /dev/null +++ b/Tools/udpClient/udpconsole.h @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vt100.h" + +#define BUFLEN 1024 + +struct sockaddr_in si_local; +struct sockaddr_in si_remote; +int fd; +int local_port; +int remote_port; +char buf[BUFLEN]; +char buf2[BUFLEN]; +char srv_addr[16]; + +/*void wait_and_exit(void);*/ +void term_error(void); +int flush_term(int term_fd, struct termios *p); +/*int keypress(int term_fd);*/ +int checktty(struct termios *p, int term_fd); diff --git a/Tools/udpClient/vt100.c b/Tools/udpClient/vt100.c new file mode 100644 index 0000000..2d2b348 --- /dev/null +++ b/Tools/udpClient/vt100.c @@ -0,0 +1,64 @@ +#include "vt100.h" + +// defines +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_CR 0x0D +#define ASCII_LF 0x0A +#define ASCII_ESC 0x1B +#define ASCII_DEL 0x7F + +#define VT100_ARROWUP 'A' +#define VT100_ARROWDOWN 'B' +#define VT100_ARROWRIGHT 'C' +#define VT100_ARROWLEFT 'D' +#define VT100_ATTR_OFF 0 +#define VT100_BOLD 1 +#define VT100_USCORE 4 +#define VT100_BLINK 5 +#define VT100_REVERSE 7 +#define VT100_BOLD_OFF 21 +#define VT100_USCORE_OFF 24 +#define VT100_BLINK_OFF 25 +#define VT100_REVERSE_OFF 27 + + +int strToVt100(const char *srcBuf, int srcBufLen, char *dstBuf, int maxDstBufLen) +{ + int result = 0; + int i; + for (i=0; i < srcBufLen; i++) + { + switch (*srcBuf) + { + case ASCII_LF: + case ASCII_CR: +// *dstBuf++ = ASCII_ESC; +// *dstBuf++ = '['; + *dstBuf++ = ASCII_CR; +// result +=3; + result ++; + break; + case ASCII_DEL: +// *dstBuf++ = ASCII_ESC; +// *dstBuf++ = '['; + *dstBuf++ = ASCII_BS; +// result +=3; + result ++; + break; + default: + *dstBuf++ = *srcBuf; + result++; + break; + } + srcBuf++; + } + return result; +} + +int vt100Tostr(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen) +{ + strncpy(dstBuf, scrBuf, srcBufLen); + return srcBufLen; +} + diff --git a/Tools/udpClient/vt100.h b/Tools/udpClient/vt100.h new file mode 100644 index 0000000..658f2e8 --- /dev/null +++ b/Tools/udpClient/vt100.h @@ -0,0 +1,5 @@ +#include + +int strToVt100(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen); + +int vt100Tostr(const char *scrBuf, int srcBufLen, char *dstBuf, int maxDstBufLen);